mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2025-03-25 03:31:50 +00:00
Table sorting.
This commit is contained in:
parent
51cf09ece7
commit
29e16b66b7
@ -20,7 +20,9 @@ and the SRTM altitude are in <b>bold</b> if the discrepancy is more than 60m ver
|
|||||||
|
|
||||||
<p>Unless otherwise specified data is expressed in UTM in WGS84 datum. Coordinates are expresed in meters.</p>
|
<p>Unless otherwise specified data is expressed in UTM in WGS84 datum. Coordinates are expresed in meters.</p>
|
||||||
|
|
||||||
<table cellpadding="6" cellspacing="8">
|
<p>Click on column headings to sort.</p>
|
||||||
|
|
||||||
|
<table cellpadding="6" cellspacing="8" class="table-sort">
|
||||||
<tr><th>Survex Station</th><th>x [m]</th><th>y [m]</th><th>lat. [deg]</th><th>long. [deg]</th><th>alt [m]</th><th>SRTM<br> alt</th><th>SRTM [m]<br> ref</th><th>Used on <br />this Entrance</th><th>Cave</th></tr>
|
<tr><th>Survex Station</th><th>x [m]</th><th>y [m]</th><th>lat. [deg]</th><th>long. [deg]</th><th>alt [m]</th><th>SRTM<br> alt</th><th>SRTM [m]<br> ref</th><th>Used on <br />this Entrance</th><th>Cave</th></tr>
|
||||||
{% for s in stations %}
|
{% for s in stations %}
|
||||||
<tr>
|
<tr>
|
||||||
@ -110,6 +112,399 @@ Coordinate systems in Austria are explained in:<br>
|
|||||||
<a href="/stations">Troggle UTM and lat./lomg. and altitude report</a><br>
|
<a href="/stations">Troggle UTM and lat./lomg. and altitude report</a><br>
|
||||||
<a href="/entrances">Troggle entrances</a><br>
|
<a href="/entrances">Troggle entrances</a><br>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This script is added for ease of use.
|
||||||
|
You can safely delete it.
|
||||||
|
|
||||||
|
Radost Waszkiewicz (2023)
|
||||||
|
-->
|
||||||
|
<script>
|
||||||
|
/*
|
||||||
|
table-sort-js
|
||||||
|
Author: Lee Wannacott
|
||||||
|
Licence: MIT License Copyright (c) 2021 Lee Wannacott
|
||||||
|
*/
|
||||||
|
|
||||||
|
function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
|
||||||
|
function getHTMLTables() {
|
||||||
|
if (testingTableSortJS === true) {
|
||||||
|
const getTagTable = domDocumentWindow.getElementsByTagName("table");
|
||||||
|
return [getTagTable];
|
||||||
|
} else {
|
||||||
|
const getTagTable = document.getElementsByTagName("table");
|
||||||
|
return [getTagTable];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const [getTagTable] = getHTMLTables();
|
||||||
|
const columnIndexAndTableRow = {};
|
||||||
|
const fileSizeColumnTextAndRow = {};
|
||||||
|
for (let table of getTagTable) {
|
||||||
|
if (table.classList.contains("table-sort")) {
|
||||||
|
makeTableSortable(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeTableSortable(sortableTable) {
|
||||||
|
let createTableHead;
|
||||||
|
let tableBody;
|
||||||
|
if (sortableTable.getElementsByTagName("thead").length === 0) {
|
||||||
|
if (testingTableSortJS === true) {
|
||||||
|
createTableHead = domDocumentWindow.createElement("thead");
|
||||||
|
} else {
|
||||||
|
createTableHead = document.createElement("thead");
|
||||||
|
}
|
||||||
|
createTableHead.appendChild(sortableTable.rows[0]);
|
||||||
|
sortableTable.insertBefore(createTableHead, sortableTable.firstChild);
|
||||||
|
if (sortableTable.querySelectorAll("tbody").length > 1) {
|
||||||
|
tableBody = sortableTable.querySelectorAll("tbody")[1];
|
||||||
|
} else {
|
||||||
|
tableBody = sortableTable.querySelector("tbody");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tableBody = sortableTable.querySelector("tbody");
|
||||||
|
}
|
||||||
|
|
||||||
|
const tableHead = sortableTable.querySelector("thead");
|
||||||
|
const tableHeadHeaders = tableHead.querySelectorAll("th");
|
||||||
|
|
||||||
|
for (let [columnIndex, th] of tableHeadHeaders.entries()) {
|
||||||
|
if (!th.classList.contains("disable-sort")) {
|
||||||
|
th.style.cursor = "pointer";
|
||||||
|
makeEachColumnSortable(th, columnIndex, tableBody, sortableTable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeEachColumnSortable(th, columnIndex, tableBody, sortableTable) {
|
||||||
|
const desc = th.classList.contains("order-by-desc");
|
||||||
|
let tableArrows = sortableTable.classList.contains("table-arrows");
|
||||||
|
const [arrowUp, arrowDown] = [" ▲", " ▼"];
|
||||||
|
const fillValue = "!X!Y!Z!";
|
||||||
|
|
||||||
|
if (desc && tableArrows) {
|
||||||
|
th.insertAdjacentText("beforeend", arrowDown);
|
||||||
|
} else if (tableArrows) {
|
||||||
|
th.insertAdjacentText("beforeend", arrowUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortDataAttributes(tableRows, columnData) {
|
||||||
|
for (let [i, tr] of tableRows.entries()) {
|
||||||
|
const dataAttributeTd = tr.querySelectorAll("td").item(columnIndex)
|
||||||
|
.dataset.sort;
|
||||||
|
columnData.push(`${dataAttributeTd}#${i}`);
|
||||||
|
columnIndexAndTableRow[columnData[i]] = tr.innerHTML;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortFileSize(tableRows, columnData) {
|
||||||
|
const numberWithUnitType =
|
||||||
|
/[.0-9]+(\s?B|\s?KB|\s?KiB|\s?MB|\s?MiB|\s?GB|\s?GiB|T\s?B|\s?TiB)/i;
|
||||||
|
const unitType =
|
||||||
|
/(\s?B|\s?KB|\s?KiB|\s?MB|\s?MiB|\s?GB|G\s?iB|\s?TB|\s?TiB)/i;
|
||||||
|
const fileSizes = {
|
||||||
|
Kibibyte: 1024,
|
||||||
|
Mebibyte: 1.049e6,
|
||||||
|
Gibibyte: 1.074e9,
|
||||||
|
Tebibyte: 1.1e12,
|
||||||
|
Pebibyte: 1.126e15,
|
||||||
|
Kilobyte: 1000,
|
||||||
|
Megabyte: 1e6,
|
||||||
|
Gigabyte: 1e9,
|
||||||
|
Terabyte: 1e12,
|
||||||
|
};
|
||||||
|
function removeUnitTypeConvertToBytes(fileSizeTd, _replace, i) {
|
||||||
|
fileSizeTd = fileSizeTd.replace(unitType, "");
|
||||||
|
fileSizeTd = fileSizeTd.replace(
|
||||||
|
fileSizeTd,
|
||||||
|
fileSizeTd * fileSizes[_replace]
|
||||||
|
);
|
||||||
|
if (i) {
|
||||||
|
columnData.push(`${fileSizeTd}#${i}`);
|
||||||
|
}
|
||||||
|
return fileSizeTd;
|
||||||
|
}
|
||||||
|
for (let [i, tr] of tableRows.entries()) {
|
||||||
|
let fileSizeTd = tr
|
||||||
|
.querySelectorAll("td")
|
||||||
|
.item(columnIndex).textContent;
|
||||||
|
if (fileSizeTd.match(numberWithUnitType)) {
|
||||||
|
if (fileSizeTd.match(/\s?KB/i)) {
|
||||||
|
removeUnitTypeConvertToBytes(fileSizeTd, "Kilobyte", i);
|
||||||
|
} else if (fileSizeTd.match(/\s?KiB/i)) {
|
||||||
|
removeUnitTypeConvertToBytes(fileSizeTd, "Kibibyte", i);
|
||||||
|
} else if (fileSizeTd.match(/\s?MB/i)) {
|
||||||
|
// TODO: figure out why refactoring this line breaks test.
|
||||||
|
fileSizeTd = removeUnitTypeConvertToBytes(fileSizeTd, "Megabyte");
|
||||||
|
columnData.push(`${fileSizeTd}#${i}`);
|
||||||
|
} else if (fileSizeTd.match(/\s?MiB/i)) {
|
||||||
|
removeUnitTypeConvertToBytes(fileSizeTd, "Mebibyte", i);
|
||||||
|
} else if (fileSizeTd.match(/\s?GB/i)) {
|
||||||
|
removeUnitTypeConvertToBytes(fileSizeTd, "Gigabyte", i);
|
||||||
|
} else if (fileSizeTd.match(/\s?GiB/i)) {
|
||||||
|
removeUnitTypeConvertToBytes(fileSizeTd, "Gibibyte", i);
|
||||||
|
} else if (fileSizeTd.match(/\s?TB/i)) {
|
||||||
|
removeUnitTypeConvertToBytes(fileSizeTd, "Terabyte", i);
|
||||||
|
} else if (fileSizeTd.match(/\s?TiB/i)) {
|
||||||
|
removeUnitTypeConvertToBytes(fileSizeTd, "Tebibyte", i);
|
||||||
|
} else if (fileSizeTd.match(/\s?B/i)) {
|
||||||
|
fileSizeTd = fileSizeTd.replace(unitType, "");
|
||||||
|
columnData.push(`${fileSizeTd}#${i}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
columnData.push(`${fillValue}#${i}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let [timesClickedColumn, columnIndexesClicked] = [0, []];
|
||||||
|
|
||||||
|
function rememberSort(timesClickedColumn, columnIndexesClicked) {
|
||||||
|
// if user clicked different column from first column reset times clicked.
|
||||||
|
columnIndexesClicked.push(columnIndex);
|
||||||
|
if (timesClickedColumn === 1 && columnIndexesClicked.length > 1) {
|
||||||
|
const lastColumnClicked =
|
||||||
|
columnIndexesClicked[columnIndexesClicked.length - 1];
|
||||||
|
const secondLastColumnClicked =
|
||||||
|
columnIndexesClicked[columnIndexesClicked.length - 2];
|
||||||
|
if (lastColumnClicked !== secondLastColumnClicked) {
|
||||||
|
timesClickedColumn = 0;
|
||||||
|
columnIndexesClicked.shift();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getColSpanData(sortableTable, colSpanData, colSpanSum) {
|
||||||
|
sortableTable.querySelectorAll("th").forEach((th, index) => {
|
||||||
|
colSpanData[index] = th.colSpan;
|
||||||
|
if (index === 0) colSpanSum[index] = th.colSpan;
|
||||||
|
else colSpanSum[index] = colSpanSum[index - 1] + th.colSpan;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTableData(tableProperties) {
|
||||||
|
const {
|
||||||
|
tableRows,
|
||||||
|
columnData,
|
||||||
|
isFileSize,
|
||||||
|
isDataAttribute,
|
||||||
|
colSpanData,
|
||||||
|
colSpanSum,
|
||||||
|
} = tableProperties;
|
||||||
|
for (let [i, tr] of tableRows.entries()) {
|
||||||
|
let tdTextContent = tr
|
||||||
|
.querySelectorAll("td")
|
||||||
|
.item(
|
||||||
|
colSpanData[columnIndex] === 1
|
||||||
|
? colSpanSum[columnIndex] - 1
|
||||||
|
: colSpanSum[columnIndex] - colSpanData[columnIndex]
|
||||||
|
).textContent;
|
||||||
|
if (tdTextContent.length === 0) {
|
||||||
|
tdTextContent = "";
|
||||||
|
}
|
||||||
|
if (tdTextContent.trim() !== "") {
|
||||||
|
if (isFileSize) {
|
||||||
|
fileSizeColumnTextAndRow[columnData[i]] = tr.innerHTML;
|
||||||
|
}
|
||||||
|
if (!isFileSize && !isDataAttribute) {
|
||||||
|
columnData.push(`${tdTextContent}#${i}`);
|
||||||
|
columnIndexAndTableRow[`${tdTextContent}#${i}`] = tr.innerHTML;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Fill in blank table cells dict key with filler value.
|
||||||
|
columnData.push(`${fillValue}#${i}`);
|
||||||
|
columnIndexAndTableRow[`${fillValue}#${i}`] = tr.innerHTML;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isPunctSort = th.classList.contains("punct-sort");
|
||||||
|
const isAlphaSort = th.classList.contains("alpha-sort");
|
||||||
|
function sortAscending(a, b) {
|
||||||
|
if (a.includes(`${fillValue}#`)) {
|
||||||
|
return 1;
|
||||||
|
} else if (b.includes(`${fillValue}#`)) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return a.localeCompare(
|
||||||
|
b,
|
||||||
|
navigator.languages[0] || navigator.language,
|
||||||
|
{ numeric: !isAlphaSort, ignorePunctuation: !isPunctSort }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortDescending(a, b) {
|
||||||
|
return sortAscending(b, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearArrows(arrowUp = "▲", arrowDown = "▼") {
|
||||||
|
th.innerHTML = th.innerHTML.replace(arrowUp, "");
|
||||||
|
th.innerHTML = th.innerHTML.replace(arrowDown, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (columnData[0] === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeTableArrow(arrowDirection) {
|
||||||
|
if (tableArrows) {
|
||||||
|
clearArrows(arrowUp, arrowDown);
|
||||||
|
th.insertAdjacentText("beforeend", arrowDirection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortColumn(sortDirection) {
|
||||||
|
columnData.sort(sortDirection, {
|
||||||
|
numeric: !isAlphaSort,
|
||||||
|
ignorePunctuation: !isPunctSort,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timesClickedColumn === 1) {
|
||||||
|
if (desc) {
|
||||||
|
changeTableArrow(arrowDown);
|
||||||
|
sortColumn(sortDescending);
|
||||||
|
} else {
|
||||||
|
changeTableArrow(arrowUp);
|
||||||
|
sortColumn(sortAscending);
|
||||||
|
}
|
||||||
|
} else if (timesClickedColumn === 2) {
|
||||||
|
timesClickedColumn = 0;
|
||||||
|
if (desc) {
|
||||||
|
changeTableArrow(arrowUp);
|
||||||
|
sortColumn(sortAscending);
|
||||||
|
} else {
|
||||||
|
changeTableArrow(arrowDown);
|
||||||
|
sortColumn(sortDescending);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTable(tableProperties) {
|
||||||
|
const { tableRows, columnData, isFileSize } = tableProperties;
|
||||||
|
for (let [i, tr] of tableRows.entries()) {
|
||||||
|
if (isFileSize) {
|
||||||
|
tr.innerHTML = fileSizeColumnTextAndRow[columnData[i]];
|
||||||
|
let fileSizeInBytesHTML = tr
|
||||||
|
.querySelectorAll("td")
|
||||||
|
.item(columnIndex).innerHTML;
|
||||||
|
const fileSizeInBytesText = tr
|
||||||
|
.querySelectorAll("td")
|
||||||
|
.item(columnIndex).textContent;
|
||||||
|
const fileSizes = {
|
||||||
|
Kibibyte: 1024,
|
||||||
|
Mebibyte: 1.049e6,
|
||||||
|
Gibibyte: 1.074e9,
|
||||||
|
Tebibyte: 1.1e12,
|
||||||
|
Pebibyte: 1.126e15,
|
||||||
|
};
|
||||||
|
// Remove the unique identifyer for duplicate values(#number).
|
||||||
|
columnData[i] = columnData[i].replace(/#[0-9]*/, "");
|
||||||
|
const fileSize = columnData[i];
|
||||||
|
if (fileSize < fileSizes.Kibibyte) {
|
||||||
|
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
|
||||||
|
fileSizeInBytesText,
|
||||||
|
`${parseFloat(fileSize).toFixed(2)} B`
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
fileSize >= fileSizes.Kibibyte &&
|
||||||
|
fileSize < fileSizes.Mebibyte
|
||||||
|
) {
|
||||||
|
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
|
||||||
|
fileSizeInBytesText,
|
||||||
|
`${(fileSize / fileSizes.Kibibyte).toFixed(2)} KiB`
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
fileSize >= fileSizes.Mebibyte &&
|
||||||
|
fileSize < fileSizes.Gibibyte
|
||||||
|
) {
|
||||||
|
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
|
||||||
|
fileSizeInBytesText,
|
||||||
|
`${(fileSize / fileSizes.Mebibyte).toFixed(2)} MiB`
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
fileSize >= fileSizes.Gibibyte &&
|
||||||
|
fileSize < fileSizes.Tebibyte
|
||||||
|
) {
|
||||||
|
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
|
||||||
|
fileSizeInBytesText,
|
||||||
|
`${(fileSize / fileSizes.Gibibyte).toFixed(2)} GiB`
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
fileSize >= fileSizes.Tebibyte &&
|
||||||
|
fileSize < fileSizes.Pebibyte
|
||||||
|
) {
|
||||||
|
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
|
||||||
|
fileSizeInBytesText,
|
||||||
|
`${(fileSize / fileSizes.Tebibyte).toFixed(2)} TiB`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
|
||||||
|
fileSizeInBytesText,
|
||||||
|
"NaN"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
tr.querySelectorAll("td").item(columnIndex).innerHTML =
|
||||||
|
fileSizeInBytesHTML;
|
||||||
|
} else if (!isFileSize) {
|
||||||
|
tr.innerHTML = columnIndexAndTableRow[columnData[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
th.addEventListener("click", function () {
|
||||||
|
const [columnData, colSpanData, colSpanSum] = [[], {}, {}];
|
||||||
|
|
||||||
|
const visibleTableRows = Array.prototype.filter.call(
|
||||||
|
tableBody.querySelectorAll("tr"),
|
||||||
|
(tr) => {
|
||||||
|
return tr.style.display !== "none";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const isDataAttribute = th.classList.contains("data-sort");
|
||||||
|
if (isDataAttribute) {
|
||||||
|
sortDataAttributes(visibleTableRows, columnData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const isFileSize = th.classList.contains("file-size-sort");
|
||||||
|
if (isFileSize) {
|
||||||
|
sortFileSize(visibleTableRows, columnData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const isRememberSort = sortableTable.classList.contains("remember-sort");
|
||||||
|
if (!isRememberSort) {
|
||||||
|
rememberSort(timesClickedColumn, columnIndexesClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
timesClickedColumn += 1;
|
||||||
|
|
||||||
|
getColSpanData(sortableTable, colSpanData, colSpanSum);
|
||||||
|
const tableProperties = {
|
||||||
|
tableRows: visibleTableRows,
|
||||||
|
columnData,
|
||||||
|
isFileSize,
|
||||||
|
isDataAttribute,
|
||||||
|
colSpanData,
|
||||||
|
colSpanSum,
|
||||||
|
};
|
||||||
|
getTableData(tableProperties);
|
||||||
|
updateTable(tableProperties);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
document.readyState === "complete" ||
|
||||||
|
document.readyState === "interactive"
|
||||||
|
) {
|
||||||
|
tableSortJs();
|
||||||
|
} else if (document.readyState === "loading") {
|
||||||
|
document.addEventListener("DOMContentLoaded", tableSortJs, false);
|
||||||
|
}
|
||||||
|
if (typeof module == "object") {
|
||||||
|
module.exports = tableSortJs;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user