diff options
author | Tor Andersson <tor@ccxvii.net> | 2022-03-30 13:10:21 +0200 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2022-04-03 13:38:29 +0200 |
commit | 8875d16a5d50541f1b0b914e0b9666fe4c2b26a8 (patch) | |
tree | f1fde32de8edd30b98b6f0401da57c1ed3af9745 /public/sort.js | |
parent | f5598b5b6ae749edf81e6b8856def815315037df (diff) | |
download | server-8875d16a5d50541f1b0b914e0b9666fe4c2b26a8.tar.gz |
Add sort.js for sorted tables.
Diffstat (limited to 'public/sort.js')
-rw-r--r-- | public/sort.js | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/public/sort.js b/public/sort.js new file mode 100644 index 0000000..b98334d --- /dev/null +++ b/public/sort.js @@ -0,0 +1,67 @@ +"use strict"; + +function sort_table_column(table, column) { + const minute = 60000; + const hour = 60 * minute; + const day = 24 * hour; + const week = 7 * day; + + function is_date(s) { + if (s.match(/^\d{4}-\d{2}-\d{2}$/)) + return true; + if (s.match(/^\d+ (minutes?|hours?|days|weeks) ago$/)) + return true; + if (s.match(/^(Yesterday|now)$/)) + return true; + return false; + } + + function parse_date(s) { + if (s.match(/^\d{4}-\d{2}-\d{2}$/)) return new Date(s).valueOf(); + if (s === 'now') return Date.now(); + if (s === 'Yesterday') return Date.now() - day; + let [ _, value, unit ] = s.match(/^(\d+) (minutes?|hours?|days|weeks) ago$/); + switch (unit) { + default: unit = 0; break; + case 'minute': case 'minutes': unit = minute; break; + case 'hours': case 'hours': unit = hour; break; + case 'days': unit = day; break; + case 'weeks': unit = week; break; + } + return Date.now() - Number(value) * unit; + } + + let tbody = table.querySelector("tbody"); + let rows = Array.from(tbody.querySelectorAll("tr")); + rows.sort((row_a, row_b) => { + let cell_a = row_a.querySelectorAll("td")[column].textContent; + let cell_b = row_b.querySelectorAll("td")[column].textContent; + if (is_date(cell_a) && is_date(cell_b)) { + let age_a = parse_date(cell_a); + let age_b = parse_date(cell_b); + if (age_a > age_b) return -1; + if (age_a < age_b) return 1; + return 0; + } else if (cell_a.match(/^\d+$/) && cell_b.match(/^\d+$/)) { + cell_a = Number(cell_a); + cell_b = Number(cell_b); + if (cell_a > cell_b) return -1; + if (cell_a < cell_b) return 1; + return 0; + } else { + if (cell_a > cell_b) return 1; + if (cell_a < cell_b) return -1; + return 0; + } + }); + rows.forEach(row => tbody.appendChild(row)); +} + +document.querySelectorAll("table.sort").forEach(table => { + table.querySelectorAll("th").forEach((th, column) => { + if (th.textContent !== "") { + th.addEventListener("click", evt => sort_table_column(table, column)); + th.style.cursor = "pointer"; + } + }); +}); |