4

The individual table rows are giving me a problem. I have created what I want using divs but I need to use a table instead of divs. My table has 220 cells, 10 rows, and 22 columns. Each cell has to have the value of i inside the innerHTML. Here is similar to what i want using Divs ( although the cell height and width does not have to be set ):

<!DOCTYPE html>
<html>
    <head>
        <style>
            #container{ 
            width:682px; height:310px; 
            background-color:#555; font-size:85%;
            }

            .cell { 
            width:30px; height:30px;
            background-color:#333; color:#ccc;
            float:left; margin-right:1px;
            margin-bottom:1px;
            }
        </style>
    </head>

    <body>
        <div id="container">
            <script>
                for( var i = 1; i <= 220; i++ ){
                    document.getElementById( 'container' ).innerHTML += 
                    '<div class="cell">' + i + '</div>'
                }
            </script>
        </div>
    </body>
</html>

http://jsfiddle.net/8r6619wL/

This is my starting attempt using a table:

<script>
    for( var i = 0; i <= 10; i++ )
    {
        document.getElementById( 'table' ).innerHTML +=
        '<tr id = "row' + i + '"><td>...</td></tr>';
    }
</script>

But that code somehow dynamically creates a bunch of tbody elements. Thanks for help as I newb

  • Use `document.createElement()` instead of `innerHTML` for dynamically inserting elements. `innerHTML` will remove any events attached to the child elements and will have to re-render _every single row element_ all over again each time you parse it. – Makaze Dec 22 '14 at 00:03

4 Answers4

7

You can do this with nested loops - one to add cells to each row and one to add rows to the table. JSFiddle

var table = document.createElement('table'), tr, td, row, cell;
for (row = 0; row < 10; row++) {
    tr = document.createElement('tr');
    for (cell = 0; cell < 22; cell++) {
        td = document.createElement('td');
        tr.appendChild(td);
        td.innerHTML = row * 22 + cell + 1;
    }
    table.appendChild(tr);
}
document.getElementById('container').appendChild(table);

Alternatively, you can create an empty row of 22 cells, clone it 10 times, and then add the numbers to the cells.

var table = document.createElement('table'),
    tr = document.createElement('tr'),
    cells, i;
for (i = 0; i < 22; i++) { // Create an empty row
    tr.appendChild(document.createElement('td'));
}
for (i = 0; i < 10; i++) { // Add 10 copies of it to the table
    table.appendChild(tr.cloneNode(true));
}
cells = table.getElementsByTagName('td'); // get all of the cells
for (i = 0; i < 220; i++) {               // number them
    cells[i].innerHTML = i + 1;
}
document.getElementById('container').appendChild(table);

And a third option: add the cells in a single loop, making a new row every 22 cells.

var table = document.createElement('table'), tr, td, i;
for (i = 0; i < 220; i++) { 
    if (i % 22 == 0) { // every 22nd cell (including the first)
        tr = table.appendChild(document.createElement('tr')); // add a new row
    }
    td = tr.appendChild(document.createElement('td'));
    td.innerHTML = i + 1;
}
document.getElementById('container').appendChild(table);

Edit - how I would do this nowadays (2021)... with a helper function of some kind to build dom elements, and using map.

function make(tag, content) {
  const el = document.createElement(tag);
  content.forEach(c => el.appendChild(c));
  return el;
}

document.getElementById("container").appendChild(make(
    "table", [...Array(10).keys()].map(row => make(
      "tr", [...Array(22).keys()].map(column => make(
        "td", [document.createTextNode(row * 22 + column + 1)]
    ))
  ))
));
Stuart
  • 9,597
  • 1
  • 21
  • 30
2

There are a lot of ways to do this, but one I've found to be helpful is to create a fragment then append everything into it. It's fast and limits DOM re-paints/re-flows from a loop.

Take a look at this jsbin example.

Here's the modified code:

function newNode(node, text, styles) {
  node.innerHTML = text;
  node.className = styles;
  return node;
}

var fragment = document.createDocumentFragment(),
  container = document.getElementById("container");

for(var i = 1; i <= 10; i++) {
  var tr = document.createElement("tr");
  var td = newNode(document.createElement("td"), i, "cell");
  tr.appendChild(td);
  fragment.appendChild(tr);
}

container.appendChild(fragment);

You can modify whatever you want inside the loop, but this should get you started.

psdpainter
  • 631
  • 1
  • 10
  • 25
  • What about the other tds though?Is it possible to do this: http://jsfiddle.net/8r6619wL/ to the table? –  Dec 22 '14 at 00:12
1

That's because the DOM magically wraps a <tbody> element around stray table rows in your table, as it is designed to do. Fortunately, you can rewrite your loop in a way that will add all of those table rows at once, rather than one at a time.

The simplest solution to achieve this would be to store a string variable, and concatenate your rows onto that. Then, after you've concatenated your rows together into one string, you can set the innerHTML of your table element to that one string like so:

<script>
(function() {
    var rows = '';
    for( var i = 0; i <= 10; i++ )
    {
        rows += '<tr id = "row' + i + '"><td>...</td></tr>';
    }
    document.getElementById( 'table' ).innerHTML = rows;
}());
</script>

Here's a JSFiddle that demonstrates what I've just written. If you inspect the HTML using your browser's developer tools, you'll notice that one (and only one) tbody wraps around all of your table rows.

Also, if you're wondering, the odd-looking function which wraps around that code is simply a fancy way of keeping the variables you've created from becoming global (because they don't need to be). See this blog post for more details on how that works.

Community
  • 1
  • 1
caleb531
  • 4,111
  • 6
  • 31
  • 41
  • This helps me move forward, but the end goal is for the table to look like this: http://jsfiddle.net/8r6619wL/. My plan was to loop through the rows first, then inside of each row, loop through each td element. Is this possible to do this and keep I incrementing? –  Dec 22 '14 at 00:07
0

please check this out. This is a very simple way to create a table using js and HTML

<body>
    <table cellspacing="5" >
        <thead>
            <tr>
                <td>Particulate count</td>
                <td>Temperature</td>
                <td>Humidity</td>
            </tr>
        </thead>
        <tbody id="xxx">

        </tbody>
    </table>

    <script>
        for (var a=0; a < 2; a++) {
            var table1 = document.getElementById('xxx');
            var rowrow =  document.createElement('tr');
        
            for ( i=0; i <1; i++) {
                var cell1  =  document.createElement('td');
                var text1 = document.createTextNode('test1'+a);

                var cell2  =  document.createElement('td');
                var text2 = document.createTextNode('test2'+a);

                var cell3  =  document.createElement('td');
                var text3 = document.createTextNode('test3'+a);

                cell1.appendChild(text1);
                rowrow.appendChild(cell1);

                cell2.appendChild(text2);
                rowrow.appendChild(cell2);

                cell3.appendChild(text3);
                rowrow.appendChild(cell3);
            }
            table1.appendChild(rowrow);
        }
    </script>
</body>
</html>