jquery-tablesorter 1.9.5 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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");
|