jquery-tablesorter 1.9.5 → 1.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.markdown +7 -2
- data/lib/jquery-tablesorter/version.rb +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +73 -29
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +156 -90
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets-filter-formatter.js +437 -235
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +257 -167
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.black-ice.css +1 -0
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.blue.css +1 -0
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap.css +8 -1
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap_2.css +1 -0
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.dark.css +1 -0
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.default.css +1 -0
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.dropbox.css +1 -0
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.green.css +1 -0
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.grey.css +1 -0
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.ice.css +1 -0
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.jui.css +1 -0
- metadata +55 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52e8ad84b6ff1a950b33ee5b7079c1ec4729ee5a
|
4
|
+
data.tar.gz: e1327f89930c43ee5f0f3c998e9211d1ea7b4fae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 745b66745f32af6cd49bf7b1d2be20776f4a5d171fb468718a07e914ce330515f88fc4549a2d1c2645b3ff086c52bb6d8ba0271676586ae81482a31a3856331b
|
7
|
+
data.tar.gz: 3ee46d3579ed98b99e42e82ebcbae2841a6ecb3bb4643bec2e81469373e34532551f1b141cb8e7949bf0ceea9af160b25a5e1f0c96d8f51513e462acf9d7c05d
|
data/MIT-LICENSE
CHANGED
data/README.markdown
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.15.0 (2/19/2014), [documentation]
|
8
8
|
|
9
9
|
Any issue associate with the js/css files, please report to [Mottie's fork].
|
10
10
|
|
@@ -62,6 +62,7 @@ Avaliable theme names:
|
|
62
62
|
* theme.black-ice
|
63
63
|
* theme.blue
|
64
64
|
* theme.bootstrap
|
65
|
+
* theme.bootstrap_2
|
65
66
|
* theme.dark
|
66
67
|
* theme.default
|
67
68
|
* theme.dropbox
|
@@ -94,6 +95,10 @@ pager theme:
|
|
94
95
|
4. Update `README.md` and `CHANGELOG.md`
|
95
96
|
|
96
97
|
|
98
|
+
### Licensing
|
99
|
+
|
100
|
+
* Licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php) license.
|
101
|
+
* Original jquery-tablesorter code is dual licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php) and [GPL](http://www.gnu.org/licenses/gpl.html) licenses (see [Mottie's fork]).
|
102
|
+
|
97
103
|
[Mottie's fork]: https://github.com/Mottie/tablesorter
|
98
104
|
[documentation]: http://mottie.github.com/tablesorter/docs/index.html
|
99
|
-
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*!
|
2
2
|
* tablesorter pager plugin
|
3
|
-
* updated
|
3
|
+
* updated 2/19/2014 (v2.15.0)
|
4
4
|
*/
|
5
5
|
/*jshint browser:true, jquery:true, unused:false */
|
6
6
|
;(function($) {
|
@@ -63,6 +63,9 @@
|
|
63
63
|
|
64
64
|
// Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
|
65
65
|
savePages: true,
|
66
|
+
|
67
|
+
// defines custom storage key
|
68
|
+
storageKey: 'tablesorter-pager',
|
66
69
|
|
67
70
|
// if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
|
68
71
|
// table row set to a height to compensate; default is false
|
@@ -112,10 +115,12 @@
|
|
112
115
|
r = 'removeClass',
|
113
116
|
d = p.cssDisabled,
|
114
117
|
dis = !!disable,
|
115
|
-
|
118
|
+
first = ( dis || p.page === 0 ),
|
119
|
+
tp = Math.min( p.totalPages, p.filteredPages ),
|
120
|
+
last = ( dis || (p.page === tp - 1) || p.totalPages === 0 );
|
116
121
|
if ( p.updateArrows ) {
|
117
|
-
p.$container.find(p.cssFirst + ',' + p.cssPrev)[
|
118
|
-
p.$container.find(p.cssNext + ',' + p.cssLast)[
|
122
|
+
p.$container.find(p.cssFirst + ',' + p.cssPrev)[ first ? a : r ](d).attr('aria-disabled', first);
|
123
|
+
p.$container.find(p.cssNext + ',' + p.cssLast)[ last ? a : r ](d).attr('aria-disabled', last);
|
119
124
|
}
|
120
125
|
},
|
121
126
|
|
@@ -167,7 +172,7 @@
|
|
167
172
|
c.$table.trigger('pagerComplete', p);
|
168
173
|
// save pager info to storage
|
169
174
|
if (p.savePages && ts.storage) {
|
170
|
-
ts.storage(table,
|
175
|
+
ts.storage(table, p.storageKey, {
|
171
176
|
page : p.page,
|
172
177
|
size : p.size
|
173
178
|
});
|
@@ -235,32 +240,28 @@
|
|
235
240
|
// process data
|
236
241
|
if ( typeof(p.ajaxProcessing) === "function" ) {
|
237
242
|
// ajaxProcessing result: [ total, rows, headers ]
|
238
|
-
var i, j, hsh, $f, $sh, t, th, d, l,
|
243
|
+
var i, j, hsh, $f, $sh, t, th, d, l, rr_count,
|
239
244
|
c = table.config,
|
240
245
|
$t = c.$table,
|
241
246
|
tds = '',
|
242
247
|
result = p.ajaxProcessing(data, table) || [ 0, [] ],
|
243
248
|
hl = $t.find('thead th').length;
|
244
249
|
|
245
|
-
|
250
|
+
// Clean up any previous error.
|
251
|
+
ts.showError(table);
|
246
252
|
|
247
253
|
if ( exception ) {
|
248
254
|
if (c.debug) {
|
249
255
|
ts.log('Ajax Error', xhr, exception);
|
250
256
|
}
|
251
|
-
|
257
|
+
ts.showError(table,
|
252
258
|
xhr.status === 0 ? 'Not connected, verify Network' :
|
253
259
|
xhr.status === 404 ? 'Requested page not found [404]' :
|
254
260
|
xhr.status === 500 ? 'Internal Server Error [500]' :
|
255
261
|
exception === 'parsererror' ? 'Requested JSON parse failed' :
|
256
262
|
exception === 'timeout' ? 'Time out error' :
|
257
263
|
exception === 'abort' ? 'Ajax Request aborted' :
|
258
|
-
'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']' )
|
259
|
-
.click(function(){
|
260
|
-
$(this).remove();
|
261
|
-
})
|
262
|
-
// add error row to thead instead of tbody, or clicking on the header will result in a parser error
|
263
|
-
.appendTo( $t.find('thead:first') );
|
264
|
+
'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']' );
|
264
265
|
c.$tbodies.eq(0).empty();
|
265
266
|
} else {
|
266
267
|
// process ajax object
|
@@ -293,7 +294,11 @@
|
|
293
294
|
tds += '</tr>';
|
294
295
|
}
|
295
296
|
// add rows to first tbody
|
296
|
-
|
297
|
+
if (p.processAjaxOnInit) {
|
298
|
+
c.$tbodies.eq(0).html( tds );
|
299
|
+
} else {
|
300
|
+
p.processAjaxOnInit = true;
|
301
|
+
}
|
297
302
|
}
|
298
303
|
// only add new header text if the length matches
|
299
304
|
if ( th && th.length === hl ) {
|
@@ -333,7 +338,7 @@
|
|
333
338
|
fixHeight(table, p);
|
334
339
|
// apply widgets after table has rendered
|
335
340
|
$t.trigger('applyWidgets');
|
336
|
-
$t.trigger('
|
341
|
+
$t.trigger('updateRows', [false, function(){
|
337
342
|
if (p.initialized) {
|
338
343
|
$t.trigger('updateComplete');
|
339
344
|
$t.trigger('pagerChange', p);
|
@@ -463,7 +468,10 @@
|
|
463
468
|
p.page = 0;
|
464
469
|
p.size = p.totalRows;
|
465
470
|
p.totalPages = 1;
|
466
|
-
$(table)
|
471
|
+
$(table)
|
472
|
+
.addClass('pagerDisabled')
|
473
|
+
.removeAttr('aria-describedby')
|
474
|
+
.find('tr.pagerSavedHeightSpacer').remove();
|
467
475
|
renderTable(table, table.config.rowsCopy, p);
|
468
476
|
if (table.config.debug) {
|
469
477
|
ts.log('pager disabled');
|
@@ -471,7 +479,7 @@
|
|
471
479
|
}
|
472
480
|
// disable size selector
|
473
481
|
p.$size.add(p.$goto).each(function(){
|
474
|
-
$(this).addClass(p.cssDisabled)[0].disabled = true;
|
482
|
+
$(this).attr('aria-disabled', 'true').addClass(p.cssDisabled)[0].disabled = true;
|
475
483
|
});
|
476
484
|
},
|
477
485
|
|
@@ -551,24 +559,31 @@
|
|
551
559
|
p.initialized = false;
|
552
560
|
$(table).unbind('destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager');
|
553
561
|
if (ts.storage) {
|
554
|
-
ts.storage(table,
|
562
|
+
ts.storage(table, p.storageKey, '');
|
555
563
|
}
|
556
564
|
},
|
557
565
|
|
558
566
|
enablePager = function(table, p, triggered){
|
559
|
-
var
|
560
|
-
|
567
|
+
var info,
|
568
|
+
c = table.config;
|
569
|
+
p.$size.add(p.$goto).removeClass(p.cssDisabled).removeAttr('disabled').attr('aria-disabled', 'false');
|
561
570
|
p.isDisabled = false;
|
562
571
|
p.page = $.data(table, 'pagerLastPage') || p.page || 0;
|
563
|
-
p.size = $.data(table, 'pagerLastSize') || parseInt(
|
564
|
-
|
565
|
-
p.totalPages = Math.ceil( Math.min( p.
|
572
|
+
p.size = $.data(table, 'pagerLastSize') || parseInt(p.$size.find('option[selected]').val(), 10) || p.size || 10;
|
573
|
+
p.$size.val(p.size); // set page size
|
574
|
+
p.totalPages = Math.ceil( Math.min( p.totalRows, p.filteredRows ) / p.size );
|
575
|
+
// if table id exists, include page display with aria info
|
576
|
+
if ( table.id ) {
|
577
|
+
info = table.id + '_pager_info';
|
578
|
+
p.$container.find(p.cssPageDisplay).attr('id', info);
|
579
|
+
c.$table.attr('aria-describedby', info);
|
580
|
+
}
|
566
581
|
if ( triggered ) {
|
567
|
-
|
582
|
+
c.$table.trigger('updateRows');
|
568
583
|
setPageSize(table, p.size, p);
|
569
584
|
hideRowsSetup(table, p);
|
570
585
|
fixHeight(table, p);
|
571
|
-
if (
|
586
|
+
if (c.debug) {
|
572
587
|
ts.log('pager enabled');
|
573
588
|
}
|
574
589
|
}
|
@@ -583,6 +598,8 @@
|
|
583
598
|
p.size = $.data(table, 'pagerLastSize') || p.size || 10;
|
584
599
|
p.totalPages = Math.ceil( p.totalRows / p.size );
|
585
600
|
renderTable(table, rows, p);
|
601
|
+
// update display here in case all rows are removed
|
602
|
+
updatePageDisplay(table, p, false);
|
586
603
|
}
|
587
604
|
};
|
588
605
|
|
@@ -609,7 +626,7 @@
|
|
609
626
|
ts.setFilters(table, p.currentFilters, false);
|
610
627
|
}
|
611
628
|
if (p.savePages && ts.storage) {
|
612
|
-
t = ts.storage(table,
|
629
|
+
t = ts.storage(table, p.storageKey) || {}; // fixes #387
|
613
630
|
p.page = isNaN(t.page) ? p.page : t.page;
|
614
631
|
p.size = ( isNaN(t.size) ? p.size : t.size ) || 10;
|
615
632
|
$.data(table, 'pagerLastSize', p.size);
|
@@ -664,6 +681,7 @@
|
|
664
681
|
ctrls = [ p.cssFirst, p.cssPrev, p.cssNext, p.cssLast ];
|
665
682
|
fxn = [ moveToFirstPage, moveToPrevPage, moveToNextPage, moveToLastPage ];
|
666
683
|
pager.find(ctrls.join(','))
|
684
|
+
.attr("tabindex", 0)
|
667
685
|
.unbind('click.pager')
|
668
686
|
.bind('click.pager', function(e){
|
669
687
|
e.stopPropagation();
|
@@ -734,8 +752,34 @@
|
|
734
752
|
});
|
735
753
|
};
|
736
754
|
|
737
|
-
}()
|
738
|
-
|
755
|
+
}() });
|
756
|
+
|
757
|
+
// see #486
|
758
|
+
ts.showError = function(table, message){
|
759
|
+
$(table).each(function(){
|
760
|
+
var $row,
|
761
|
+
c = this.config,
|
762
|
+
errorRow = c.pager && c.pager.cssErrorRow || c.widgetOptions.pager_css && c.widgetOptions.pager_css.errorRow || 'tablesorter-errorRow';
|
763
|
+
if (c) {
|
764
|
+
if (typeof message === 'undefined') {
|
765
|
+
c.$table.find('thead').find(c.selectorRemove).remove();
|
766
|
+
} else {
|
767
|
+
$row = ( /tr\>/.test(message) ? $(message) : $('<tr><td colspan="' + c.columns + '">' + message + '</td></tr>') )
|
768
|
+
.click(function(){
|
769
|
+
$(this).remove();
|
770
|
+
})
|
771
|
+
// add error row to thead instead of tbody, or clicking on the header will result in a parser error
|
772
|
+
.appendTo( c.$table.find('thead:first') )
|
773
|
+
.addClass( errorRow + ' ' + c.selectorRemove.replace(/^[.#]/, '') )
|
774
|
+
.attr({
|
775
|
+
role : 'alert',
|
776
|
+
'aria-live' : 'assertive'
|
777
|
+
});
|
778
|
+
}
|
779
|
+
}
|
780
|
+
});
|
781
|
+
};
|
782
|
+
|
739
783
|
// extend plugin scope
|
740
784
|
$.fn.extend({
|
741
785
|
tablesorterPager: $.tablesorterPager.construct
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**!
|
2
|
-
* TableSorter 2.
|
2
|
+
* TableSorter 2.15.0 - 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.15.0";
|
28
28
|
|
29
29
|
ts.parsers = [];
|
30
30
|
ts.widgets = [];
|
@@ -82,6 +82,7 @@
|
|
82
82
|
tableClass : '',
|
83
83
|
cssAsc : '',
|
84
84
|
cssDesc : '',
|
85
|
+
cssNone : '',
|
85
86
|
cssHeader : '',
|
86
87
|
cssHeaderRow : '',
|
87
88
|
cssProcessing : '', // processing icon applied to header during sort/filter
|
@@ -116,18 +117,31 @@
|
|
116
117
|
childRow : 'tablesorter-childRow',
|
117
118
|
header : 'tablesorter-header',
|
118
119
|
headerRow : 'tablesorter-headerRow',
|
120
|
+
headerIn : 'tablesorter-header-inner',
|
119
121
|
icon : 'tablesorter-icon',
|
120
122
|
info : 'tablesorter-infoOnly',
|
121
123
|
processing : 'tablesorter-processing',
|
122
124
|
sortAsc : 'tablesorter-headerAsc',
|
123
|
-
sortDesc : 'tablesorter-headerDesc'
|
125
|
+
sortDesc : 'tablesorter-headerDesc',
|
126
|
+
sortNone : 'tablesorter-headerUnSorted'
|
127
|
+
};
|
128
|
+
|
129
|
+
// labels applied to sortable headers for accessibility (aria) support
|
130
|
+
ts.language = {
|
131
|
+
sortAsc : 'Ascending sort applied, ',
|
132
|
+
sortDesc : 'Descending sort applied, ',
|
133
|
+
sortNone : 'No sort applied, ',
|
134
|
+
nextAsc : 'activate to apply an ascending sort',
|
135
|
+
nextDesc : 'activate to apply a descending sort',
|
136
|
+
nextNone : 'activate to remove the sort'
|
124
137
|
};
|
125
138
|
|
126
139
|
/* debuging utils */
|
127
140
|
function log() {
|
128
|
-
var
|
141
|
+
var a = arguments[0],
|
142
|
+
s = arguments.length > 1 ? Array.prototype.slice.call(arguments) : a;
|
129
143
|
if (typeof console !== "undefined" && typeof console.log !== "undefined") {
|
130
|
-
console.log(s);
|
144
|
+
console[ /error/i.test(a) ? 'error' : /warn/i.test(a) ? 'warn' : 'log' ](s);
|
131
145
|
} else {
|
132
146
|
alert(s);
|
133
147
|
}
|
@@ -206,7 +220,7 @@
|
|
206
220
|
tb = c.$tbodies = c.$table.children('tbody:not(.' + c.cssInfoBlock + ')'),
|
207
221
|
rows, list, l, i, h, ch, p, time, parsersDebug = "";
|
208
222
|
if ( tb.length === 0) {
|
209
|
-
return c.debug ? log('*Empty table!* Not building a parser cache') : '';
|
223
|
+
return c.debug ? log('Warning: *Empty table!* Not building a parser cache') : '';
|
210
224
|
} else if (c.debug) {
|
211
225
|
time = new Date();
|
212
226
|
log('Detecting parsers for each column');
|
@@ -255,7 +269,7 @@
|
|
255
269
|
tc.cache = {};
|
256
270
|
// if no parsers found, return - it's an empty table.
|
257
271
|
if (!parsers) {
|
258
|
-
return tc.debug ? log('*Empty table!* Not building a cache') : '';
|
272
|
+
return tc.debug ? log('Warning: *Empty table!* Not building a cache') : '';
|
259
273
|
}
|
260
274
|
if (tc.debug) {
|
261
275
|
cacheTime = new Date();
|
@@ -314,7 +328,11 @@
|
|
314
328
|
c2 = c.cache,
|
315
329
|
r, n, totalRows, checkCell, $bk, $tb,
|
316
330
|
i, j, k, l, pos, appendTime;
|
317
|
-
|
331
|
+
// empty table - fixes #206/#346
|
332
|
+
if (isEmptyObject(c2)) {
|
333
|
+
// run pager appender in case the table was just emptied
|
334
|
+
return c.appender ? c.appender(table, rows) : '';
|
335
|
+
}
|
318
336
|
if (c.debug) {
|
319
337
|
appendTime = new Date();
|
320
338
|
}
|
@@ -427,7 +445,7 @@
|
|
427
445
|
h = c.onRenderTemplate.apply($t, [index, t]);
|
428
446
|
if (h && typeof h === 'string') { t = h; } // only change t if something is returned
|
429
447
|
}
|
430
|
-
$(this).html('<div class="
|
448
|
+
$(this).html('<div class="' + ts.css.headerIn + '">' + t + '</div>'); // faster than wrapInner
|
431
449
|
|
432
450
|
if (c.onRenderHeader) { c.onRenderHeader.apply($t, [index]); }
|
433
451
|
|
@@ -443,9 +461,12 @@
|
|
443
461
|
// add cell to headerList
|
444
462
|
c.headerList[index] = this;
|
445
463
|
// add to parent in case there are multiple rows
|
446
|
-
$t.parent().addClass(ts.css.headerRow + ' ' + c.cssHeaderRow);
|
464
|
+
$t.parent().addClass(ts.css.headerRow + ' ' + c.cssHeaderRow).attr('role', 'row');
|
447
465
|
// allow keyboard cursor to focus on element
|
448
466
|
if (c.tabIndex) { $t.attr("tabindex", 0); }
|
467
|
+
}).attr({
|
468
|
+
scope: 'col',
|
469
|
+
role : 'columnheader'
|
449
470
|
});
|
450
471
|
// enable/disable sorting
|
451
472
|
updateHeader(table);
|
@@ -467,11 +488,20 @@
|
|
467
488
|
}
|
468
489
|
|
469
490
|
function updateHeader(table) {
|
470
|
-
var s, c = table.config;
|
491
|
+
var s, $th, c = table.config;
|
471
492
|
c.$headers.each(function(index, th){
|
493
|
+
$th = $(th);
|
472
494
|
s = ts.getData( th, c.headers[index], 'sorter' ) === 'false';
|
473
495
|
th.sortDisabled = s;
|
474
|
-
$
|
496
|
+
$th[ s ? 'addClass' : 'removeClass' ]('sorter-false').attr('aria-disabled', '' + s);
|
497
|
+
// aria-controls - requires table ID
|
498
|
+
if (table.id) {
|
499
|
+
if (s) {
|
500
|
+
$th.removeAttr('aria-controls');
|
501
|
+
} else {
|
502
|
+
$th.attr('aria-controls', table.id);
|
503
|
+
}
|
504
|
+
}
|
475
505
|
});
|
476
506
|
}
|
477
507
|
|
@@ -479,11 +509,15 @@
|
|
479
509
|
var f, i, j, l,
|
480
510
|
c = table.config,
|
481
511
|
list = c.sortList,
|
512
|
+
none = ts.css.sortNone + ' ' + c.cssNone,
|
482
513
|
css = [ts.css.sortAsc + ' ' + c.cssAsc, ts.css.sortDesc + ' ' + c.cssDesc],
|
514
|
+
aria = ['ascending', 'descending'],
|
483
515
|
// find the footer
|
484
516
|
$t = $(table).find('tfoot tr').children().removeClass(css.join(' '));
|
485
517
|
// remove all header information
|
486
|
-
c.$headers
|
518
|
+
c.$headers
|
519
|
+
.removeClass(css.join(' '))
|
520
|
+
.addClass(none).attr('aria-sort', 'none');
|
487
521
|
l = list.length;
|
488
522
|
for (i = 0; i < l; i++) {
|
489
523
|
// direction = 2 means reset!
|
@@ -493,7 +527,7 @@
|
|
493
527
|
if (f.length) {
|
494
528
|
for (j = 0; j < f.length; j++) {
|
495
529
|
if (!f[j].sortDisabled) {
|
496
|
-
f.eq(j).addClass(css[list[i][1]]);
|
530
|
+
f.eq(j).removeClass(none).addClass(css[list[i][1]]).attr('aria-sort', aria[list[i][1]]);
|
497
531
|
// add sorted class to footer, if it exists
|
498
532
|
if ($t.length) {
|
499
533
|
$t.filter('[data-column="' + list[i][0] + '"]').eq(j).addClass(css[list[i][1]]);
|
@@ -503,6 +537,15 @@
|
|
503
537
|
}
|
504
538
|
}
|
505
539
|
}
|
540
|
+
// add verbose aria labels
|
541
|
+
c.$headers.not('.sorter-false').each(function(){
|
542
|
+
var $this = $(this),
|
543
|
+
nextSort = this.order[(this.count + 1) % (c.sortReset ? 3 : 2)],
|
544
|
+
txt = $this.text() + ': ' +
|
545
|
+
ts.language[ $this.hasClass(ts.css.sortAsc) ? 'sortAsc' : $this.hasClass(ts.css.sortDesc) ? 'sortDesc' : 'sortNone' ] +
|
546
|
+
ts.language[ nextSort === 0 ? 'nextAsc' : nextSort === 1 ? 'nextDesc' : 'nextNone' ];
|
547
|
+
$this.attr('aria-label', txt );
|
548
|
+
});
|
506
549
|
}
|
507
550
|
|
508
551
|
// automatically add col group, and column sizes if set
|
@@ -543,9 +586,9 @@
|
|
543
586
|
var a, i, j, o, s,
|
544
587
|
c = table.config,
|
545
588
|
k = !e[c.sortMultiSortKey],
|
546
|
-
$
|
589
|
+
$table = $(table);
|
547
590
|
// Only call sortStart if sorting is enabled
|
548
|
-
$
|
591
|
+
$table.trigger("sortStart", table);
|
549
592
|
// get current column sort order
|
550
593
|
cell.count = e[c.sortResetKey] ? 2 : (cell.count + 1) % (c.sortReset ? 3 : 2);
|
551
594
|
// reset all sorts on non-current column - issue #30
|
@@ -629,7 +672,7 @@
|
|
629
672
|
}
|
630
673
|
}
|
631
674
|
// sortBegin event triggered immediately before the sort
|
632
|
-
$
|
675
|
+
$table.trigger("sortBegin", table);
|
633
676
|
// setTimeout needed so the processing icon shows up
|
634
677
|
setTimeout(function(){
|
635
678
|
// set css for headers
|
@@ -729,46 +772,11 @@
|
|
729
772
|
}
|
730
773
|
}
|
731
774
|
|
732
|
-
function
|
775
|
+
function bindMethods(table){
|
733
776
|
var c = table.config,
|
734
|
-
$
|
735
|
-
j, downTime;
|
736
|
-
// apply event handling to headers
|
737
|
-
c.$headers
|
738
|
-
// http://stackoverflow.com/questions/5312849/jquery-find-self;
|
739
|
-
.find(c.selectorSort).add( c.$headers.filter(c.selectorSort) )
|
740
|
-
.unbind('mousedown.tablesorter mouseup.tablesorter sort.tablesorter keypress.tablesorter')
|
741
|
-
.bind('mousedown.tablesorter mouseup.tablesorter sort.tablesorter keypress.tablesorter', function(e, external) {
|
742
|
-
// only recognize left clicks or enter
|
743
|
-
if ( ((e.which || e.button) !== 1 && !/sort|keypress/.test(e.type)) || (e.type === 'keypress' && e.which !== 13) ) {
|
744
|
-
return;
|
745
|
-
}
|
746
|
-
// ignore long clicks (prevents resizable widget from initializing a sort)
|
747
|
-
if (e.type === 'mouseup' && external !== true && (new Date().getTime() - downTime > 250)) { return; }
|
748
|
-
// set timer on mousedown
|
749
|
-
if (e.type === 'mousedown') {
|
750
|
-
downTime = new Date().getTime();
|
751
|
-
return e.target.tagName === "INPUT" ? '' : !c.cancelSelection;
|
752
|
-
}
|
753
|
-
if (c.delayInit && isEmptyObject(c.cache)) { buildCache(table); }
|
754
|
-
// jQuery v1.2.6 doesn't have closest()
|
755
|
-
var $cell = /TH|TD/.test(this.tagName) ? $(this) : $(this).parents('th, td').filter(':first'), cell = $cell[0];
|
756
|
-
if (!cell.sortDisabled) {
|
757
|
-
initSort(table, cell, e);
|
758
|
-
}
|
759
|
-
});
|
760
|
-
if (c.cancelSelection) {
|
761
|
-
// cancel selection
|
762
|
-
c.$headers
|
763
|
-
.attr('unselectable', 'on')
|
764
|
-
.bind('selectstart', false)
|
765
|
-
.css({
|
766
|
-
'user-select': 'none',
|
767
|
-
'MozUserSelect': 'none' // not needed for jQuery 1.8+
|
768
|
-
});
|
769
|
-
}
|
777
|
+
$table = c.$table;
|
770
778
|
// apply easy methods that trigger bound events
|
771
|
-
$
|
779
|
+
$table
|
772
780
|
.unbind('sortReset update updateRows updateCell updateAll addRows sorton appendCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave '.split(' ').join('.tablesorter '))
|
773
781
|
.bind("sortReset.tablesorter", function(e){
|
774
782
|
e.stopPropagation();
|
@@ -782,7 +790,8 @@
|
|
782
790
|
ts.refreshWidgets(table, true, true);
|
783
791
|
ts.restoreHeaders(table);
|
784
792
|
buildHeaders(table);
|
785
|
-
bindEvents(table);
|
793
|
+
ts.bindEvents(table, c.$headers);
|
794
|
+
bindMethods(table);
|
786
795
|
commonUpdate(table, resort, callback);
|
787
796
|
})
|
788
797
|
.bind("update.tablesorter updateRows.tablesorter", function(e, resort, callback) {
|
@@ -793,10 +802,10 @@
|
|
793
802
|
})
|
794
803
|
.bind("updateCell.tablesorter", function(e, cell, resort, callback) {
|
795
804
|
e.stopPropagation();
|
796
|
-
$
|
805
|
+
$table.find(c.selectorRemove).remove();
|
797
806
|
// get position from the dom
|
798
807
|
var l, row, icell,
|
799
|
-
$tb = $
|
808
|
+
$tb = $table.find('tbody'),
|
800
809
|
// update cache - format: function(s, table, cell, cellIndex)
|
801
810
|
// no closest in jQuery v1.2.6 - tbdy = $tb.index( $(cell).closest('tbody') ),$row = $(cell).closest('tr');
|
802
811
|
tbdy = $tb.index( $(cell).parents('tbody').filter(':first') ),
|
@@ -809,7 +818,7 @@
|
|
809
818
|
l = c.cache[tbdy].normalized[row].length - 1;
|
810
819
|
c.cache[tbdy].row[table.config.cache[tbdy].normalized[row][l]] = $row;
|
811
820
|
c.cache[tbdy].normalized[row][icell] = c.parsers[icell].format( getElementText(table, cell, icell), table, cell, icell );
|
812
|
-
checkResort($
|
821
|
+
checkResort($table, resort, callback);
|
813
822
|
}
|
814
823
|
})
|
815
824
|
.bind("addRows.tablesorter", function(e, $row, resort, callback) {
|
@@ -819,9 +828,10 @@
|
|
819
828
|
updateHeader(table);
|
820
829
|
commonUpdate(table, resort, callback);
|
821
830
|
} else {
|
822
|
-
var i,
|
831
|
+
var i, j,
|
832
|
+
rows = $row.filter('tr').length,
|
823
833
|
dat = [], l = $row[0].cells.length,
|
824
|
-
tbdy = $
|
834
|
+
tbdy = $table.find('tbody').index( $row.parents('tbody').filter(':first') );
|
825
835
|
// fixes adding rows to an empty table - see issue #179
|
826
836
|
if (!c.parsers) {
|
827
837
|
buildParserCache(table);
|
@@ -840,20 +850,20 @@
|
|
840
850
|
dat = [];
|
841
851
|
}
|
842
852
|
// resort using current settings
|
843
|
-
checkResort($
|
853
|
+
checkResort($table, resort, callback);
|
844
854
|
}
|
845
855
|
})
|
846
856
|
.bind("sorton.tablesorter", function(e, list, callback, init) {
|
847
857
|
var c = table.config;
|
848
858
|
e.stopPropagation();
|
849
|
-
$
|
859
|
+
$table.trigger("sortStart", this);
|
850
860
|
// update header count index
|
851
861
|
updateHeaderSortCount(table, list);
|
852
862
|
// set css for headers
|
853
863
|
setHeadersCss(table);
|
854
864
|
// fixes #346
|
855
865
|
if (c.delayInit && isEmptyObject(c.cache)) { buildCache(table); }
|
856
|
-
$
|
866
|
+
$table.trigger("sortBegin", this);
|
857
867
|
// sort the table and append it to the dom
|
858
868
|
multisort(table);
|
859
869
|
appendToTable(table, init);
|
@@ -905,11 +915,11 @@
|
|
905
915
|
ts.setup = function(table, c) {
|
906
916
|
// if no thead or tbody, or tablesorter is already present, quit
|
907
917
|
if (!table || !table.tHead || table.tBodies.length === 0 || table.hasInitialized === true) {
|
908
|
-
return c.debug ? log('stopping initialization! No table, thead, tbody or tablesorter has already been initialized') : '';
|
918
|
+
return c.debug ? log('ERROR: stopping initialization! No table, thead, tbody or tablesorter has already been initialized') : '';
|
909
919
|
}
|
910
920
|
|
911
921
|
var k = '',
|
912
|
-
$
|
922
|
+
$table = $(table),
|
913
923
|
m = $.metadata;
|
914
924
|
// initialization flag
|
915
925
|
table.hasInitialized = false;
|
@@ -931,11 +941,20 @@
|
|
931
941
|
// digit sort text location; keeping max+/- for backwards compatibility
|
932
942
|
c.string = { 'max': 1, 'min': -1, 'max+': 1, 'max-': -1, 'zero': 0, 'none': 0, 'null': 0, 'top': true, 'bottom': false };
|
933
943
|
// add table theme class only if there isn't already one there
|
934
|
-
if (!/tablesorter\-/.test($
|
944
|
+
if (!/tablesorter\-/.test($table.attr('class'))) {
|
935
945
|
k = (c.theme !== '' ? ' tablesorter-' + c.theme : '');
|
936
946
|
}
|
937
|
-
c.$table = $
|
938
|
-
|
947
|
+
c.$table = $table
|
948
|
+
.addClass(ts.css.table + ' ' + c.tableClass + k)
|
949
|
+
.attr({ role : 'grid'});
|
950
|
+
c.$tbodies = $table.children('tbody:not(.' + c.cssInfoBlock + ')').attr({
|
951
|
+
'aria-live' : 'polite',
|
952
|
+
'aria-relevant' : 'all'
|
953
|
+
});
|
954
|
+
//
|
955
|
+
if (c.$table.find('caption').length) {
|
956
|
+
c.$table.attr('aria-labelledby', 'theCaption');
|
957
|
+
}
|
939
958
|
c.widgetInit = {}; // keep a list of initialized widgets
|
940
959
|
// build headers
|
941
960
|
buildHeaders(table);
|
@@ -948,27 +967,31 @@
|
|
948
967
|
// delayInit will delay building the cache until the user starts a sort
|
949
968
|
if (!c.delayInit) { buildCache(table); }
|
950
969
|
// bind all header events and methods
|
951
|
-
bindEvents(table);
|
970
|
+
ts.bindEvents(table, c.$headers);
|
971
|
+
bindMethods(table);
|
952
972
|
// get sort list from jQuery data or metadata
|
953
|
-
// in jQuery < 1.4, an error occurs when calling $
|
954
|
-
if (c.supportsDataObject && typeof $
|
955
|
-
c.sortList = $
|
956
|
-
} else if (m && ($
|
957
|
-
c.sortList = $
|
973
|
+
// in jQuery < 1.4, an error occurs when calling $table.data()
|
974
|
+
if (c.supportsDataObject && typeof $table.data().sortlist !== 'undefined') {
|
975
|
+
c.sortList = $table.data().sortlist;
|
976
|
+
} else if (m && ($table.metadata() && $table.metadata().sortlist)) {
|
977
|
+
c.sortList = $table.metadata().sortlist;
|
958
978
|
}
|
959
979
|
// apply widget init code
|
960
980
|
ts.applyWidget(table, true);
|
961
981
|
// if user has supplied a sort list to constructor
|
962
982
|
if (c.sortList.length > 0) {
|
963
|
-
$
|
964
|
-
} else
|
965
|
-
|
966
|
-
|
983
|
+
$table.trigger("sorton", [c.sortList, {}, !c.initWidgets]);
|
984
|
+
} else {
|
985
|
+
setHeadersCss(table);
|
986
|
+
if (c.initWidgets) {
|
987
|
+
// apply widget format
|
988
|
+
ts.applyWidget(table);
|
989
|
+
}
|
967
990
|
}
|
968
991
|
|
969
992
|
// show processesing icon
|
970
993
|
if (c.showProcessing) {
|
971
|
-
$
|
994
|
+
$table
|
972
995
|
.unbind('sortBegin.tablesorter sortEnd.tablesorter')
|
973
996
|
.bind('sortBegin.tablesorter sortEnd.tablesorter', function(e) {
|
974
997
|
ts.isProcessing(table, e.type === 'sortBegin');
|
@@ -981,7 +1004,7 @@
|
|
981
1004
|
if (c.debug) {
|
982
1005
|
ts.benchmark("Overall initialization time", $.data( table, 'startoveralltimer'));
|
983
1006
|
}
|
984
|
-
$
|
1007
|
+
$table.trigger('tablesorter-initialized', table);
|
985
1008
|
if (typeof c.initialized === 'function') { c.initialized(table); }
|
986
1009
|
};
|
987
1010
|
|
@@ -993,7 +1016,8 @@
|
|
993
1016
|
// default to all headers
|
994
1017
|
$h = $ths || table.find('.' + ts.css.header);
|
995
1018
|
if (toggle) {
|
996
|
-
|
1019
|
+
// don't use sortList if custom $ths used
|
1020
|
+
if (typeof $ths !== 'undefined' && c.sortList.length > 0) {
|
997
1021
|
// get headers from the sortList
|
998
1022
|
$h = $h.filter(function(){
|
999
1023
|
// get data-column from attr to keep compatibility with jQuery 1.2.6
|
@@ -1009,6 +1033,7 @@
|
|
1009
1033
|
// detach tbody but save the position
|
1010
1034
|
// don't use tbody because there are portions that look for a tbody index (updateCell)
|
1011
1035
|
ts.processTbody = function(table, $tb, getIt){
|
1036
|
+
table = $(table)[0];
|
1012
1037
|
var holdr;
|
1013
1038
|
if (getIt) {
|
1014
1039
|
table.isProcessing = true;
|
@@ -1026,14 +1051,55 @@
|
|
1026
1051
|
$(table)[0].config.$tbodies.empty();
|
1027
1052
|
};
|
1028
1053
|
|
1054
|
+
ts.bindEvents = function(table, $headers){
|
1055
|
+
table = $(table)[0];
|
1056
|
+
var downTime,
|
1057
|
+
c = table.config;
|
1058
|
+
// apply event handling to headers and/or additional headers (stickyheaders, scroller, etc)
|
1059
|
+
$headers
|
1060
|
+
// http://stackoverflow.com/questions/5312849/jquery-find-self;
|
1061
|
+
.find(c.selectorSort).add( $headers.filter(c.selectorSort) )
|
1062
|
+
.unbind('mousedown.tablesorter mouseup.tablesorter sort.tablesorter keyup.tablesorter')
|
1063
|
+
.bind('mousedown.tablesorter mouseup.tablesorter sort.tablesorter keyup.tablesorter', function(e, external) {
|
1064
|
+
var cell, type = e.type;
|
1065
|
+
// only recognize left clicks or enter
|
1066
|
+
if ( ((e.which || e.button) !== 1 && !/sort|keyup/.test(type)) || (type === 'keyup' && e.which !== 13) ) {
|
1067
|
+
return;
|
1068
|
+
}
|
1069
|
+
// ignore long clicks (prevents resizable widget from initializing a sort)
|
1070
|
+
if (type === 'mouseup' && external !== true && (new Date().getTime() - downTime > 250)) { return; }
|
1071
|
+
// set timer on mousedown
|
1072
|
+
if (type === 'mousedown') {
|
1073
|
+
downTime = new Date().getTime();
|
1074
|
+
return e.target.tagName === "INPUT" ? '' : !c.cancelSelection;
|
1075
|
+
}
|
1076
|
+
if (c.delayInit && isEmptyObject(c.cache)) { buildCache(table); }
|
1077
|
+
// jQuery v1.2.6 doesn't have closest()
|
1078
|
+
cell = /TH|TD/.test(this.tagName) ? this : $(this).parents('th, td')[0];
|
1079
|
+
if (!cell.sortDisabled) {
|
1080
|
+
initSort(table, cell, e);
|
1081
|
+
}
|
1082
|
+
});
|
1083
|
+
if (c.cancelSelection) {
|
1084
|
+
// cancel selection
|
1085
|
+
$headers
|
1086
|
+
.attr('unselectable', 'on')
|
1087
|
+
.bind('selectstart', false)
|
1088
|
+
.css({
|
1089
|
+
'user-select': 'none',
|
1090
|
+
'MozUserSelect': 'none' // not needed for jQuery 1.8+
|
1091
|
+
});
|
1092
|
+
}
|
1093
|
+
};
|
1094
|
+
|
1029
1095
|
// restore headers
|
1030
1096
|
ts.restoreHeaders = function(table){
|
1031
|
-
var c = table.config;
|
1097
|
+
var c = $(table)[0].config;
|
1032
1098
|
// don't use c.$headers here in case header cells were swapped
|
1033
1099
|
c.$table.find(c.selectorHeaders).each(function(i){
|
1034
1100
|
// only restore header cells if it is wrapped
|
1035
1101
|
// because this is also used by the updateAll method
|
1036
|
-
if ($(this).find('.
|
1102
|
+
if ($(this).find('.' + ts.css.headerIn).length){
|
1037
1103
|
$(this).html( c.headerContent[i] );
|
1038
1104
|
}
|
1039
1105
|
});
|
@@ -1055,7 +1121,7 @@
|
|
1055
1121
|
.removeData('tablesorter')
|
1056
1122
|
.unbind('sortReset update updateAll updateRows updateCell addRows sorton appendCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave keypress sortBegin sortEnd '.split(' ').join('.tablesorter '));
|
1057
1123
|
c.$headers.add($f)
|
1058
|
-
.removeClass( [ts.css.header, c.cssHeader, c.cssAsc, c.cssDesc, ts.css.sortAsc, ts.css.sortDesc].join(' ') )
|
1124
|
+
.removeClass( [ts.css.header, c.cssHeader, c.cssAsc, c.cssDesc, ts.css.sortAsc, ts.css.sortDesc, ts.css.sortNone].join(' ') )
|
1059
1125
|
.removeAttr('data-column');
|
1060
1126
|
$r.find(c.selectorSort).unbind('mousedown.tablesorter mouseup.tablesorter keypress.tablesorter');
|
1061
1127
|
ts.restoreHeaders(table);
|
@@ -1088,7 +1154,6 @@
|
|
1088
1154
|
if ( xD < yD ) { return -1; }
|
1089
1155
|
if ( xD > yD ) { return 1; }
|
1090
1156
|
}
|
1091
|
-
|
1092
1157
|
// chunk/tokenize
|
1093
1158
|
xN = a.replace(r.chunk, '\\0$1\\0').replace(/\\0$/, '').replace(/^\\0/, '').split('\\0');
|
1094
1159
|
yN = b.replace(r.chunk, '\\0$1\\0').replace(/\\0$/, '').replace(/^\\0/, '').split('\\0');
|
@@ -1316,7 +1381,7 @@
|
|
1316
1381
|
// remove previous widgets
|
1317
1382
|
for (i = 0; i < l; i++){
|
1318
1383
|
if ( w[i] && w[i].id && (doAll || $.inArray( w[i].id, cw ) < 0) ) {
|
1319
|
-
if (c.debug) { log( 'Refeshing widgets: Removing ' + w[i].id
|
1384
|
+
if (c.debug) { log( 'Refeshing widgets: Removing "' + w[i].id + '"' ); }
|
1320
1385
|
// only remove widgets that have been initialized - fixes #442
|
1321
1386
|
if (w[i].hasOwnProperty('remove') && c.widgetInit[w[i].id]) {
|
1322
1387
|
w[i].remove(table, c, c.widgetOptions);
|
@@ -1423,7 +1488,7 @@
|
|
1423
1488
|
ts.addParser({
|
1424
1489
|
id: "currency",
|
1425
1490
|
is: function(s) {
|
1426
|
-
return (/^\(?\d+[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]|[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+\)?$/).test((s || '').replace(/[
|
1491
|
+
return (/^\(?\d+[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]|[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+\)?$/).test((s || '').replace(/[+\-,. ]/g,'')); // £$€¤¥¢
|
1427
1492
|
},
|
1428
1493
|
format: function(s, table) {
|
1429
1494
|
var n = ts.formatFloat((s || '').replace(/[^\w,. \-()]/g, ""), table);
|
@@ -1503,8 +1568,9 @@
|
|
1503
1568
|
},
|
1504
1569
|
format: function(s, table, cell, cellIndex) {
|
1505
1570
|
if (s) {
|
1506
|
-
var c = table.config,
|
1507
|
-
|
1571
|
+
var c = table.config,
|
1572
|
+
ci = c.$headers.filter('[data-column=' + cellIndex + ']:last'),
|
1573
|
+
format = ci.length && ci[0].dateFormat || ts.getData( ci, c.headers[cellIndex], 'dateFormat') || c.dateFormat;
|
1508
1574
|
s = s.replace(/\s+/g," ").replace(/[\-.,]/g, "/"); // escaped - because JSHint in Firefox was showing it as an error
|
1509
1575
|
if (format === "mmddyyyy") {
|
1510
1576
|
s = s.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/, "$3/$1/$2");
|