|
|
|
@ -16,8 +16,7 @@
|
|
|
|
|
// Import magic numbers and data
|
|
|
|
|
import {
|
|
|
|
|
dom, COLUMN, COLUMN_LITERAL, COMPARISON, ATTRIBUTES,
|
|
|
|
|
columnAscendingByDefault, columnIsSortable, columnNeedsCasefold,
|
|
|
|
|
columnIsNumeric, element
|
|
|
|
|
columnAscendingByDefault, columnIsSortable, COLUMN_TRANSFORMATION, element
|
|
|
|
|
} from './js/constants.js';
|
|
|
|
|
|
|
|
|
|
// Hidden communities for transparency.
|
|
|
|
@ -192,21 +191,12 @@ function makeRowComparer(column, ascending) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Callback to obtain sortable content from cell text.
|
|
|
|
|
let contentToSortable = (text) => text.trim();
|
|
|
|
|
|
|
|
|
|
if (columnNeedsCasefold(column)) {
|
|
|
|
|
// Make certain columns sort regardless of casing.
|
|
|
|
|
contentToSortable = (text) => text.toLowerCase().trim();
|
|
|
|
|
}
|
|
|
|
|
else if (columnIsNumeric(column)) {
|
|
|
|
|
// Make certain columns sort on parsed numeric value instead of text.
|
|
|
|
|
contentToSortable = (text) => parseInt(text);
|
|
|
|
|
}
|
|
|
|
|
const columnToSortable = COLUMN_TRANSFORMATION[column] ?? ((el) => el.innerText.trim());
|
|
|
|
|
|
|
|
|
|
// Construct comparer using derived property to determine sort order.
|
|
|
|
|
const rowComparer = compareProp(
|
|
|
|
|
ascending ? compareAscending : compareDescending,
|
|
|
|
|
row => contentToSortable(row.children[column].innerText)
|
|
|
|
|
row => columnToSortable(row.children[column])
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return rowComparer;
|
|
|
|
@ -248,17 +238,22 @@ function setSortState(table, { ascending, column }) {
|
|
|
|
|
}
|
|
|
|
|
table.setAttribute(ATTRIBUTES.SORTING.ASCENDING, ascending);
|
|
|
|
|
table.setAttribute(ATTRIBUTES.SORTING.COLUMN, column);
|
|
|
|
|
// This can be used to style column headers in a consistent way, i.e.
|
|
|
|
|
// #tbl_communities[data-sort-asc=true][sorted-by=name]::after #th_name, ...
|
|
|
|
|
table.setAttribute(ATTRIBUTES.SORTING.COLUMN_LITERAL, COLUMN_LITERAL[column]);
|
|
|
|
|
|
|
|
|
|
// No way around this for brief CSS.
|
|
|
|
|
const headers = table.querySelectorAll("th");
|
|
|
|
|
headers.forEach((th, colno) => {
|
|
|
|
|
th.removeAttribute(ATTRIBUTES.SORTING.ACTIVE);
|
|
|
|
|
});
|
|
|
|
|
headers[column].setAttribute(ATTRIBUTES.SORTING.ACTIVE, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This is best done in JS, as it would require <noscript> styles otherwise.
|
|
|
|
|
function markSortableColumns() {
|
|
|
|
|
const table = dom.tbl_communities();
|
|
|
|
|
for (const th of table.querySelectorAll('th')) {
|
|
|
|
|
if (th.id.includes("qr_code")) continue;
|
|
|
|
|
th.classList.add('sortable');
|
|
|
|
|
const header_cells = table.querySelectorAll('th');
|
|
|
|
|
for (let colno = 0; colno < header_cells.length; colno++) {
|
|
|
|
|
if (!columnIsSortable(colno)) continue;
|
|
|
|
|
header_cells[colno].classList.add('sortable');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|