I'm currently trying to add column-level filtering to an HTML table, generated from a click event listener, using the TableFilter JavaScript library, however I'm receiving the following error in the console:
Error: Could not instantiate TableFilter: HTML table requires at least 1 row.
The code I'm using to generate the table is below; in essence I'm taking in an array of objects, then looping through them to create a header row, then data rows and then appending the table to a <div>. The table itself renders without issue, but I'm unable to attach filters - could anyone shed any light on why this error is occurring? I'd suspected it might be something to do with trying to add a filter to the table before the element had been rendered, but I couldn't see why that would be the case. I'm aware that the documentation for the library recommends adding a <script> tag under the table, and I've also tried this however I'm not sure how to do that correctly since the table doesn't exist until the click event takes place (hence adding it to the onclick function).
HTML
<html>
<head>
<script src="script.js"></script>
<script src="/TableFilter/dist/tablefilter/tablefilter.js"></script>
</head>
<body>
<button id="my-button">Create Table</button>
<div id="my-table-container">
<!-- table -->
</div>
<script>
button = document.getElementById('my-button');
button.addEventListener('click', renderTable);
</script>
</body>
</html>
JavaScript
const createTableFromObjectArray = (data, containerRef, tableRef) => {
// elements
let container = document.getElementById(containerRef);
let table = document.createElement('table');
table.setAttribute('id', tableRef);
// clear the DOM if the table is already present
while (container.firstChild) {
container.removeChild(container.firstChild);
}
// create header
let headerRow = document.createElement('tr');
const colNames = Object.keys(data[0]);
colNames.forEach(name => {
let headerCell = document.createElement('th');
let headerText = document.createTextNode(name);
headerCell.appendChild(headerText);
headerRow.append(headerCell);
});
table.appendChild(headerRow);
// add rows to table
data.forEach(doc => {
let tableRow = document.createElement('tr');
Object.values(doc).forEach(value => {
let rowCell = document.createElement('td');
let cellText = document.createTextNode(value);
rowCell.appendChild(cellText);
tableRow.appendChild(rowCell);
});
table.appendChild(tableRow);
});
// add table to DOM and add filters
container.appendChild(table);
let tf = new TableFilter(table, {
base_path: '/TableFilter/dist/tablefilter/'
});
tf.init();
}
const renderTable = () => {
const data = [{'Name': 'John', 'Eyes': 'Blue', 'Hair': 'Brown'}];
const containerRef = 'my-table-container';
const tableRef = 'my-table';
createTableFromObjectArray(data, containerRef, tableRef);
}