Annotation of /alx-src/branches/alx-web-050/js/jquery.tablesorter.js
Parent Directory | Revision Log
Revision 1600 -
(hide annotations)
(download)
(as text)
Thu Dec 2 19:56:40 2010 UTC (13 years, 9 months ago) by niro
File MIME type: application/javascript
File size: 23366 byte(s)
Thu Dec 2 19:56:40 2010 UTC (13 years, 9 months ago) by niro
File MIME type: application/javascript
File size: 23366 byte(s)
-import from 050
1 | niro | 1600 | /* |
2 | * | ||
3 | * TableSorter 2.0 - Client-side table sorting with ease! | ||
4 | * Version 2.0.3 | ||
5 | * @requires jQuery v1.2.3 | ||
6 | * | ||
7 | * Copyright (c) 2007 Christian Bach | ||
8 | * Examples and docs at: http://tablesorter.com | ||
9 | * Dual licensed under the MIT and GPL licenses: | ||
10 | * http://www.opensource.org/licenses/mit-license.php | ||
11 | * http://www.gnu.org/licenses/gpl.html | ||
12 | * | ||
13 | */ | ||
14 | /** | ||
15 | * | ||
16 | * @description Create a sortable table with multi-column sorting capabilitys | ||
17 | * | ||
18 | * @example $('table').tablesorter(); | ||
19 | * @desc Create a simple tablesorter interface. | ||
20 | * | ||
21 | * @example $('table').tablesorter({ sortList:[[0,0],[1,0]] }); | ||
22 | * @desc Create a tablesorter interface and sort on the first and secound column in ascending order. | ||
23 | * | ||
24 | * @example $('table').tablesorter({ headers: { 0: { sorter: false}, 1: {sorter: false} } }); | ||
25 | * @desc Create a tablesorter interface and disableing the first and secound column headers. | ||
26 | * | ||
27 | * @example $('table').tablesorter({ 0: {sorter:"integer"}, 1: {sorter:"currency"} }); | ||
28 | * @desc Create a tablesorter interface and set a column parser for the first and secound column. | ||
29 | * | ||
30 | * | ||
31 | * @param Object settings An object literal containing key/value pairs to provide optional settings. | ||
32 | * | ||
33 | * @option String cssHeader (optional) A string of the class name to be appended to sortable tr elements in the thead of the table. | ||
34 | * Default value: "header" | ||
35 | * | ||
36 | * @option String cssAsc (optional) A string of the class name to be appended to sortable tr elements in the thead on a ascending sort. | ||
37 | * Default value: "headerSortUp" | ||
38 | * | ||
39 | * @option String cssDesc (optional) A string of the class name to be appended to sortable tr elements in the thead on a descending sort. | ||
40 | * Default value: "headerSortDown" | ||
41 | * | ||
42 | * @option String sortInitialOrder (optional) A string of the inital sorting order can be asc or desc. | ||
43 | * Default value: "asc" | ||
44 | * | ||
45 | * @option String sortMultisortKey (optional) A string of the multi-column sort key. | ||
46 | * Default value: "shiftKey" | ||
47 | * | ||
48 | * @option String textExtraction (optional) A string of the text-extraction method to use. | ||
49 | * For complex html structures inside td cell set this option to "complex", | ||
50 | * on large tables the complex option can be slow. | ||
51 | * Default value: "simple" | ||
52 | * | ||
53 | * @option Object headers (optional) An array containing the forces sorting rules. | ||
54 | * This option let's you specify a default sorting rule. | ||
55 | * Default value: null | ||
56 | * | ||
57 | * @option Array sortList (optional) An array containing the forces sorting rules. | ||
58 | * This option let's you specify a default sorting rule. | ||
59 | * Default value: null | ||
60 | * | ||
61 | * @option Array sortForce (optional) An array containing forced sorting rules. | ||
62 | * This option let's you specify a default sorting rule, which is prepended to user-selected rules. | ||
63 | * Default value: null | ||
64 | * | ||
65 | * @option Array sortAppend (optional) An array containing forced sorting rules. | ||
66 | * This option let's you specify a default sorting rule, which is appended to user-selected rules. | ||
67 | * Default value: null | ||
68 | * | ||
69 | * @option Boolean widthFixed (optional) Boolean flag indicating if tablesorter should apply fixed widths to the table columns. | ||
70 | * This is usefull when using the pager companion plugin. | ||
71 | * This options requires the dimension jquery plugin. | ||
72 | * Default value: false | ||
73 | * | ||
74 | * @option Boolean cancelSelection (optional) Boolean flag indicating if tablesorter should cancel selection of the table headers text. | ||
75 | * Default value: true | ||
76 | * | ||
77 | * @option Boolean debug (optional) Boolean flag indicating if tablesorter should display debuging information usefull for development. | ||
78 | * | ||
79 | * @type jQuery | ||
80 | * | ||
81 | * @name tablesorter | ||
82 | * | ||
83 | * @cat Plugins/Tablesorter | ||
84 | * | ||
85 | * @author Christian Bach/christian.bach@polyester.se | ||
86 | */ | ||
87 | |||
88 | (function($) { | ||
89 | $.extend({ | ||
90 | tablesorter: new function() { | ||
91 | |||
92 | var parsers = [], widgets = []; | ||
93 | |||
94 | this.defaults = { | ||
95 | cssHeader: "header", | ||
96 | cssAsc: "headerSortUp", | ||
97 | cssDesc: "headerSortDown", | ||
98 | sortInitialOrder: "asc", | ||
99 | sortMultiSortKey: "shiftKey", | ||
100 | sortForce: null, | ||
101 | sortAppend: null, | ||
102 | textExtraction: "simple", | ||
103 | parsers: {}, | ||
104 | widgets: [], | ||
105 | widgetZebra: {css: ["even","odd"]}, | ||
106 | headers: {}, | ||
107 | widthFixed: false, | ||
108 | cancelSelection: true, | ||
109 | sortList: [], | ||
110 | headerList: [], | ||
111 | dateFormat: "us", | ||
112 | decimal: '.', | ||
113 | debug: false | ||
114 | }; | ||
115 | |||
116 | /* debuging utils */ | ||
117 | function benchmark(s,d) { | ||
118 | log(s + "," + (new Date().getTime() - d.getTime()) + "ms"); | ||
119 | } | ||
120 | |||
121 | this.benchmark = benchmark; | ||
122 | |||
123 | function log(s) { | ||
124 | if (typeof console != "undefined" && typeof console.debug != "undefined") { | ||
125 | console.log(s); | ||
126 | } else { | ||
127 | alert(s); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | /* parsers utils */ | ||
132 | function buildParserCache(table,$headers) { | ||
133 | |||
134 | if(table.config.debug) { var parsersDebug = ""; } | ||
135 | |||
136 | var rows = table.tBodies[0].rows; | ||
137 | |||
138 | if(table.tBodies[0].rows[0]) { | ||
139 | |||
140 | var list = [], cells = rows[0].cells, l = cells.length; | ||
141 | |||
142 | for (var i=0;i < l; i++) { | ||
143 | var p = false; | ||
144 | |||
145 | if($.metadata && ($($headers[i]).metadata() && $($headers[i]).metadata().sorter) ) { | ||
146 | |||
147 | p = getParserById($($headers[i]).metadata().sorter); | ||
148 | |||
149 | } else if((table.config.headers[i] && table.config.headers[i].sorter)) { | ||
150 | |||
151 | p = getParserById(table.config.headers[i].sorter); | ||
152 | } | ||
153 | if(!p) { | ||
154 | p = detectParserForColumn(table,cells[i]); | ||
155 | } | ||
156 | |||
157 | if(table.config.debug) { parsersDebug += "column:" + i + " parser:" +p.id + "\n"; } | ||
158 | |||
159 | list.push(p); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | if(table.config.debug) { log(parsersDebug); } | ||
164 | |||
165 | return list; | ||
166 | }; | ||
167 | |||
168 | function detectParserForColumn(table,node) { | ||
169 | var l = parsers.length; | ||
170 | for(var i=1; i < l; i++) { | ||
171 | if(parsers[i].is($.trim(getElementText(table.config,node)),table,node)) { | ||
172 | return parsers[i]; | ||
173 | } | ||
174 | } | ||
175 | // 0 is always the generic parser (text) | ||
176 | return parsers[0]; | ||
177 | } | ||
178 | |||
179 | function getParserById(name) { | ||
180 | var l = parsers.length; | ||
181 | for(var i=0; i < l; i++) { | ||
182 | if(parsers[i].id.toLowerCase() == name.toLowerCase()) { | ||
183 | return parsers[i]; | ||
184 | } | ||
185 | } | ||
186 | return false; | ||
187 | } | ||
188 | |||
189 | /* utils */ | ||
190 | function buildCache(table) { | ||
191 | |||
192 | if(table.config.debug) { var cacheTime = new Date(); } | ||
193 | |||
194 | |||
195 | var totalRows = (table.tBodies[0] && table.tBodies[0].rows.length) || 0, | ||
196 | totalCells = (table.tBodies[0].rows[0] && table.tBodies[0].rows[0].cells.length) || 0, | ||
197 | parsers = table.config.parsers, | ||
198 | cache = {row: [], normalized: []}; | ||
199 | |||
200 | for (var i=0;i < totalRows; ++i) { | ||
201 | |||
202 | /** Add the table data to main data array */ | ||
203 | var c = table.tBodies[0].rows[i], cols = []; | ||
204 | |||
205 | cache.row.push($(c)); | ||
206 | |||
207 | for(var j=0; j < totalCells; ++j) { | ||
208 | cols.push(parsers[j].format(getElementText(table.config,c.cells[j]),table,c.cells[j])); | ||
209 | } | ||
210 | |||
211 | cols.push(i); // add position for rowCache | ||
212 | cache.normalized.push(cols); | ||
213 | cols = null; | ||
214 | }; | ||
215 | |||
216 | if(table.config.debug) { benchmark("Building cache for " + totalRows + " rows:", cacheTime); } | ||
217 | |||
218 | return cache; | ||
219 | }; | ||
220 | |||
221 | function getElementText(config,node) { | ||
222 | |||
223 | if(!node) return ""; | ||
224 | |||
225 | var t = ""; | ||
226 | |||
227 | if(config.textExtraction == "simple") { | ||
228 | if(node.childNodes[0] && node.childNodes[0].hasChildNodes()) { | ||
229 | t = node.childNodes[0].innerHTML; | ||
230 | } else { | ||
231 | t = node.innerHTML; | ||
232 | } | ||
233 | } else { | ||
234 | if(typeof(config.textExtraction) == "function") { | ||
235 | t = config.textExtraction(node); | ||
236 | } else { | ||
237 | t = $(node).text(); | ||
238 | } | ||
239 | } | ||
240 | return t; | ||
241 | } | ||
242 | |||
243 | function appendToTable(table,cache) { | ||
244 | |||
245 | if(table.config.debug) {var appendTime = new Date()} | ||
246 | |||
247 | var c = cache, | ||
248 | r = c.row, | ||
249 | n= c.normalized, | ||
250 | totalRows = n.length, | ||
251 | checkCell = (n[0].length-1), | ||
252 | tableBody = $(table.tBodies[0]), | ||
253 | rows = []; | ||
254 | |||
255 | for (var i=0;i < totalRows; i++) { | ||
256 | rows.push(r[n[i][checkCell]]); | ||
257 | if(!table.config.appender) { | ||
258 | |||
259 | var o = r[n[i][checkCell]]; | ||
260 | var l = o.length; | ||
261 | for(var j=0; j < l; j++) { | ||
262 | |||
263 | tableBody[0].appendChild(o[j]); | ||
264 | |||
265 | } | ||
266 | |||
267 | //tableBody.append(r[n[i][checkCell]]); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | if(table.config.appender) { | ||
272 | |||
273 | table.config.appender(table,rows); | ||
274 | } | ||
275 | |||
276 | rows = null; | ||
277 | |||
278 | if(table.config.debug) { benchmark("Rebuilt table:", appendTime); } | ||
279 | |||
280 | //apply table widgets | ||
281 | applyWidget(table); | ||
282 | |||
283 | // trigger sortend | ||
284 | setTimeout(function() { | ||
285 | $(table).trigger("sortEnd"); | ||
286 | },0); | ||
287 | |||
288 | }; | ||
289 | |||
290 | function buildHeaders(table) { | ||
291 | |||
292 | if(table.config.debug) { var time = new Date(); } | ||
293 | |||
294 | var meta = ($.metadata) ? true : false, tableHeadersRows = []; | ||
295 | |||
296 | for(var i = 0; i < table.tHead.rows.length; i++) { tableHeadersRows[i]=0; }; | ||
297 | |||
298 | $tableHeaders = $("thead th",table); | ||
299 | |||
300 | $tableHeaders.each(function(index) { | ||
301 | |||
302 | this.count = 0; | ||
303 | this.column = index; | ||
304 | this.order = formatSortingOrder(table.config.sortInitialOrder); | ||
305 | |||
306 | if(checkHeaderMetadata(this) || checkHeaderOptions(table,index)) this.sortDisabled = true; | ||
307 | |||
308 | if(!this.sortDisabled) { | ||
309 | $(this).addClass(table.config.cssHeader); | ||
310 | } | ||
311 | |||
312 | // add cell to headerList | ||
313 | table.config.headerList[index]= this; | ||
314 | }); | ||
315 | |||
316 | if(table.config.debug) { benchmark("Built headers:", time); log($tableHeaders); } | ||
317 | |||
318 | return $tableHeaders; | ||
319 | |||
320 | }; | ||
321 | |||
322 | function checkCellColSpan(table, rows, row) { | ||
323 | var arr = [], r = table.tHead.rows, c = r[row].cells; | ||
324 | |||
325 | for(var i=0; i < c.length; i++) { | ||
326 | var cell = c[i]; | ||
327 | |||
328 | if ( cell.colSpan > 1) { | ||
329 | arr = arr.concat(checkCellColSpan(table, headerArr,row++)); | ||
330 | } else { | ||
331 | if(table.tHead.length == 1 || (cell.rowSpan > 1 || !r[row+1])) { | ||
332 | arr.push(cell); | ||
333 | } | ||
334 | //headerArr[row] = (i+row); | ||
335 | } | ||
336 | } | ||
337 | return arr; | ||
338 | }; | ||
339 | |||
340 | function checkHeaderMetadata(cell) { | ||
341 | if(($.metadata) && ($(cell).metadata().sorter === false)) { return true; }; | ||
342 | return false; | ||
343 | } | ||
344 | |||
345 | function checkHeaderOptions(table,i) { | ||
346 | if((table.config.headers[i]) && (table.config.headers[i].sorter === false)) { return true; }; | ||
347 | return false; | ||
348 | } | ||
349 | |||
350 | function applyWidget(table) { | ||
351 | var c = table.config.widgets; | ||
352 | var l = c.length; | ||
353 | for(var i=0; i < l; i++) { | ||
354 | |||
355 | getWidgetById(c[i]).format(table); | ||
356 | } | ||
357 | |||
358 | } | ||
359 | |||
360 | function getWidgetById(name) { | ||
361 | var l = widgets.length; | ||
362 | for(var i=0; i < l; i++) { | ||
363 | if(widgets[i].id.toLowerCase() == name.toLowerCase() ) { | ||
364 | return widgets[i]; | ||
365 | } | ||
366 | } | ||
367 | }; | ||
368 | |||
369 | function formatSortingOrder(v) { | ||
370 | |||
371 | if(typeof(v) != "Number") { | ||
372 | i = (v.toLowerCase() == "desc") ? 1 : 0; | ||
373 | } else { | ||
374 | i = (v == (0 || 1)) ? v : 0; | ||
375 | } | ||
376 | return i; | ||
377 | } | ||
378 | |||
379 | function isValueInArray(v, a) { | ||
380 | var l = a.length; | ||
381 | for(var i=0; i < l; i++) { | ||
382 | if(a[i][0] == v) { | ||
383 | return true; | ||
384 | } | ||
385 | } | ||
386 | return false; | ||
387 | } | ||
388 | |||
389 | function setHeadersCss(table,$headers, list, css) { | ||
390 | // remove all header information | ||
391 | $headers.removeClass(css[0]).removeClass(css[1]); | ||
392 | |||
393 | var h = []; | ||
394 | $headers.each(function(offset) { | ||
395 | if(!this.sortDisabled) { | ||
396 | h[this.column] = $(this); | ||
397 | } | ||
398 | }); | ||
399 | |||
400 | var l = list.length; | ||
401 | for(var i=0; i < l; i++) { | ||
402 | h[list[i][0]].addClass(css[list[i][1]]); | ||
403 | } | ||
404 | } | ||
405 | |||
406 | function fixColumnWidth(table,$headers) { | ||
407 | var c = table.config; | ||
408 | if(c.widthFixed) { | ||
409 | var colgroup = $('<colgroup>'); | ||
410 | $("tr:first td",table.tBodies[0]).each(function() { | ||
411 | colgroup.append($('<col>').css('width',$(this).width())); | ||
412 | }); | ||
413 | $(table).prepend(colgroup); | ||
414 | }; | ||
415 | } | ||
416 | |||
417 | function updateHeaderSortCount(table,sortList) { | ||
418 | var c = table.config, l = sortList.length; | ||
419 | for(var i=0; i < l; i++) { | ||
420 | var s = sortList[i], o = c.headerList[s[0]]; | ||
421 | o.count = s[1]; | ||
422 | o.count++; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | /* sorting methods */ | ||
427 | function multisort(table,sortList,cache) { | ||
428 | |||
429 | if(table.config.debug) { var sortTime = new Date(); } | ||
430 | |||
431 | var dynamicExp = "var sortWrapper = function(a,b) {", l = sortList.length; | ||
432 | |||
433 | for(var i=0; i < l; i++) { | ||
434 | |||
435 | var c = sortList[i][0]; | ||
436 | var order = sortList[i][1]; | ||
437 | var s = (getCachedSortType(table.config.parsers,c) == "text") ? ((order == 0) ? "sortText" : "sortTextDesc") : ((order == 0) ? "sortNumeric" : "sortNumericDesc"); | ||
438 | |||
439 | var e = "e" + i; | ||
440 | |||
441 | dynamicExp += "var " + e + " = " + s + "(a[" + c + "],b[" + c + "]); "; | ||
442 | dynamicExp += "if(" + e + ") { return " + e + "; } "; | ||
443 | dynamicExp += "else { "; | ||
444 | } | ||
445 | |||
446 | // if value is the same keep orignal order | ||
447 | var orgOrderCol = cache.normalized[0].length - 1; | ||
448 | dynamicExp += "return a[" + orgOrderCol + "]-b[" + orgOrderCol + "];"; | ||
449 | |||
450 | for(var i=0; i < l; i++) { | ||
451 | dynamicExp += "}; "; | ||
452 | } | ||
453 | |||
454 | dynamicExp += "return 0; "; | ||
455 | dynamicExp += "}; "; | ||
456 | |||
457 | eval(dynamicExp); | ||
458 | |||
459 | cache.normalized.sort(sortWrapper); | ||
460 | |||
461 | if(table.config.debug) { benchmark("Sorting on " + sortList.toString() + " and dir " + order+ " time:", sortTime); } | ||
462 | |||
463 | return cache; | ||
464 | }; | ||
465 | |||
466 | function sortText(a,b) { | ||
467 | return ((a < b) ? -1 : ((a > b) ? 1 : 0)); | ||
468 | }; | ||
469 | |||
470 | function sortTextDesc(a,b) { | ||
471 | return ((b < a) ? -1 : ((b > a) ? 1 : 0)); | ||
472 | }; | ||
473 | |||
474 | function sortNumeric(a,b) { | ||
475 | return a-b; | ||
476 | }; | ||
477 | |||
478 | function sortNumericDesc(a,b) { | ||
479 | return b-a; | ||
480 | }; | ||
481 | |||
482 | function getCachedSortType(parsers,i) { | ||
483 | return parsers[i].type; | ||
484 | }; | ||
485 | |||
486 | /* public methods */ | ||
487 | this.construct = function(settings) { | ||
488 | |||
489 | return this.each(function() { | ||
490 | |||
491 | if(!this.tHead || !this.tBodies) return; | ||
492 | |||
493 | var $this, $document,$headers, cache, config, shiftDown = 0, sortOrder; | ||
494 | |||
495 | this.config = {}; | ||
496 | |||
497 | config = $.extend(this.config, $.tablesorter.defaults, settings); | ||
498 | |||
499 | // store common expression for speed | ||
500 | $this = $(this); | ||
501 | |||
502 | // build headers | ||
503 | $headers = buildHeaders(this); | ||
504 | |||
505 | // try to auto detect column type, and store in tables config | ||
506 | this.config.parsers = buildParserCache(this,$headers); | ||
507 | |||
508 | |||
509 | // build the cache for the tbody cells | ||
510 | cache = buildCache(this); | ||
511 | |||
512 | // get the css class names, could be done else where. | ||
513 | var sortCSS = [config.cssDesc,config.cssAsc]; | ||
514 | |||
515 | // fixate columns if the users supplies the fixedWidth option | ||
516 | fixColumnWidth(this); | ||
517 | |||
518 | // apply event handling to headers | ||
519 | // this is to big, perhaps break it out? | ||
520 | $headers.click(function(e) { | ||
521 | |||
522 | $this.trigger("sortStart"); | ||
523 | |||
524 | var totalRows = ($this[0].tBodies[0] && $this[0].tBodies[0].rows.length) || 0; | ||
525 | |||
526 | if(!this.sortDisabled && totalRows > 0) { | ||
527 | |||
528 | |||
529 | // store exp, for speed | ||
530 | var $cell = $(this); | ||
531 | |||
532 | // get current column index | ||
533 | var i = this.column; | ||
534 | |||
535 | // get current column sort order | ||
536 | this.order = this.count++ % 2; | ||
537 | |||
538 | // user only whants to sort on one column | ||
539 | if(!e[config.sortMultiSortKey]) { | ||
540 | |||
541 | // flush the sort list | ||
542 | config.sortList = []; | ||
543 | |||
544 | if(config.sortForce != null) { | ||
545 | var a = config.sortForce; | ||
546 | for(var j=0; j < a.length; j++) { | ||
547 | if(a[j][0] != i) { | ||
548 | config.sortList.push(a[j]); | ||
549 | } | ||
550 | } | ||
551 | } | ||
552 | |||
553 | // add column to sort list | ||
554 | config.sortList.push([i,this.order]); | ||
555 | |||
556 | // multi column sorting | ||
557 | } else { | ||
558 | // the user has clicked on an all ready sortet column. | ||
559 | if(isValueInArray(i,config.sortList)) { | ||
560 | |||
561 | // revers the sorting direction for all tables. | ||
562 | for(var j=0; j < config.sortList.length; j++) { | ||
563 | var s = config.sortList[j], o = config.headerList[s[0]]; | ||
564 | if(s[0] == i) { | ||
565 | o.count = s[1]; | ||
566 | o.count++; | ||
567 | s[1] = o.count % 2; | ||
568 | } | ||
569 | } | ||
570 | } else { | ||
571 | // add column to sort list array | ||
572 | config.sortList.push([i,this.order]); | ||
573 | } | ||
574 | }; | ||
575 | setTimeout(function() { | ||
576 | //set css for headers | ||
577 | setHeadersCss($this[0],$headers,config.sortList,sortCSS); | ||
578 | appendToTable($this[0],multisort($this[0],config.sortList,cache)); | ||
579 | },1); | ||
580 | // stop normal event by returning false | ||
581 | return false; | ||
582 | } | ||
583 | // cancel selection | ||
584 | }).mousedown(function() { | ||
585 | if(config.cancelSelection) { | ||
586 | this.onselectstart = function() {return false}; | ||
587 | return false; | ||
588 | } | ||
589 | }); | ||
590 | |||
591 | // apply easy methods that trigger binded events | ||
592 | $this.bind("update",function() { | ||
593 | |||
594 | // rebuild parsers. | ||
595 | this.config.parsers = buildParserCache(this,$headers); | ||
596 | |||
597 | // rebuild the cache map | ||
598 | cache = buildCache(this); | ||
599 | |||
600 | }).bind("sorton",function(e,list) { | ||
601 | |||
602 | $(this).trigger("sortStart"); | ||
603 | |||
604 | config.sortList = list; | ||
605 | |||
606 | // update and store the sortlist | ||
607 | var sortList = config.sortList; | ||
608 | |||
609 | // update header count index | ||
610 | updateHeaderSortCount(this,sortList); | ||
611 | |||
612 | //set css for headers | ||
613 | setHeadersCss(this,$headers,sortList,sortCSS); | ||
614 | |||
615 | |||
616 | // sort the table and append it to the dom | ||
617 | appendToTable(this,multisort(this,sortList,cache)); | ||
618 | |||
619 | }).bind("appendCache",function() { | ||
620 | |||
621 | appendToTable(this,cache); | ||
622 | |||
623 | }).bind("applyWidgetId",function(e,id) { | ||
624 | |||
625 | getWidgetById(id).format(this); | ||
626 | |||
627 | }).bind("applyWidgets",function() { | ||
628 | // apply widgets | ||
629 | applyWidget(this); | ||
630 | }); | ||
631 | |||
632 | if($.metadata && ($(this).metadata() && $(this).metadata().sortlist)) { | ||
633 | config.sortList = $(this).metadata().sortlist; | ||
634 | } | ||
635 | // if user has supplied a sort list to constructor. | ||
636 | if(config.sortList.length > 0) { | ||
637 | $this.trigger("sorton",[config.sortList]); | ||
638 | } | ||
639 | |||
640 | // apply widgets | ||
641 | applyWidget(this); | ||
642 | }); | ||
643 | }; | ||
644 | |||
645 | this.addParser = function(parser) { | ||
646 | var l = parsers.length, a = true; | ||
647 | for(var i=0; i < l; i++) { | ||
648 | if(parsers[i].id.toLowerCase() == parser.id.toLowerCase()) { | ||
649 | a = false; | ||
650 | } | ||
651 | } | ||
652 | if(a) { parsers.push(parser); }; | ||
653 | }; | ||
654 | |||
655 | this.addWidget = function(widget) { | ||
656 | widgets.push(widget); | ||
657 | }; | ||
658 | |||
659 | this.formatFloat = function(s) { | ||
660 | var i = parseFloat(s); | ||
661 | return (isNaN(i)) ? 0 : i; | ||
662 | }; | ||
663 | this.formatInt = function(s) { | ||
664 | var i = parseInt(s); | ||
665 | return (isNaN(i)) ? 0 : i; | ||
666 | }; | ||
667 | |||
668 | this.isDigit = function(s,config) { | ||
669 | var DECIMAL = '\\' + config.decimal; | ||
670 | var exp = '/(^[+]?0(' + DECIMAL +'0+)?$)|(^([-+]?[1-9][0-9]*)$)|(^([-+]?((0?|[1-9][0-9]*)' + DECIMAL +'(0*[1-9][0-9]*)))$)|(^[-+]?[1-9]+[0-9]*' + DECIMAL +'0+$)/'; | ||
671 | return RegExp(exp).test($.trim(s)); | ||
672 | }; | ||
673 | |||
674 | this.clearTableBody = function(table) { | ||
675 | if($.browser.msie) { | ||
676 | function empty() { | ||
677 | while ( this.firstChild ) this.removeChild( this.firstChild ); | ||
678 | } | ||
679 | empty.apply(table.tBodies[0]); | ||
680 | } else { | ||
681 | table.tBodies[0].innerHTML = ""; | ||
682 | } | ||
683 | }; | ||
684 | } | ||
685 | }); | ||
686 | |||
687 | // extend plugin scope | ||
688 | $.fn.extend({ | ||
689 | tablesorter: $.tablesorter.construct | ||
690 | }); | ||
691 | |||
692 | var ts = $.tablesorter; | ||
693 | |||
694 | // add default parsers | ||
695 | ts.addParser({ | ||
696 | id: "text", | ||
697 | is: function(s) { | ||
698 | return true; | ||
699 | }, | ||
700 | format: function(s) { | ||
701 | return $.trim(s.toLowerCase()); | ||
702 | }, | ||
703 | type: "text" | ||
704 | }); | ||
705 | |||
706 | ts.addParser({ | ||
707 | id: "digit", | ||
708 | is: function(s,table) { | ||
709 | var c = table.config; | ||
710 | return $.tablesorter.isDigit(s,c); | ||
711 | }, | ||
712 | format: function(s) { | ||
713 | return $.tablesorter.formatFloat(s); | ||
714 | }, | ||
715 | type: "numeric" | ||
716 | }); | ||
717 | |||
718 | ts.addParser({ | ||
719 | id: "currency", | ||
720 | is: function(s) { | ||
721 | return /^[£$€?.]/.test(s); | ||
722 | }, | ||
723 | format: function(s) { | ||
724 | return $.tablesorter.formatFloat(s.replace(new RegExp(/[^0-9.]/g),"")); | ||
725 | }, | ||
726 | type: "numeric" | ||
727 | }); | ||
728 | |||
729 | ts.addParser({ | ||
730 | id: "ipAddress", | ||
731 | is: function(s) { | ||
732 | return /^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(s); | ||
733 | }, | ||
734 | format: function(s) { | ||
735 | var a = s.split("."), r = "", l = a.length; | ||
736 | for(var i = 0; i < l; i++) { | ||
737 | var item = a[i]; | ||
738 | if(item.length == 2) { | ||
739 | r += "0" + item; | ||
740 | } else { | ||
741 | r += item; | ||
742 | } | ||
743 | } | ||
744 | return $.tablesorter.formatFloat(r); | ||
745 | }, | ||
746 | type: "numeric" | ||
747 | }); | ||
748 | |||
749 | ts.addParser({ | ||
750 | id: "url", | ||
751 | is: function(s) { | ||
752 | return /^(https?|ftp|file):\/\/$/.test(s); | ||
753 | }, | ||
754 | format: function(s) { | ||
755 | return jQuery.trim(s.replace(new RegExp(/(https?|ftp|file):\/\//),'')); | ||
756 | }, | ||
757 | type: "text" | ||
758 | }); | ||
759 | |||
760 | ts.addParser({ | ||
761 | id: "isoDate", | ||
762 | is: function(s) { | ||
763 | return /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(s); | ||
764 | }, | ||
765 | format: function(s) { | ||
766 | return $.tablesorter.formatFloat((s != "") ? new Date(s.replace(new RegExp(/-/g),"/")).getTime() : "0"); | ||
767 | }, | ||
768 | type: "numeric" | ||
769 | }); | ||
770 | |||
771 | ts.addParser({ | ||
772 | id: "percent", | ||
773 | is: function(s) { | ||
774 | return /\%$/.test($.trim(s)); | ||
775 | }, | ||
776 | format: function(s) { | ||
777 | return $.tablesorter.formatFloat(s.replace(new RegExp(/%/g),"")); | ||
778 | }, | ||
779 | type: "numeric" | ||
780 | }); | ||
781 | |||
782 | ts.addParser({ | ||
783 | id: "usLongDate", | ||
784 | is: function(s) { | ||
785 | return s.match(new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/)); | ||
786 | }, | ||
787 | format: function(s) { | ||
788 | return $.tablesorter.formatFloat(new Date(s).getTime()); | ||
789 | }, | ||
790 | type: "numeric" | ||
791 | }); | ||
792 | |||
793 | ts.addParser({ | ||
794 | id: "shortDate", | ||
795 | is: function(s) { | ||
796 | return /\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/.test(s); | ||
797 | }, | ||
798 | format: function(s,table) { | ||
799 | var c = table.config; | ||
800 | s = s.replace(/\-/g,"/"); | ||
801 | if(c.dateFormat == "us") { | ||
802 | // reformat the string in ISO format | ||
803 | s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$1/$2"); | ||
804 | } else if(c.dateFormat == "uk") { | ||
805 | //reformat the string in ISO format | ||
806 | s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$2/$1"); | ||
807 | } else if(c.dateFormat == "dd/mm/yy" || c.dateFormat == "dd-mm-yy") { | ||
808 | s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/, "$1/$2/$3"); | ||
809 | } | ||
810 | return $.tablesorter.formatFloat(new Date(s).getTime()); | ||
811 | }, | ||
812 | type: "numeric" | ||
813 | }); | ||
814 | |||
815 | ts.addParser({ | ||
816 | id: "time", | ||
817 | is: function(s) { | ||
818 | return /^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(s); | ||
819 | }, | ||
820 | format: function(s) { | ||
821 | return $.tablesorter.formatFloat(new Date("2000/01/01 " + s).getTime()); | ||
822 | }, | ||
823 | type: "numeric" | ||
824 | }); | ||
825 | |||
826 | |||
827 | ts.addParser({ | ||
828 | id: "metadata", | ||
829 | is: function(s) { | ||
830 | return false; | ||
831 | }, | ||
832 | format: function(s,table,cell) { | ||
833 | var c = table.config, p = (!c.parserMetadataName) ? 'sortValue' : c.parserMetadataName; | ||
834 | return $(cell).metadata()[p]; | ||
835 | }, | ||
836 | type: "numeric" | ||
837 | }); | ||
838 | |||
839 | // add default widgets | ||
840 | ts.addWidget({ | ||
841 | id: "zebra", | ||
842 | format: function(table) { | ||
843 | if(table.config.debug) { var time = new Date(); } | ||
844 | $("tr:visible",table.tBodies[0]) | ||
845 | .filter(':even') | ||
846 | .removeClass(table.config.widgetZebra.css[1]).addClass(table.config.widgetZebra.css[0]) | ||
847 | .end().filter(':odd') | ||
848 | .removeClass(table.config.widgetZebra.css[0]).addClass(table.config.widgetZebra.css[1]); | ||
849 | if(table.config.debug) { $.tablesorter.benchmark("Applying Zebra widget", time); } | ||
850 | } | ||
851 | }); | ||
852 | })(jQuery); |
Properties
Name | Value |
---|---|
svn:executable | * |