sorttable.js (4256B)
- /*
- * Copyright 2007 Stuart Langridge http://www.kryogenix.org/code/browser/sorttable/
- * Copyright 2018, 2023 Haelwenn (lanodan) Monnier <contact@hacktivis.me>
- * SPDX-License-Identifier: X11
- */
- /* Usage:
- * Add <script src="sorttable.js"></script> to your (x)HTML pages
- * Add class="sortable" to any table you'd like to make sortable
- * See sorttable.css for an example of styling
- */
- sorttable = {
- done : false
- };
- sorttable.init = function() {
- // quit if this function has already been called
- if(sorttable.done) return;
- // flag this function so we don't do the same thing twice
- sorttable.done = true;
- var sortableElements = document.getElementsByClassName("sortable");
- Array.prototype.filter.call(sortableElements, function(sortableElement) {
- if(sortableElement.nodeName == "TABLE" || sortableElement.nodeName == "table")
- {
- sorttable.makeSortable(sortableElement);
- }
- });
- };
- sorttable.makeSortable = function(table) {
- // Only one thead row is supported
- if(table.tHead.rows.length != 1) return;
- // work through each column and calculate its type
- headrow = table.tHead.rows[0].cells;
- for(var i = 0; i < headrow.length; i++)
- {
- // skip this col
- if(!headrow[i].classList.contains("sorttable_nosort"))
- {
- // make it clickable to sort
- headrow[i].sorttable_columnindex = i;
- headrow[i].sorttable_tbody = table.tBodies[0];
- headrow[i].addEventListener("click", event => {
- if(event.target)
- {
- sorttable.innerSortFunction(event.target)
- }
- });
- headrow[i].addEventListener("keydown", event => {
- if(event.target && (event.key && event.key == "Enter"))
- {
- sorttable.innerSortFunction(event.target);
- }
- });
- headrow[i].setAttribute("tabindex", "0");
- headrow[i].classList.add('made_sortable');
- }
- }
- };
- sorttable.compareFn = function(a, b) {
- // Note: Returns are reversed
- if(a[0]<b[0]) {return 1};
- if(a[0]>b[0]) {return -1};
- return 0;
- };
- sorttable.innerSortFunction = function(tr) {
- if(tr.classList.contains("sorttable_sorted"))
- {
- sorttable.reverse(tr.sorttable_tbody);
- tr.classList.replace('sorttable_sorted', 'sorttable_sorted_reverse');
- }
- else if(tr.classList.contains("sorttable_sorted_reverse"))
- {
- sorttable.reverse(tr.sorttable_tbody);
- tr.classList.replace('sorttable_sorted_reverse', 'sorttable_sorted');
- }
- else
- {
- // remove sorttable_sorted classes
- theadRow = tr.parentNode;
- theadRow.childNodes.forEach(function(
- cell) { cell.classList.remove('sorttable_sorted_reverse', 'sorttable_sorted'); });
- // build an array to sort. This is a Schwartzian transform thing,
- // i.e., we "decorate" each row with the actual sort key,
- // sort based on the sort keys, and then put the rows back in order
- // which is a lot faster because you only do getInnerText once per row
- row_array = [];
- col = tr.sorttable_columnindex;
- rows = tr.sorttable_tbody.rows;
- for(var j = 0; j < rows.length; j++)
- {
- row_array[row_array.length] =
- [ sorttable.getElementValue(rows[j].cells[col]), rows[j] ];
- }
- row_array.sort(sorttable.compareFn);
- tb = tr.sorttable_tbody;
- row_array.forEach(function(row) { tb.appendChild(row[1]); });
- tr.classList.add('sorttable_sorted');
- }
- };
- // - Use data-value="" attribute if you want to override innerHTML
- // - Use data-type="" attribute if you want to use non-lexical sorting
- // Example: <td data-value="1337" data-type="int">Leet</td>
- sorttable.getElementValue = function(element) {
- if(element === undefined)
- {
- return "\u0000"; // null
- console.log("Warning: Empty cells found");
- };
- let value = element.dataset.value ? element.dataset.value : element.innerText;
- switch(element.dataset.type)
- {
- case undefined:
- return value;
- case "int":
- var v = parseInt(value);
- return v != NaN ? v : value;
- case "float":
- var v = parseFloat(value);
- return v != NaN ? v : value;
- default:
- console.log(`Warning: Unhandled type ${element.dataset.type}`);
- return value;
- };
- };
- sorttable.reverse = function(tbody) {
- // reverse the rows in a tbody
- newrows = [];
- for(var i = 0; i < tbody.rows.length; i++)
- {
- newrows[newrows.length] = tbody.rows[i];
- }
- for(var i = newrows.length - 1; i >= 0; i--)
- {
- tbody.appendChild(newrows[i]);
- }
- delete newrows;
- };
- sorttable.init()