-1

I need to generate a table from an array of objects.

For example, the array is:

let arr = [{name: 'Player1',score:10},
{name: 'Player2',score: 7},
{name: 'Player3',score:3}]

And the HTML output should be:

Name Score
Player1 10
PLayer2 7
Player3 3

I could not think of a way to achieve this through vanilla JS. Also, after the table is created, how will I apply CSS to it?

Any help would be appreciated.

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
RaptorRV
  • 55
  • 1
  • 9
  • [Loop over the data](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#for...of_statement) and create a row for each object where each cell is the value of a property. – Andy Jun 07 '22 at 07:36
  • 1
    https://stackoverflow.com/questions/72380775/write-multiple-values-from-json-file-into-html-table-with-javascipt/72381646#72381646 – Andy Jun 07 '22 at 07:40

3 Answers3

2

You can use something like

<body>
<div class="main-container">
    <table>
        <thead>
            <tr>
                <th>player</th>
                <th>score</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
</div>
<script>
    const data = [{ name: 'Player 1', score: 10 },
    { name: 'Player 2', score: 7 },
    { name: 'Player 3', score: 3 }]

    const table = document.querySelector('tbody')
    data.forEach((item) => {
        table.innerHTML = table.innerHTML + `<tr>
                <td>${item.name}</td>
                <td>${item.score}</td>
            </tr>`
    })
</script>
Alexey
  • 21
  • 2
  • So changing the innerHTML of the table actually has an impact on the HTML output. As a newbie, I did not know that. Thanks. – RaptorRV Jun 07 '22 at 07:46
  • 2
    FYI [Why is "element.innerHTML+=" bad code?](https://stackoverflow.com/questions/11515383/why-is-element-innerhtml-bad-code). – Andy Jun 07 '22 at 07:49
  • Don't use `table.innerHTML +=`. Use `table.appendChild()` instead. – Donald Duck Jun 07 '22 at 09:25
2

You can loop through the array and for each element add a row to a newly forged table that will be added to the document at the end.

This is a demo:

let players = [
  {name: 'Player1',score:10},
  {name: 'Player2',score: 7},
  {name: 'Player3',score:3}
];

const newTable = document.createElement("table");
newTable.innerHTML = "<thead><th>Player</th><th>Score</th></thead>";
for(player of players){
    const newRow = document.createElement("tr");
    const tdPlayer = document.createElement("td");
    const tdScore = document.createElement("td");
    tdPlayer.textContent = player.name;
    tdScore.textContent = player.score;    
    newRow.appendChild(tdPlayer);
    newRow.appendChild(tdScore);
    newTable.appendChild(newRow);
}

const target = document.getElementById('target');
target.appendChild(newTable);
table{
  border: solid 1px black;
}

table td{
  border: solid 1px black;
}
<div id="target">
</div>
Diego D
  • 6,156
  • 2
  • 17
  • 30
  • for the sake of records `innerHTML` it's not the best way to go and to scale... but it surely gets the job done... just keep in mind – Diego D Jun 07 '22 at 12:09
0

Based on Diego D's answer, I made a more scalable (extensible) function (primarily for my needs).

const players = [
  {name: 'Player1', score: 10, id:'aaa', address: 'usa'},
  {name: 'Player2', score: 7,  id:'bbb', address: 'mars'},
  {name: 'Player3', score: 3,  id:'ccc', address: 'jupyter'},
];
const fullHeaders = Object.keys(players[0]);  //use full header
const selectedHeaders = ['name', 'score'];    //or filter as needed

const table1 = makeTable(fullHeaders, players);
const table2 = makeTable(selectedHeaders, players);

function makeTable(headers, players, target = document.body) {
  const newTable = document.createElement("table");

  const thead = document.createElement("thead");
  for(header of headers) {
    const th = document.createElement("th");
    th.textContent = header;
    thead.appendChild(th);
  }
  newTable.appendChild(thead);

  for(player of players) {
    const newRow = document.createElement("tr");
    for(header of headers) {
      const td = document.createElement("td");
      td.textContent = player[header];
      newRow.appendChild(td);
    }
    newTable.appendChild(newRow);
  }

  return target.appendChild(newTable);
}
Sangbok Lee
  • 2,132
  • 3
  • 15
  • 33