The previous page filled a table when the page loaded with data from an array included in the page. The process can be run to replace the data rows in response to any event. The data can be included in the initial page load, as this case, or retrieved using an RPC or AJAX.

The source data for this example is in a two dimenstional array. This JavaScript Array easily maps to a table. However, other structures can be used; for example, an array of objects with a property for each cell or an XML document.

HTML  

To use this method the HTML needs to include a properly formed table. It can be the minimum as shown below or a filled table where the data rows will be replaced later.

<div id="tableDiv">
    <table id="tbl" class="" summary="">
        <thead>
            <tr><th>First Name</th><th>Last Name</th>
            <th>Dept</th><th>Office</th></tr>
        </thead>
        <tbody id="data-area"><tr><td></td></tr></tbody>
    </table>
</div>

Every table has a tbody whether it is coded or not. If it has not been coded the browser will add it. This method replaces the tbody. The new one holds the new data rows. By explicitly coding the tbody, there is an ID available. That ID is used to store a reference to the tbody in the variable dataArea.

JavaScript  

 1. function fillTable(dataArea, source) {
 2.     var row, cell, dataRow, txtNode;
 3,     var i, j, k;
 4.     var theTable = dataArea.parentNode;
 5.     var docFragment = document.createDocumentFragment();
 6.
 7.     newtbody = document.createElement("tbody");
 8.     newtbody.id = "data-area";
 9.
10.     docFragment.appendChild(newtbody);
11.     for (var i = 0, j = source.length; i < j; i++) {
12.         dataRow = source[i];
13.         row = document.createElement("tr");
14.         row.className = dataRow[0];
15.         newtbody.appendChild(row);
16.
17.         for (k = 1; k < 5; k++) {
18.             cell = document.createElement("td");
19.             row.appendChild(cell);
20.             txtNode = document.createTextNode(dataRow[k]);
21.             cell.appendChild(txtNode);
22.         }   
23.     }
24.     theTable.replaceChild(docFragment, dataArea);
25. }

The first step, line 5, is to create a documentFragment. This is available in IE6+, Safari, Firefox, et al. It will hold the new table elements while the new rows are being assembled, and it is automatically removed when inserted into the document structure.

Lines 7 and 8, create a new tbody that is added to the document fragment on line 10. Since it is not yet part of the document, having the same ID as the existing tboby is not a problem.

A pair of nested for-loops are used to fill the table fragment. The order the elements are added to the fragment is to satisfy DOM Insertion Order Leaks with IE .

The last step, line 24, is to replace the tbody with the tbody in the document fragment.

cell.appendChild(document.createTextNode(dataRow[k])); is somewhat faster than using innerHTML or innerText (textContent in Firefox) in this example.

Threaded JavaScript  

Finally, the code used when the page loads to call the fillTable function cause it to run in a separate thread. Calling a function using setTimeout runs that code in a separate thread. For pages heavy with images, this technique allows the browser to continue loading and displaying the images while the table code is running.

<script type="text/javascript">
    setTimeout(function(){fillTable("data-area", dataArray);}, 0);
</script>

The next technique uses a different approach to improve performance.