Section IV.8. Dynamic Tables


IV.8. Dynamic Tables

The IE and W3C DOMs have identical convenience facilities for dynamically creating and modifying table structures (unfortunately, they are broken in IE 5/Mac). Once you have a reference to the table or, preferably, tbody element object, the rest is the same across DOMs until you get to populating the TD elements with content (as discussed in the previous section). This facility makes it possible, for example, to let client-side scripts sort the table on each column in response to user requestno need to go back to the server.

The regularity of tables and the design behind the table row and cell construction methods permit very compact and tight loops to generate a lot of a document's tree. Essentially the process is:

  1. Insert an empty TR element at the desired position in the table.

  2. Insert empty TD elements into the new tr element object.

  3. Populate the TD elements with content.

Sources for your table data can be JavaScript arrays (arrays of objects are particularly useful) or, in more recent browsers, external XML documents loaded into virtual documents by way of the XMLHttpRequest object (see Online Section VII). This discussion doesn't cover the Microsoft proprietary data binding capabilities, which are available in IE for Windows and, with some limitations, for the Mac. Read more about data binding under the dataFld property of all objects in Chapter 2 of Dynamic HTML, Third Edition.

JavaScript-Formatted Data

If you are using server-side programming to assemble part of the pages served up to the client, and if the page contains updated data retrieved from a database, consider passing the data along to the client in a format that is convenient for client-side scripting. The data doesn't have to be embedded directly into the HTML content, but it can be output with a content type of text/javascript that is retrieved by the client in a <script> tag that loads an external .js file.

As shown in Example IV-9, the convenience of having the data already formatted as JavaScript objects and/or arrays simplifies further scripted manipulation of the data in the page. You can also pass data to the browser in this form but as a string, and let the client reconstruct the actual JavaScript objecta form often referred to as JavaScript Object Notation, or JSON. See Online Section VII for more about JSON.


Example IV-9 is a code listing for a simple application that uses an array of objects embedded within the document as a data source.

Example IV-9. Dynamic table

 <html> <head> <title>Dynamic Table</title> <style type="text/css"> body {background-color: #ffffff} table {border-spacing: 0} td {border: 2px groove black; padding: 7px} th {border: 2px groove black; padding: 7px} .ctr {text-align: center} </style> <script type="text/javascript"> // Table data -- an array of objects var jsData = new Array( ); jsData[0] = {bowl:"I", year:1967, winner:"Packers", winScore:35, loser:"Chiefs", losScore:10}; jsData[1] = {bowl:"II", year:1968, winner:"Packers", winScore:33, loser:"Raiders (Oakland)", losScore:14}; jsData[2] = {bowl:"III", year:1969, winner:"Jets", winScore:16, loser:"Colts (Balto)", losScore:7}; jsData[3] = {bowl:"IV", year:1970, winner:"Chiefs", winScore:23, loser:"Vikings", losScore:7}; jsData[4] = {bowl:"V", year:1971, winner:"Colts (Balto)", winScore:16, loser:"Cowboys", losScore:13}; // Sorting function dispatcher (invoked by table column links) function sortTable(link) {     // Sorting functions     function sortByYear(a, b) {         return a.year - b.year;     }     function sortByWinScore(a, b) {         return b.winScore - a.winScore;     }     function sortByLosScore(a, b) {         return b.losScore - a.losScore;     }     function sortByWinner(a, b) {         a = a.winner.toLowerCase( );         b = b.winner.toLowerCase( );         return ((a < b) ? -1 : ((a > b) ? 1 : 0));     }     function sortByLoser(a, b) {         a = a.loser.toLowerCase( );         b = b.loser.toLowerCase( );         return ((a < b) ? -1 : ((a > b) ? 1 : 0));     }     switch (link.firstChild.nodeValue) {         case "Year" :             jsData.sort(sortByYear);             break;         case "Winner" :             jsData.sort(sortByWinner);             break;         case "Loser" :             jsData.sort(sortByLoser);             break;         case "Win" :             jsData.sort(sortByWinScore);             break;         case "Lose" :             jsData.sort(sortByLosScore);             break;     }     drawTable("bowlData"); } // Remove existing table rows function clearTable(tbody) {     while (tbody.rows.length > 0) {         tbody.deleteRow(0);     } } // Draw table from 'jsData' array of objects function drawTable(tbodyID) {     var tr, td;     tbody = document.getElementById(tbodyID);     // remove existing rows, if any     clearTable(tbody);     // loop through data source     for (var i = 0; i < jsData.length; i++) {         tr = tbody.insertRow(tbody.rows.length);         td = tr.insertCell(tr.cells.length);         td.setAttribute("class", "ctr");         td.appendChild(document.createTextNode(jsData[i].bowl));         td = tr.insertCell(tr.cells.length);         td.appendChild(document.createTextNode(jsData[i].year));         td = tr.insertCell(tr.cells.length);         td.appendChild(document.createTextNode(jsData[i].winner));         td = tr.insertCell(tr.cells.length);         td.appendChild(document.createTextNode(jsData[i].loser));         td = tr.insertCell(tr.cells.length);         td.setAttribute("class", "ctr");         td.appendChild(document.createTextNode(jsData[i].winScore + " - " + jsData[i].losScore));     } } function init( ) {     drawTable("bowlData"); } window.onload = init; </script> </head> <body> <h1>Super Bowl Games</h1> <hr> <table > <thead> <tr><th>Bowl</th>     <th><a href="#" title="Sort by Year"     onclick="return sortTable(this)">Year</a></th>     <th><a href="#" title="Sort by Winning Team"     onclick="return sortTable(this)">Winner</a></th>     <th><a href="#" title="Sort by Losing Team"     onclick="return sortTable(this)">Loser</a></th>     <th>Score <a href="#" title="Sort by Winning Score"     onclick="return sortTable(this)">Win</a> - <a href="#"     title="Sort by Losing Score" onclick="return sortTable(this)">Lose</a></th> </tr> </thead> <table> <tbody ></tbody> </table> </body> </html> 

Figure IV-2 shows the table as rendered by JavaScript from the embedded data. The function that generates the table also redraws the table when the data is sorted and redisplayed.

Figure IV-2. A dynamically sortable table rendered from embedded JavaScript data


Notice in Example IV-9 that the HTML portion simply provides a tbody placeholder for the dynamic table data. A tbody element object has the same insertRow( ) method available to it as the table element object (and the thead and tfoot, for that matter). While it's true that a separate function could be used for simply replacing the content of TD elements after the first table is created, the process in this example (i.e., removing rows and making new ones for each redrawing) allows one function to handle both the initial and subsequent table drawing. Note that if you were deploying Example IV-9 for scriptless accessibility, the initial page download would include a table pre-filled with data in a default order, and the href attributes of links in the column headings would target URLs of server scripts that return the page with data sorted on that column's data.




Dynamic HTML. The Definitive Reference
Dynamic HTML: The Definitive Reference
ISBN: 0596527403
EAN: 2147483647
Year: 2004
Pages: 120
Authors: Danny Goodman

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net