Saturday, November 22, 2008

Adding table rows with JS in IE

Phew, I finally cracked it! After about three hours of stressing over the lack of a debugger in IE, I manage to fix my code. I'm using the mootols JavaScript library, as it has some useful features that make JS considerably easier. Also, it was the JS library already included in the page I was editing (otherwise, I'd have likely used JQuery). Anyway, here's a bit of code:

 function add_blank_team(){
  var table = $('forms');
  var row = table.getElement('tr').clone();
  var boxes = row.getElements('input');
  for(var i = 0; i < boxes.length; i++) {
   var name = boxes[i].getAttribute('name');
   if(name == "QuizTeamName[]" || name == "QuizTeamID[]") {
    boxes[i].value = "";
   else if(name == "QuizTeamScore[]") {
    boxes[i].value = 0;

As a quick explanation, this is a function which adds a blank row to a score card table. It's for a pub quiz event! Anyway, the table has the id 'forms', there are two cells per row with four inputs overall (but two are hidden). The idea is to clone an existing row (which means no need to recreate a mini-DOM for a table row in JS!), empty the relevant boxes, and attach it at the end of the table.

As the code is shown above, it'll work flawlessly in everything but IE. Why? Well, as I've just discovered, IE takes the DOM a little more literally than other browsers. It's all to do with TBODY...

Not many people bother with the TBODY tag in HTML (I certainly don't), but it's a part of the spec, and browsers deal with its absence by adding it to the DOM automatically. Most browsers know that they're done this, so if you try to do something silly, like add a row to a table outside of the body, it does what it thinks you meant: add the row to the TBODY. Indeed, this worked in Firefox, Safari and Opera. IE however, isn't happy with that (though it won't tell you!).

The fix is simple: change that first line as follows

  var table = $('forms').getElement('tbody');

This works for all browsers. Even if you don't think there's a TBODY, it really is there. Just take a look in the DOM explorer (varies between browsers).

No comments: