2

I am trying to animate a table row sliding up, then adding a new table row, and animate the new table row sliding down. I have read up on how to animate a table row, now I am trying to queue up these animations.

<table>
    <tr>
        <td><div><a class="trigger" "href="#">Hide this row and add a row after this one</a></div></td>
        <td><div>content</div></td>
        <td><div>content</div></td>
    </tr>
    <!-- new table row will be added here -->
    <tr class="another-row">
        <td><div>content</div></td>
        <td><div>content</div></td>
        <td><div>content</div></td>
    </tr>
    <tr id="new-row" style="display:none">
        <td><div>this row will appear after the row that was clicked</div></td>
        <td><div>content</div></td>
        <td><div>content</div></td>
    </tr>
</table>

Here's the javascript I have:

$('.trigger').click(function(){

    var $clickedTableRow = $(this).closest('tr');
    var $newTableRow = $('#new-row');

    $clickedTableRow.find('td > div').slideUp('slow', function(){
        alert('animation complete, ready to hide table row');
        $clickedTableRow.hide();
        //however, this executes after each div has finished sliding up, instead of after the last one has finished
    });

});

When I call the slideUp() function, it appears as if each div slides up simultaneously, but the complete function is called after each div instead of once after all of those divs have finished. How can I queue the $clickedTableRow.hide(); function to happen only after all divs have finished? Then once the $clickedTableRow has been hidden, I want to queue up the animation that slides down the new table row:

$newTableRow
    .insertAfter($clickedTableRow)
    .show()
    .find('td > div')
    .slideDown(panelSpeed);

How can I queue up these multiple actions?

Community
  • 1
  • 1
Andrew
  • 227,796
  • 193
  • 515
  • 708

3 Answers3

2

One possibility is to set a flag that is used to check if the queued code has run.

Here's a simple example: http://jsfiddle.net/4J4TY/

Something like this:

$('.trigger').click(function(){

    var hasRun = false; // determine if queued code has run yet

    var $clickedTableRow = $(this).closest('tr');
    var $newTableRow = $('#new-row');

    $clickedTableRow.find('td > div').slideUp('slow', function(){
        if( !hasRun ) {
            hasRun = true;
            alert('animation complete, ready to hide table row');
            $clickedTableRow.hide();
        }
    });

});

Now the flag is set to true the first time it runs, so the code inside the if() will only execute once.

user113716
  • 318,772
  • 63
  • 451
  • 440
  • 1
    This seems like good solution as long as it's ok to execute the code when there may still be animations running. – fehays Sep 27 '10 at 22:09
  • 1
    @fehays - Not sure what you mean. The code is in the callback to the `slideUp()` method, so it will run after the animations are complete. – user113716 Sep 27 '10 at 22:17
  • 1
    @patrick - but based on your selector you are animating multiple elements so the first one to complete will set hasRun to true even if there are more. apologize in advance if i'm missing something. – fehays Sep 27 '10 at 22:20
  • @patrick - I stand corrected. It looks like they all execute at the same time. When the animation is complete for all of them. – fehays Sep 27 '10 at 22:47
  • @fehays - Yeah, the callback is like putting a queued `.each()` after the animation, so they happen in unison (or seemingly) after the `slideUp()` on every element is complete. – user113716 Sep 27 '10 at 23:05
  • @Andrew - Glad it worked for you. I know what you mean. It sort of seems like each callback should happen after each individual element, but instead the animation happens as a group, then the callback happens as a group. :o) – user113716 Sep 28 '10 at 00:44
0

There is a parameter named 'queue: true/false' in the options. Use this to queue animations. If you call the stop method, a new queue will be created and they will run together again.

EDIT: Sorry wasnt explaining myself very well. You want to make the hide part of the animation queue, so dont put it in the complete, add it to the queue of animations with queue = true.

James Westgate
  • 11,306
  • 8
  • 61
  • 68
0

Here is one example of how to check to see if the animations have completed:

http://www.gmarwaha.com/blog/2009/06/09/jquery-waiting-for-multiple-animations-to-complete/

I'm not sure if this is the most efficient solution, but it does work. I can't seem to find a builtin jquery utility for checking if all animations are complete.

fehays
  • 3,147
  • 1
  • 24
  • 43