Animating Table Rows with jQuery

jQuery contains a powerful and flexible animation engine.  However, it has some limitations, primarily due to underlying limitations of CSS-based layout

For example, there is no simple way to slideUp() a table row (<tr> element).  The slideUp animation will animate the element’s height to zero.  However, a table row is always tall enough to show its elements, so the animation cannot actually shrink the element.

To work around this, we can wrap the contents of each cell in a <div> element, then slideUp() the <div> elements.  Doing this in the HTML would create ugly and non-semantic markup, so we can do it in jQuery instead.

For example: Demo

$('tr')
    .children('td, th')
    .animate({ padding: 0 })
    .wrapInner('<div />')
    .children()
    .slideUp(function() { $(this).closest('tr').remove(); });

Explanation:

  1. Get all of the cells in the row
  2. Animate away any padding in the cells
  3. Wrap all of the contents of each cell in one <div> element for each cell (calling wrapInner())
  4. Select the new <div> elements
  5. Slide up the <div>s, and remove the rows when finished.

If you don’t remove the rows, their borders will still be visible.  Therefore, if you want the rows to stay after the animation, call hide() instead of remove().

4 comments:

Cool! I made it reusable like this:

$.fn.slideUpRow = function (duration) {
$(this).children('td, th')
.animate({ padding: 0 })
.wrapInner('<div/>')
.children()
.slideUp(duration, function () {
$(this).closest('tr').remove();
});
};

This comment has been removed by the author.

This is based on Tim Scott's plugin, but is more flexible, as you can pass a callback to do something other than remove the row. You can call it like:

$row.tableRowHide(200, function($row) { $row.remove(); });

The $.then() part ensures that all the children have finished sliding up before we call the callback.

jQuery.fn.tableRowHide = function(duration, callback) {
if (duration == null) {
duration = 200;
}
return $.when($(this).children('td').wrapInner('<div/>').children().slideUp(duration)).then(function() {
if (typeof callback === 'function') {
return callback($(this).closest('tr'));
}
});
};

Post a Comment