stupidtable.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Stupid jQuery table plugin.
  2. // Call on a table
  3. // sortFns: Sort functions for your datatypes.
  4. (function($) {
  5. $.fn.stupidtable = function(sortFns) {
  6. return this.each(function() {
  7. var $table = $(this);
  8. sortFns = sortFns || {};
  9. // Merge sort functions with some default sort functions.
  10. sortFns = $.extend({}, $.fn.stupidtable.default_sort_fns, sortFns);
  11. // ==================================================== //
  12. // Begin execution! //
  13. // ==================================================== //
  14. // Do sorting when THs are clicked
  15. $table.on("click.stupidtable", "thead th", function() {
  16. var $this = $(this);
  17. var th_index = 0;
  18. var dir = $.fn.stupidtable.dir;
  19. // Account for colspans
  20. $this.parents("tr").find("th").slice(0, $this.index() + 1).each(function() {
  21. var cols = $(this).attr("colspan") || 1;
  22. th_index += parseInt(cols,10);
  23. });
  24. th_index = th_index - 1;
  25. // Determine (and/or reverse) sorting direction, default `asc`
  26. var sort_dir = $this.data("sort-default") || dir.ASC;
  27. if ($this.data("sort-dir"))
  28. sort_dir = $this.data("sort-dir") === dir.ASC ? dir.DESC : dir.ASC;
  29. // Choose appropriate sorting function.
  30. var type = $this.data("sort") || null;
  31. // Prevent sorting if no type defined
  32. if (type === null) {
  33. return;
  34. }
  35. // Trigger `beforetablesort` event that calling scripts can hook into;
  36. // pass parameters for sorted column index and sorting direction
  37. $table.trigger("beforetablesort", {column: $this.index(), direction: sort_dir});
  38. // More reliable method of forcing a redraw
  39. $table.css("display");
  40. // Run sorting asynchronously on a timeout to force browser redraw after
  41. // `beforetablesort` callback. Also avoids locking up the browser too much.
  42. setTimeout(function() {
  43. // Gather the elements for this column
  44. var sortMethod = sortFns[type];
  45. $table.children("tbody").each(function(index,tbody){
  46. var column = [];
  47. var $tbody = $(tbody);
  48. var trs = $tbody.children("tr").not('[data-sort-ignore]');
  49. // Extract the data for the column that needs to be sorted and pair it up
  50. // with the TR itself into a tuple
  51. trs.each(function(index,tr) {
  52. var $e = $(tr).children().eq(th_index);
  53. var sort_val = $e.data("sort-value");
  54. var order_by = typeof(sort_val) !== "undefined" ? sort_val : $e.text();
  55. column.push([order_by, tr]);
  56. });
  57. // Sort by the data-order-by value
  58. column.sort(function(a, b) { return sortMethod(a[0], b[0]); });
  59. if (sort_dir != dir.ASC)
  60. column.reverse();
  61. // Replace the content of tbody with the sorted rows. Strangely (and
  62. // conveniently!) enough, .append accomplishes this for us.
  63. trs = $.map(column, function(kv) { return kv[1]; });
  64. $tbody.append(trs);
  65. });
  66. // Reset siblings
  67. $table.find("th").data("sort-dir", null).removeClass("sorting-desc sorting-asc");
  68. $this.data("sort-dir", sort_dir).addClass("sorting-"+sort_dir);
  69. // Trigger `aftertablesort` event. Similar to `beforetablesort`
  70. $table.trigger("aftertablesort", {column: $this.index(), direction: sort_dir});
  71. // More reliable method of forcing a redraw
  72. $table.css("display");
  73. }, 10);
  74. });
  75. });
  76. };
  77. // Enum containing sorting directions
  78. $.fn.stupidtable.dir = {ASC: "asc", DESC: "desc"};
  79. $.fn.stupidtable.default_sort_fns = {
  80. "int": function(a, b) {
  81. return parseInt(a, 10) - parseInt(b, 10);
  82. },
  83. "float": function(a, b) {
  84. return parseFloat(a) - parseFloat(b);
  85. },
  86. "string": function(a, b) {
  87. return a.localeCompare(b);
  88. },
  89. "string-ins": function(a, b) {
  90. a = a.toLocaleLowerCase();
  91. b = b.toLocaleLowerCase();
  92. return a.localeCompare(b);
  93. }
  94. };
  95. })(jQuery);