logo

blog

My little blog can’t be this cute!

sorttable.js (3743B)


  1. /*
  2. * Copyright 2007 Stuart Langridge http://www.kryogenix.org/code/browser/sorttable/
  3. * Distributed under the terms of the X11 license
  4. *
  5. * Copyright 2018 Haelwenn (lanodan) Monnier <contact@hacktivis.me>
  6. * Distributed under the terms of the CC-BY 4.0 License
  7. */
  8. /* Usage:
  9. * Add <script src="sorttable.js"></script> to your HTML pages
  10. * Add class="sortable" to any table you'd like to make sortable
  11. * See sorttable.css for an example of styling
  12. */
  13. sorttable = {
  14. done : false,
  15. init : function() {
  16. // quit if this function has already been called
  17. if (sorttable.done) return;
  18. // flag this function so we don't do the same thing twice
  19. sorttable.done = true;
  20. var sortableElements = document.getElementsByClassName("sortable");
  21. Array.prototype.filter.call(sortableElements, function(sortableElement) {
  22. if (sortableElement.nodeName == "TABLE") { sorttable.makeSortable(sortableElement); }
  23. });
  24. },
  25. makeSortable : function(table) {
  26. // Only one thead row is supported
  27. if (table.tHead.rows.length != 1) return;
  28. // work through each column and calculate its type
  29. headrow = table.tHead.rows[0].cells;
  30. for (var i = 0; i < headrow.length; i++) {
  31. if (!headrow[i].classList.contains("sorttable_nosort")) { // skip this col
  32. // make it clickable to sort
  33. headrow[i].sorttable_columnindex = i;
  34. headrow[i].sorttable_tbody = table.tBodies[0];
  35. headrow[i].addEventListener("click", event => { if(event.target){ sorttable.innerSortFunction(event.target) } });
  36. headrow[i].addEventListener("keydown", event => { if(event.target && (event.key && event.key == "Enter")){ sorttable.innerSortFunction(event.target); } });
  37. headrow[i].setAttribute("tabindex", "0");
  38. headrow[i].classList.add('made_sortable');
  39. }
  40. }
  41. },
  42. innerSortFunction : function(tr) {
  43. if (tr.classList.contains("sorttable_sorted")) {
  44. sorttable.reverse(tr.sorttable_tbody);
  45. tr.classList.replace('sorttable_sorted', 'sorttable_sorted_reverse');
  46. } else if (tr.classList.contains("sorttable_sorted_reverse")) {
  47. sorttable.reverse(tr.sorttable_tbody);
  48. tr.classList.replace('sorttable_sorted_reverse', 'sorttable_sorted');
  49. } else {
  50. // remove sorttable_sorted classes
  51. theadRow = tr.parentNode;
  52. theadRow.childNodes.forEach(function(cell) {
  53. cell.classList.remove('sorttable_sorted_reverse', 'sorttable_sorted');
  54. });
  55. // build an array to sort. This is a Schwartzian transform thing,
  56. // i.e., we "decorate" each row with the actual sort key,
  57. // sort based on the sort keys, and then put the rows back in order
  58. // which is a lot faster because you only do getInnerText once per row
  59. row_array = [];
  60. col = tr.sorttable_columnindex;
  61. rows = tr.sorttable_tbody.rows;
  62. for (var j = 0; j < rows.length; j++) {
  63. row_array[row_array.length] = [ sorttable.getElementValue(rows[j].cells[col]), rows[j] ];
  64. }
  65. row_array.sort().reverse();
  66. tb = tr.sorttable_tbody;
  67. row_array.forEach(function(row) { tb.appendChild(row[1]); });
  68. delete row_array;
  69. tr.classList.add('sorttable_sorted');
  70. }
  71. },
  72. // Use data-value="" attribute if you want to override innerHTML
  73. // Example: <td data-value="1337">Leet</td>
  74. getElementValue : function(element) {
  75. if(element === undefined) {
  76. return "\u0000"; // null
  77. console.log("Warning: Empty cells found");
  78. }
  79. if (element.dataset.value) {
  80. return element.dataset.value;
  81. } else {
  82. return element.innerText;
  83. }
  84. },
  85. reverse : function(tbody) {
  86. // reverse the rows in a tbody
  87. newrows = [];
  88. for (var i = 0; i < tbody.rows.length; i++) { newrows[newrows.length] = tbody.rows[i]; }
  89. for (var i = newrows.length - 1; i >= 0; i--) { tbody.appendChild(newrows[i]); }
  90. delete newrows;
  91. }
  92. };
  93. sorttable.init()