All tables sortable

Make all tables on any page sortable by converting them to dataTables

  1. // ==UserScript==
  2. // @name All tables sortable
  3. // @namespace https://greasyfork.org/ru/users/303426
  4. // @version 1.4
  5. // @description Make all tables on any page sortable by converting them to dataTables
  6. // @author Титан
  7. // @match *://*/*
  8. // @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iI2ZmZiIgY2xhc3M9ImJpIGJpLXRhYmxlIiB2aWV3Qm94PSIwIDAgMTYgMTYiPgogIDxwYXRoIGQ9Ik0wIDJhMiAyIDAgMCAxIDItMmgxMmEyIDIgMCAwIDEgMiAydjEyYTIgMiAwIDAgMS0yIDJIMmEyIDIgMCAwIDEtMi0yVjJ6bTE1IDJoLTR2M2g0VjR6bTAgNGgtNHYzaDRWOHptMCA0aC00djNoM2ExIDEgMCAwIDAgMS0xdi0yem0tNSAzdi0zSDZ2M2g0em0tNSAwdi0zSDF2MmExIDEgMCAwIDAgMSAxaDN6bS00LTRoNFY4SDF2M3ptMC00aDRWNEgxdjN6bTUtM3YzaDRWNEg2em00IDRINnYzaDRWOHoiLz4KPC9zdmc+
  9. // @require https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js
  10. // @grant GM_registerMenuCommand
  11. // @require https://cdn.jsdelivr.net/npm/datatables.net@1.13.6/js/jquery.dataTables.min.js
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17. let autolaunch = false;
  18.  
  19. function ConvertTables() {
  20. if (document.querySelector("head > link[href=\"https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css\"]") == null)
  21. $('head').append('<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">'); // add dataTAbles css
  22.  
  23.  
  24. let tables = $('table')
  25.  
  26. for (let i = 0; i < tables.length; i++) {
  27. try {
  28. ConvertTable_ToDataTable(tables[i]);
  29. } catch (e) {
  30. console.log(`[All tables sortable] table ${i}/${tables.length} error: ${e}`);
  31. console.log(tables[i]);
  32. }
  33. }
  34. }
  35. function ConvertTableFromSelection() {
  36. const selection = window.getSelection();
  37. let node;
  38. if (selection?.anchorNode?.nodeType === 1) {
  39. node = selection?.anchorNode;
  40. } else {
  41. node = selection?.anchorNode?.parentElement;
  42. }
  43.  
  44. const table = node?.closest("table");
  45. if (table) {
  46. addDatatablesCSS();
  47. try {
  48. ConvertTable_ToDataTable(table);
  49. } catch (e) {
  50. console.error("[All tables sortable] selected table error:", e, table);
  51. }
  52. } else {
  53. alert("No table found near selected text.");
  54. }
  55. }
  56.  
  57.  
  58.  
  59. function ConvertTable_ToDataTable(table) {
  60. if (!table.querySelector("thead")) {
  61. ConvertHeadlessTable_ToHeadedTable(table);
  62. }
  63.  
  64. $(table).DataTable({
  65. "paging": false,
  66. });
  67. }
  68.  
  69. function ConvertHeadlessTable_ToHeadedTable(table) {
  70. let tbody = table.querySelector("tbody");
  71. if (tbody && tbody.rows.length > 0) {
  72. let thead = document.createElement("thead");
  73. let firstRow = tbody.rows[0]; // first row = header
  74. thead.appendChild(firstRow); // move it to <thead>
  75. table.insertBefore(thead, tbody); // add <thead> before <tbody>
  76. }
  77. }
  78.  
  79. GM_registerMenuCommand('Convert Tables', () => {
  80. ConvertTables();
  81. });
  82. GM_registerMenuCommand("Convert table containing selected text", () => {
  83. ConvertTableFromSelection();
  84. });
  85.  
  86.  
  87. $(document).ready(function() {
  88. window.alert = (function() { // suppress DataTables alert
  89. let nativeAlert = window.alert;
  90. return function(message) {
  91. //window.alert = nativeAlert;
  92. message.indexOf("DataTables warning") === 0 ?
  93. console.warn(message) :
  94. nativeAlert(message);
  95. }
  96. })();
  97.  
  98. if (autolaunch) {
  99. ConvertTables();
  100. }
  101.  
  102. });
  103.  
  104. })();