summaryrefslogtreecommitdiff
path: root/public/sort.js
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2022-03-30 13:10:21 +0200
committerTor Andersson <tor@ccxvii.net>2022-04-03 13:38:29 +0200
commit8875d16a5d50541f1b0b914e0b9666fe4c2b26a8 (patch)
treef1fde32de8edd30b98b6f0401da57c1ed3af9745 /public/sort.js
parentf5598b5b6ae749edf81e6b8856def815315037df (diff)
downloadserver-8875d16a5d50541f1b0b914e0b9666fe4c2b26a8.tar.gz
Add sort.js for sorted tables.
Diffstat (limited to 'public/sort.js')
-rw-r--r--public/sort.js67
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";
+ }
+ });
+});