Skip to content

Instantly share code, notes, and snippets.

@DvdGiessen
Last active July 7, 2023 10:04
Show Gist options
  • Save DvdGiessen/6256ab5cbdb17e58593a1d74a9b009e9 to your computer and use it in GitHub Desktop.
Save DvdGiessen/6256ab5cbdb17e58593a1d74a9b009e9 to your computer and use it in GitHub Desktop.
JS function to make tables sortable and filterable
function sortableFilterable(tableElement) {
if (tableElement.tHead && tableElement.tHead.rows.length > 0) {
const headers = tableElement.tHead.rows.item(0).cells;
for (const header of headers) {
if (typeof header.dataset.sortType !== 'undefined' && ['auto', 'string', 'integer'].indexOf(header.dataset.sortType) >= 0) {
header.addEventListener('click', () => {
// Classes
const reverseSort = header.classList.contains('sorted') && !header.classList.contains('sorted-reverse');
for (const h of headers) {
h.classList.remove('sorted', 'sorted-reverse');
}
header.classList.add('sorted');
if (reverseSort) {
header.classList.add('sorted-reverse');
}
// Find offset
let cellIndex = 0;
for (const h of headers) {
if (h === header) break;
cellIndex += h.colspan || 1;
}
// Sort each tbody
for (const tbody of tableElement.tBodies) {
const rows = Array.prototype.slice.call(tbody.rows);
rows.sort((a, b) => {
if (reverseSort) {
const c = a;
a = b;
b = c;
}
if (a.cells.length <= cellIndex || b.cells.length <= cellIndex) {
return 0;
}
const aCell = a.cells.item(cellIndex);
const bCell = b.cells.item(cellIndex);
const aValue = typeof aCell.dataset.sortValue !== 'undefined' ? aCell.dataset.sortValue : aCell.innerText;
const bValue = typeof bCell.dataset.sortValue !== 'undefined' ? bCell.dataset.sortValue : bCell.innerText;
let type = typeof header.dataset.sortType !== 'undefined' ? header.dataset.sortType : 'auto';
if (type === 'auto') {
if(!isNaN(aValue) && !isNaN(bValue)) {
type = 'integer';
} else {
type = 'string';
}
}
switch (type) {
case 'string':
return aValue.localeCompare(bValue, undefined, {sensitivity: 'base', numeric: true});
case 'integer':
return ((+aValue) - (+bValue)) || 0;
default:
return 0;
}
});
// Reorder the DOM elements
for (const row of rows) {
tbody.appendChild(row);
}
}
});
header.style.cursor = 'pointer';
}
}
}
const filterInput = document.createElement('input');
filterInput.type = 'search';
filterInput.addEventListener('input', () => {
const terms = filterInput.value.toLowerCase().split(' ');
for (const tbody of tableElement.tBodies) {
for (const row of tbody.rows) {
const rowContent = row.innerHTML.replace(/<[^>]+>/g, ' ').toLowerCase();
let shouldHide = true;
for (const term of terms) {
if (rowContent.indexOf(term) >= 0) {
shouldHide = false;
break;
}
}
row.style.display = shouldHide ? 'none' : null;
}
}
});
tableElement.parentElement.insertBefore(filterInput, tableElement);
return filterInput;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment