Steven Matthews
Steven Matthews

Reputation: 11285

Iterating over table cells

So I have this code (from the gracious help from this site!)

window.onload = function inventorytable() {
var tableRows = document.getElementById

("inventorytable").getElementsByTagName("tbody")[0].getElementsByTagName("tr");

Now from here, I want to get all of the TDs, under all of the TRs. I also want to be able to perform operations on the TDs, depending on which TD (i.e. which column) they are in the table.

So for example, if I have

<tr>
<th>Processor Speed</th>
<th>Amount of RAM</th>
<tr>
<td>2.0</td>
<td>3.0</td>
</tr>
<tr>
<td>3.2</td>
<td>4.0</td>
</tr>

I want to be able to select each TD separately, depending on its order within the TR, and then add text to it. There will be a variable number of TRs, at least 20, and possibly more. There are going to be about 10-15 TDs.

The text added would be something like " Ghz" or " GB"

Upvotes: 0

Views: 2968

Answers (3)

Šime Vidas
Šime Vidas

Reputation: 185913

This is how I would do it:

var table = document.getElementById( 'inventorytable' );

[].forEach.call( table.rows, function ( row, i ) {
    [].forEach.call( row.cells, function ( cell, j ) {

        // this function runs for every cell in the table
        cell // references the current cell
        row // references the current row (the row the cell is in)
        i // the row index (0 = first row, 1 = second row, etc.)
        j // the cell index (0 = first cell in row, 1 = second cell in row, etc.)

    });
});

Live demo: http://jsfiddle.net/6tXUm/

Note: You need to include ES5 shim since some older browsers (mainly IE8) don't implement the new ES5 features like forEach.

Upvotes: 1

Akkuma
Akkuma

Reputation: 2265

If you want to simplify your life and logic here is an example of what you want: http://jsfiddle.net/Akkuma/2wJ8G/

What I'm doing is first getting the exact table and from there grabbing all td elements. It will automatically run through each one in order of row, as that is their order in the markup. You don't need to first select document.getElementsByTagName('tr'). If you need to filter you can look up the tree or select elements at a higher level first, for instance the thead.

In the second example, I know explicitly there is only one tbody and can access the area, which is of length 1, and chain .getElementsByTagName('td') to get only those td within the tbody (you could have a td in your thead or tfoot)

The third example uses @Rob W 's recommendation of using table dom traversal. At least in my example using it only complicated the code.

The final example combines Rob W's recommendation (ex3) with ex2. This allows you to skip having to write two loops.

Upvotes: 0

Felix Kling
Felix Kling

Reputation: 816394

You have to iterate over all tr elements (which is a NodeList [MDN], returned from getElementsByTagName [MDN]):

for(var i = 0, l = tableRows.length; i < l; i++) {
    var row = tableRows[i];
    //...
}

Inside the loop you can get all tds of one row again with getElementsByTagName or using the .cells [MDN] property. You can then decide to either iterate over them as well or to access the specific cells explicitly, such as cells[1] to access the second cell (second column) in that row.

If the cells contain simple text or you don't have any event handlers bound to their descendants, you can simply use innerHTML [MDN] to change the element's text content.

Otherwise you have to create a new text node and append it to the cell (that might be the best option in any case).


The Mozilla Developer Network is a great source for all kinds of information, including the DOM and JavaScript.

Upvotes: 2

Related Questions