0

I would like to create a function that maps a grid, represented as a nested array, to a html table.

For example take list:

[
    ['a', 'b', 'c'],
    ['d', 'e', 'f'],
    ['f', 'g', 'h']
]

and alter html table to show:

a b c 
d e f
f g h

Assume table size predetermined and list matches the dimensions.

So something that completes:

table border="1">
<tr>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
</tr>
<tr>
<td>row 2, cell 1</td>
<td>row 2, cell 2</td>
</tr>
</table>


<script>
update = [['a','b'],['c','d']]

function updateTableHTML(myArray) {
  // maps the list onto the existing table
}

updateTableHTML(update)
</script>
sock
  • 17
  • 1
  • 1
  • 4
  • 1
    please show us the code you have developed so far – S. Pauk Apr 05 '15 at 06:06
  • [Here is the link to similar post][1] [1]: http://stackoverflow.com/questions/15164655/generate-html-table-from-2d-javascript-array – XTR-Cold Apr 05 '15 at 06:11
  • Thanks, but my problem requires updating the existing table rather than creating a new one based on the list. I'll add my code – sock Apr 05 '15 at 06:28
  • @sock Okay good deal, be sure to also include in your question that this is a requirement. – jdphenix Apr 05 '15 at 06:29
  • Use a templating language such as Handlebars. –  Apr 05 '15 at 07:18
  • 2
    I keep getting amazed by questions where the poster did absolutely nothing to solve the question himself AND where the question looks like it comes out of a course AND the great lengths that some users here will still go to post an awesome answer (props to the user that did) – user1914292 Apr 05 '15 at 07:38
  • @user1914292 Don't blame him, everyone has been a noob at some point of their programming experience (of course this doesn't give you the right to post zero-effort questions, but still). Btw I keep getting amazed too ahahah. – Marco Bonelli Apr 05 '15 at 07:57

3 Answers3

2

You can either use the Array.prototype.forEach method, or a simple for loop. You just have to step throught each component of your bidimensional array and create a <td> element inside your table.

By the way, I don't feel comfortable with the assumption that the table already has got the right number of rows and columns (i.e. the update array fits the dimensions of the table): it's better to re-build the <tbody> from scratch to avoid any error and create a more flexible function. So let's assume an initial situation like this:

<table>
    <tbody id="your-table-body-id">
        <!-- whatever... -->
    </tbody>
</table>

Old school for loops

Here's an example with simple for loops:

function updateTableHTML(myArray) {
    var tableBody = document.getElementById("your-table-body-id"),
        newRow, newCell;

    // Reset the table
    tableBody.innerHTML = "";

    // Build the new table
    for (var i=0; i < myArray.length; i++) {
        newRow = document.createElement("tr");
        tableBody.appendChild(newRow);

        if (myArray[i] instanceof Array) {
            for (var j=0; j < myArray[i].length; j++) {
                newCell = document.createElement("td");
                newCell.textContent = update[i][j];
                newRow.appendChild(newCell);
            }
        } else {
            newCell = document.createElement("td");
            newCell.textContent = myArray[i];
            newRow.appendChild(newCell);
        }
    }
}

Fancy Array methods

And here's an example with the Array.prototype.forEach method:

function updateTableHTML(myArray) {
    var tableBody = document.getElementById("your-table-body-id");

    // Reset the table
    tableBody.innerHTML = "";

    // Build the new table
    myArray.forEach(function(row) {
        var newRow = document.createElement("tr");
        tableBody.appendChild(newRow);

        if (row instanceof Array) {
            row.forEach(function(cell) {
                var newCell = document.createElement("td");
                newCell.textContent = cell;
                newRow.appendChild(newCell);
            });
        } else {
            newCell = document.createElement("td");
            newCell.textContent = row;
            newRow.appendChild(newCell);
        }
    });
}

Notes

Be aware that the Array.prototype.forEach method may not be supported in every browser (i.e. Internet Explorer < 9). The for method looks easier and more comprehensible to me (although I'm not sure which one is faster), but that's your choice.

Also, in case you were wondering: I'm checking if (row instanceof Array) because in a situation like the following:

update = ["a", "b", "c"];

I am assuming you want a result like this:

a
b
c

and therefore you'll have to check if the value is an array before looping again and building the cells of each row.

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
  • ver newCell = document.createElement("td"); that should be var ... Uncaught SyntaxError: Unexpected identifier – Bruce Lim Oct 23 '16 at 03:08
0

do this

var a = [
   ['a', 'b', 'c'],
   ['d', 'e', 'f'],
   ['f', 'g', 'h']
];
var html = "<table>";
for(var i in a){
    html += "<tr>";
      for(var j in a[i])
        html += "<td>"+a[i][j]+"</td>";
    html += "</tr>";
}

html += "</table>";
document.write(html);
user3252197
  • 79
  • 1
  • 3
0

Simple solution

Since you say you're absolutely sure the dimensions all match up, then you can simply do

function updateTableHTML(update) {
    var cells = table.querySelectorAll('td');                       // get cells
    update = Array.concat.apply([], update);                        // flatten array
    update . forEach(function(v, i) { cells[i].textContent = v; }); // update
}

cells is just a list of all the <td> elements (flat).

We flatten the update nested array using Array#concat with apply. Array.concat.apply([], [[1, 2], [3, 4]]) turns into [].concat([1, 2], [3,4]), which yields [1, 2, 3, 4].

Now we have two parallel one-dimensional arrays, so we just need to loop through the update array and set the content of the corresponding element (cell) to each value.