Search code examples
javascripthtmljsonhtml-tablenested-lists

How to dynamically create a table from a JSON with nested lists using Javascript?


I'm trying to create an HTML table from a JSON file which values can include nested lists.

Example:

{
     "entry 1":[
         ["text1", "text2", "text3"],
         ["text4", "text5", "text6"],
         ["text7", "text8", "text9"]
    ],
    "entry 2": "N/A",
    "entry 3": [
         ["text1", "text2", "text3"],
         ["text4", "text5", "text6"]
    ],
    "entry 4": [
         ["text1", "text2"],
         ["text3", "text4"]
    ]
}

My goal is to create an HTML table with a predefined header for the two columns:

  • header_title_1
  • header_title_2

That will never change, and the table should look like this:

table_example

Thanks for your help !


Solution

  • Using the for...in iterator on the object to get the key. I created a row for each property, then a cell for the key and value. Then if the value isn't an array, like the entry2 key, we make it an array to iterate through the elements.

    Creating a new row for each element in the array and creating a new cell for the items in the array. If it is an array, the value would be converted to a string separated by the comma ',' or it would be set just as it is.

    Then we append the elements to the body of the table.

    const tbody = document.getElementById('table').tBodies[0];
    const obj = {"entry 1":[["text1","text2","text3"],["text4","text5","text6"],["text7","text8","text9"]],"entry 2":"N/A","entry 3":[["text1","text2","text3"],["text4","text5","text6"]],"entry 4":[["text1","text2"],["text3","text4"]]};
    
    function createTable(obj) {
      tbody.innerHTML = ''; // To reset the table
      
      for (const key in obj) {
        if (!obj.hasOwnProperty(key)) continue;
        const value = Array.isArray(obj[key]) ? obj[key] : [obj[key]];
        const row = document.createElement('tr');
        const key_cell = Object.assign(document.createElement('td'), {
          innerText: key
        });
        const value_column = Object.assign(document.createElement('td'), {
          innerText: value.splice(0, 1)[0]
        });
    
        row.append(...[key_cell, value_column]);
        tbody.append(row);
    
        value.forEach(val => {
          const inner_row = document.createElement('tr');
          const empty_key_cell = document.createElement('td');
          const value_cell = Object.assign(document.createElement('td'), {
            innerText: val
          });
          inner_row.append(...[empty_key_cell, value_cell]);
          tbody.append(inner_row);
        });
      }
    }
    
    createTable(obj);
    <table id="table" border="1" width="100%">
      <thead>
        <td>header_title_1</td>
        <td>header_title_2</td>
      </thead>
      <tbody></tbody>
    </table>