Сделаем объект, где ключами будут имена типов данных, а значениями - функции сравнения значений соответствующих типов:
const sort = {
number: (a, b) => a - b,
string: (a, b) => a.localeCompare(b),
};
Функция сортировки - принимает таблицу (может быть передана в виде элемента или селектора) и индекс столбца, по значениям которого надо отсортировать строки. По индексу столбца стучимся в его заголовок, получаем из него имя типа данных, по имени типа извлекаем функцию сравнения. Из тела таблицы достаём строки, превращаем их в массив, сортируем, добавляем обратно:
function sortTable(table, colIndex) {
if (typeof table === 'string') {
table = document.querySelector(table);
}
const head = table.tHead.rows[0];
const compare = sort[head.cells[colIndex].dataset.type] ?? sort.string;
const value = row => row.cells[colIndex].innerText;
const tbody = table.tBodies[0];
tbody.append(...[...tbody.rows].sort((a, b) => compare(value(a), value(b))));
[...head.cells].forEach((n, i) => n.classList.toggle('sorted', i == colIndex));
}
Стилизуем заголовок столбца, по которому выполнена сортировка:
.sorted {
background: #ccc;
}
.sorted::after {
content: " \2193";
}
Всё, можно пользоваться:
// просто дёргаем сортировку
sortTable('#grid', 0);
sortTable(document.querySelector('table'), 1);
// или, сортируем по клику на заголовки столбцов
document.querySelectorAll('#grid th').forEach(function(n) {
n.addEventListener('click', this);
}, ({ target: t }) => sortTable(t.closest('table'), t.cellIndex));