255

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?

15 Answers 15

393

If you want to go through each row(<tr>), knowing/identifying the row(<tr>), and iterate through each column(<td>) of each row(<tr>), then this is the way to go.

var table = document.getElementById("mytab1");
for (var i = 0, row; row = table.rows[i]; i++) {
   //iterate through rows
   //rows would be accessed using the "row" variable assigned in the for loop
   for (var j = 0, col; col = row.cells[j]; j++) {
     //iterate through columns
     //columns would be accessed using the "col" variable assigned in the for loop
   }  
}

If you just want to go through the cells(<td>), ignoring which row you're on, then this is the way to go.

var table = document.getElementById("mytab1");
for (var i = 0, cell; cell = table.cells[i]; i++) {
     //iterate through cells
     //cells would be accessed using the "cell" variable assigned in the for loop
}
Sign up to request clarification or add additional context in comments.

8 Comments

ex2, table.cells isnt browser compatible
@WilliamRemacle I posted this answer almost 4 years ago.. IE 9 was not even a thought at the time!
@JohnHartsock I know but I used your solution and figured out that it does not work on IE. It is just a comment to warn the others... I voted up your answer anyway ;-)
function itTable() { document.writeln("itTable"); var table = document.getElementById("mytab"); for (var i = 0, row; row = table.rows[i]; i++) { document.writeln(i); for (var j = 0, col; col = row.cells[j]; j++) { document.writeln(j); } } document.writeln("end-itTable"); } Why would this code not let me loop through a table similar to the one above.
For those (coming here through google) needing a simple and small shim for table.cells (to patch up some older/IE-oriented code), see my answer to Q: Does Firefox browser not recognize table.cells?
|
81

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
    })
})

7 Comments

Can't use jquery...company doesn't allow it. Don't ask why.
That's a crazy policy. You could always just copy-n-paste the relevant functions you need from jQuery to your own application code. Unless there's a policy against using other people's code online, but then you wouldn't be here.
@Judy: Disagree on "crazy policy".... there are plenty of reasons for not using jQuery
Another reason to disallow JQuery is for embedded websites e.g. I'm using an embedded WiFi chip which only has 250Kb for the whole website. It's a squeeze with all the images as it is.
jQuery in useless where you need 2-3 functions. It is slow and confusing when coding along with PHP.
|
45

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) 
{
    for(let cell of row.cells) 
    {
       console.log(cell.innerText)
    }
}
<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>

for ( let [i,row] of [...mytab1.rows].entries() ) 
{
    for( let [j,cell] of [...row.cells].entries() ) 
    {
       console.log(`[${i},${j}] = ${cell.innerText}`)
    }
}
<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>

4 Comments

clean I would say
Notice the "for ... of" in the loops. Would've been nice to have some explanation in your answer. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Simple, elegant and functional, excellent contribution
Elegant way to do the work without dom/jQuery. How could I finally get all inputs in the cell? (Or all inputs in a row)
18

var table=document.getElementById("mytab1");
var r=0; //start counting rows in table
while(row=table.rows[r++])
{
  var c=0; //start counting columns in row
  while(cell=row.cells[c++])
  {
    cell.innerHTML='[R'+r+'C'+c+']'; // do sth with cell
  }
}
<table id="mytab1">
  <tr>
    <td>A1</td><td>A2</td><td>A3</td>
  </tr>
  <tr>
    <td>B1</td><td>B2</td><td>B3</td>
  </tr>
  <tr>
    <td>C1</td><td>C2</td><td>C3</td>
  </tr>
</table>

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).

1 Comment

in previous post: while (cell=row[r].cells[c++] should be row.cells[c++], row being the current object, and an example for the sth code: mycoldata = cell.innerHTML
14

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). Furthermore, it gives your code access to both element and index vars rather than just the element, and if you prefer to hide the index, you can just ignore it in the callback arg list.

If you require this to run in an old version (pre-ES2015) of Javascript, Array.from can be polyfilled.

2 Comments

I'm getting VM150:11 Uncaught TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator)) on this line ` Array.from(tr.cells).forEach((cell, col_ind) => {` running on Chrome
@Cooper is it possible that your table does not have a "rows" child element or some rows do not have any cells? If so, I've updated the example to handle this
7

Here's one solution using modern Javascript ES6+

    const rows = document.querySelector("table")?.rows;
    if (!rows) {
      return;
    }
    Array.from(rows).forEach(row => {
      console.log(row);
      const cells = Array.from(row.cells);
      cells.forEach(cell => {
        console.log(cell);
      });
    });

Array.from() converts the HTMLCollection of rows and/or cells into a regular Javascript Array which you can iterate through.

Documentation for table.rows usage: https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableElement/rows

Documentation for row.cells usage: https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableRowElement

Comments

4

My solution, using es6:

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

var data = [...table.rows].map(row => [...row.cells].map(td => td.innerText));

console.log(data)

REFERENCES:
https://developer.mozilla.org/pt-BR/docs/Web/API/HTMLCollection

Comments

3

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
    });

4 Comments

Uncaught TypeError: Cannot read property 'toArray' of undefined --> This is what I got, when I tried this solution.
Strange. I tried it again and it worked. I couldn't reproduce the error you pointed, though. Maybe the problem is the browser. I tested using Edge and IE and both did't work. Chrome, Firefox and Safari worked as expected.
I used chrome too.
This works for me too. The Object.defineProperty obviously has to go before the rest of the code, but it works. @Vineela Thonupunuri did you try it with the code in the correct order?
2

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 = "";
     }
}

3 Comments

Is that even JavaScript? Because your for loop looks somewhat like PHP.
A lot of languages are surprisingly similar when you know what to look for. PHP would use a $ in front of each variable, this doesn't. var is also a keyword used by JavaScript, not PHP although if they added it I may have missed it. - edit- gah no enter for newline... As I say: Logic is universal. Knowing how to transcribe it into alternate languages is an incredibly useful skill which isn't difficult to learn - we are beings of intellect with excellent pattern matching abilities. Identify the changes between each language or simply use the lexer language definition...
If you are answering a question # of rows doesnt say anything... Please update your answer with the full code.
2

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');
cells.forEach(function(cell) {
  console.log(cell.innerHTML);
})
<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>

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');
cells.forEach(function(cell) {
  console.log(cell.innerHTML);
})
<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>

1 Comment

Simplest way to modify all cells. I used this for removing cell styles.
1

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]);    
}

Comments

0

This is a different method using the childNodes and HTMLCollection

    <script>
        var tab = document.getElementsByTagName("table")
        for (var val of tab[0].childNodes[1].childNodes.values())
            if (HTMLCollection.prototype.isPrototypeOf(val.children)) {
                for (var i of val.children) {
                    console.log(i.childNodes[0])
                }
            }
    </script>

Comments

0

I leave this just for future reference for scraping a specific HTML table column and printing the results.

//select what table you want to scrape (is zero based)
//set 0 if there is only one
setTable=0;
//select what column you want to scrape (is zero based)
//in this case I would be scrapping column 2
setColumnToScrape=1;
var table = document.getElementsByTagName("tbody")[setTable];
for (var i = 0, row; row = table.rows[i]; i++) {
  col = row.cells[setColumnToScrape];
  document.write(col.innerHTML + "<br>");
}

Comments

0

Pure Javascript

function numberofRow(){
  var x = document.getElementById("mytab1").rows.length;
  document.getElementById("mytab1").innerHTML = x;
}
numberofRow();
<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>

Comments

-1

es6:

const table = document.getElementById('some-table');
const cells = table.getElementsByTagName('td');

for (let cell of cells) {
   // do something with cell here
}

earlier versions:

var table = document.getElementById('some-table');
var cells = table.getElementsByTagName('td');
for ( var i in cells ) {
   // do something with cells[i]
}

source: https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.