views:

115

answers:

3

Hello. I'm experiencing an odd problem when trying to navigate through a table's rows and cells in a while loop using javascript. I'm using Firefox 3.5.7 on Win7 with Firebug enabled.

I have this markup:

<table>
    <tbody>
        <tr id='firstRow'><td>a</td><td>b</td><td>c</td></tr>
        <tr><td>a</td><td>b</td><td>c</td></tr>
        <tr><td>a</td><td>b</td><td>c</td></tr>
    </tbody>
</table>

And this javascript:

var row = document.getElementById('firstRow');
console.log(row); // Row call 1
while (row) {
    console.log(row); // Row call 2
    row = row.nextSibling;
}

The problem I'm having is that on the line commented "Row call 1", Firebug is outputting

<tr id='firstRow'>

as expected. However, in the while loop, Firebug is giving me

<tr id='firstRow'>
<TextNode textContent="\n">

It is giving me different output for the exact same row, even immediately after the while loop begins executing and nothing else touched the row. For subsequent rows, it of course does not have id='firstRow' as an attribute.

The bigger problem this is giving me is that if I'm in the while loop, and I want to access a particular cell of the current row using row.cells[0], Firebug will give me an error that row.cells is undefined.

I want to know if someone could shed some light on this situation I am experiencing.

+1  A: 

The TextNode is correct, because you do have that after the </tr>.

A simple workaround is to skip those textnodes - by either counting or testing if

row.tagName == 'TR'
Francis
Testing for 'tr' did not allow me to traverse all the rows. As the other guy mentioned, it has to be 'TR', for tagName and nodeName.
Bob
+1  A: 

Firefox is picking up the whitespace between your tr elements as an additional node. Simply add a test that the node is indeed a tr before doing anything with it:

var row = document.getElementById('firstRow');
console.log(row); // Row call 1
while (row) {
    if(row.nodeName == "TR"){
       console.log(row); // Row call 2 
    }
    row = row.nextSibling;
}

Note that the text nodes have a nodeName of #text and that nodeName will always return the element name in all caps regardless of how you have it in your document.

Doug Neiner
Thanks, this did it.
Bob
A: 

Use the tbody.rows collection. It's simpler:

var row = document.getElementById('firstRow');
console.log(row); // Row call 1
var tbody = row.parentNode;
var rows = tbody.rows;
for (var i=row.rowIndex+1; i<rows.length; i++) {
 row = rows[i];
 console.log(row); // Row call 2, 3 ...
}

For more info, see http://msdn.microsoft.com/en-us/library/ms537484%28VS.85%29.aspx (or just google rowIndex)

EDIT: If the table also contains thead and/or tfoot then it might be more appropriate to use row.sectionRowIndex

Sean Hogan