datatable.js - jscancer - Javascript crap (relatively small) | |
git clone git://git.codemadness.org/jscancer | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
datatable.js (9134B) | |
--- | |
1 var datatable_parse_date = Date.parse, | |
2 datatable_parse_float = parseFloat, | |
3 datatable_parse_int = parseInt, | |
4 datatable_parse_string = String; | |
5 | |
6 function datatable_sort_default(x, y) { | |
7 return x > y ? 1 : (x == y ? 0 : -1); | |
8 } | |
9 | |
10 function datatable_init(el) { | |
11 var thead = el.tHead; | |
12 var ths = thead.children[0].children, | |
13 cols = []; | |
14 for (var i = 0; i < ths.length; i++) | |
15 cols.push({ | |
16 filterable: ["1", "true"].indexOf(ths[i].getAttr… | |
17 parsefn: window["datatable_parse_" + (ths[i].… | |
18 sortfn: window["datatable_sort_" + (ths[i].g… | |
19 sortable: ["1", "true"].indexOf(ths[i].getAttr… | |
20 }); | |
21 var d = { | |
22 table: el, | |
23 thead: thead, | |
24 ths: ths, | |
25 tbody: el.tBodies[0], | |
26 cols: cols, | |
27 sort: [], // sort options: [colidx, order (ASC = 0, DES… | |
28 lazyscroll: ["1", "true"].indexOf(el.getAttribute("data-… | |
29 search: "" // previous search text. | |
30 }; | |
31 d.data_raw = d.data = datatable_data_parse(d); | |
32 | |
33 if (d.lazyscroll) { | |
34 var bodytable = document.createElement("table"); | |
35 bodytable.className = el.className; | |
36 bodytable.cellSpacing = bodytable.cellPadding = bodytabl… | |
37 | |
38 var tr = document.createElement("tr"); | |
39 for (var i = 0; i < ths.length; i++) { | |
40 var th = ths[i].cloneNode(true); | |
41 th.innerHTML = ""; | |
42 tr.appendChild(th); | |
43 } | |
44 var bodythead = document.createElement("thead"); | |
45 bodythead.appendChild(tr); | |
46 | |
47 tr = document.createElement("tr"); | |
48 var newths = []; | |
49 for (var i = 0; i < ths.length; i++) | |
50 newths.push(tr.appendChild(ths[i].cloneNode(true… | |
51 d.ths = newths; // set new columns (for sorting etc).. | |
52 var elthead = document.createElement("thead"); | |
53 elthead.appendChild(tr); | |
54 | |
55 var headerstable = document.createElement("table"); | |
56 headerstable.cellSpacing = headerstable.cellPadding = he… | |
57 headerstable.className = el.className; | |
58 headerstable.appendChild(elthead); | |
59 | |
60 var headersel = document.createElement("div"); | |
61 headersel.className = "datatable-lazyscroll-headers"; | |
62 headersel.appendChild(headerstable); | |
63 | |
64 bodytable.appendChild(bodythead); | |
65 | |
66 var bodyel = document.createElement("div"); | |
67 bodyel.className = "datatable-lazyscroll-body"; | |
68 bodyel.appendChild(bodytable); | |
69 | |
70 var containerel = document.createElement("div"); | |
71 containerel.className = "datatable-lazyscroll-container"; | |
72 containerel.appendChild(headersel); | |
73 containerel.appendChild(bodyel); | |
74 | |
75 var bodytbody = bodytable.appendChild(document.createEle… | |
76 var startfiller = bodytbody.appendChild(document.createE… | |
77 var endfiller = bodytbody.appendChild(document.createEle… | |
78 | |
79 el.parentNode.insertBefore(containerel, el); | |
80 | |
81 var rowheight = 25; | |
82 d.display = function(data) { | |
83 var nrows = data.length; | |
84 | |
85 bodytable.style.height = (nrows * rowheight) + "… | |
86 | |
87 var start = parseInt(bodyel.scrollTop / rowheigh… | |
88 end = Math.min(parseInt((bodyel.scrollTop + … | |
89 | |
90 startfiller.style.height = (start * rowheight) +… | |
91 endfiller.style.height = ((nrows - end - 1) * ro… | |
92 | |
93 // remove nodes but keep first startfiller and e… | |
94 for (var c = bodytbody.childNodes; c.length > 2;… | |
95 bodytbody.removeChild(startfiller.nextSi… | |
96 | |
97 for (var i = start, prev = startfiller, p = body… | |
98 prev = p.insertBefore(d.data[i].tr, prev… | |
99 }; | |
100 d.scroll = function(y) { | |
101 bodyel.scrollTop = y; | |
102 }; | |
103 | |
104 var curscrollleft, verticalscrolltimer; | |
105 var scroll = function() { | |
106 // handle left / right scroll. | |
107 var scrolleft = bodyel.scrollLeft; | |
108 if (curscrollleft !== scrolleft) | |
109 headersel.scrollLeft = curscrollleft = s… | |
110 // handle up/down scroll. | |
111 clearTimeout(verticalscrolltimer); | |
112 verticalscrolltimer = setTimeout(function() { | |
113 d.display(d.data); | |
114 }, 16); | |
115 }; | |
116 window.addEventListener("resize", scroll); | |
117 bodyel.addEventListener("scroll", scroll); | |
118 d.display(d.data); | |
119 } else { | |
120 d.display = function(data) { | |
121 var tbody = document.createElement("tbody"); | |
122 for (var i = 0; i < data.length; i++) | |
123 tbody.appendChild(data[i].tr); | |
124 d.table.replaceChild(tbody, d.tbody); | |
125 tbody.style.display = data.length ? "table-row-g… | |
126 d.tbody = tbody; | |
127 }; | |
128 } | |
129 // setup click event handlers for sorting. | |
130 for (var i = 0; i < d.ths.length; i++) | |
131 d.cols[i].sortable && d.ths[i].addEventListener("click",… | |
132 return function(e) { | |
133 // shift-click for multi-select modifier. | |
134 datatable_sort_column_toggle(d, idx, e.s… | |
135 d.data = datatable_sort(d, d.data); | |
136 d.display(d.data); | |
137 }; | |
138 }(i), false); | |
139 return d; | |
140 } | |
141 | |
142 function datatable_sort_column_get(d, idx) { | |
143 for (var i = 0; i < d.sort.length; i++) | |
144 if (d.sort[i][0] == idx) | |
145 return i; | |
146 return -1; | |
147 } | |
148 | |
149 function datatable_sort_column_set(d, idx, order, multi) { | |
150 var c = datatable_sort_column_get(d, idx); | |
151 if (multi) | |
152 if (c != -1) | |
153 d.sort[c][1] = order; | |
154 else | |
155 d.sort.push([ idx, order ]); | |
156 else | |
157 d.sort = [ [idx, order] ]; | |
158 | |
159 for (var i = 0; i < d.ths.length; i++) { | |
160 var c = " " + d.ths[i].className + " "; | |
161 d.ths[i].className = c.replace(/ sort-(asc|desc) /g, " "… | |
162 } | |
163 for (var i = 0; i < d.sort.length; i++) | |
164 d.ths[d.sort[i][0]].className += " sort-" + (d.sort[i][1… | |
165 } | |
166 | |
167 // toggle sort or use default order: ASC. | |
168 function datatable_sort_column_toggle(d, idx, multi) { | |
169 var c = datatable_sort_column_get(d, idx); | |
170 datatable_sort_column_set(d, idx, c == -1 || d.sort[c][1] ? 0 : … | |
171 } | |
172 | |
173 function datatable_data_parse(d) { | |
174 var data = [], trs = d.tbody.children; | |
175 // NOTE: assumes each tr has only "<td>" childnodes. | |
176 for (var i = 0; i < trs.length; i++) { | |
177 var values = [], fv = []; | |
178 for (var j = 0, trc = trs[i].children; j < trc.length; j… | |
179 var td = trc[j], v = td.getAttribute("data-value… | |
180 // prefer data-value attribute, else use cell co… | |
181 // also set preprocess values to filter on cell … | |
182 // and data-value (case-insensitive). | |
183 var s = td.textContent || td.innerText; | |
184 if (typeof(v) != "undefined" && v !== null) { | |
185 fv.push([ s.toLowerCase(), v.toLowerCase… | |
186 values.push(d.cols[j].parsefn(v)); | |
187 } else { | |
188 fv.push([ s.toLowerCase() ]); | |
189 values.push(d.cols[j].parsefn(s)); | |
190 } | |
191 } | |
192 data.push({ | |
193 filtervalues: fv, | |
194 tr: trs[i], | |
195 values: values | |
196 }); | |
197 } | |
198 return data; | |
199 } | |
200 | |
201 function datatable_sort(d, data) { | |
202 // setup sort functions once (in order for multi-select). | |
203 var sortfns = d.sort.map(function(s) { | |
204 return (function(c, o, fn) { | |
205 if (o) | |
206 return function(xvals, yvals) { | |
207 return -fn(xvals[c], yvals[c]); | |
208 }; | |
209 else | |
210 return function(xvals, yvals) { | |
211 return fn(xvals[c], yvals[c]); | |
212 }; | |
213 })(s[0], s[1], d.cols[s[0]].sortfn); | |
214 }); | |
215 return data.sort(function(x, y) { | |
216 for (var i = 0, r; i < sortfns.length; i++) | |
217 if ((r = sortfns[i](x.values, y.values)) != 0) | |
218 return r; | |
219 return r; | |
220 }); | |
221 } | |
222 | |
223 function datatable_filter(d, data, s) { | |
224 var ret = [], tok = s.toLowerCase().split(" "); | |
225 for (var i = 0; i < data.length; i++) { | |
226 var fc = 0; | |
227 for (var k = 0; k < tok.length && fc < tok.length; k++) { | |
228 var f = false; | |
229 for (var j = 0; j < data[i].filtervalues.length … | |
230 for (var l = 0; l < data[i].filtervalues… | |
231 d.cols[j].filterable… | |
232 if (data[i].filtervalues[j][l].i… | |
233 f = true; | |
234 if (f) | |
235 fc++; | |
236 } | |
237 // all tokens (separated by space) must match. | |
238 if (fc == tok.length) | |
239 ret.push(data[i]); | |
240 } | |
241 return ret; | |
242 } | |
243 | |
244 function datatable_filter_text(d, s) { | |
245 s = s.toLowerCase(); | |
246 if (d.search == s) | |
247 return; | |
248 // if token string is different or string not in previous search… | |
249 // else filter on existing data and no need to sort. | |
250 if ((d.search.split(" ").length != s.split(" ").length) || | |
251 s.indexOf(d.search) == -1) { | |
252 d.data = datatable_sort(d, datatable_filter(d, d.data_ra… | |
253 } else { | |
254 d.data = datatable_filter(d, d.data, s); | |
255 } | |
256 d.search = s; | |
257 d.display(d.data); | |
258 if (d.scroll) | |
259 d.scroll(0); | |
260 } | |
261 | |
262 function datatable_filter_delayed(d, fn, e) { | |
263 clearTimeout(d.filter_timer); | |
264 d.filter_timer = setTimeout(function() { | |
265 fn(e); | |
266 }, 150); // filter delay in ms. | |
267 } | |
268 | |
269 function datatable_autoload() { | |
270 // convert to Array (not changed in-place, mandatory). | |
271 var ds = [], dl = [], els = document.getElementsByClassName && d… | |
272 for (var i = 0; i < els.length; i++) | |
273 dl.push(els[i]); | |
274 for (var i = 0, d; i < dl.length; i++) { | |
275 if ((d = datatable_init(dl[i])) === null) | |
276 continue; | |
277 var input = dl[i].parentNode.getElementsByClassName("fil… | |
278 // delayed filtering. | |
279 for (var j = 0; j < input.length; j++) { | |
280 input[j].addEventListener("input", (function(d, … | |
281 return function(e) { | |
282 datatable_filter_delayed(d, func… | |
283 datatable_filter_text(d,… | |
284 }, e); | |
285 }; | |
286 })(d, input[j]), false); | |
287 } | |
288 ds.push(d); | |
289 } | |
290 return ds; | |
291 } |