Question

I'm trying to slide a div containing a table up, change the rows of the table with ajax calls, and then slide the containing table back down. I can't seem to get the series of callbacks to work effectively.

$("div#grid").slideUp('fast', function() {
    //eaery row but the first
    $("#testtable tr")
        .not(":first")
        .filter(":has(input[type='checkbox'][checked])")
        .each(function() {
            //change html using ajax calls
            editrow($(this).attr("id"));
         });

     })
     .slideDown('fast');  // want this to wait until editrow() has been run on each row

editrow() contains ajax calls to edit the html of the given row. The problem is the div slides up, then back down immediately. I need it to wait until the functions have executed on each row, changing the html of the table, before sliding it back down.

Was it helpful?

Solution

If you need the slide down animation to happen after all the ajax calls are done then you could first count the amount of rows that will be edited, save that to a variable and for each successfull ajax call decrement that number. If the successfull ajasx call decreases the number to 0 then do the slide down animation.

Something like this:

$("div#grid").slideUp('fast', function() {
  //every row but the first
  rowsToUpdate = $("#testtable tr")
      .not(":first")
      .filter(":has(input[type='checkbox'][checked])");
  $("#testtable").data('rowsToUpdate', rowsToUpdate.length);
  rowsToUpdate.each(function() {
        //change html using ajax calls
        editrow($(this).attr("id"));
     });

 });

 function editrow(id) {
     $.ajax({
         complete : function () {
             // On complete, not success as we always want to show the table again?
             rowsToUpdate = $("#testtable").data('rowsToUpdate')--;
             $("#testtable").data('rowsToUpdate', rowsToUpdate);
             if (rowsToUpdate == 0) {
                 $("div#grid").slideDown('fast');
             }
         }
 }

Warning. Totally untested code.

OTHER TIPS

I'm guessing the first row is a "checkall" type thing? Maybe that's the header? Ideally, you should use checked="checked" not checked="true". And you should simply use "checked" attribute verifying in jQuery.

The following should work in jQuery 1.3+

First try and get one or two steps done. Then try and move to more complex stuff.

$("div#grid").slideUp('fast', function() {
   $(this).slideDown('fast');
});

If that works, then the next phase...

$("div#grid").slideUp('fast', function() {
  // For each table row with a checkbox that isn't in the first row
  $("#testtable tr").not(":first").filter(":has(input[type='checkbox'][checked])")
     .each(function(){
          // I substituted your custom function so we can find out if this works first
          alert($(this).attr("id"));
     });
});

And if that works, then move on...

$("div#grid").slideUp('fast', function() {
  // For each table row with a checkbox that isn't in the first row
  $("#testtable tr").not(":first").filter(":has(input[type='checkbox'][checked])")
     .each(function(){
          // Original function reinserted
          editrow($(this).attr("id"));
     });
     $(this).slideDown('fast');
});

Just remember to put your id="" in the table row not the checkbox itself.

I think you should have $(this).slideDown('fast'); in a success event from your ajax call. This won't work with your current situation (at least, not how I think you would like it to work) because each of the ajax calls will hopefully have a success event triggered. Is it possible for you to pass an array to your ajax call so you can do one call, as opposed to a bunch of different ones? Not seeing exactly what your doing makes it difficult, but I think that's your best bet.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top