Home > database >  javascript make html table dynamically from json data
javascript make html table dynamically from json data

Time:12-29

i have json data like this, form a html table with dynamic headings. leave empty item in that box if there is no value

[
    {
        "name":"value1",
        "email":"[email protected]"
    },
    {
        "id":"123",
        "name":"value2",
    },
    {
        "name":"value3",
        "email":"[email protected]",
        "messsage":"lorem ipsum"
    },
    {
        "name":"value4",
        "email":"[email protected]"
    }
]

example table image

CodePudding user response:

This is an example on how to accept an array of arbitrary objects and just render them on a table by inspecting all of their properties.

Maybe this is an answer trying to address a problem bigger than what was strictly asked anyway it could be interesting to inspect this option.

The main issue with this solution is that, since there's no guarantee on the fact that all objects in the array will be consistent with their properties, the very first step is navigating the whole array collecting a set of unique property names found and use it to build the table header.

Such array of unique property names will be used also later to build the table rows. Since the list of objects doesn't hold the order of the property names, they will be listed randomly in the output table.

The way header and rows get built from the propertyNames and data goes like this:

const header = buildTableHeader(uniquePropertyNames);
const rows = buildTableBody(uniquePropertyNames, data);

The order of items in the uniquePropertyNames will rule how they will be rendered on the output table.

The entry point is just:

renderObjectsToTable(data, '#target');

Where '#target' is the selector to fetch the target table to render the data inside.

const data = [
  {
    "name": "value1",
    "email": "[email protected]"
  },
  {
    "id": "123",
    "name": "value2",
  },
  {
    "name": "value3",
    "email": "[email protected]",
    "messsage": "lorem ipsum"
  },
  {
    "name": "value4",
    "email": "[email protected]"
  }
];

renderObjectsToTable(data, '#target');
  
function renderObjectsToTable(objects, target){

  const uniquePropertyNames = [];
  objects.forEach(obj => {
    for (const prop in obj) {
      if(!uniquePropertyNames.includes(prop))
        uniquePropertyNames.push(prop);
    }
  });

  const header = buildTableHeader(uniquePropertyNames);
  const rows = buildTableBody(uniquePropertyNames, data);

  const table = document.querySelector(target);
  table.querySelector('thead').append(header);
  table.querySelector('tbody').append(...rows);
}


function buildTableHeader(propertyNames){
  const headerRow = document.createElement('tr');
  propertyNames.forEach( prop => {
    const headerCell = document.createElement('th');
    headerCell.innerText = prop;
    headerRow.append(headerCell);
  });
  return headerRow;
}

function buildTableBody(propertyNames, objects){
  const tableRows = [];
  objects.forEach(obj => {
    debugger;
    const currentRow = document.createElement('tr');
    propertyNames.forEach(prop => {
      const tableCell = document.createElement('td');
      debugger;
      const value = (obj[prop] === undefined) ? '' : obj[prop];
      tableCell.innerText = value;
      currentRow.append(tableCell);
    });
    tableRows.push(currentRow);
  });
  return tableRows;
}
#target{
  border-collapse: collapse;
}

#target th,
#target td
{
  border: solid 1px;
  padding: .2em;
}
<table id="target">
  <thead></thead>
  <tbody></tbody>
</table>

CodePudding user response:

const data = [{
    "name": "value1",
    "email": "[email protected]"
  },
  {
    "id": "123",
    "name": "value2",
  },
  {
    "name": "value3",
    "email": "[email protected]",
    "messsage": "lorem ipsum"
  },
  {
    "name": "value4",
    "email": "[email protected]"
  }
];

const tableBody = document.querySelector("tbody");
data.forEach(d => {
  tableBody.innerHTML  = `<tr>
                    <td>${d.id || ""}</td>
                    <td>${d.name || ""}</td>
                    <td>${d.email || ""}</td>
                    <td>${d.messsage || ""}</td>
                </tr>`;
})
table {
  border-collapse: collapse;
}

table :where(tr, th, td) {
  border: 1px solid gray;
}
<table>
  <thead>
    <tr>
      <th>id</th>
      <th>name</th>
      <th>email</th>
      <th>message</th>
    </tr>
  </thead>
  <tbody></tbody>
</table>

CodePudding user response:

Try running this: Sorry I don't have link to run this code. Just copy and paste then run. Hope this helps!

<!DOCTYPE html>
<html>

<body>

</body>
<script>
    document.addEventListener("DOMContentLoaded", function (event) {
        addTable();
    });
    const json = [
        {
            "name": "value1",
            "email": "[email protected]"
        },
        {
            "id": "123",
            "name": "value2",
        },
        {
            "name": "value3",
            "email": "[email protected]",
            "messsage": "lorem ipsum"
        },
        {
            "name": "value4",
            "email": "[email protected]"
        }
    ];

    function addTable() {
        var _headers = [];
        var body = document.getElementsByTagName('body')[0];
        var table = document.createElement('TABLE');
        table.border = '1';

        var tableBody = document.createElement('TBODY');
        var tableHeader = document.createElement('THEAD');
        table.appendChild(tableHeader);
        table.appendChild(tableBody);

        json.forEach(function (obj) {
            for (let key in obj) {
                if (_headers.find(elementKey => elementKey == key)) { }
                else _headers.push(key);
            }
        });

        for (let index = 0; index < json.length; index  ) {
            var _item = json[index];
            var tr = document.createElement('TR');
            tableBody.appendChild(tr);

            _headers.forEach(function (key) {

                var td = document.createElement('TD');
                td.appendChild(document.createTextNode(_item[key] !=null? _item[key] : ''));
                tr.appendChild(td);
            })

        }

        _headers.forEach(function (header) {

            var th = document.createElement('TH');
            th.appendChild(document.createTextNode(header));

            tableHeader.appendChild(th);

        })

        body.appendChild(table);
    }
</script>

</html>
  • Related