Home > Enterprise >  Create <tr> in Javascript using loops
Create <tr> in Javascript using loops

Time:11-17

I am trying to create a table where each cell consists of a letter and a number. see an image of the target table:

target table

Here is the HTML code that I am using. It's a simple button that when clicked, should call the populateTable() function and then display the table on the page.

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8"/>
        <title>Document</title>
    <style>
     table { border-collapse: collapse; margin: 1em 0; }
     td { border: 1px solid black; padding: 0.3em; }
    </style>
    </head>
    <body>
    
    <h2>Table</h2>
    <table id="the-table"></table>
    <button type="button" onclick="populateTable();">Populate table</button> 
    
    <script src="table.js"></script>
    </body>
</html>

But the main issue here is my JS code.

function populateTable(){
    letters = ["a", "b", "c", "d", "e"]
    numbers = ["1", "2", "3", "4", "5"]
    
    for(let i = 0; i < numbers.length; i  ){
        document.getElementById("the-table").innerHTML  = "<tr>"
        for(let j = 0; j < letters.length; j  ){
            document.getElementById("the-table").innerHTML  = "<td>"   letters[j]   numbers[i]   "</td>"
        }
        document.getElementById("the-table").innerHTML  = "</tr>"
    }
}

How can I create a new <tr> after inner loop exits?

The outcome of this current code looks like this

Please help :'D

I tried moving around the

document.getElementById("the-table").innerHTML  = "<tr>"

and

document.getElementById("the-table").innerHTML  = "</tr>"

but to no avail. I tried looking for an answer online, but I found nothing that is useful to my case. things like appendChild were not really what i am looking for exactly. I just want to know why these lines mentioned above ("<tr>") won't work and what's the easiest way to fix this?

CodePudding user response:

You can use creatElement instead of writing text. InnerHtml can be problematic security wise. Look into XSS if you are curious.

const letters = ["a", "b", "c", "d", "e"]
const numbers = ["1", "2", "3", "4", "5"]

const table = document.getElementById("the-table");

function populateTable() {
  for (let i = 0; i < numbers.length; i  ) {
    const row = document.createElement("tr");
    for (let j = 0; j < letters.length; j  ) {
      const column = document.createElement("td");
      column.textContent = letters[j]   numbers[i];
      row.appendChild(column);
    }
    table.appendChild(row);
  }
}
table {
  border-collapse: collapse;
  margin: 1em 0;
}

td {
  border: 1px solid black;
  padding: 0.3em;
}
<h2>Table</h2>
<table id="the-table"></table>
<button type="button" onclick="populateTable();">Populate table</button>

Your original logic was good but innerHTML is troublesome. If you inspect the html you will see that with innerHtml:

<table id="the-table"><tbody><tr></tr></tbody><tbody><tr><td>a1</td></tr></tbody><tbody><tr><td>b1</td></tr></tbody><tbody><tr><td>c1</td></tr></tbody><tbody><tr><td>d1</td></tr></tbody><tbody><tr><td>e1</td></tr></tbody><tbody><tr></tr></tbody><tbody><tr><td>a2</td></tr></tbody><tbody><tr><td>b2</td></tr></tbody><tbody><tr><td>c2</td></tr></tbody><tbody><tr><td>d2</td></tr></tbody><tbody><tr><td>e2</td></tr></tbody><tbody><tr></tr></tbody><tbody><tr><td>a3</td></tr></tbody><tbody><tr><td>b3</td></tr></tbody><tbody><tr><td>c3</td></tr></tbody><tbody><tr><td>d3</td></tr></tbody><tbody><tr><td>e3</td></tr></tbody><tbody><tr></tr></tbody><tbody><tr><td>a4</td></tr></tbody><tbody><tr><td>b4</td></tr></tbody><tbody><tr><td>c4</td></tr></tbody><tbody><tr><td>d4</td></tr></tbody><tbody><tr><td>e4</td></tr></tbody><tbody><tr></tr></tbody><tbody><tr><td>a5</td></tr></tbody><tbody><tr><td>b5</td></tr></tbody><tbody><tr><td>c5</td></tr></tbody><tbody><tr><td>d5</td></tr></tbody><tbody><tr><td>e5</td></tr></tbody></table>

If you really want to use innerHTML, there is an answer showcasing how. Don't do it if you can. A topic on the subject: innerHTML is adding tbody, why?. Their recommendation is the same as mine "You shouldn't really be building up a table with innerHTML operations anyways."

CodePudding user response:

The issue here is that everytime you call = on the table element it creates a new tbody. So all the TDs will show up on a new line. You need to create a variable and create the entire inner table structure and then add it to your table like so. If you inspect the elements after running your code you can see all the tbodies. I hope this helps.

It should be noted, this is not the "proper" way to do this. I'm just providing the fix for the method you chose, as that's how people learn and grow :)

function populateTable(){
    letters = ["a", "b", "c", "d", "e"]
    numbers = ["1", "2", "3", "4", "5"]
    innerTable = '';
    
    for(let i = 0; i < numbers.length; i  ){
        innerTable  = "<tr>"
        
        for(let j = 0; j < letters.length; j  ){
            innerTable  = "<td>"   letters[j]   numbers[i]   "</td>"
        }
        
        innerTable  = "</tr>"
    }
    
    document.getElementById("the-table").innerHTML  = innerTable;
}

CodePudding user response:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8"/>
        <title>Document</title>
    <style>
     table { border-collapse: collapse; margin: 1em 0; }
     td { border: 1px solid black; padding: 0.3em; }
    </style>
    </head>
    <body>
    
    <h2>Table</h2>
    <table id="the-table"></table>
    <button type="button" onclick="populateTable();">Populate table</button> 
    
    <script >
    function populateTable(){
    letters = ["a", "b", "c", "d", "e"]
    numbers = ["1", "2", "3", "4", "5"]
    let str=""
    numbers.map(n=>{
        str ="<tr>"
        letters.map(l=>{
            str =`<td> ${l} ${n} </td>`
        })
        str ="</tr>"
    })
        //console.log('str ',str);
        document.getElementById("the-table").innerHTML=str;
    }

    </script>
    </body>
</html>

By using ES6 you can use the nested map to iterate the array. Then add to the string after every iteration. Here is the newly created populateTable() function for you.

function populateTable(){
    letters = ["a", "b", "c", "d", "e"]
    numbers = ["1", "2", "3", "4", "5"]
    let str=""
    numbers.map(n=>{
        str ="<tr>"
        letters.map(l=>{
            str =`<td> ${l} ${n} </td>`
        })
        str ="</tr>"
    })
        console.log('str ',str);
        document.getElementById("the-table").innerHTML=str;
    } 
  • Related