If I have an HTML table...say
<div id="myTabDiv">
<table name="mytab" id="mytab1">
<tr>
<td>col1 Val1</td>
<td>col2 Val2</td>
</tr>
<tr>
<td>col1 Val3</td>
<td>col2 Val4</td>
</tr>
</table>
</div>
How would I iterate through all table rows (assuming the number of rows could change each time I check) and retrieve values from each cell in each row from within JavaScript?
This question is related to
javascript
Better solution: use Javascript's native Array.from()
and to convert HTMLCollection object to an array, after which you can use standard array functions.
var t = document.getElementById('mytab1');
if(t) {
Array.from(t.rows).forEach((tr, row_ind) => {
Array.from(tr.cells).forEach((cell, col_ind) => {
console.log('Value at row/col [' + row_ind + ',' + col_ind + '] = ' + cell.textContent);
});
});
}
You could also reference tr.rowIndex
and cell.colIndex
instead of using row_ind
and col_ind
.
I much prefer this approach over the top 2 highest-voted answers because it does not clutter your code with global variables i
, j
, row
and col
, and therefore it delivers clean, modular code that will not have any side effects (or raise lint / compiler warnings)... without other libraries (e.g. jquery).
If you require this to run in an old version (pre-ES2015) of Javascript, Array.from
can be polyfilled.
You can consider using jQuery. With jQuery it's super-easy and might look like this:
$('#mytab1 tr').each(function(){
$(this).find('td').each(function(){
//do your stuff, you can use $(this) to get current cell
})
})
Using a single for loop:
var table = document.getElementById('tableID');
var count = table.rows.length;
for(var i=0; i<count; i++) {
console.log(table.rows[i]);
}
var table=document.getElementById("mytab1");_x000D_
var r=0; //start counting rows in table_x000D_
while(row=table.rows[r++])_x000D_
{_x000D_
var c=0; //start counting columns in row_x000D_
while(cell=row.cells[c++])_x000D_
{_x000D_
cell.innerHTML='[R'+r+'C'+c+']'; // do sth with cell_x000D_
}_x000D_
}
_x000D_
<table id="mytab1">_x000D_
<tr>_x000D_
<td>A1</td><td>A2</td><td>A3</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>B1</td><td>B2</td><td>B3</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>C1</td><td>C2</td><td>C3</td>_x000D_
</tr>_x000D_
</table>
_x000D_
In each pass through while loop r/c iterator increases and new row/cell object from collection is assigned to row/cell variables. When there's no more rows/cells in collection, false is assigned to row/cell variable and iteration through while loop stops (exits).
Try
for (let row of mytab1.rows)
{
for(let cell of row.cells)
{
let val = cell.innerText; // your code below
}
}
for (let row of mytab1.rows) _x000D_
{_x000D_
for(let cell of row.cells) _x000D_
{_x000D_
console.log(cell.innerText)_x000D_
}_x000D_
}
_x000D_
<div id="myTabDiv">_x000D_
<table name="mytab" id="mytab1">_x000D_
<tr> _x000D_
<td>col1 Val1</td>_x000D_
<td>col2 Val2</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>col1 Val3</td>_x000D_
<td>col2 Val4</td>_x000D_
</tr>_x000D_
</table>_x000D_
</div>
_x000D_
for ( let [i,row] of [...mytab1.rows].entries() ) _x000D_
{_x000D_
for( let [j,cell] of [...row.cells].entries() ) _x000D_
{_x000D_
console.log(`[${i},${j}] = ${cell.innerText}`)_x000D_
}_x000D_
}
_x000D_
<div id="myTabDiv">_x000D_
<table name="mytab" id="mytab1">_x000D_
<tr> _x000D_
<td>col1 Val1</td>_x000D_
<td>col2 Val2</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>col1 Val3</td>_x000D_
<td>col2 Val4</td>_x000D_
</tr>_x000D_
</table>_x000D_
</div>
_x000D_
You can use .querySelectorAll()
to select all td
elements, then loop over these with .forEach()
. Their values can be retrieved with .innerHTML
:
const cells = document.querySelectorAll('td');_x000D_
cells.forEach(function(cell) {_x000D_
console.log(cell.innerHTML);_x000D_
})
_x000D_
<table name="mytab" id="mytab1">_x000D_
<tr> _x000D_
<td>col1 Val1</td>_x000D_
<td>col2 Val2</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>col1 Val3</td>_x000D_
<td>col2 Val4</td>_x000D_
</tr>_x000D_
</table>
_x000D_
If you want to only select columns from a specific row, you can make use of the pseudo-class :nth-child()
to select a specific tr
, optionally in conjunction with the child combinator (>
) (which can be useful if you have a table within a table):
const cells = document.querySelectorAll('tr:nth-child(2) > td');_x000D_
cells.forEach(function(cell) {_x000D_
console.log(cell.innerHTML);_x000D_
})
_x000D_
<table name="mytab" id="mytab1">_x000D_
<tr> _x000D_
<td>col1 Val1</td>_x000D_
<td>col2 Val2</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>col1 Val3</td>_x000D_
<td>col2 Val4</td>_x000D_
</tr>_x000D_
</table>
_x000D_
If you want one with a functional style, like this:
const table = document.getElementById("mytab1");
const cells = table.rows.toArray()
.flatMap(row => row.cells.toArray())
.map(cell => cell.innerHTML); //["col1 Val1", "col2 Val2", "col1 Val3", "col2 Val4"]
You may modify the prototype object of HTMLCollection (allowing to use in a way that resembles extension methods in C#) and embed into it a function that converts collection into array, allowing to use higher order funcions with the above style (kind of linq style in C#):
Object.defineProperty(HTMLCollection.prototype, "toArray", {
value: function toArray() {
return Array.prototype.slice.call(this, 0);
},
writable: true,
configurable: true
});
This solution worked perfectly for me
var table = document.getElementById("myTable").rows;
var y;
for(i = 0; i < # of rows; i++)
{ for(j = 0; j < # of columns; j++)
{
y = table[i].cells;
//do something with cells in a row
y[j].innerHTML = "";
}
}
Source: Stackoverflow.com