206

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?

Brett DeWoody
  • 50,328
  • 25
  • 121
  • 168
GregH
  • 10,640
  • 21
  • 63
  • 96

11 Answers11

337

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
}
pants
  • 182
  • 13
John Hartsock
  • 78,484
  • 22
  • 123
  • 143
  • 4
    ex2, table.cells isnt browser compatible – EricG Dec 14 '12 at 13:14
  • 8
    @WilliamRemacle I posted this answer almost 4 years ago.. IE 9 was not even a thought at the time! – John Hartsock Feb 06 '14 at 21:14
  • @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 ;-) – William Remacle Feb 07 '14 at 18:53
  • 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. – Doug Hauf Mar 03 '14 at 19:05
  • 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](http://stackoverflow.com/a/23730355/588079) to [Q: Does Firefox browser not recognize table.cells?](http://stackoverflow.com/q/10701076/588079) – GitaarLAB May 19 '14 at 05:42
  • What does the first "row" do in: for (var i = 0, row; row = table.rows[i]; i++) { – Heneer Oct 01 '19 at 12:40
  • Is there a way to assign tags to `` and ``s of html table generated from dataframe? – user12379095 Jun 09 '20 at 08:48
  • I understood the loop but how to read the value in the cell? – iatharva Mar 01 '21 at 14:38
71

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
    })
})
Matthias Braun
  • 24,493
  • 16
  • 114
  • 144
dzida
  • 8,092
  • 2
  • 33
  • 55
  • 3
    Can't use jquery...company doesn't allow it. Don't ask why. – GregH Jun 17 '10 at 20:46
  • 22
    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. – Clinton Apr 01 '11 at 00:39
  • 14
    @Judy: Disagree on "crazy policy".... there are plenty of reasons for not using jQuery – Bigjim Mar 05 '14 at 16:02
  • JQuery is something that I have not used in a while and seems at just a glance something that is complex and not easy to get around in. But I think that is just because I have not used it all that much. – Doug Hauf Mar 22 '14 at 18:43
  • 5
    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. – Nick Feb 19 '15 at 15:24
  • jQuery in useless where you need 2-3 functions. It is slow and confusing when coding along with PHP. – TomeeNS May 19 '17 at 08:16
  • They probably don't allow it because it uses outside resources which aren't controlled by them. It also adds additional overhead and may be slower than default functions... They also change the language from something user-friendly and easy to read into a short-hand style language for most things - not all.. Some of the functions added by JQuery are much nicer to read such as the foreach function with callback - much shorter than writing the same repetitive for each code every time. – Acecool Dec 26 '17 at 07:56
19

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>
Kamil Kiełczewski
  • 53,729
  • 20
  • 259
  • 241
  • 3
    clean I would say – Shobi Apr 20 '19 at 17:11
  • Notice the "for ... of" in the loops. Would've been nice to have some explanation in your answer. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of – pensum Mar 08 '21 at 15:50
17

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

sbrbot
  • 5,075
  • 3
  • 31
  • 63
  • 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 – fib Littul Oct 04 '15 at 18:19
5

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.

mwag
  • 2,387
  • 22
  • 25
3

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 = "";
     }
}
Karim O.
  • 1,197
  • 5
  • 19
  • 33
  • Is that even JavaScript? Because your for loop looks somewhat like PHP. – aravk33 Sep 28 '17 at 13:30
  • 2
    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... – Acecool Dec 26 '17 at 07:58
  • If you are answering a question `# of rows` doesnt say anything... Please update your answer with the full code. – Si8 Dec 22 '20 at 16:09
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
    });
l30_4l3X
  • 81
  • 2
  • 4
  • Uncaught TypeError: Cannot read property 'toArray' of undefined --> This is what I got, when I tried this solution. – Vineela Thonupunuri Oct 21 '19 at 21:02
  • 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. – l30_4l3X Oct 22 '19 at 04:38
  • I used chrome too. – Vineela Thonupunuri Oct 22 '19 at 18:08
  • 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? – FlippingBinary Nov 08 '19 at 18:45
1

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>
Obsidian Age
  • 36,816
  • 9
  • 39
  • 58
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]);    
}
Foram Shah
  • 83
  • 4
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>");
}
D.Snap
  • 1,195
  • 1
  • 14
  • 13
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>
L3xpert
  • 169
  • 1
  • 8