JSFiddle - React, Tailwind, and code Playground
HTML
<table id="data">
<tbody>
<tr>
<th>Column A</th>
<th>Column B</th>
<th>Column C</th>
<th>Column D</th>
</tr>
<tr>
<td>1</td>
<td>222.12</td>
<td>Shanghai</td>
<td>Bread</td>
</tr>
<tr>
<td>2</td>
<td>3.14</td>
<td>New York</td>
<td>Land</td>
</tr>
<tr>
<td>3</td>
<td>631.1</td>
<td>London</td>
<td>Peace</td>
</tr>
</tbody>
</table>
<ul id="control">
</ul>
CSS
html {
font-size: 13px;
font-family: Arial, sans-serif;
}
td, th {
padding: 4px 14px 6px;
text-align: center;
}
th {
font-weight: bold;
}
tr:first-child {
border-bottom: 1px solid #999;
}
tr:hover {
background-color: #efefef;
}
tr:first-child:hover {
background-color: #666;
color: white;
}
#control {
margin: 10px 0;
}
#control li {
margin: 2px 4px 3px;
}
#control input[type='checkbox'] {
margin-right: 3px;
}
#control label {
vertical-align: 2px;
font-size: 11px;
font-weight: bold;
}
JavaScript
// Generate a set of checkboxes to show hide columns
// as well as store table in variables
// DO NOT use this for very large tables
var header = $('#data th');
var row = $('#data tr');
var control = $('#control');
var table = new Array();
var visibleCol = new Array();
// Populate visibleCol
for (var i = 0; i < row.length; i++) {
visibleCol.push(i);
}
header.each(function(index) {
// Obtain current heading text
var heading = this.innerText || this.textContent;
var headerCount = index;
// Grab current column
var col = $('table td:nth-child(' + (index + 1) + '), table th:eq(' + (index) + ')');
// Create checkbox controls for table
var listitem = $('<li></li>').appendTo(control);
// Create the checkbox
$('<input type="checkbox" id="' + heading + '" checked="checked" />').appendTo(listitem).toggle(function() {
// Removal
col.remove();
for (var i = 0; i < row.length; i++) {
if (visibleCol[i] === headerCount) {
visibleCol.splice(i, 1);
break;
}
}
}, function() {
// Insertion is really really complex
// Find the next column
var insertAfter = visibleCol.length - 1;
for (var i = 0; i < visibleCol.length; i++) {
if (visibleCol[i] > headerCount) {
insertAfter = i - 1;
break;
}
}
visibleCol.splice(i, 0, headerCount);
row.each(function(index) {
// Insert it back
if (insertAfter < 0) {
$(this).prepend(col[index]);
} else {
$(this).children(':eq(' + insertAfter + ')').after(col[index]);
}
});
});
var label = $('<label></label>').appendTo(listitem).attr('for', heading).text(heading);
});