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);