jquery-tablesorter 1.10.10 → 1.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/jquery-tablesorter/version.rb +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +47 -18
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +206 -167
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets-filter-formatter-select2.js +134 -0
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets-filter-formatter.js +69 -67
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +98 -51
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-extract.js +82 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-build-table.js +17 -5
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-cssStickyHeaders.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +359 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +272 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +49 -18
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-reflow.js +179 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +18 -45
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-staticRow.js +123 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 618934fed3abb717299bc8c54013a3b1d3d53863
|
4
|
+
data.tar.gz: afbd307142ac50a3577cee070ae22a9f8b1a2bea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5fd391890c8feef67fba3c66f00f9e9f1f45d2bc1bc78fad870fa2db6d10c54ce0b68269ce4afcb8c04fb5d5b0b402d9c086add0085b53d94ec4905570cb758
|
7
|
+
data.tar.gz: e29cceab65caa5c1a248d1b90ae61cdc46364dbadb9be1ae68e01097fe34428b8f4e462928452b98f1f659b41c7a472aa90df1defffcba228d237ae356cf2503
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
Simple integration of jquery-tablesorter into the asset pipeline.
|
6
6
|
|
7
|
-
Current tablesorter version: 2.
|
7
|
+
Current tablesorter version: 2.16.1 (4/24/2014), [documentation]
|
8
8
|
|
9
9
|
Any issue associate with the js/css files, please report to [Mottie's fork].
|
10
10
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*!
|
2
2
|
* tablesorter pager plugin
|
3
|
-
* updated 4/
|
3
|
+
* updated 4/23/2014 (v2.16.0)
|
4
4
|
*/
|
5
5
|
/*jshint browser:true, jquery:true, unused:false */
|
6
6
|
;(function($) {
|
@@ -58,6 +58,10 @@
|
|
58
58
|
// starting page of the pager (zero based index)
|
59
59
|
page: 0,
|
60
60
|
|
61
|
+
// reset pager after filtering; set to desired page #
|
62
|
+
// set to false to not change page at filter start
|
63
|
+
pageReset: 0,
|
64
|
+
|
61
65
|
// Number of visible rows
|
62
66
|
size: 10,
|
63
67
|
|
@@ -125,15 +129,23 @@
|
|
125
129
|
},
|
126
130
|
|
127
131
|
updatePageDisplay = function(table, p, completed) {
|
128
|
-
var i, pg, s, out,
|
132
|
+
var i, pg, s, out, regex,
|
129
133
|
c = table.config,
|
130
134
|
f = c.$table.hasClass('hasFilters') && !p.ajaxUrl,
|
131
|
-
t =
|
132
|
-
(p.countChildRows ? '' : ',.' + c.cssChildRow),
|
135
|
+
t = [],
|
133
136
|
sz = p.size || 10; // don't allow dividing by zero
|
137
|
+
t = [ (c.widgetOptions && c.widgetOptions.filter_filteredRow || 'filtered'), c.selectorRemove ];
|
138
|
+
if (p.countChildRows) { t.push(c.cssChildRow); }
|
139
|
+
regex = new RegExp( '(' + t.join('|') + ')' );
|
134
140
|
p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method
|
135
|
-
p.filteredRows = (f) ?
|
136
|
-
p.filteredPages =
|
141
|
+
p.filteredRows = (f) ? 0 : p.totalRows;
|
142
|
+
p.filteredPages = p.totalPages;
|
143
|
+
if (f) {
|
144
|
+
$.each(c.cache[0].normalized, function(i, el) {
|
145
|
+
p.filteredRows += p.regexRows.test(el[c.columns].$row[0].className) ? 0 : 1;
|
146
|
+
});
|
147
|
+
p.filteredPages = Math.ceil( p.filteredRows / sz ) || 0;
|
148
|
+
}
|
137
149
|
if ( Math.min( p.totalPages, p.filteredPages ) >= 0 ) {
|
138
150
|
t = (p.size * p.page > p.filteredRows);
|
139
151
|
p.startRow = (t) ? 1 : (p.filteredRows === 0 ? 0 : p.size * p.page + 1);
|
@@ -448,12 +460,13 @@
|
|
448
460
|
},
|
449
461
|
|
450
462
|
renderTable = function(table, rows, p) {
|
451
|
-
var
|
463
|
+
var $tb, index, count, added,
|
452
464
|
$t = $(table),
|
453
465
|
c = table.config,
|
466
|
+
f = c.$table.hasClass('hasFilters'),
|
454
467
|
l = rows && rows.length || 0, // rows may be undefined
|
455
468
|
s = ( p.page * p.size ),
|
456
|
-
e =
|
469
|
+
e = p.size;
|
457
470
|
if ( l < 1 ) { return; } // empty table, abort!
|
458
471
|
if ( p.page >= p.totalPages ) {
|
459
472
|
// lets not render the table more than once
|
@@ -465,18 +478,25 @@
|
|
465
478
|
if ( !p.removeRows ) {
|
466
479
|
hideRows(table, p);
|
467
480
|
} else {
|
468
|
-
if ( e > rows.length ) {
|
469
|
-
e = rows.length;
|
470
|
-
}
|
471
481
|
ts.clearTableBody(table);
|
472
482
|
$tb = ts.processTbody(table, c.$tbodies.eq(0), true);
|
473
|
-
|
474
|
-
|
483
|
+
// not filtered, start from the calculated starting point (s)
|
484
|
+
// if filtered, start from zero
|
485
|
+
index = f ? 0 : s;
|
486
|
+
count = f ? 0 : s;
|
487
|
+
added = 0;
|
488
|
+
while (added < e && index < rows.length) {
|
489
|
+
if (!f || !/filtered/.test(rows[index][0].className)){
|
490
|
+
count++;
|
491
|
+
if (count > s && added <= e) {
|
492
|
+
added++;
|
493
|
+
$tb.append(rows[index]);
|
494
|
+
}
|
495
|
+
}
|
496
|
+
index++;
|
475
497
|
}
|
476
|
-
|
477
498
|
ts.processTbody(table, $tb, false);
|
478
499
|
}
|
479
|
-
|
480
500
|
updatePageDisplay(table, p);
|
481
501
|
if ( !p.isDisabled ) { fixHeight(table, p); }
|
482
502
|
$t.trigger('applyWidgets');
|
@@ -594,6 +614,7 @@
|
|
594
614
|
p.$container.hide(); // hide pager
|
595
615
|
table.config.appender = null; // remove pager appender function
|
596
616
|
p.initialized = false;
|
617
|
+
delete table.config.rowsCopy;
|
597
618
|
$(table).unbind('destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager');
|
598
619
|
if (ts.storage) {
|
599
620
|
ts.storage(table, p.storageKey, '');
|
@@ -647,7 +668,8 @@
|
|
647
668
|
var t, ctrls, fxn,
|
648
669
|
table = this,
|
649
670
|
c = table.config,
|
650
|
-
|
671
|
+
wo = c.widgetOptions,
|
672
|
+
p = c.pager = $.extend( true, {}, $.tablesorterPager.defaults, settings ),
|
651
673
|
$t = c.$table,
|
652
674
|
// added in case the pager is reinitialized after being destroyed.
|
653
675
|
pager = p.$container = $(p.container).addClass('tablesorter-pager').show();
|
@@ -669,17 +691,24 @@
|
|
669
691
|
$.data(table, 'pagerLastSize', p.size);
|
670
692
|
}
|
671
693
|
|
694
|
+
// skipped rows
|
695
|
+
p.regexRows = new RegExp('(' + (wo.filter_filteredRow || 'filtered') + '|' + c.selectorRemove.substring(1) + '|' + c.cssChildRow + ')');
|
696
|
+
|
672
697
|
$t
|
673
698
|
.unbind('filterStart filterEnd sortEnd disable enable destroy update updateRows updateAll addRows pageSize '.split(' ').join('.pager '))
|
674
699
|
.bind('filterStart.pager', function(e, filters) {
|
675
700
|
p.currentFilters = filters;
|
676
|
-
|
701
|
+
// don't change page is filters are the same (pager updating, etc)
|
702
|
+
if (p.pageReset !== false && (c.lastCombinedFilter || '') !== (filters || []).join('')) {
|
703
|
+
p.page = p.pageReset; // fixes #456 & #565
|
704
|
+
}
|
677
705
|
})
|
678
706
|
// update pager after filter widget completes
|
679
707
|
.bind('filterEnd.pager sortEnd.pager', function() {
|
680
708
|
if (p.initialized) {
|
681
|
-
|
709
|
+
// update page display first, so we update p.filteredPages
|
682
710
|
updatePageDisplay(table, p, false);
|
711
|
+
moveToPage(table, p, false);
|
683
712
|
fixHeight(table, p);
|
684
713
|
}
|
685
714
|
})
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**!
|
2
|
-
* TableSorter 2.
|
2
|
+
* TableSorter 2.16.1 - Client-side table sorting with ease!
|
3
3
|
* @requires jQuery v1.2.6+
|
4
4
|
*
|
5
5
|
* Copyright (c) 2007 Christian Bach
|
@@ -24,7 +24,7 @@
|
|
24
24
|
|
25
25
|
var ts = this;
|
26
26
|
|
27
|
-
ts.version = "2.
|
27
|
+
ts.version = "2.16.1";
|
28
28
|
|
29
29
|
ts.parsers = [];
|
30
30
|
ts.widgets = [];
|
@@ -64,7 +64,8 @@
|
|
64
64
|
|
65
65
|
emptyTo : 'bottom', // sort empty cell to bottom, top, none, zero
|
66
66
|
stringTo : 'max', // sort strings in numerical column as max, min, top, bottom, zero
|
67
|
-
textExtraction : '
|
67
|
+
textExtraction : 'basic', // text extraction method/function - function(node, table, cellIndex){}
|
68
|
+
textAttribute : 'data-text',// data-attribute that contains alternate cell text (used in textExtraction function)
|
68
69
|
textSorter : null, // choose overall or specific column sorter function(a, b, direction, table, columnIndex) [alt: ts.sortText]
|
69
70
|
numberSorter : null, // choose overall numeric sorter function(a, b, direction, maxColumnValue)
|
70
71
|
|
@@ -167,20 +168,19 @@
|
|
167
168
|
function getElementText(table, node, cellIndex) {
|
168
169
|
if (!node) { return ""; }
|
169
170
|
var c = table.config,
|
170
|
-
t = c.textExtraction
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
text = $(node).text();
|
176
|
-
}
|
171
|
+
t = c.textExtraction || '',
|
172
|
+
text = "";
|
173
|
+
if (t === "basic") {
|
174
|
+
// check data-attribute first
|
175
|
+
text = $(node).attr(c.textAttribute) || node.textContent || node.innerText || $(node).text() || "";
|
177
176
|
} else {
|
178
|
-
if (typeof
|
177
|
+
if (typeof(t) === "function") {
|
179
178
|
text = t(node, table, cellIndex);
|
180
|
-
} else if (typeof
|
179
|
+
} else if (typeof(t) === "object" && t.hasOwnProperty(cellIndex)) {
|
181
180
|
text = t[cellIndex](node, table, cellIndex);
|
182
181
|
} else {
|
183
|
-
|
182
|
+
// previous "simple" method
|
183
|
+
text = node.textContent || node.innerText || $(node).text() || "";
|
184
184
|
}
|
185
185
|
}
|
186
186
|
return $.trim(text);
|
@@ -219,41 +219,47 @@
|
|
219
219
|
var c = table.config,
|
220
220
|
// update table bodies in case we start with an empty table
|
221
221
|
tb = c.$tbodies = c.$table.children('tbody:not(.' + c.cssInfoBlock + ')'),
|
222
|
-
rows, list, l, i, h, ch, p, time,
|
223
|
-
|
222
|
+
rows, list, l, i, h, ch, p, time,
|
223
|
+
j = 0,
|
224
|
+
parsersDebug = "",
|
225
|
+
len = tb.length;
|
226
|
+
if ( len === 0) {
|
224
227
|
return c.debug ? log('Warning: *Empty table!* Not building a parser cache') : '';
|
225
228
|
} else if (c.debug) {
|
226
229
|
time = new Date();
|
227
230
|
log('Detecting parsers for each column');
|
228
231
|
}
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
.filter('[
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
232
|
+
list = [];
|
233
|
+
while (j < len) {
|
234
|
+
rows = tb[j].rows;
|
235
|
+
if (rows[j]) {
|
236
|
+
l = rows[j].cells.length;
|
237
|
+
for (i = 0; i < l; i++) {
|
238
|
+
// tons of thanks to AnthonyM1229 for working out the following selector (issue #74) to make this work in IE8!
|
239
|
+
// More fixes to this selector to work properly in iOS and jQuery 1.8+ (issue #132 & #174)
|
240
|
+
h = c.$headers.filter(':not([colspan])');
|
241
|
+
h = h.add( c.$headers.filter('[colspan="1"]') ) // ie8 fix
|
242
|
+
.filter('[data-column="' + i + '"]:last');
|
243
|
+
ch = c.headers[i];
|
244
|
+
// get column parser
|
245
|
+
p = ts.getParserById( ts.getData(h, ch, 'sorter') );
|
246
|
+
// empty cells behaviour - keeping emptyToBottom for backwards compatibility
|
247
|
+
c.empties[i] = ts.getData(h, ch, 'empty') || c.emptyTo || (c.emptyToBottom ? 'bottom' : 'top' );
|
248
|
+
// text strings behaviour in numerical sorts
|
249
|
+
c.strings[i] = ts.getData(h, ch, 'string') || c.stringTo || 'max';
|
250
|
+
if (!p) {
|
251
|
+
p = detectParserForColumn(table, rows, -1, i);
|
252
|
+
}
|
253
|
+
if (c.debug) {
|
254
|
+
parsersDebug += "column:" + i + "; parser:" + p.id + "; string:" + c.strings[i] + '; empty: ' + c.empties[i] + "\n";
|
255
|
+
}
|
256
|
+
list.push(p);
|
251
257
|
}
|
252
|
-
list.push(p);
|
253
258
|
}
|
259
|
+
j += (list.length) ? len : 1;
|
254
260
|
}
|
255
261
|
if (c.debug) {
|
256
|
-
log(parsersDebug);
|
262
|
+
log(parsersDebug ? parsersDebug : "No parsers detected");
|
257
263
|
benchmark("Completed detecting parsers", time);
|
258
264
|
}
|
259
265
|
c.parsers = list;
|
@@ -261,72 +267,87 @@
|
|
261
267
|
|
262
268
|
/* utils */
|
263
269
|
function buildCache(table) {
|
264
|
-
var
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
parsers =
|
269
|
-
|
270
|
-
tc.cache = {};
|
270
|
+
var cc, t, v, i, j, k, $row, rows, cols, cacheTime,
|
271
|
+
totalRows, rowData, colMax,
|
272
|
+
c = table.config,
|
273
|
+
$tb = c.$table.children('tbody'),
|
274
|
+
parsers = c.parsers;
|
275
|
+
c.cache = {};
|
271
276
|
// if no parsers found, return - it's an empty table.
|
272
277
|
if (!parsers) {
|
273
|
-
return
|
278
|
+
return c.debug ? log('Warning: *Empty table!* Not building a cache') : '';
|
274
279
|
}
|
275
|
-
if (
|
280
|
+
if (c.debug) {
|
276
281
|
cacheTime = new Date();
|
277
282
|
}
|
278
283
|
// processing icon
|
279
|
-
if (
|
284
|
+
if (c.showProcessing) {
|
280
285
|
ts.isProcessing(table, true);
|
281
286
|
}
|
282
|
-
for (k = 0; k <
|
283
|
-
|
287
|
+
for (k = 0; k < $tb.length; k++) {
|
288
|
+
colMax = []; // column max value per tbody
|
289
|
+
cc = c.cache[k] = {
|
290
|
+
normalized: [] // array of normalized row data; last entry contains "rowData" above
|
291
|
+
// colMax: # // added at the end
|
292
|
+
};
|
293
|
+
|
284
294
|
// ignore tbodies with class name from c.cssInfoBlock
|
285
|
-
if (!$(
|
286
|
-
totalRows = (
|
287
|
-
totalCells = (b[k].rows[0] && b[k].rows[0].cells.length) || 0;
|
295
|
+
if (!$tb.eq(k).hasClass(c.cssInfoBlock)) {
|
296
|
+
totalRows = ($tb[k] && $tb[k].rows.length) || 0;
|
288
297
|
for (i = 0; i < totalRows; ++i) {
|
298
|
+
rowData = {
|
299
|
+
// order: original row order #
|
300
|
+
// $row : jQuery Object[]
|
301
|
+
child: [] // child row text (filter widget)
|
302
|
+
};
|
289
303
|
/** Add the table data to main data array */
|
290
|
-
|
304
|
+
$row = $($tb[k].rows[i]);
|
305
|
+
rows = [ new Array(c.columns) ];
|
291
306
|
cols = [];
|
292
307
|
// if this is a child row, add it to the last row's children and continue to the next row
|
293
308
|
// ignore child row class, if it is the first row
|
294
|
-
if (
|
295
|
-
|
309
|
+
if ($row.hasClass(c.cssChildRow) && i !== 0) {
|
310
|
+
t = cc.normalized.length - 1;
|
311
|
+
cc.normalized[t][c.columns].$row = cc.normalized[t][c.columns].$row.add($row);
|
296
312
|
// add "hasChild" class name to parent row
|
297
|
-
if (
|
298
|
-
|
313
|
+
if (!$row.prev().hasClass(c.cssChildRow)) {
|
314
|
+
$row.prev().addClass(ts.css.cssHasChild);
|
299
315
|
}
|
316
|
+
// save child row content (un-parsed!)
|
317
|
+
rowData.child[t] = $.trim( $row[0].textContent || $row[0].innerText || $row.text() || "" );
|
300
318
|
// go to the next for loop
|
301
319
|
continue;
|
302
320
|
}
|
303
|
-
|
304
|
-
|
321
|
+
rowData.$row = $row;
|
322
|
+
rowData.order = i; // add original row position to rowCache
|
323
|
+
for (j = 0; j < c.columns; ++j) {
|
305
324
|
if (typeof parsers[j] === 'undefined') {
|
306
|
-
if (
|
307
|
-
log('No parser found for cell:',
|
325
|
+
if (c.debug) {
|
326
|
+
log('No parser found for cell:', $row[0].cells[j], 'does it have a header?');
|
308
327
|
}
|
309
328
|
continue;
|
310
329
|
}
|
311
|
-
t = getElementText(table,
|
330
|
+
t = getElementText(table, $row[0].cells[j], j);
|
312
331
|
// allow parsing if the string is empty, previously parsing would change it to zero,
|
313
332
|
// in case the parser needs to extract data from the table cell attributes
|
314
|
-
v = parsers[j].format(t, table,
|
333
|
+
v = parsers[j].format(t, table, $row[0].cells[j], j);
|
315
334
|
cols.push(v);
|
316
335
|
if ((parsers[j].type || '').toLowerCase() === "numeric") {
|
317
|
-
|
336
|
+
// determine column max value (ignore sign)
|
337
|
+
colMax[j] = Math.max(Math.abs(v) || 0, colMax[j] || 0);
|
318
338
|
}
|
319
339
|
}
|
320
|
-
|
321
|
-
|
340
|
+
// ensure rowData is always in the same location (after the last column)
|
341
|
+
cols[c.columns] = rowData;
|
342
|
+
cc.normalized.push(cols);
|
322
343
|
}
|
323
|
-
|
344
|
+
cc.colMax = colMax;
|
324
345
|
}
|
325
346
|
}
|
326
|
-
if (
|
347
|
+
if (c.showProcessing) {
|
327
348
|
ts.isProcessing(table); // remove processing icon
|
328
349
|
}
|
329
|
-
if (
|
350
|
+
if (c.debug) {
|
330
351
|
benchmark("Building cache for " + totalRows + " rows", cacheTime);
|
331
352
|
}
|
332
353
|
}
|
@@ -337,11 +358,11 @@
|
|
337
358
|
wo = c.widgetOptions,
|
338
359
|
b = table.tBodies,
|
339
360
|
rows = [],
|
340
|
-
|
341
|
-
|
342
|
-
i,
|
361
|
+
cc = c.cache,
|
362
|
+
n, totalRows, $bk, $tb,
|
363
|
+
i, k, appendTime;
|
343
364
|
// empty table - fixes #206/#346
|
344
|
-
if (isEmptyObject(
|
365
|
+
if (isEmptyObject(cc)) {
|
345
366
|
// run pager appender in case the table was just emptied
|
346
367
|
return c.appender ? c.appender(table, rows) :
|
347
368
|
table.isUpdating ? c.$table.trigger("updateComplete", table) : ''; // Fixes #532
|
@@ -354,19 +375,13 @@
|
|
354
375
|
if ($bk.length && !$bk.hasClass(c.cssInfoBlock)) {
|
355
376
|
// get tbody
|
356
377
|
$tb = ts.processTbody(table, $bk, true);
|
357
|
-
|
358
|
-
n = c2[k].normalized;
|
378
|
+
n = cc[k].normalized;
|
359
379
|
totalRows = n.length;
|
360
|
-
checkCell = totalRows ? (n[0].length - 1) : 0;
|
361
380
|
for (i = 0; i < totalRows; i++) {
|
362
|
-
|
363
|
-
rows.push(r[pos]);
|
381
|
+
rows.push(n[i][c.columns].$row);
|
364
382
|
// removeRows used by the pager plugin; don't render if using ajax - fixes #411
|
365
383
|
if (!c.appender || (c.pager && (!c.pager.removeRows || !wo.pager_removeRows) && !c.pager.ajax)) {
|
366
|
-
|
367
|
-
for (j = 0; j < l; j++) {
|
368
|
-
$tb.append(r[pos][j]);
|
369
|
-
}
|
384
|
+
$tb.append(n[i][c.columns].$row);
|
370
385
|
}
|
371
386
|
}
|
372
387
|
// restore tbody
|
@@ -386,52 +401,6 @@
|
|
386
401
|
}
|
387
402
|
}
|
388
403
|
|
389
|
-
// computeTableHeaderCellIndexes from:
|
390
|
-
// http://www.javascripttoolbox.com/lib/table/examples.php
|
391
|
-
// http://www.javascripttoolbox.com/temp/table_cellindex.html
|
392
|
-
function computeThIndexes(t) {
|
393
|
-
var matrix = [],
|
394
|
-
lookup = {},
|
395
|
-
cols = 0, // determine the number of columns
|
396
|
-
trs = $(t).children('thead, tfoot').children('tr'), // children tr in tfoot - see issue #196 & #547
|
397
|
-
i, j, k, l, c, cells, rowIndex, cellId, rowSpan, colSpan, firstAvailCol, matrixrow;
|
398
|
-
for (i = 0; i < trs.length; i++) {
|
399
|
-
cells = trs[i].cells;
|
400
|
-
for (j = 0; j < cells.length; j++) {
|
401
|
-
c = cells[j];
|
402
|
-
rowIndex = c.parentNode.rowIndex;
|
403
|
-
cellId = rowIndex + "-" + $(c).index();
|
404
|
-
rowSpan = c.rowSpan || 1;
|
405
|
-
colSpan = c.colSpan || 1;
|
406
|
-
if (typeof(matrix[rowIndex]) === "undefined") {
|
407
|
-
matrix[rowIndex] = [];
|
408
|
-
}
|
409
|
-
// Find first available column in the first row
|
410
|
-
for (k = 0; k < matrix[rowIndex].length + 1; k++) {
|
411
|
-
if (typeof(matrix[rowIndex][k]) === "undefined") {
|
412
|
-
firstAvailCol = k;
|
413
|
-
break;
|
414
|
-
}
|
415
|
-
}
|
416
|
-
lookup[cellId] = firstAvailCol;
|
417
|
-
cols = Math.max(firstAvailCol, cols);
|
418
|
-
// add data-column
|
419
|
-
$(c).attr({ 'data-column' : firstAvailCol }); // 'data-row' : rowIndex
|
420
|
-
for (k = rowIndex; k < rowIndex + rowSpan; k++) {
|
421
|
-
if (typeof(matrix[k]) === "undefined") {
|
422
|
-
matrix[k] = [];
|
423
|
-
}
|
424
|
-
matrixrow = matrix[k];
|
425
|
-
for (l = firstAvailCol; l < firstAvailCol + colSpan; l++) {
|
426
|
-
matrixrow[l] = "x";
|
427
|
-
}
|
428
|
-
}
|
429
|
-
}
|
430
|
-
}
|
431
|
-
// may not be accurate if # header columns !== # tbody columns
|
432
|
-
t.config.columns = cols + 1; // add one because it's a zero-based index
|
433
|
-
}
|
434
|
-
|
435
404
|
function formatSortingOrder(v) {
|
436
405
|
// look for "d" in "desc" order; return true
|
437
406
|
return (/^d/i.test(v) || v === 1);
|
@@ -446,7 +415,8 @@
|
|
446
415
|
if (c.debug) {
|
447
416
|
time = new Date();
|
448
417
|
}
|
449
|
-
|
418
|
+
// children tr in tfoot - see issue #196 & #547
|
419
|
+
c.columns = ts.computeColumnIndex( c.$table.children('thead, tfoot').children('tr') );
|
450
420
|
// add icon if cssIcon option exists
|
451
421
|
i = c.cssIcon ? '<i class="' + ( c.cssIcon === ts.css.icon ? ts.css.icon : c.cssIcon + ' ' + ts.css.icon ) + '"></i>' : '';
|
452
422
|
c.$headers = $(table).find(c.selectorHeaders).each(function(index) {
|
@@ -701,8 +671,8 @@
|
|
701
671
|
|
702
672
|
// sort multiple columns
|
703
673
|
function multisort(table) { /*jshint loopfunc:true */
|
704
|
-
var i, k, num, col,
|
705
|
-
|
674
|
+
var i, k, num, col, sortTime, colMax,
|
675
|
+
cache, order, sort, x, y,
|
706
676
|
dir = 0,
|
707
677
|
c = table.config,
|
708
678
|
cts = c.textSorter || '',
|
@@ -716,8 +686,7 @@
|
|
716
686
|
for (k = 0; k < bl; k++) {
|
717
687
|
colMax = c.cache[k].colMax;
|
718
688
|
cache = c.cache[k].normalized;
|
719
|
-
|
720
|
-
orgOrderCol = (cache && cache[0]) ? cache[0].length - 1 : 0;
|
689
|
+
|
721
690
|
cache.sort(function(a, b) {
|
722
691
|
// cache is undefined here in IE, so don't use it!
|
723
692
|
for (i = 0; i < l; i++) {
|
@@ -727,7 +696,7 @@
|
|
727
696
|
dir = order === 0;
|
728
697
|
|
729
698
|
if (c.sortStable && a[col] === b[col] && l === 1) {
|
730
|
-
return a[
|
699
|
+
return a[c.columns].order - b[c.columns].order;
|
731
700
|
}
|
732
701
|
|
733
702
|
// fallback to natural sort since it is more robust
|
@@ -761,7 +730,7 @@
|
|
761
730
|
}
|
762
731
|
if (sort) { return sort; }
|
763
732
|
}
|
764
|
-
return a[
|
733
|
+
return a[c.columns].order - b[c.columns].order;
|
765
734
|
});
|
766
735
|
}
|
767
736
|
if (c.debug) { benchmark("Sorting on " + sortList.toString() + " and dir " + order + " time", sortTime); }
|
@@ -772,7 +741,7 @@
|
|
772
741
|
if (table.isUpdating) {
|
773
742
|
$table.trigger('updateComplete');
|
774
743
|
}
|
775
|
-
if (
|
744
|
+
if ($.isFunction(callback)) {
|
776
745
|
callback($table[0]);
|
777
746
|
}
|
778
747
|
}
|
@@ -786,8 +755,8 @@
|
|
786
755
|
resortComplete($table, callback);
|
787
756
|
}, true]);
|
788
757
|
} else {
|
789
|
-
$table.trigger('applyWidgets');
|
790
758
|
resortComplete($table, callback);
|
759
|
+
ts.applyWidget($table[0], false);
|
791
760
|
}
|
792
761
|
}
|
793
762
|
|
@@ -797,12 +766,15 @@
|
|
797
766
|
// apply easy methods that trigger bound events
|
798
767
|
$table
|
799
768
|
.unbind('sortReset update updateRows updateCell updateAll addRows updateComplete sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave '.split(' ').join(c.namespace + ' '))
|
800
|
-
.bind("sortReset" + c.namespace, function(e){
|
769
|
+
.bind("sortReset" + c.namespace, function(e, callback){
|
801
770
|
e.stopPropagation();
|
802
771
|
c.sortList = [];
|
803
772
|
setHeadersCss(table);
|
804
773
|
multisort(table);
|
805
774
|
appendToTable(table);
|
775
|
+
if ($.isFunction(callback)) {
|
776
|
+
callback(table);
|
777
|
+
}
|
806
778
|
})
|
807
779
|
.bind("updateAll" + c.namespace, function(e, resort, callback){
|
808
780
|
e.stopPropagation();
|
@@ -826,20 +798,24 @@
|
|
826
798
|
table.isUpdating = true;
|
827
799
|
$table.find(c.selectorRemove).remove();
|
828
800
|
// get position from the dom
|
829
|
-
var
|
801
|
+
var v, row, icell,
|
830
802
|
$tb = $table.find('tbody'),
|
803
|
+
$cell = $(cell),
|
831
804
|
// update cache - format: function(s, table, cell, cellIndex)
|
832
805
|
// no closest in jQuery v1.2.6 - tbdy = $tb.index( $(cell).closest('tbody') ),$row = $(cell).closest('tr');
|
833
|
-
tbdy = $tb.index( $
|
834
|
-
$row = $
|
835
|
-
cell = $
|
806
|
+
tbdy = $tb.index( $cell.parents('tbody').filter(':first') ),
|
807
|
+
$row = $cell.parents('tr').filter(':first');
|
808
|
+
cell = $cell[0]; // in case cell is a jQuery object
|
836
809
|
// tbody may not exist if update is initialized while tbody is removed for processing
|
837
810
|
if ($tb.length && tbdy >= 0) {
|
838
811
|
row = $tb.eq(tbdy).find('tr').index( $row );
|
839
|
-
icell = $
|
840
|
-
|
841
|
-
|
842
|
-
|
812
|
+
icell = $cell.index();
|
813
|
+
c.cache[tbdy].normalized[row][c.columns].$row = $row;
|
814
|
+
v = c.cache[tbdy].normalized[row][icell] = c.parsers[icell].format( getElementText(table, cell, icell), table, cell, icell );
|
815
|
+
if ((c.parsers[icell].type || '').toLowerCase() === "numeric") {
|
816
|
+
// update column max value (ignore sign)
|
817
|
+
c.cache[tbdy].colMax[icell] = Math.max(Math.abs(v) || 0, c.cache[tbdy].colMax[icell] || 0);
|
818
|
+
}
|
843
819
|
checkResort($table, resort, callback);
|
844
820
|
}
|
845
821
|
})
|
@@ -851,26 +827,34 @@
|
|
851
827
|
updateHeader(table);
|
852
828
|
commonUpdate(table, resort, callback);
|
853
829
|
} else {
|
854
|
-
var i, j,
|
830
|
+
var i, j, l, rowData, cells,
|
855
831
|
rows = $row.filter('tr').length,
|
856
|
-
dat = [], l = $row[0].cells.length,
|
857
832
|
tbdy = $table.find('tbody').index( $row.parents('tbody').filter(':first') );
|
858
833
|
// fixes adding rows to an empty table - see issue #179
|
859
|
-
if (!c.parsers) {
|
834
|
+
if (!(c.parsers && c.parsers.length)) {
|
860
835
|
buildParserCache(table);
|
861
836
|
}
|
862
837
|
// add each row
|
863
838
|
for (i = 0; i < rows; i++) {
|
839
|
+
l = $row[i].cells.length;
|
840
|
+
cells = [];
|
841
|
+
rowData = {
|
842
|
+
child: [],
|
843
|
+
$row : $row.eq(i),
|
844
|
+
order: c.cache[tbdy].normalized.length
|
845
|
+
};
|
864
846
|
// add each cell
|
865
847
|
for (j = 0; j < l; j++) {
|
866
|
-
|
848
|
+
cells[j] = c.parsers[j].format( getElementText(table, $row[i].cells[j], j), table, $row[i].cells[j], j );
|
849
|
+
if ((c.parsers[j].type || '').toLowerCase() === "numeric") {
|
850
|
+
// update column max value (ignore sign)
|
851
|
+
c.cache[tbdy].colMax[j] = Math.max(Math.abs(cells[j]) || 0, c.cache[tbdy].colMax[j] || 0);
|
852
|
+
}
|
867
853
|
}
|
868
|
-
// add the row
|
869
|
-
|
854
|
+
// add the row data to the end
|
855
|
+
cells.push(rowData);
|
870
856
|
// update cache
|
871
|
-
c.cache[tbdy].
|
872
|
-
c.cache[tbdy].normalized.push(dat);
|
873
|
-
dat = [];
|
857
|
+
c.cache[tbdy].normalized.push(cells);
|
874
858
|
}
|
875
859
|
// resort using current settings
|
876
860
|
checkResort($table, resort, callback);
|
@@ -893,28 +877,27 @@
|
|
893
877
|
// sort the table and append it to the dom
|
894
878
|
multisort(table);
|
895
879
|
appendToTable(table, init);
|
896
|
-
$table
|
897
|
-
|
898
|
-
|
899
|
-
if (typeof callback === "function") {
|
880
|
+
$table.trigger("sortEnd", this);
|
881
|
+
ts.applyWidget(table);
|
882
|
+
if ($.isFunction(callback)) {
|
900
883
|
callback(table);
|
901
884
|
}
|
902
885
|
})
|
903
886
|
.bind("appendCache" + c.namespace, function(e, callback, init) {
|
904
887
|
e.stopPropagation();
|
905
888
|
appendToTable(table, init);
|
906
|
-
if (
|
889
|
+
if ($.isFunction(callback)) {
|
907
890
|
callback(table);
|
908
891
|
}
|
909
892
|
})
|
910
893
|
.bind("updateCache" + c.namespace, function(e, callback){
|
911
894
|
// rebuild parsers
|
912
|
-
if (!c.parsers) {
|
895
|
+
if (!(c.parsers && c.parsers.length)) {
|
913
896
|
buildParserCache(table);
|
914
897
|
}
|
915
898
|
// rebuild the cache map
|
916
899
|
buildCache(table);
|
917
|
-
if (
|
900
|
+
if ($.isFunction(callback)) {
|
918
901
|
callback(table);
|
919
902
|
}
|
920
903
|
})
|
@@ -972,8 +955,6 @@
|
|
972
955
|
$.data(table, "tablesorter", c);
|
973
956
|
if (c.debug) { $.data( table, 'startoveralltimer', new Date()); }
|
974
957
|
|
975
|
-
// constants
|
976
|
-
c.supportsTextContent = $('<span>x</span>')[0].textContent === 'x';
|
977
958
|
// removing this in version 3 (only supports jQuery 1.7+)
|
978
959
|
c.supportsDataObject = (function(version) {
|
979
960
|
version[0] = parseInt(version[0], 10);
|
@@ -1005,6 +986,8 @@
|
|
1005
986
|
c.$table.attr('aria-labelledby', 'theCaption');
|
1006
987
|
}
|
1007
988
|
c.widgetInit = {}; // keep a list of initialized widgets
|
989
|
+
// change textExtraction via data-attribute
|
990
|
+
c.textExtraction = c.$table.attr('data-text-extraction') || c.textExtraction || 'basic';
|
1008
991
|
// build headers
|
1009
992
|
buildHeaders(table);
|
1010
993
|
// fixate columns if the users supplies the fixedWidth option
|
@@ -1034,7 +1017,9 @@
|
|
1034
1017
|
setHeadersCss(table);
|
1035
1018
|
if (c.initWidgets) {
|
1036
1019
|
// apply widget format
|
1037
|
-
|
1020
|
+
setTimeout(function(){
|
1021
|
+
ts.applyWidget(table, false);
|
1022
|
+
}, 0);
|
1038
1023
|
}
|
1039
1024
|
}
|
1040
1025
|
|
@@ -1057,6 +1042,53 @@
|
|
1057
1042
|
if (typeof c.initialized === 'function') { c.initialized(table); }
|
1058
1043
|
};
|
1059
1044
|
|
1045
|
+
|
1046
|
+
// computeTableHeaderCellIndexes from:
|
1047
|
+
// http://www.javascripttoolbox.com/lib/table/examples.php
|
1048
|
+
// http://www.javascripttoolbox.com/temp/table_cellindex.html
|
1049
|
+
ts.computeColumnIndex = function(trs) {
|
1050
|
+
var matrix = [],
|
1051
|
+
lookup = {},
|
1052
|
+
cols = 0, // determine the number of columns
|
1053
|
+
i, j, k, l, $cell, cell, cells, rowIndex, cellId, rowSpan, colSpan, firstAvailCol, matrixrow;
|
1054
|
+
for (i = 0; i < trs.length; i++) {
|
1055
|
+
cells = trs[i].cells;
|
1056
|
+
for (j = 0; j < cells.length; j++) {
|
1057
|
+
cell = cells[j];
|
1058
|
+
$cell = $(cell);
|
1059
|
+
rowIndex = cell.parentNode.rowIndex;
|
1060
|
+
cellId = rowIndex + "-" + $cell.index();
|
1061
|
+
rowSpan = cell.rowSpan || 1;
|
1062
|
+
colSpan = cell.colSpan || 1;
|
1063
|
+
if (typeof(matrix[rowIndex]) === "undefined") {
|
1064
|
+
matrix[rowIndex] = [];
|
1065
|
+
}
|
1066
|
+
// Find first available column in the first row
|
1067
|
+
for (k = 0; k < matrix[rowIndex].length + 1; k++) {
|
1068
|
+
if (typeof(matrix[rowIndex][k]) === "undefined") {
|
1069
|
+
firstAvailCol = k;
|
1070
|
+
break;
|
1071
|
+
}
|
1072
|
+
}
|
1073
|
+
lookup[cellId] = firstAvailCol;
|
1074
|
+
cols = Math.max(firstAvailCol, cols);
|
1075
|
+
// add data-column
|
1076
|
+
$cell.attr({ 'data-column' : firstAvailCol }); // 'data-row' : rowIndex
|
1077
|
+
for (k = rowIndex; k < rowIndex + rowSpan; k++) {
|
1078
|
+
if (typeof(matrix[k]) === "undefined") {
|
1079
|
+
matrix[k] = [];
|
1080
|
+
}
|
1081
|
+
matrixrow = matrix[k];
|
1082
|
+
for (l = firstAvailCol; l < firstAvailCol + colSpan; l++) {
|
1083
|
+
matrixrow[l] = "x";
|
1084
|
+
}
|
1085
|
+
}
|
1086
|
+
}
|
1087
|
+
}
|
1088
|
+
// may not be accurate if # header columns !== # tbody columns
|
1089
|
+
return cols + 1; // add one because it's a zero-based index
|
1090
|
+
};
|
1091
|
+
|
1060
1092
|
// *** Process table ***
|
1061
1093
|
// add processing indicator
|
1062
1094
|
ts.isProcessing = function(table, toggle, $ths) {
|
@@ -1186,6 +1218,7 @@
|
|
1186
1218
|
$t.toggleClass(ts.css.table + ' ' + c.tableClass + ' tablesorter-' + c.theme, removeClasses === false);
|
1187
1219
|
// clear flag in case the plugin is initialized again
|
1188
1220
|
table.hasInitialized = false;
|
1221
|
+
delete table.config.cache;
|
1189
1222
|
if (typeof callback === 'function') {
|
1190
1223
|
callback(table);
|
1191
1224
|
}
|
@@ -1387,8 +1420,11 @@
|
|
1387
1420
|
wo = c.widgetOptions,
|
1388
1421
|
widgets = [],
|
1389
1422
|
time, w, wd;
|
1423
|
+
// prevent numerous consecutive widget applications
|
1424
|
+
if (init !== false && table.hasInitialized && (table.isApplyingWidgets || table.isUpdating)) { return; }
|
1390
1425
|
if (c.debug) { time = new Date(); }
|
1391
1426
|
if (c.widgets.length) {
|
1427
|
+
table.isApplyingWidgets = true;
|
1392
1428
|
// ensure unique widget ids
|
1393
1429
|
c.widgets = $.grep(c.widgets, function(v, k){
|
1394
1430
|
return $.inArray(v, c.widgets) === k;
|
@@ -1424,6 +1460,9 @@
|
|
1424
1460
|
}
|
1425
1461
|
});
|
1426
1462
|
}
|
1463
|
+
setTimeout(function(){
|
1464
|
+
table.isApplyingWidgets = false;
|
1465
|
+
}, 0);
|
1427
1466
|
if (c.debug) {
|
1428
1467
|
w = c.widgets.length;
|
1429
1468
|
benchmark("Completed " + (init === true ? "initializing " : "applying ") + w + " widget" + (w !== 1 ? "s" : ""), time);
|