Convert HTML tables to JSON div elements.
by stitot
HTML
<script src="https://cdn.jsdelivr.net/npm/@highcharts/grid-pro/grid-pro.js"></script>
<button id="convert-tables">Click to convert tables</button>
<table class="static">
<thead>
<tr><th>Name</th><th>Age</th><th>City</th></tr>
</thead>
<tbody>
<tr><td>Ada</td><td>36</td><td>London</td></tr>
<tr><td>Linus</td><td>55</td><td>Helsinki</td></tr>
<tr><td>Grace</td><td>40</td><td>New York</td></tr>
<tr><td>Alan</td><td>35</td><td>Manchester</td></tr>
<tr><td>Katherine</td><td>29</td><td>Toronto</td></tr>
<tr><td>Tim</td><td>48</td><td>San Francisco</td></tr>
<tr><td>Margaret</td><td>50</td><td>Sydney</td></tr>
</tbody>
</table>
<p>Just some lorem lipsum</p>
<table class="static">
<thead>
<tr><th>Country</th><th>Population (millions)</th><th>GDP (USD billions)</th></tr>
</thead>
<tbody>
<tr><td>Norway</td><td>5.5</td><td>579</td></tr>
<tr><td>Sweden</td><td>10.5</td><td>635</td></tr>
<tr><td>Finland</td><td>5.6</td><td>300</td></tr>
<tr><td>Denmark</td><td>5.9</td><td>420</td></tr>
<tr><td>Iceland</td><td>0.4</td><td>34</td></tr>
</tbody>
</table>
CSS
@import url("https://cdn.jsdelivr.net/npm/@highcharts/grid-pro/css/grid-pro.css");
table.static {
border-collapse: collapse;
margin: 20px 0;
th, td {
border: 1px solid #000;
padding: 8px;
}
}
JavaScript
let gridIndex = 0;
function parseValue(value) {
const trimmed = value.trim();
const num = Number(trimmed);
return !isNaN(num) && trimmed !== "" ? num : trimmed;
}
/* Assumes a well formed table with thead etc., but could be refactored to use e.g. first row in body as headers etc */
function tableToObject(table) {
const headers = [...table.tHead.rows[0].cells].map((c) =>
c.textContent.trim(),
);
const rows = [...table.tBodies[0].rows];
const data = Object.fromEntries(headers.map((h) => [h, []]));
rows.forEach((tr) => {
[...tr.cells].forEach((cell, i) => {
const key = headers[i];
if (key) data[key].push(parseValue(cell.textContent));
});
});
return data;
}
function replaceWithGrid(table, data) {
const div = document.createElement("div");
const id = `grid-converted-${++gridIndex}`;
div.id = id;
table.parentNode.insertBefore(div, table);
table.remove();
Grid.grid(id, {
dataTable: {
columns: data,
},
});
}
function convertAllTables() {
document.querySelectorAll("table").forEach((table) => {
const data = tableToObject(table);
replaceWithGrid(table, data);
});
}
document
.getElementById("convert-tables")
?.addEventListener("click", convertAllTables);