8

If I have an a tag:

<a id="delete-event" href="/delete/1234">Delete</a>

And some javascript which prompts to confirm the delete:

 $("#delete-event").click(function(e) {
    e.preventDefault();

    bootbox.confirm("Are you sure you wish to delete this?", function(confirmed) {
        if(confirmed) {
            return true;
        }
    }); 
});

I thought doing e.preventDefault() would prevent the a href from firing, but its not. When I click the a tag it simply goes to the url, without executing the javascript. How can I make this work?

Thanks.

Justin
  • 42,716
  • 77
  • 201
  • 296
  • Is your jQuery after the `a` is rendered to the page or within a `ready` event? – Brandon Jul 08 '12 at 00:37
  • Yeah, the JS above is inside $(document).ready() – Justin Jul 08 '12 at 00:37
  • If you get rid of the `bootbox.confirm()` just as a test, does it work? – Brandon Jul 08 '12 at 00:38
  • Replace the `bootbox.confirm` with just a JS alert to see if it even gets that far. I don't think `return true` will cause the link to fire after you've already done `preventDefault()` – sachleen Jul 08 '12 at 00:39
  • @sachleen You're probably right, replace `return true;` with `window.location = $('#delete-event').attr('href');` – Brandon Jul 08 '12 at 00:41
  • Is there a jQuery way to fire the event using the `e` object, without the hack of window.location? – Justin Jul 08 '12 at 00:42
  • @Justin I'm not sure, honestly, but I wouldn't consider using window.location a hack. I know you can use [`.trigger()`](http://api.jquery.com/trigger/) but that will execute your code again, too. – sachleen Jul 08 '12 at 00:54

5 Answers5

15

This code works:

You can't just do return true and expect the link to fire after you've done e.preventDefault(). I had to replace your bootbox.confirm() with a JS confirm but it should still work.

$("#delete-event").click(function(e) {
    e.preventDefault();
    var a = confirm("yes?");
    if(a) window.location = $('#delete-event').attr('href');
});​

DEMO

Try replacing your code block with the one I provided above. If that works, put your bootbox confirmation back in and try again. That'll tell you where the error is.

sachleen
  • 30,730
  • 8
  • 78
  • 73
7

It's better to prevent it only when needed. For example, if the user selected "Cancel" from the confirm box, then prevent the default.

$("#delete-event").click(function(e) {
    if (!confirm('Are you sure you wish to delete this?')) {
        e.preventDefault();
    } 
});​

Demo: http://jsfiddle.net/SCCDX/

Normally, when you need a confirm this is the best way to accomplish it, and it's event more useful for confirmations before submitting forms.

I am not sure if bootbox replicates the behavior of browsers when you ask for confirmation. So it may not work in this scenario. If that is the case a better approach is to set a flag somewhere.

$("#delete-event").click(function(e) {
    if (!$(this).data('confirmed')) {
       e.preventDefault()
    } else {
       bootbox.confirm("Are you sure you wish to delete this?", function(confirmed) {
          if(confirmed) {
              $(this).data('confirmed', 1).click();           
          }
       });        
    }
});​

// Disclaimer: This code is untested. clicking on the link may cause data loss. lol 

Somehow, I don't like the window.location method, cause it may cause any other events attached to this element to fail.

SMathew
  • 3,993
  • 1
  • 18
  • 10
2

I met this problem too.

You can use window.location make browser visit new page, but current page is not recorded in the browser history (at least with google chrome).

So I agree with SMathew that the new event should be triggered. But due to some security reason, the click event on anchors triggered by jQuery do not make browser visit new page. Finally I found the following code works.

$("a.confirm").on('click', function(e) {
    if (!$(this).data('confirmed')) {
        e.preventDefault();
        var a = this;
        bootbox.confirm("Are you sure?", "No", "Yes", function(result) {
            if(result) {
                $(a).data('confirmed', 1);
                if (document.createEvent) {
                    var evObj = document.createEvent('MouseEvents');
                    evObj.initEvent('click', true, true);
                    a.dispatchEvent(evObj);
                }
                else if (document.createEventObject) {
                    a.fireEvent('onclick');
                }
            }
        });
    }
});

I just test above code in google chrome, and I found fire event code from https://getsatisfaction.com/issuu/topics/opening_the_issuu_smartlook_viewer_with_my_flash_website?utm_content=topic_link&utm_medium=email&utm_source=reply_notification

MORE

I found this post https://stackoverflow.com/a/18132076/1194307 , and jQuery.simulate can be used to solve this problem. My final code looks like:

$("[data-toggle=confirm]").on('click', function(e) {
    var a = $(this);
    if (!a.data('confirmed')) {
        e.preventDefault();

        var question = a.data('question');
        if (!question) question = 'Are you sure?';

        var yes = a.data('yes');
        if (!yes) yes = 'Yes';

        var no = a.data('no');
        if (!no) no = 'No';

        bootbox.confirm(question, no, yes, function(result) {
            if(result) {
                a.data('confirmed', 1).simulate('click');
            }
        });
    }
});

It works on anchors and form buttons.

Community
  • 1
  • 1
lonecat
  • 309
  • 2
  • 5
0

You need to return false; for anchor tags.

See this jsFiddle.

Dean Brundage
  • 2,038
  • 18
  • 31
0

Try this code:

$(".SelectedPassengers").each(function () {
            debugger;

        if ($(this).text() == "") {
            debugger;
            var id = this.id.split('-');
            alert("Please Select Passenger " + id[1]);
            var h = "" + this.id;
          // $(this).preventDefault();
           //$('#' + h).focus();
           //this.preventDefault();
           stopEvent = "enter";
        }

    });
    if (stopEvent != "") {
        stopEvent = "";
        event.preventDefault();
        return false;
    }
Tristan
  • 3,301
  • 8
  • 22
  • 27