3

I have a jquery click event for a bunch of links and one drop-down selector in my MVC view and I preventDefault on them before doing the event, because most of them redirect to a view (the redirect stops my jquery code doesn't it?). After all of my callbacks in my click event, I would like the links and drop-down selector to do their default event so it doesn't just sit on the page like nothing has happened.

Is there an easy way to get all of the links/drop-down to return to default and then programatically click them in jquery? I've tried $(this).click() and $(this).submit() and e.click() and e.submit() with no luck.

Here is my code

 $("input,a,select").not("#SubmitButton").click(function (e) {
        e.preventDefault();
        console.log("prevented default");
        deletePreview($(this));
    });
    function deletePreview(button) {
        console.log("clicked");
        //Delete Offer from DB
        $.post('@Url.Content("~/")Offer/DeleteJoAnnOffer/?offerId=' + offerID, function (data) {
              console.log("finished deleting");
              if (button.attr('id') == "CancelButton") {
                 window.location.href = '@Url.Content("~/")Offer/CreateJoAnn/';
              } else {

                  //DO DEFAULT ACTION HERE

              }
       });
    };

[EDIT]: One more question: If I don't use preventDefault(), my jquery event executes (well the initial part because my console logs "clicked"), but I cannot confirm if the jquery posts are actually executing because the console refreshes on the new page.

Evan Layman
  • 3,691
  • 9
  • 31
  • 48
  • good question. I would like to know this too :) – cmplieger Aug 17 '11 at 22:07
  • possible duplicate of [How to reenable event.preventDefault?](http://stackoverflow.com/questions/1164132/how-to-reenable-event-preventdefault) – John Flatness Aug 17 '11 at 22:14
  • for second question: if post execution is not fast enough, it's request can get cancelled (request aborted). So it might or might not get executed. If you turn your ajax request into synchronous, you won't have this problem. – longchiwen Aug 17 '11 at 23:58

2 Answers2

2

"post" function in jquery is async operation (async flag is true by default). Your code inside click event will execute in full before page will reload so there is no need to use preventDefault. You have to change post function in deletePreview to be synchronous:

        $("input,a,select").not("#SubmitButton").click(function (e) {
             console.log("you do not need to call prevented default :)");
             deletePreview($(this));
         });
         function deletePreview(button) {
             console.log("clicked");
             //Delete Offer from DB
             $.ajax('@Url.Content("~/")Offer/DeleteJoAnnOffer/?offerId=' + offerID,
             {
                 async: false,
                 success: function (data) {
                     console.log("finished deleting");
                     if (button.attr('id') == "CancelButton") {
                         window.location.href = '@Url.Content("~/")Offer/CreateJoAnn/';
                     } else {

                         //DO DEFAULT ACTION HERE

                     }
                 }
             });
         };

This means that code inside click event will wait until ajax call in deletePreview is completed.

See http://api.jquery.com/jQuery.ajax/ for explanation on async parameter

longchiwen
  • 822
  • 6
  • 11
  • I understand `$.post` is asynchronous, however by setting `async: false`, does this actually make the link wait on my click event to finish before doing its action? I thought that turning off `async` just makes the jquery code wait on that call. – Evan Layman Aug 18 '11 at 00:07
  • That is exactly what happens. And usually you want operations to be asynchronous. But if you want to ensure ajax request has completed, you must not navigate away from page. Navigating away will cause document to unload, which will cause underlying XMLHttpRequest object to get destroyed and cancelling any pending requests in the process. You can achieve this by either making operation synchronous, or to execute elements default action in "success" handler of ajax object. In both cases you will have to wait for ajax call to complete, but first option requires less coding and is more readable. – longchiwen Aug 18 '11 at 00:21
  • Great thanks I will try this out. If I have 5 nested $.post calls, I need to convert all 5 to synchronous ajax post calls, right? – Evan Layman Aug 18 '11 at 00:33
  • Yes. Or you can create one service function that will perform all 5 tasks (just some sort of wrapper function). This will be faster since you will only do one round trip to server. – longchiwen Aug 18 '11 at 00:44
  • After adding the type: "POST" parameter, it works! Thanks! I'll consider creating a wrapper function too. – Evan Layman Aug 18 '11 at 16:14
0

I think in your case you don't need to call the preventDefault, because your event handler will be executed first. (Maybe in the if you could call it when you want to navigate somewhere else.)

Tz_
  • 2,949
  • 18
  • 13
  • I do not want to preventDefault altogether, I just thought that since the page was redirecting before all of the console output, my posts were not being completed. Am I wrong in thinking this? – Evan Layman Aug 17 '11 at 23:22