Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Turn nested JSON data into HTML table?

I'm trying to use javascript to convert this JSON data into HTML table.

This is my code so far; however, I am confused about how to process the 'contacts' part and put them into a cell like this: first_name + last_name + position of the CEO and CTO.

I was thinking of using company_info[i]["contacts"].forEach(function(e){} to extract the contacts data but I am not sure how to put it together in the cell.

Any help appreciated!

My code:

function CreateTableFromJSON() {
  var company_info = [{
      "id": 1,
      "company_name": "ACompany",
      "established": 1999,
      "industry": "Tech",
      "contacts": [{
          "first_name": "AAFirst",
          "last_name": "AALast",
          "position": "CEO"
        },
        {
          "first_name": "ABFirst",
          "last_name": "ABLast",
          "position": "CTO"
        }
      ]
    },
    {
      "id": 2,
      "company_name": "BCompany",
      "established": 1998,
      "industry": "Med",
      "contacts": [{
          "first_name": "BAFirst",
          "last_name": "BALast",
          "position": "CEO"
        },
        {
          "first_name": "BBFirst",
          "last_name": "BBLast",
          "position": "CTO"
        }
      ]
    },
    {
      "id": 3,
      "company_name": "CCompany",
      "established": 1997,
      "industry": "Ivest",
      "contacts": [{
          "first_name": "CAFirst",
          "last_name": "CALast",
          "position": "CEO"
        },
        {
          "first_name": "CBFirst",
          "last_name": "CBLast",
          "position": "CTO"
        }
      ]
    },
    {
      "id": 4,
      "company_name": "DCompany",
      "established": 1996,
      "industry": "Tech",
      "contacts": [{
          "first_name": "DAFirst",
          "last_name": "DALast",
          "position": "CEO"
        },
        {
          "first_name": "DBFirst",
          "last_name": "DBLast",
          "position": "CTO"
        }
      ]
    },
    {
      "id": 5,
      "company_name": "ECompany",
      "established": 1995,
      "industry": "Med",
      "contacts": [{
          "first_name": "EAFirst",
          "last_name": "EALast",
          "position": "CEO"
        },
        {
          "first_name": "EBFirst",
          "last_name": "EBLast",
          "position": "CTO"
        }
      ]
    }
  ]
  // EXTRACT VALUE FOR HTML HEADER. 
  // ('ID', 'Company Name', 'Established','Industry', 'Contacts')

  var col = [];

  for (var i = 0; i < company_info.length; i++) {
    for (var key in company_info[i]) {
      if (col.indexOf(key) === -1) {
        col.push(key);
      }
    }
  }
  //Create a table
  var table = document.createElement("table");
  //Create  table rows
  var tr = table.insertRow(-1);
  //Create table headers
  for (var i = 0; i < col.length; i++) {
    var th = document.createElement("th"); // TABLE HEADER.
    th.innerHTML = col[i];
    tr.appendChild(th);
  }

  //Add JSON data to table as rows
  for (var i = 0; i < company_info.length; i++) {
    tr = table.insertRow(-1);
    for (var j = 0; j < col.length; j++) {
      var tabCell = tr.insertCell(-1);
      tabCell.innerHTML = company_info[i][col[j]];

    }
  

}

var divContainer = document.getElementById("showData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
<html>
<head>
    <title>Convert JSON Data to HTML Table</title>
    <style>
        table, th, td 
        {
            margin:10px 0;
            border:solid 1px #333;
            padding:2px 4px;
            font:15px Verdana;
        }
        th {
            font-weight:bold;
        }
    </style>
</head>
<body>
    <input type="button" onclick="CreateTableFromJSON()" value="Create Table From JSON" />
    <div id="showData"></div>
    <script type="text/javascript" src="script.js"></script>
</body>
</html>

  
like image 857
ChuChu Avatar asked Dec 20 '17 22:12

ChuChu


2 Answers

As I understood, You want to put contacts array in the cell. We know that contacts column is 4 in nested for loop. You can write a simple if validation to check what the current j is. If j is not 4 which is contacts column, insert value in the table. If the current j value is 4, then make one more nested for loop which will loop contacts array in each object.

  var company_info = [{
      "id": 1,
      "company_name": "ACompany",
      "established": 1999,
      "industry": "Tech",
      "contacts": [{
        "first_name": "AAFirst",
        "last_name": "AALast",
        "position": "CEO"
      }, {
        "first_name": "ABFirst",
        "last_name": "ABLast",
        "position": "CTO"
      }]
    }, {
      "id": 2,
      "company_name": "BCompany",
      "established": 1998,
      "industry": "Med",
      "contacts": [{
        "first_name": "BAFirst",
        "last_name": "BALast",
        "position": "CEO"
      }, {
        "first_name": "BBFirst",
        "last_name": "BBLast",
        "position": "CTO"
      }]
    }, {
      "id": 3,
      "company_name": "CCompany",
      "established": 1997,
      "industry": "Ivest",
      "contacts": [{
        "first_name": "CAFirst",
        "last_name": "CALast",
        "position": "CEO"
      }, {
        "first_name": "CBFirst",
        "last_name": "CBLast",
        "position": "CTO"
      }]
    }, {
      "id": 4,
      "company_name": "DCompany",
      "established": 1996,
      "industry": "Tech",
      "contacts": [{
        "first_name": "DAFirst",
        "last_name": "DALast",
        "position": "CEO"
      }, {
        "first_name": "DBFirst",
        "last_name": "DBLast",
        "position": "CTO"
      }]
    }, {
      "id": 5,
      "company_name": "ECompany",
      "established": 1995,
      "industry": "Med",
      "contacts": [{
        "first_name": "EAFirst",
        "last_name": "EALast",
        "position": "CEO"
      }, {
        "first_name": "EBFirst",
        "last_name": "EBLast",
        "position": "CTO"
      }]
    }]
    // EXTRACT VALUE FOR HTML HEADER. 
    // ('ID', 'Company Name', 'Established','Industry', 'Contacts')

  var col = [];

  for (var i = 0; i < company_info.length; i++) {
    for (var key in company_info[i]) {
      if (col.indexOf(key) === -1) {
        col.push(key);
      }
    }
  }
  //Create a table
  var table = document.createElement("table");
  //Create  table rows
  var tr = table.insertRow(-1);
  //Create table headers
  for (var i = 0; i < col.length; i++) {
    var th = document.createElement("th"); // TABLE HEADER.
    th.innerHTML = col[i];
    tr.appendChild(th);
  }

  //Add JSON data to table as rows
  for (var i = 0; i < company_info.length; i++) {

    tr = table.insertRow(-1);

    for (var j = 0; j < col.length; j++) {
      var tabCell = tr.insertCell(-1);
      if (j !== 4) {
        tabCell.appendChild(document.createTextNode(company_info[i][col[j]]));
      } else {
        for (var x = 0; x < company_info[i].contacts.length; x++) {
          var firstName = company_info[i].contacts[x].first_name,
            lastName = company_info[i].contacts[x].last_name,
            position = company_info[i].contacts[x].position;

          tabCell.appendChild(document.createTextNode(" " + firstName + " " + lastName + ", " + position));
        }
      }
    }

  }


  var divContainer = document.getElementById("showData");
  divContainer.innerHTML = "";
  divContainer.appendChild(table);
<div id="showData">

</div>

Let me know if this is what you want. If not, I will edit the answer.

like image 136
Alican Balik Avatar answered Oct 11 '22 16:10

Alican Balik


I think the best approach is to add the contacts as divs or as ul/lis inside the contacts cell (in my approach down bellow, I used divs).

I also used array functions forEach to iterate the arrays, which can easily convert them to simple for loops if you want:

function CreateTableFromJSON(array) {
  var table = document.createElement("table");                             // the table elements

  var col = Object.keys(array[0]);                                         // the columns names (I think taking the keys of the first object will suffice)
  
  // HEADER:
  var tr = table.insertRow(-1);                                            // the header row
  col.forEach(function(key) {                                              // for each key in col
    var th = document.createElement("th");                                 // create a header cell
    th.textContent = key;                                                  // use textContent instead of innerHTML (it's better)
    tr.appendChild(th);
  });

  // ROWS:
  array.forEach(function(obj) {                                            // for each object obj in company_info
    var tr = table.insertRow(-1);                                          // create a row for it
    col.forEach(function(key) {                                            // and for each key in col
      var tabCell = tr.insertCell(-1);                                     // create a cell
      if (Array.isArray(obj[key])) {                                       // if the current value is an array, then
        obj[key].forEach(function(contact) {                               // for each entry in that array
          var div = document.createElement("div");                         // create a div and fill it
          div.textContent = contact.first_name + " " + contact.last_name + ", " + contact.position;
          tabCell.appendChild(div);                                        // then add the div to the current cell
        });
      } else {                                                             // otherwise, if the value is not an array (it's a string)
        tabCell.textContent = obj[key];                                    // add it as text
      }
    });
  });

  var divContainer = document.getElementById("showData");
  divContainer.innerHTML = "";
  divContainer.appendChild(table);
}

var company_info = [{"id":1,"company_name":"ACompany","established":1999,"industry":"Tech","contacts":[{"first_name":"AAFirst","last_name":"AALast","position":"CEO"},{"first_name":"ABFirst","last_name":"ABLast","position":"CTO"}]},{"id":2,"company_name":"BCompany","established":1998,"industry":"Med","contacts":[{"first_name":"BAFirst","last_name":"BALast","position":"CEO"},{"first_name":"BBFirst","last_name":"BBLast","position":"CTO"}]},{"id":3,"company_name":"CCompany","established":1997,"industry":"Ivest","contacts":[{"first_name":"CAFirst","last_name":"CALast","position":"CEO"},{"first_name":"CBFirst","last_name":"CBLast","position":"CTO"}]},{"id":4,"company_name":"DCompany","established":1996,"industry":"Tech","contacts":[{"first_name":"DAFirst","last_name":"DALast","position":"CEO"},{"first_name":"DBFirst","last_name":"DBLast","position":"CTO"}]},{"id":5,"company_name":"ECompany","established":1995,"industry":"Med","contacts":[{"first_name":"EAFirst","last_name":"EALast","position":"CEO"},{"first_name":"EBFirst","last_name":"EBLast","position":"CTO"}]}];

CreateTableFromJSON(company_info);
table { border-collapse: collapse; }
td, th { border: 1px solid black; }
tr { background: #ccc; }
tr:nth-child(odd) { background: #eee; }
td > div { white-space: pre; }
<div id="showData"></div>
like image 20
ibrahim mahrir Avatar answered Oct 11 '22 18:10

ibrahim mahrir