Replacement for HTML tables on smaller devices
6 April 2023
Sometimes it's hard show all content from HTML table on mobile devices in a way that it looks good an readable. There are already various methods for tables to look better on smaller screen but there is one that in some cases might work better in a way that it render data in non-table way. This method should work fine on tables that uses its first row as column names container.
In short, we'll implement DOM manipulation and create mobile specific HTML (new elements derived from existrng original table, tr and td elements) visible only at smaller width devices (vida media queries) and extracted from original table layout.
document.addEventListener('DOMContentLoaded', function () {
generateMobileTables();
}, false);
function generateMobileTables() {
var selector = "responsive";
var allTables = document.getElementsByClassName(selector);
if (allTables.length > 0) {
var tableWrapper = document.createElement('div');
tableWrapper.setAttribute("class", "table-wrapper");
for (i = 0; i < allTables.length; ++i) {
allTables[i].parentNode.insertBefore(tableWrapper, allTables[i]);
tableWrapper.appendChild(allTables[i]);
}
for (i = 0; i < allTables.length; ++i) {
var tbl = allTables[i];
var columns = [];
var first_row_cells = tbl.rows[0].cells;
for (c = 0; c < first_row_cells.length; ++c) {
columns.push(first_row_cells[c].innerHTML);
}
var mobileTable = document.createElement('div');
mobileTable.setAttribute("class", "mobile-table");
var rows = tbl.rows;
if (rows.length <= 1) continue;
for (r = 1; r < rows.length; ++r) {
for (c = 0; c < rows[r].cells.length; ++c) {
var html = rows[r].cells[c].innerHTML;
if (html == "" || html == " ") html = "-";
var p = document.createElement('p');
p.innerHTML = columns[c];
mobileTable.append(p);
var div = document.createElement('div');
div.innerHTML = html;
mobileTable.append(div);
}
var hr = document.createElement('hr');
mobileTable.append(hr);
}
tbl.parentElement.after(mobileTable);
}
}
}
.mobile-table {
display: none;
border: solid 1px #ddd;
padding: 2rem;
}
.mobile-table > p {
font-weight: bold;
margin-bottom: 0;
}
.mobile-table > div {
margin-bottom: 1rem;
}
.mobile-table hr:last-child {
display: none;
}
@media only screen and (max-width: 640px){
.table-wrapper {
display: none;
}
.mobile-table {
display: block;
}
}