88 lines
2.7 KiB
JavaScript
88 lines
2.7 KiB
JavaScript
(function () {
|
|
function sortableValue(row, index, type) {
|
|
var cell = row.children[index];
|
|
if (!cell) {
|
|
return "";
|
|
}
|
|
var value = cell.dataset.sortValue || cell.textContent || "";
|
|
value = value.trim();
|
|
if (type === "number") {
|
|
var parsed = Number.parseInt(value, 10);
|
|
return Number.isNaN(parsed) ? 0 : parsed;
|
|
}
|
|
return value.toLocaleLowerCase("pt-BR");
|
|
}
|
|
|
|
function compareRows(index, type, direction) {
|
|
return function (left, right) {
|
|
var leftValue = sortableValue(left, index, type);
|
|
var rightValue = sortableValue(right, index, type);
|
|
var result;
|
|
if (type === "number") {
|
|
result = leftValue - rightValue;
|
|
} else {
|
|
result = leftValue.localeCompare(rightValue, "pt-BR", {
|
|
numeric: true,
|
|
sensitivity: "base",
|
|
});
|
|
}
|
|
return direction === "desc" ? -result : result;
|
|
};
|
|
}
|
|
|
|
function updateIndicators(table, activeButton, direction) {
|
|
table.querySelectorAll(".table-sort").forEach(function (button) {
|
|
var header = button.closest("th");
|
|
var indicator = button.querySelector(".sort-indicator");
|
|
if (header) {
|
|
header.removeAttribute("aria-sort");
|
|
}
|
|
if (indicator) {
|
|
indicator.textContent = "";
|
|
}
|
|
});
|
|
|
|
var activeHeader = activeButton.closest("th");
|
|
if (activeHeader) {
|
|
activeHeader.setAttribute("aria-sort", direction === "desc" ? "descending" : "ascending");
|
|
}
|
|
var activeIndicator = activeButton.querySelector(".sort-indicator");
|
|
if (activeIndicator) {
|
|
activeIndicator.textContent = direction === "desc" ? "↓" : "↑";
|
|
}
|
|
}
|
|
|
|
function sortTable(table, button) {
|
|
var tbody = table.tBodies[0];
|
|
if (!tbody) {
|
|
return;
|
|
}
|
|
|
|
var index = Number.parseInt(button.dataset.sortIndex || "0", 10);
|
|
var type = button.dataset.sortType || "text";
|
|
var currentIndex = table.dataset.sortIndex;
|
|
var currentDirection = table.dataset.sortDirection || "asc";
|
|
var direction = currentIndex === String(index) && currentDirection === "asc" ? "desc" : "asc";
|
|
|
|
Array.from(tbody.rows)
|
|
.sort(compareRows(index, type, direction))
|
|
.forEach(function (row) {
|
|
tbody.appendChild(row);
|
|
});
|
|
|
|
table.dataset.sortIndex = String(index);
|
|
table.dataset.sortDirection = direction;
|
|
updateIndicators(table, button, direction);
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
document.querySelectorAll("[data-sortable-table]").forEach(function (table) {
|
|
table.querySelectorAll(".table-sort").forEach(function (button) {
|
|
button.addEventListener("click", function () {
|
|
sortTable(table, button);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
})();
|