Mercurial > repos > rlegendre > ribo_tools
comparison lightbox/js/stupidtable.js @ 8:adc01e560eae
Uploaded
author | rlegendre |
---|---|
date | Mon, 20 Oct 2014 11:34:11 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
7:015db5db052c | 8:adc01e560eae |
---|---|
1 // Stupid jQuery table plugin. | |
2 | |
3 // Call on a table | |
4 // sortFns: Sort functions for your datatypes. | |
5 (function($) { | |
6 | |
7 $.fn.stupidtable = function(sortFns) { | |
8 return this.each(function() { | |
9 var $table = $(this); | |
10 sortFns = sortFns || {}; | |
11 | |
12 // ==================================================== // | |
13 // Utility functions // | |
14 // ==================================================== // | |
15 | |
16 // Merge sort functions with some default sort functions. | |
17 sortFns = $.extend({}, $.fn.stupidtable.default_sort_fns, sortFns); | |
18 | |
19 // Return the resulting indexes of a sort so we can apply | |
20 // this result elsewhere. This returns an array of index numbers. | |
21 // return[0] = x means "arr's 0th element is now at x" | |
22 var sort_map = function(arr, sort_function) { | |
23 var map = []; | |
24 var index = 0; | |
25 var sorted = arr.slice(0).sort(sort_function); | |
26 for (var i=0; i<arr.length; i++) { | |
27 index = $.inArray(arr[i], sorted); | |
28 | |
29 // If this index is already in the map, look for the next index. | |
30 // This handles the case of duplicate entries. | |
31 while ($.inArray(index, map) != -1) { | |
32 index++; | |
33 } | |
34 map.push(index); | |
35 } | |
36 | |
37 return map; | |
38 }; | |
39 | |
40 // Apply a sort map to the array. | |
41 var apply_sort_map = function(arr, map) { | |
42 var clone = arr.slice(0), | |
43 newIndex = 0; | |
44 for (var i=0; i<map.length; i++) { | |
45 newIndex = map[i]; | |
46 clone[newIndex] = arr[i]; | |
47 } | |
48 return clone; | |
49 }; | |
50 | |
51 // ==================================================== // | |
52 // Begin execution! // | |
53 // ==================================================== // | |
54 | |
55 // Do sorting when THs are clicked | |
56 $table.on("click", "th", function() { | |
57 var trs = $table.children("tbody").children("tr"); | |
58 var $this = $(this); | |
59 var th_index = 0; | |
60 var dir = $.fn.stupidtable.dir; | |
61 | |
62 $table.find("th").slice(0, $this.index()).each(function() { | |
63 var cols = $(this).attr("colspan") || 1; | |
64 th_index += parseInt(cols,10); | |
65 }); | |
66 | |
67 // Determine (and/or reverse) sorting direction, default `asc` | |
68 var sort_dir = $this.data("sort-default") || dir.ASC; | |
69 if ($this.data("sort-dir")) | |
70 sort_dir = $this.data("sort-dir") === dir.ASC ? dir.DESC : dir.ASC; | |
71 | |
72 // Choose appropriate sorting function. | |
73 var type = $this.data("sort") || null; | |
74 | |
75 // Prevent sorting if no type defined | |
76 if (type === null) { | |
77 return; | |
78 } | |
79 | |
80 // Trigger `beforetablesort` event that calling scripts can hook into; | |
81 // pass parameters for sorted column index and sorting direction | |
82 $table.trigger("beforetablesort", {column: th_index, direction: sort_dir}); | |
83 // More reliable method of forcing a redraw | |
84 $table.css("display"); | |
85 | |
86 // Run sorting asynchronously on a timout to force browser redraw after | |
87 // `beforetablesort` callback. Also avoids locking up the browser too much. | |
88 setTimeout(function() { | |
89 // Gather the elements for this column | |
90 var column = []; | |
91 var sortMethod = sortFns[type]; | |
92 | |
93 // Push either the value of the `data-order-by` attribute if specified | |
94 // or just the text() value in this column to column[] for comparison. | |
95 trs.each(function(index,tr) { | |
96 var $e = $(tr).children().eq(th_index); | |
97 var sort_val = $e.data("sort-value"); | |
98 var order_by = typeof(sort_val) !== "undefined" ? sort_val : $e.text(); | |
99 column.push(order_by); | |
100 }); | |
101 | |
102 // Create the sort map. This column having a sort-dir implies it was | |
103 // the last column sorted. As long as no data-sort-desc is specified, | |
104 // we're free to just reverse the column. | |
105 var theMap; | |
106 if (sort_dir == dir.ASC) | |
107 theMap = sort_map(column, sortMethod); | |
108 else | |
109 theMap = sort_map(column, function(a, b) { return -sortMethod(a, b); }); | |
110 | |
111 // Reset siblings | |
112 $table.find("th").data("sort-dir", null).removeClass("sorting-desc sorting-asc"); | |
113 $this.data("sort-dir", sort_dir).addClass("sorting-"+sort_dir); | |
114 | |
115 var sortedTRs = $(apply_sort_map(trs, theMap)); | |
116 $table.children("tbody").remove(); | |
117 $table.append("<tbody />").append(sortedTRs); | |
118 | |
119 // Trigger `aftertablesort` event. Similar to `beforetablesort` | |
120 $table.trigger("aftertablesort", {column: th_index, direction: sort_dir}); | |
121 // More reliable method of forcing a redraw | |
122 $table.css("display"); | |
123 }, 10); | |
124 }); | |
125 }); | |
126 }; | |
127 | |
128 // Enum containing sorting directions | |
129 $.fn.stupidtable.dir = {ASC: "asc", DESC: "desc"}; | |
130 | |
131 $.fn.stupidtable.default_sort_fns = { | |
132 "int": function(a, b) { | |
133 return parseInt(a, 10) - parseInt(b, 10); | |
134 }, | |
135 "float": function(a, b) { | |
136 return parseFloat(a) - parseFloat(b); | |
137 }, | |
138 "string": function(a, b) { | |
139 if (a < b) return -1; | |
140 if (a > b) return +1; | |
141 return 0; | |
142 }, | |
143 "string-ins": function(a, b) { | |
144 a = a.toLowerCase(); | |
145 b = b.toLowerCase(); | |
146 if (a < b) return -1; | |
147 if (a > b) return +1; | |
148 return 0; | |
149 } | |
150 }; | |
151 | |
152 })(jQuery); |