Search code examples
javascriptjquerywijmo

jQuery ajax after fade out and remove table row animation


There are lots of demos out there explaining how to fade out a table row and that for IE's sake we must fade out the table cells, then remove the row after the animation completes. For example this question: fadeout and remove table row

I have this technique working great. Now I want to refresh my table with an ajax call after the row has been faded out and removed. If I put this ajax load in the fadeOut complete callback it will fire once for every column in my table (as I'm fading out the table cells, not the row). This causes a bunch of ajax requests to stack up. (Works fine, bust is wasteful and bad practice.)

So I'd like to fade out and remove a table row, then fire an event/call a function only once to update the grid. What is the best practice for this in jQuery? I need to animate out all table cells, but have only one animation complete callback.

There is no callback on .remove(), so should I use some other effect like a .hide() and put the .remove() inside of its callback along with the ajax? How will this fair with cross-browser compatibility? Are there any known issues with effects on a table row in older versions of IE?


Notes: not that it makes any difference, but I happen to be using the wijmo grid widget which is built on top of jQuery UI. But its just a normal html table in markup. The fadeout/remove works fine.


Solution

  • The problem you're facing is that the callback for fadeOut executes for each matched element (all tds), not for the entire collection. What you need to do is put the remove and the ajax after the last element has faded out. Below you can find the code from the question you referenced updated to match this need (the alert & remove will only execute once):

    // don't use live, switch to delegate
    $('#tbl').delegate('td', 'click', function() {  
        var tr = $(this).parents('tr:first'),
            tds = tr.find('td'),
            l = tds.length;
    
        tds.fadeOut('fast', function(){ 
            if (! --l) {
                tr.remove();                    
                alert('ajax');
            }
        });    
    
        return false;
    });
    

    And here's a small example of it in action: http://jsfiddle.net/a76A6/2/