sorttable.js (3743B)
- /*
- * Copyright 2007 Stuart Langridge http://www.kryogenix.org/code/browser/sorttable/
- * Distributed under the terms of the X11 license
- *
- * Copyright 2018 Haelwenn (lanodan) Monnier <contact@hacktivis.me>
- * Distributed under the terms of the CC-BY 4.0 License
- */
- /* Usage:
- * Add <script src="sorttable.js"></script> to your 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,
- 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") { sorttable.makeSortable(sortableElement); }
- });
- },
- 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++) {
- if (!headrow[i].classList.contains("sorttable_nosort")) { // skip this col
- // 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');
- }
- }
- },
- 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().reverse();
- tb = tr.sorttable_tbody;
- row_array.forEach(function(row) { tb.appendChild(row[1]); });
- delete row_array;
- tr.classList.add('sorttable_sorted');
- }
- },
- // Use data-value="" attribute if you want to override innerHTML
- // Example: <td data-value="1337">Leet</td>
- getElementValue : function(element) {
- if(element === undefined) {
- return "\u0000"; // null
- console.log("Warning: Empty cells found");
- }
- if (element.dataset.value) {
- return element.dataset.value;
- } else {
- return element.innerText;
- }
- },
- 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()