Иногда требуется отсортировать HTML таблицу, без обращения к серверу. Это можно спокойно сделать на простом JavaScript.
Как отсортировать таблицу на чистом javascript
03.04.2021
Результат:

Небольшой CSS для вывода указателя по какому столбцу сортируем:
.table thead th {
vertical-align: middle;
cursor: pointer;
position: relative;
user-select: none;
}
.table thead th > div {
padding-right: 20px;
user-select: none;
}
th._active_up div::after {
content: '';
position: absolute;
top: 50%;
right: 10px;
border: 10px solid transparent; /* Прозрачные границы */
border-top: 10px solid #ffeeba; /* Добавляем треугольник */
}
th._active_down div::after {
content: '';
position: absolute;
top: 25%;
right: 10px;
border: 10px solid transparent; /* Прозрачные границы */
border-bottom: 10px solid #ffeeba; /* Добавляем треугольник */
}
JavaScript отвечающий за сортировку:
const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent;
const comparer = (idx, asc) => (a, b) => ((v1, v2) =>
v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) ? v1 - v2 : v1.toString().localeCompare(v2)
)(getCellValue(asc ? a : b, idx), getCellValue(asc ? b : a, idx));
// do the work...
document.querySelectorAll('th').forEach(th => th.addEventListener('click', ((event) => {
const table = th.closest('table');
const THs = document.querySelectorAll('th');
if (th.classList.contains("_active_up")) {
th.classList.add("_active_down");
th.classList.remove("_active_up");
} else if (th.classList.contains("_active_down")) {
th.classList.add("_active_up");
th.classList.remove("_active_down");
} else {
THs.forEach(el => { el.classList.remove("_active_down") });
THs.forEach(el => { el.classList.remove("_active_up") });
th.classList.add("_active_up");
}
Array.from(table.querySelectorAll('tr:nth-child(n+2)'))
.sort(comparer(Array.from(th.parentNode.children).indexOf(th), this.asc = !this.asc))
.forEach(tr => table.appendChild(tr) );
})));
Пример самой HTML таблицы:
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">
<div>ID</div>
</th>
<th scope="col">
<div>Наименование</div>
</th>
<th scope="col">
<div>Код товара</div>
</th>
<th scope="col">
<div>Статус</div>
</th>
<th scope="col">
<div>Новый товар</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<?
foreach($aItems as $oItem)
{
?>
<td scope="row">
<b><?=$oItem->id?></b>
</td>
<td>
<?=$oItem->title?>
</td>
<td>
<?=$oItem->code?$oItem->code:$oItem->sku?>
</td>
<td>
<div class="alert <?=$oItem->status=='1'?'alert-success':'alert-danger'?> " role="alert">
<?=$oItem->status=='1'?'OK':$oItem->ru_message?>
</div>
</td>
<td>
<div class="alert <?=$oItem->is_new=='1'?'alert-warning':'alert-info'?> " role="alert">
<?=$oItem->is_new=='1'?'<b>Да</b>':'Нет'?>
</div>
</td>
</tr>
<?
}
?>
</tbody>
</table>