Friday, August 28, 2009

Javascript: insert table rows / table body

If you write lots of javascript, there will someday come a time when you need to do one of the following DOM manipulations:
  • Insert a new table body, discarding the old one
  • Insert some number of table rows after some given row
This can be easily accomplished using a javascript library like jQuery, but there is a major downside to this: very bad performance! (for big chunks of html)

The reason for this is that a library like jQuery must preform all sorts of checks for all sorts of corner cases, such as checking if the html you are inserting contains script blocks and running them if your browser does not support script eval (IE6 - 7). It must clean each string before turning it into DOM objects.

For this reason, it is better to use plain javascript to write all the table manipulation functions, and make assumptions about the html you will be inserting (so you dont have to clean it). Here is a collection of such functions that i have used in production code. They are on average 2 or 3 times faster than using jQuery for the same insert.

Inserting table rows after a row

Example Usage:

You can insert 1 or more rows this way.

Replacing a table body with a new table body
Note: html does not include the actual tbody tag, just the rows and columns.

Another function that I often use is a helper function for replacing the table body to be used with jQuery's ajax functions:

Caveats of using these functions:
  • On browsers that dont support scriptEval, scripts that are inserted into the table body will not be executed upon insertion. You will need to deal with them yourself. I usually include them in a hidden input with a predefined ID, and then eval the value of that input after insertion.
  • Leading and trailing whitespace counts as a DOM node in IE, and will have weird effects if the html used in these methods contains it. If you are in charge of creating the html you insert, make sure it doesnt have unneeded whitespace between and around nodes.
  • I dont know if liveQuery plugin will know about these dom modifications.