Can't dynamically add rows to a <TABLE> in IE?

11,969

Solution 1

You need to create a TBODY element to add your new TR to and then add the TBODY to your table, like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title></title></head><body>

<table id="employeetable">
    <tr>
        <th>Name</th>
        <th>Job</th>
    </tr>
</table>

<script type="text/javascript">
    function addEmployee(employeeName, employeeJob) {
        var tableElement = document.getElementById("employeetable");
        if (tableElement) {
            var newTable = document.createElement('tbody');   // New
            var newRow = document.createElement("tr");
            var nameCell = document.createElement("td");
            var jobCell = document.createElement("td");
            nameCell.appendChild(document.createTextNode(employeeName));
            jobCell.appendChild(document.createTextNode(employeeJob));
            newRow.appendChild(nameCell);
            newRow.appendChild(jobCell);
            newTable.appendChild(newRow);   // New
            tableElement.appendChild(newTable);   // New
            alert("code executed!");
        }
    }

    setTimeout("addEmployee(\"Bob Smith\", \"CEO\");", 1000);
    setTimeout("addEmployee(\"John Franks\", \"Vice President\");", 2000);
    setTimeout("addEmployee(\"Jane Doe\", \"Director of Marketing\");", 3000);
</script>

</body></html>

Solution 2

Apparently, in IE you need to append your row to the TBody element, not the Table element... See discussion at Ruby-Forum.

Expanding on the discussion there, the <table> markup is generally done without explicit <thead> and <tbody> markup, but the <tbody> ELEMENT is where you actually need to add your new row, as <table> does not contain <tr> elements directly.

Solution 3

Edit: now works in IE! insertSiblingNodesAfter uses the parentNode of the sibling, which happens to be a tbody in IE


It's hard to know what quirks are in store when you try to manipulate the DOM cross-browser. I'd recommend that you use an existing library that has been fully tested across all major browsers, and accounts for quirks.

Personally I use MochiKit, you can dive into DOM manipulation here: http://mochikit.com/doc/html/MochiKit/DOM.html

Your final function might look something like this:

function addEmployee(employeeName, employeeJob) {
    var trs = getElementsByTagAndClassName("tr", null, "employeetable");
    insertSiblingNodesAfter(trs[trs.length-1], TR({}, TD({}, employeeName), TD({}, employeeJob));
    alert("code executed!");
}
Share:
11,969
Guilherme David da Costa
Author by

Guilherme David da Costa

Professional developer since 2000. Currently Senior Developer at Virtual Advantage. I work on ScoutCMS.

Updated on July 13, 2022

Comments

  • Guilherme David da Costa
    Guilherme David da Costa almost 2 years

    I have an AJAX application that downloads a JSON object and uses the data to add rows to an HTML <table> using Javascript DOM functions. It works perfectly... except in Internet Explorer. IE doesn't give any sort of error, and I've verified as best as I can that the code is being executed by the browser, but it simply has no effect. I created this quick and dirty page to demonstrate the problem:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"><head><title></title></head><body>
    
    <table id="employeetable">
        <tr>
            <th>Name</th>
            <th>Job</th>
        </tr>
    </table>
    
    <script type="text/javascript">
        function addEmployee(employeeName, employeeJob) {
            var tableElement = document.getElementById("employeetable");
            if (tableElement) {
                var newRow = document.createElement("tr");
                var nameCell = document.createElement("td");
                var jobCell = document.createElement("td");
                nameCell.appendChild(document.createTextNode(employeeName));
                jobCell.appendChild(document.createTextNode(employeeJob));
                newRow.appendChild(nameCell);
                newRow.appendChild(jobCell);
                tableElement.appendChild(newRow);
                alert("code executed!");
            }
        }
    
        setTimeout("addEmployee(\"Bob Smith\", \"CEO\");", 1000);
        setTimeout("addEmployee(\"John Franks\", \"Vice President\");", 2000);
        setTimeout("addEmployee(\"Jane Doe\", \"Director of Marketing\");", 3000);
    </script>
    
    </body></html>
    

    I haven't tried IE 8, but both IE 7 and IE 6 do not show the additional rows that are supposedly being added. I can't fathom why. Does anyone know a good workaround to this problem, or am I perhaps doing something wrong?

  • Tetsujin no Oni
    Tetsujin no Oni about 15 years
    actually, tableElement.getElementsByType('tbody') should return what is desired here....
  • Tetsujin no Oni
    Tetsujin no Oni about 15 years
    actually, <pre>tableElement.getElementsByType('tbody')</pre> should return what is desired here
  • Tetsujin no Oni
    Tetsujin no Oni about 15 years
    Sorry guys, still kinda new on the comment / answer syntax differences. Obviously, wanted to put code-style formatting on the code fragment.
  • Jason Bunting
    Jason Bunting about 15 years
    +1 for using MochiKit (my fave library), but you missed the actual answer - he needs to append rows to a TBody for IE to recognize the rows.
  • JPot
    JPot about 15 years
    Appending to tbody works consistently in all browsers, so it is safe to do it always.
  • EoghanM
    EoghanM about 15 years
    I didn't realise that appendChildNodes wasn't working - I had been using insertSiblingNodes in my own code, which works - I've updated the answer to reflect a working solution.
  • Travesty3
    Travesty3 about 13 years
    I realize this is an old post, but since others may still use it for reference, the above comment didn't work for me. What worked for me was tableElement.getElementsByTagName('tbody')[0]
  • Admin
    Admin almost 13 years
    @Wally: I tried adding <tbody> in my demo but still it does not seem to work on IE, my question