Skip to content

Instantly share code, notes, and snippets.

@scottlawsonbc
Created January 14, 2026 05:51
Show Gist options
  • Select an option

  • Save scottlawsonbc/1553c70b8b4705921ba2ce176342f807 to your computer and use it in GitHub Desktop.

Select an option

Save scottlawsonbc/1553c70b8b4705921ba2ce176342f807 to your computer and use it in GitHub Desktop.
// ————————————————————————————————————————————————————————————————————————
// TableSorter
// Purpose: Make any <table class="sortable"> clickable by column header
// to sort numerically, by date (YYYY-MM-DD), or lexically.
// ————————————————————————————————————————————————————————————————————————
const TableSorter = {
sort(table, colIndex, dir = 'asc') {
const tbody = table.tBodies[0];
const rows = Array.from(tbody.rows);
const header = rows[0]?.querySelectorAll('th').length ? rows.shift() : null;
const texts = rows.map(r => r.cells[colIndex]?.textContent.trim() || '');
const isDate = texts.every(t => /^\d{4}-\d{2}-\d{2}$/.test(t));
const isNum = !isDate && texts.every(t => t !== '' && !isNaN(+t));
rows.sort((a, b) => {
let aVal = a.cells[colIndex]?.textContent.trim() || '';
let bVal = b.cells[colIndex]?.textContent.trim() || '';
let diff;
if (isDate) diff = Date.parse(aVal) - Date.parse(bVal);
else if (isNum) diff = parseFloat(aVal) - parseFloat(bVal);
else diff = aVal.localeCompare(bVal);
return dir === 'asc' ? diff : -diff;
});
tbody.innerHTML = '';
if (header) tbody.appendChild(header);
rows.forEach(r => tbody.appendChild(r));
},
init() {
document.querySelectorAll('table.sortable').forEach(table => {
const headRow = table.tHead?.rows[0] || table.rows[0];
if (!headRow) return;
Array.from(headRow.cells).forEach((th, idx) => {
th.style.cursor = 'pointer';
th.dataset.sortDir = 'asc';
th.addEventListener('click', () => {
const dir = (th.dataset.sortDir =
th.dataset.sortDir === 'asc' ? 'desc' : 'asc');
TableSorter.sort(table, idx, dir);
});
});
});
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment