Skip to content

Commit ce4d903

Browse files
committed
Implement sortable table functionality with icons and event handling
1 parent 61cd6e1 commit ce4d903

1 file changed

Lines changed: 77 additions & 0 deletions

File tree

assets/js/init-sortable-tables.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,80 @@ document.addEventListener("DOMContentLoaded", function () {
33
new Tablesort(table);
44
});
55
});
6+
7+
(function () {
8+
function addSortIcons(table) {
9+
const headers = table.querySelectorAll("thead th");
10+
11+
headers.forEach((th) => {
12+
if (th.dataset.sortable === "false") return;
13+
14+
if (!th.querySelector(".sort-icon")) {
15+
th.insertAdjacentHTML(
16+
"beforeend",
17+
' <span class="sort-icon"><i class="fas fa-sort" aria-hidden="true"></i></span>'
18+
);
19+
}
20+
21+
if (!th.hasAttribute("aria-sort")) {
22+
th.setAttribute("aria-sort", "none");
23+
}
24+
});
25+
}
26+
27+
function resetIcons(table) {
28+
table.querySelectorAll("thead th .sort-icon i").forEach((icon) => {
29+
icon.classList.remove("fa-sort-up", "fa-sort-down");
30+
icon.classList.add("fa-sort");
31+
});
32+
33+
table.querySelectorAll("thead th").forEach((th) => {
34+
if (th.dataset.sortable === "false") return;
35+
th.setAttribute("aria-sort", "none");
36+
th.dataset.sortDir = "";
37+
});
38+
}
39+
40+
function setIcon(th, dir) {
41+
const icon = th.querySelector(".sort-icon i");
42+
if (!icon) return;
43+
44+
icon.classList.remove("fa-sort", "fa-sort-up", "fa-sort-down");
45+
46+
if (dir === "asc") {
47+
icon.classList.add("fa-sort-up");
48+
th.setAttribute("aria-sort", "ascending");
49+
} else if (dir === "desc") {
50+
icon.classList.add("fa-sort-down");
51+
th.setAttribute("aria-sort", "descending");
52+
} else {
53+
icon.classList.add("fa-sort");
54+
th.setAttribute("aria-sort", "none");
55+
}
56+
}
57+
58+
document.querySelectorAll("table").forEach((table) => {
59+
addSortIcons(table);
60+
61+
const headers = table.querySelectorAll("thead th");
62+
63+
headers.forEach((th) => {
64+
if (th.dataset.sortable === "false") return;
65+
66+
th.addEventListener("click", function () {
67+
const nextDir = th.dataset.sortDir === "asc" ? "desc" : "asc";
68+
69+
resetIcons(table);
70+
71+
th.dataset.sortDir = nextDir;
72+
setIcon(th, nextDir);
73+
});
74+
});
75+
76+
// If your sortable library emits this event, prefer it over click-only syncing.
77+
table.addEventListener("Sortable.sorted", function () {
78+
// Optional: if your library adds classes/attributes to the active <th>,
79+
// read them here and call setIcon(...) accordingly.
80+
});
81+
});
82+
})();

0 commit comments

Comments
 (0)