HomeRamblings  ⁄  JavaScript

Cross-browser AJAX updates to table elements

Published: June 29, 2008 (over 9 years ago)
Updated: over 2 years ago

It seems that one of the toughest Javascript challenge is to get your AJAX code consistently behave between browsers when you’re dealing with IE’s handling of table elements vs. Gecko and other engines. It took quite a bit of finagling to figure out exactly where the issues and trappings are. Most web developers know about IE’s, ahem, rather unque way of handling tables and the likes, but what’s a web application to do if (s)he is gonna bring some sanity to the picture? Well, Mootools 1.2 goes a long ways towards easing your misery in terms of interacting with the DOM and doing some really cool Javascript things in a consistent manner, but you still have to figure out the specifics that you’re encountering for your application’s needs. My needs were simple. I wanted to use AJAX to pop up an embedded dialog (just some fancy CSS styling to get a DIV hovering over an overlay, really), update some values, and have that info populate back to the table where said information was presently displayed. I also wanted to be able to add new records and delete existing rows through AJAX calls rather than refreshing the whole page. This article will walk you through the basic approach I used. I’ll leave out the fancy dialogs and all that and just hard-code some buttons so as to keep this article tightly focused on the task at hand: manipulating tables consistently across all browsers through Mootools 1.2. This technique was borne of some code and help I got from Jan Kassens http://blog.kassens.net/ on the IRC channel for mootools (#mootools at freenode.net). First, the HTML page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<table id="mytable" style="border: 1px solid blue">
    <tbody id="mytbody">
    <tr id="row1">
        <td>r1c1</td>
        <td>r1c2</td>
        <td>r1c3</td>
    </tr>
    <tr id="row2">
        <td>r2c1</td>
        <td>r2c2</td>
        <td>r2c3</td>
    </tr>
    <tr id="row3">
        <td>r3c1</td>
        <td>r3c2</td>
        <td>r3c3</td>
    </tr>
    <tr id="row4">
        <td>r4c1</td>
        <td>r4c2</td>
        <td>r4c3</td>
    </tr>
    </tbody>
</table>

Cut and paste that into a more complete HTML document if you’re gonna play with it. But as you can probably see, that code generates a fairly simple table with named table row elements and a named tbody element (which is very important for IE). One of the first things I found out is that you can’t inject directly on the table element in IE, you have to inject into the TBODY element, otherwise, IE just accepts your injects gleefully without ever presenting them (I know this because I could subsequently select with $('new_element') and delete the elements I dynamically created!). So now that we have that first big “gotcha” out of the way, lets look at some mootools functions you can use to mess with your tables. First, be sure you have mootools loading into your HTML document:

1
<script type="text/javascript" src="scripts/mootools-1.2-core-nc.js" charset="utf-8"></script>

And now, some javascript to let us do a little table manipulation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script type="text/javascript">

  function htmlToElements(str){
    return new Element('div', {html: '<table><tbody>' + str + '</tbody></table>'}).getElement('tr');
  }

  function add_row() {
    var myTBody = $('mytbody');

    newRow = htmlToElements("<tr><td>foo</td><td>bar</td></tr>");
    newRow.inject(myTBody);
  }
  function delete_row() {
    $('row5').dispose();
  }

  function replace_row(row) {
    var newRow = htmlToElements('<tr id="' + row + '"><td>foo</td><td>bar</td><td>replaces!</td></tr>');
    newRow.replaces($(row));
  }
</script>

With this, I can put some buttons on the page to click and call these nifty functions accordingly:

1
2
3
<button onclick="add_row();">add row</button>
<button onclick="delete_row();">delete row</button>
<button onclick="replace_row('row2');">replace row 2</button>

So, lets go over this a bit. delete_row() is the simplest one. It just shows that you can use mootool’s dollar function to grab a TR and throw it away. Works great in FF2 and IE without any tricks.

Next up, add_row(). This one turned out to be tricky because I was initially trying to add to the “mytable” TABLE element and it worked in Firefox, but not Internet Explorer. I really got frustrated with this one, trying all manner of innerHTML, outerHTML, DOM manipulators (e.g. appendChild) with no success until Jan tipped me off that its the tbody you have to work against.

Alright, so with that nasty one out of the way, the next step was getting rows into IE. It seems that just assigning innerHTML property for a TR was a major no-no and there’s plenty of blogs and other forum posts to tell you all about this one. But I get my new data from the server as HTML, not DOM objects. I needed a simple helper method to get me to DOM elements I could inject. So Jan whips up what I needed in htmlToElements(str) function in which a a fully valid table is constructed (including the TBODY element IE depends on) in which the TR is selected and returned from it.

With a TR element in hand, it was embarrassingly simple to call mootool’s inject on the TBODY element. But wait, there’s a bonus round: You can also replace an existing TR just as easily as you can add a new TR to the table and Internet Explorer (or maybe it was mootools!) tickled me pink in happily complying with my wishes. With this toolset, you can build a fairly comprehensive set of functionality to add, delete, and update your rows in any browser.

comments powered by Disqus