79

I have a table style page with rows. Each row has a checkbox. I can select all/many checkboxes and click "submit" and what is does is a Jquery ajax call for each row.

Basically I have a form for each row and I iterate over all the checked rows and submit that form which does the jquery ajax call.

So I have a button that does:

       $("input:checked").parent("form").submit();

Then each row has:

            <form name="MyForm<%=i%>" action="javascript:processRow(<%=i%>)" method="post" style="margin:0px;">
                <input type="checkbox" name="X" value="XChecked"/>
                <input type="hidden" id="XNumber<%=i%>" name="X<%=i%>" value="<%=XNumber%>"/>
                <input type="hidden" id="XId<%=i%>" name="XId<%=i%>" value="<%=XNumber%>"/>
                <input type="hidden" id="XAmt<%=i%>" name="XAmt<%=i%>" value="<%=XAmount%>"/>
                <input type="hidden" name="X" value="rXChecked"/>
            </form>

This form submits to processRow:

   function processRow(rowNum)
   {
        var Amount = $('#XAmt'+rowNum).val();
        var XId = $('#XId'+rowNum).val();
        var XNum = $('#OrderNumber'+rowNum).val();
        var queryString = "xAmt=" + "1.00" + "&xNumber=" + OrdNum + "&xId=" + xId;


        $('#coda_'+rowNum).removeClass("loader");
        $('#coda_'+rowNum).addClass("loading");


        $.ajax({
          url: "x.asp",
          cache: false,
          type:  "POST",
          data:  queryString,
          success: function(html){
            $('#result_'+rowNum).empty().append(html);
            $('#coda_'+rowNum).removeClass("loading");
            $('#coda_'+rowNum).addClass("loader");
          }
        });
   }

What I wanted to know is, from this is there a way I can tell if all my Ajax calls are complete. Reason being that want to enable/disable the submit button while all these calls are taking place.

Thanks and please note that I had to mangle my variable names due to the sensitivity of the application, so many of them may be duplicated.

PhD
  • 11,202
  • 14
  • 64
  • 112
Brian G
  • 53,704
  • 58
  • 125
  • 140
  • 1
    While detecting when all ajax calls are complete has value for any design, I think a better overall solution is to submit multiple rows at once. Sending each row as a separate ajax post is going to be *really* hard on the system in some ways, and is not (in my opinion) the best design. I'll even go so far as to say that *I promise* that some day, if you stick to this design of one-ajax-call-per-row, you'll regret it. – ErikE Oct 05 '15 at 17:34
  • Apart from the design problem pointed out by @ErikE, I'm surprised no one mentioned use of Promises to answer the original question. – Delphi.Boy Jul 27 '16 at 21:17

4 Answers4

149

The easy way

The easiest way is to use the .ajaxStop() event handler:

$(document).ajaxStop(function() {
  // place code to be executed on completion of last outstanding ajax call here
});

The hard way

You can also manually detect if any ajax call is still active:

Create a variable containing number of active Ajax connections:

var activeAjaxConnections = 0;

just before opening new Ajax connection increment that variable

$.ajax({
  beforeSend: function(xhr) {
    activeAjaxConnections++;
  },
  url (...)

in success part check if that variable equals to zero (if so, the last connection has finished)

success: function(html){
  activeAjaxConnections--;
  $('#result_'+rowNum).empty().append(html);
  $('#coda_'+rowNum).removeClass("loading");
  $('#coda_'+rowNum).addClass("loader");
  if (0 == activeAjaxConnections) {
    // this was the last Ajax connection, do the thing
  }
},
error: function(xhr, errDesc, exception) {
  activeAjaxConnections--;
  if (0 == activeAjaxConnections) {
    // this was the last Ajax connection, do the thing
  }
}

As you can see, I've added also checking for return with error

Tomasz Tybulewicz
  • 8,487
  • 3
  • 42
  • 44
  • 4
    how can you remove the ajaxStop handler again after it has been triggered? – rob Dec 16 '13 at 14:12
  • http://stackoverflow.com/questions/3709597/wait-until-all-jquery-ajax-requests-are-done – techie_28 Aug 10 '16 at 10:32
  • 3
    Regarding 'The Hard way': There's no need to mantain a variable, Jquery already does this: $.active keeps the current number of active ajax calls – Sebastianb Aug 16 '16 at 13:38
  • Is there any way to figure out which Ajax call it was, if there were multiple at the same time? – Si8 Aug 17 '18 at 13:34
  • **The hard way** - this is safe? What if multiple success/error try `activeAjaxConnections--;` at the "same time"? – KunLun Jul 31 '19 at 16:01
26

A neat solution would be to use;

$("body").ajaxStop(function() {
    //Your code
});

For more information check out the jQuery .ajaxStop function at http://api.jquery.com/ajaxStop/

Orson
  • 14,981
  • 11
  • 56
  • 70
15

Maybe:

jQuery.active == 0

Stolen from:

http://artsy.github.com/blog/2012/02/03/reliably-testing-asynchronous-ui-w-slash-rspec-and-capybara/

More info on StackOverflow:

jQuery.active function

Community
  • 1
  • 1
nothing-special-here
  • 11,230
  • 13
  • 64
  • 94
-4

How about just simply use if?

success: function(html){
   if(html.success == true ){
            $('#result_'+rowNum).empty().append(html);
            $('#coda_'+rowNum).removeClass("loading");
            $('#coda_'+rowNum).addClass("loader");

          }
   }
Jaroslav
  • 1
  • 1