jquery-tablesorter 1.17.2 → 1.17.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/jquery-tablesorter/version.rb +1 -1
  4. data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +76 -71
  5. data/vendor/assets/javascripts/jquery-tablesorter/extras/jquery.dragtable.mod.js +1 -1
  6. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +2647 -2576
  7. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +174 -119
  8. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +2487 -2471
  9. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-extract.js +15 -15
  10. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-iso8601.js +1 -1
  11. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-month.js +4 -4
  12. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-range.js +1 -1
  13. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-two-digit-year.js +12 -12
  14. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-weekday.js +4 -4
  15. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date.js +1 -1
  16. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-duration.js +1 -1
  17. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-feet-inch-fraction.js +6 -6
  18. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-file-type.js +22 -22
  19. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-globalize.js +1 -1
  20. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-ignore-articles.js +15 -15
  21. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-image.js +3 -3
  22. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +10 -3
  23. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-metric.js +2 -2
  24. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-named-numbers.js +3 -3
  25. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-network.js +1 -1
  26. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-roman.js +4 -4
  27. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-alignChar.js +122 -121
  28. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-build-table.js +13 -13
  29. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-chart.js +2 -2
  30. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +324 -324
  31. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columns.js +60 -60
  32. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +219 -219
  33. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-html5.js +360 -361
  34. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-jui.js +666 -666
  35. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-select2.js +124 -124
  36. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-type-insideRange.js +1 -1
  37. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +1448 -1433
  38. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-formatter.js +1 -1
  39. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +213 -213
  40. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-headerTitles.js +3 -3
  41. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +271 -216
  42. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +339 -320
  43. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +1057 -1045
  44. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-print.js +109 -109
  45. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-reflow.js +114 -115
  46. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-resizable.js +360 -359
  47. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-saveSort.js +59 -59
  48. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +818 -806
  49. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sort2Hash.js +128 -0
  50. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sortTbodies.js +195 -195
  51. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-staticRow.js +90 -90
  52. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +257 -257
  53. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-storage.js +76 -76
  54. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-uitheme.js +170 -170
  55. metadata +3 -3
  56. data/vendor/assets/javascripts/jquery-tablesorter/extras/jquery.quicksearch.js +0 -195
@@ -0,0 +1,128 @@
1
+ /*! Widget: sort2Hash - updated 7/28/2015 (v2.22.4) */
2
+ ;( function( $ ) {
3
+ 'use strict';
4
+ var ts = $.tablesorter || {},
5
+ s2h = {
6
+ init : function( c, wo ) {
7
+ var hasSaveSort = ts.hasWidget( c.table, 'saveSort' ),
8
+ sort = s2h.getSort( c, wo );
9
+ if ( ( sort && !hasSaveSort ) || ( sort && hasSaveSort && wo.sort2Hash_overrideSaveSort ) ) {
10
+ s2h.processHash( c, wo, sort );
11
+ }
12
+ c.$table.on( 'sortEnd.sort2hash', function() {
13
+ s2h.setHash( c, wo );
14
+ });
15
+ },
16
+ getTableId : function( c, wo ) {
17
+ // option > table id > table index on page
18
+ return wo.sort2Hash_tableId ||
19
+ c.table.id ||
20
+ 'table' + $( 'table' ).index( c.$table );
21
+ },
22
+ getSort : function( c, wo, clean ) {
23
+ // modified original code from http://www.netlobo.com/url_query_string_javascript.html
24
+ var value,
25
+ name = s2h.getTableId( c, wo ).replace( /[\[]/, '\\[' ).replace( /[\]]/, '\\]' ),
26
+ sort = ( new RegExp( '[\\#&]' + name + '=([^&]*)' ) ).exec( window.location.hash );
27
+ if ( sort === null ) {
28
+ return '';
29
+ } else {
30
+ value = s2h.processSort( c, wo, sort[ 1 ] );
31
+ if ( clean ) {
32
+ window.location.hash = window.location.hash.replace( '&' + name + '=' + sort[ 1 ], '' );
33
+ return value;
34
+ }
35
+ return sort[ 1 ];
36
+ }
37
+ },
38
+ // convert 'first%20name,asc,last%20name,desc' into [[0,0], [1,1]]
39
+ processHash : function( c, wo, sortHash ) {
40
+ var regex, column, direction, temp,
41
+ arry = decodeURI( sortHash || '' ).split( wo.sort2Hash_separator ),
42
+ indx = 0,
43
+ len = arry.length,
44
+ sort = [];
45
+ while ( indx < len ) {
46
+ // column index or text
47
+ column = arry[ indx++ ];
48
+ temp = parseInt( column, 10 );
49
+ // ignore wo.sort2Hash_useHeaderText setting &
50
+ // just see if column contains a number
51
+ if ( isNaN( temp ) || temp > c.columns ) {
52
+ regex = new RegExp( '(' + column + ')', 'i' );
53
+ column = c.$headers.filter( function( index, cell ) {
54
+ return regex.test( c.$headers[ index ].textContent || '' );
55
+ }).attr( 'data-column' );
56
+ }
57
+ direction = arry[ indx++ ];
58
+ // ignore unpaired values
59
+ if ( typeof direction !== 'undefined' ) {
60
+ // convert text to 0, 1
61
+ if ( isNaN( direction ) ) {
62
+ // default to ascending sort
63
+ direction = direction.indexOf( wo.sort2Hash_directionText[ 1 ] ) > -1 ? 1 : 0;
64
+ }
65
+ sort.push( [ column, direction ] );
66
+ }
67
+ }
68
+ if ( sort.length ) {
69
+ c.sortList = sort;
70
+ }
71
+ },
72
+
73
+ // convert [[0,0],[1,1]] to 'first%20name,asc,last%20name,desc'
74
+ processSort : function( c, wo ) {
75
+ var index, txt, column, direction,
76
+ sort = [],
77
+ arry = c.sortList || [],
78
+ len = arry.length;
79
+ for ( index = 0; index < len; index++ ) {
80
+ column = arry[ index ][ 0 ];
81
+ if ( wo.sort2Hash_useHeaderText ) {
82
+ txt = $.trim( c.$headerIndexed[ column ].text() );
83
+ if ( typeof wo.sort2Hash_processHeaderText === 'function' ) {
84
+ txt = wo.sort2Hash_processHeaderText( txt, c, column );
85
+ }
86
+ column = txt;
87
+ }
88
+ sort.push( column );
89
+ direction = wo.sort2Hash_directionText[ arry[ index ][ 1 ] ];
90
+ sort.push( direction );
91
+
92
+ }
93
+ // join with separator
94
+ return sort.join( wo.sort2Hash_separator );
95
+ },
96
+ setHash : function( c, wo ) {
97
+ var arry = [],
98
+ sort = s2h.processSort( c, wo );
99
+ if ( sort.length ) {
100
+ // remove old hash
101
+ s2h.getSort( c, wo, true );
102
+ window.location.hash += ( window.location.hash.length ? '' : wo.sort2Hash_hash ) +
103
+ '&' + s2h.getTableId( c, wo ) + '=' + encodeURI( sort );
104
+ }
105
+ }
106
+ };
107
+
108
+ ts.addWidget({
109
+ id: 'sort2Hash',
110
+ priority: 30, // after saveSort
111
+ options: {
112
+ sort2Hash_hash : '#', // hash prefix
113
+ sort2Hash_separator : '-', // don't '#' or '=' here
114
+ sort2Hash_tableId : null, // this option > table ID > table index on page,
115
+ sort2Hash_useHeaderText : false, // use column header text (true) or zero-based column index
116
+ sort2Hash_processHeaderText : null, // function( text, config, columnIndex ) {},
117
+ sort2Hash_directionText : [ 0, 1 ], // [ 'asc', 'desc' ],
118
+ sort2Hash_overrideSaveSort : false // if true, override saveSort widget if saved sort available
119
+ },
120
+ init: function(table, thisWidget, c, wo) {
121
+ s2h.init( c, wo );
122
+ },
123
+ remove: function(table, c) {
124
+ c.$table.off( 'sortEnd.sort2hash' );
125
+ }
126
+ });
127
+
128
+ })(jQuery);
@@ -5,224 +5,224 @@
5
5
  /*jshint browser:true, jquery:true, unused:false */
6
6
  /*global jQuery: false */
7
7
  ;( function( $ ) {
8
- 'use strict';
9
- var ts = $.tablesorter;
8
+ 'use strict';
9
+ var ts = $.tablesorter;
10
10
 
11
- ts.sortTbodies = {
12
- init: function( c, wo ) {
11
+ ts.sortTbodies = {
12
+ init: function( c, wo ) {
13
13
 
14
- var index, rows, txt, max, $rows,
15
- namespace = c.namespace + 'sortTbody',
16
- $tbodies = c.$table.children( 'tbody' ),
17
- len = $tbodies.length;
14
+ var index, rows, txt, max, $rows,
15
+ namespace = c.namespace + 'sortTbody',
16
+ $tbodies = c.$table.children( 'tbody' ),
17
+ len = $tbodies.length;
18
18
 
19
- // save serverSideSorting value; use to toggle internal row sorting
20
- wo.sortTbody_original_serverSideSorting = c.serverSideSorting;
19
+ // save serverSideSorting value; use to toggle internal row sorting
20
+ wo.sortTbody_original_serverSideSorting = c.serverSideSorting;
21
21
 
22
- // include info-only tbodies - we need parsed data from *all* tbodies
23
- wo.sortTbody_original_cssInfoBlock = c.cssInfoBlock;
24
- c.cssInfoBlock = wo.sortTbody_noSort;
25
- ts.sortTbodies.setTbodies( c, wo );
22
+ // include info-only tbodies - we need parsed data from *all* tbodies
23
+ wo.sortTbody_original_cssInfoBlock = c.cssInfoBlock;
24
+ c.cssInfoBlock = wo.sortTbody_noSort;
25
+ ts.sortTbodies.setTbodies( c, wo );
26
26
 
27
- // add original order index for stable sort
28
- for ( index = 0; index < len; index++ ) {
29
- $tbodies.eq( index ).attr( 'data-ts-original-order', index );
30
- }
27
+ // add original order index for stable sort
28
+ for ( index = 0; index < len; index++ ) {
29
+ $tbodies.eq( index ).attr( 'data-ts-original-order', index );
30
+ }
31
31
 
32
- c.$table
33
- .unbind( 'sortBegin updateComplete '.split( ' ' ).join( namespace + ' ' ) )
34
- .bind( 'sortBegin' + namespace, function() {
35
- ts.sortTbodies.sorter( c );
36
- })
37
- .bind( 'updateComplete' + namespace, function() {
38
- // find parsers for each column
32
+ c.$table
33
+ .unbind( 'sortBegin updateComplete '.split( ' ' ).join( namespace + ' ' ) )
34
+ .bind( 'sortBegin' + namespace, function() {
35
+ ts.sortTbodies.sorter( c );
36
+ })
37
+ .bind( 'updateComplete' + namespace, function() {
38
+ // find parsers for each column
39
+ ts.sortTbodies.setTbodies( c, wo );
40
+ c.$table.trigger( 'updateCache', [ null, c.$tbodies ] );
41
+ });
42
+
43
+ // detect parsers - in case the table contains only info-only tbodies
44
+ if ( $.isEmptyObject( c.parsers ) || c.$tbodies.length !== $tbodies.length ) {
39
45
  ts.sortTbodies.setTbodies( c, wo );
40
46
  c.$table.trigger( 'updateCache', [ null, c.$tbodies ] );
41
- });
42
-
43
- // detect parsers - in case the table contains only info-only tbodies
44
- if ( $.isEmptyObject( c.parsers ) || c.$tbodies.length !== $tbodies.length ) {
45
- ts.sortTbodies.setTbodies( c, wo );
46
- c.$table.trigger( 'updateCache', [ null, c.$tbodies ] );
47
- }
47
+ }
48
48
 
49
- // find colMax; this only matter for numeric columns
50
- $rows = $tbodies.children( 'tr' );
51
- len = $rows.length;
52
- for ( index = 0; index < c.columns; index++ ) {
53
- max = 0;
54
- if ( c.parsers[ index ].type === 'numeric' ) {
55
- for ( rows = 0; rows < len; rows++ ) {
56
- // update column max value (ignore sign)
57
- txt = ts.getParsedText( c, $rows.eq( rows ).children()[ index ], index );
58
- max = Math.max( Math.abs( txt ) || 0, max );
49
+ // find colMax; this only matter for numeric columns
50
+ $rows = $tbodies.children( 'tr' );
51
+ len = $rows.length;
52
+ for ( index = 0; index < c.columns; index++ ) {
53
+ max = 0;
54
+ if ( c.parsers[ index ].type === 'numeric' ) {
55
+ for ( rows = 0; rows < len; rows++ ) {
56
+ // update column max value (ignore sign)
57
+ txt = ts.getParsedText( c, $rows.eq( rows ).children()[ index ], index );
58
+ max = Math.max( Math.abs( txt ) || 0, max );
59
+ }
59
60
  }
61
+ c.$headerIndexed[ index ].attr( 'data-ts-col-max-value', max );
60
62
  }
61
- c.$headerIndexed[ index ].attr( 'data-ts-col-max-value', max );
62
- }
63
-
64
- },
65
-
66
- // make sure c.$tbodies is up-to-date (init & after updates)
67
- setTbodies: function( c, wo ) {
68
- c.$tbodies = c.$table.children( 'tbody' ).not( '.' + wo.sortTbody_noSort );
69
- },
70
-
71
- sorter: function( c ) {
72
- var $table = c.$table,
73
- wo = c.widgetOptions;
74
-
75
- // prevent multiple calls while processing
76
- if ( wo.sortTbody_busy !== true ) {
77
- wo.sortTbody_busy = true;
78
- var $tbodies = $table.children( 'tbody' ).not( '.' + wo.sortTbody_noSort ),
79
- primary = wo.sortTbody_primaryRow || 'tr:eq(0)',
80
- sortList = c.sortList || [],
81
- len = sortList.length;
82
-
83
- if ( len ) {
84
-
85
- // toggle internal row sorting
86
- c.serverSideSorting = !wo.sortTbody_sortRows;
87
-
88
- $tbodies.sort( function( a, b ) {
89
- var sortListIndex, txt, dir, num, colMax, sort, col, order, colA, colB, x, y,
90
- table = c.table,
91
- parsers = c.parsers,
92
- cts = c.textSorter || '',
93
- $tbodyA = $( a ),
94
- $tbodyB = $( b ),
95
- $a = $tbodyA.find( primary ).children( 'td, th' ),
96
- $b = $tbodyB.find( primary ).children( 'td, th' );
97
- for ( sortListIndex = 0; sortListIndex < len; sortListIndex++ ) {
98
- col = sortList[ sortListIndex ][0];
99
- order = sortList[ sortListIndex ][1];
100
- // sort direction, true = asc, false = desc
101
- dir = order === 0;
102
- // column txt - tbody A
103
- txt = ts.getElementText( c, $a.eq( col ), col );
104
- colA = parsers[ col ].format( txt, table, $a[ col ], col );
105
- // column txt - tbody B
106
- txt = ts.getElementText( c, $b.eq( col ), col );
107
- colB = parsers[ col ].format( txt, table, $b[ col ], col );
108
-
109
- if (c.sortStable && colA === colB && len === 1) {
110
- return $tbodyA.attr( 'data-ts-original-order' ) - $tbodyB.attr( 'data-ts-original-order' );
111
- }
112
63
 
113
- // fallback to natural sort since it is more robust
114
- num = /n/i.test( parsers && parsers[ col ] ? parsers[ col ].type || '' : '' );
115
- if ( num && c.strings[ col ] ) {
116
- colMax = c.$headerIndexed[ col ].attr( 'data-ts-col-max-value' ) ||
117
- 1.79E+308; // close to Number.MAX_VALUE
118
- // sort strings in numerical columns
119
- if ( typeof ( c.string[ c.strings[ col ] ] ) === 'boolean' ) {
120
- num = ( dir ? 1 : -1 ) * ( c.string[ c.strings[ col ] ] ? -1 : 1 );
121
- } else {
122
- num = ( c.strings[ col ] ) ? c.string[ c.strings[ col ] ] || 0 : 0;
64
+ },
65
+
66
+ // make sure c.$tbodies is up-to-date (init & after updates)
67
+ setTbodies: function( c, wo ) {
68
+ c.$tbodies = c.$table.children( 'tbody' ).not( '.' + wo.sortTbody_noSort );
69
+ },
70
+
71
+ sorter: function( c ) {
72
+ var $table = c.$table,
73
+ wo = c.widgetOptions;
74
+
75
+ // prevent multiple calls while processing
76
+ if ( wo.sortTbody_busy !== true ) {
77
+ wo.sortTbody_busy = true;
78
+ var $tbodies = $table.children( 'tbody' ).not( '.' + wo.sortTbody_noSort ),
79
+ primary = wo.sortTbody_primaryRow || 'tr:eq(0)',
80
+ sortList = c.sortList || [],
81
+ len = sortList.length;
82
+
83
+ if ( len ) {
84
+
85
+ // toggle internal row sorting
86
+ c.serverSideSorting = !wo.sortTbody_sortRows;
87
+
88
+ $tbodies.sort( function( a, b ) {
89
+ var sortListIndex, txt, dir, num, colMax, sort, col, order, colA, colB, x, y,
90
+ table = c.table,
91
+ parsers = c.parsers,
92
+ cts = c.textSorter || '',
93
+ $tbodyA = $( a ),
94
+ $tbodyB = $( b ),
95
+ $a = $tbodyA.find( primary ).children( 'td, th' ),
96
+ $b = $tbodyB.find( primary ).children( 'td, th' );
97
+ for ( sortListIndex = 0; sortListIndex < len; sortListIndex++ ) {
98
+ col = sortList[ sortListIndex ][0];
99
+ order = sortList[ sortListIndex ][1];
100
+ // sort direction, true = asc, false = desc
101
+ dir = order === 0;
102
+ // column txt - tbody A
103
+ txt = ts.getElementText( c, $a.eq( col ), col );
104
+ colA = parsers[ col ].format( txt, table, $a[ col ], col );
105
+ // column txt - tbody B
106
+ txt = ts.getElementText( c, $b.eq( col ), col );
107
+ colB = parsers[ col ].format( txt, table, $b[ col ], col );
108
+
109
+ if (c.sortStable && colA === colB && len === 1) {
110
+ return $tbodyA.attr( 'data-ts-original-order' ) - $tbodyB.attr( 'data-ts-original-order' );
123
111
  }
124
- // fall back to built-in numeric sort
125
- // var sort = $.tablesorter['sort' + s](a, b, dir, colMax, table);
126
- sort = c.numberSorter ? c.numberSorter( colA, colB, dir, colMax, table ) :
127
- ts[ 'sortNumeric' + ( dir ? 'Asc' : 'Desc' ) ]( colA, colB, num, colMax, col, table );
128
- } else {
129
- // set a & b depending on sort direction
130
- x = dir ? colA : colB;
131
- y = dir ? colB : colA;
132
- // text sort function
133
- if ( typeof ( cts ) === 'function' ) {
134
- // custom OVERALL text sorter
135
- sort = cts( x, y, dir, col, table );
136
- } else if ( typeof ( cts ) === 'object' && cts.hasOwnProperty( col ) ) {
137
- // custom text sorter for a SPECIFIC COLUMN
138
- sort = cts[ col ]( x, y, dir, col, table );
112
+
113
+ // fallback to natural sort since it is more robust
114
+ num = /n/i.test( parsers && parsers[ col ] ? parsers[ col ].type || '' : '' );
115
+ if ( num && c.strings[ col ] ) {
116
+ colMax = c.$headerIndexed[ col ].attr( 'data-ts-col-max-value' ) ||
117
+ 1.79E+308; // close to Number.MAX_VALUE
118
+ // sort strings in numerical columns
119
+ if ( typeof ( c.string[ c.strings[ col ] ] ) === 'boolean' ) {
120
+ num = ( dir ? 1 : -1 ) * ( c.string[ c.strings[ col ] ] ? -1 : 1 );
121
+ } else {
122
+ num = ( c.strings[ col ] ) ? c.string[ c.strings[ col ] ] || 0 : 0;
123
+ }
124
+ // fall back to built-in numeric sort
125
+ // var sort = $.tablesorter['sort' + s](a, b, dir, colMax, table);
126
+ sort = c.numberSorter ? c.numberSorter( colA, colB, dir, colMax, table ) :
127
+ ts[ 'sortNumeric' + ( dir ? 'Asc' : 'Desc' ) ]( colA, colB, num, colMax, col, table );
139
128
  } else {
140
- // fall back to natural sort
141
- sort = ts[ 'sortNatural' + ( dir ? 'Asc' : 'Desc' ) ]( colA, colB, col, table, c );
129
+ // set a & b depending on sort direction
130
+ x = dir ? colA : colB;
131
+ y = dir ? colB : colA;
132
+ // text sort function
133
+ if ( typeof ( cts ) === 'function' ) {
134
+ // custom OVERALL text sorter
135
+ sort = cts( x, y, dir, col, table );
136
+ } else if ( typeof ( cts ) === 'object' && cts.hasOwnProperty( col ) ) {
137
+ // custom text sorter for a SPECIFIC COLUMN
138
+ sort = cts[ col ]( x, y, dir, col, table );
139
+ } else {
140
+ // fall back to natural sort
141
+ sort = ts[ 'sortNatural' + ( dir ? 'Asc' : 'Desc' ) ]( colA, colB, col, table, c );
142
+ }
142
143
  }
144
+ if ( sort ) { return sort; }
143
145
  }
144
- if ( sort ) { return sort; }
145
- }
146
- return $tbodyA.attr( 'data-ts-original-order' ) - $tbodyB.attr( 'data-ts-original-order' );
147
- });
146
+ return $tbodyA.attr( 'data-ts-original-order' ) - $tbodyB.attr( 'data-ts-original-order' );
147
+ });
148
148
 
149
- ts.sortTbodies.restoreTbodies ( c, wo, $tbodies );
150
- wo.sortTbody_busy = false;
149
+ ts.sortTbodies.restoreTbodies( c, wo, $tbodies );
150
+ wo.sortTbody_busy = false;
151
+ }
151
152
  }
152
- }
153
- },
154
-
155
- restoreTbodies : function ( c, wo, $sortedTbodies ) {
156
- var $nosort, $tbodies, $thisTbody, tbLen, nsLen, index, targetIndex,
157
- $table = c.$table,
158
- hasShuffled = true,
159
- indx = 0;
160
-
161
- // hide entire table to improve sort performance
162
- $table.hide();
163
- $sortedTbodies.appendTo( $table );
164
-
165
- // reposition no-sort tbodies
166
- $tbodies = $table.children( 'tbody' );
167
- tbLen = $tbodies.length;
168
- $nosort = $tbodies.filter( '.' + wo.sortTbody_noSort ).appendTo( $table );
169
- nsLen = $nosort.length;
170
-
171
- if ( nsLen ) {
172
- // don't allow the while loop to cycle more times than the set number of no-sort tbodies
173
- while ( hasShuffled && indx < nsLen ) {
174
- hasShuffled = false;
175
- for ( index = 0; index < nsLen; index++ ) {
176
- targetIndex = parseInt( $nosort.eq( index ).attr( 'data-ts-original-order' ), 10 );
177
- // if target index > number of tbodies, make it last
178
- targetIndex = targetIndex >= tbLen ? tbLen : targetIndex < 0 ? 0 : targetIndex;
179
-
180
- if ( targetIndex !== $nosort.eq( index ).index() ) {
181
- hasShuffled = true;
182
- $thisTbody = $nosort.eq( index ).detach();
183
-
184
- if ( targetIndex >= tbLen ) {
185
- // Are we trying to be the last tbody?
186
- $thisTbody.appendTo( $table );
187
- } else if ( targetIndex === 0 ) {
188
- // Are we trying to be the first tbody?
189
- $thisTbody.prependTo( $table );
190
- } else {
191
- // No, we want to be somewhere in the middle!
192
- $thisTbody.insertBefore( $table.children( 'tbody:eq(' + targetIndex + ')' ) );
193
- }
153
+ },
154
+
155
+ restoreTbodies : function ( c, wo, $sortedTbodies ) {
156
+ var $nosort, $tbodies, $thisTbody, tbLen, nsLen, index, targetIndex,
157
+ $table = c.$table,
158
+ hasShuffled = true,
159
+ indx = 0;
160
+
161
+ // hide entire table to improve sort performance
162
+ $table.hide();
163
+ $sortedTbodies.appendTo( $table );
164
+
165
+ // reposition no-sort tbodies
166
+ $tbodies = $table.children( 'tbody' );
167
+ tbLen = $tbodies.length;
168
+ $nosort = $tbodies.filter( '.' + wo.sortTbody_noSort ).appendTo( $table );
169
+ nsLen = $nosort.length;
170
+
171
+ if ( nsLen ) {
172
+ // don't allow the while loop to cycle more times than the set number of no-sort tbodies
173
+ while ( hasShuffled && indx < nsLen ) {
174
+ hasShuffled = false;
175
+ for ( index = 0; index < nsLen; index++ ) {
176
+ targetIndex = parseInt( $nosort.eq( index ).attr( 'data-ts-original-order' ), 10 );
177
+ // if target index > number of tbodies, make it last
178
+ targetIndex = targetIndex >= tbLen ? tbLen : targetIndex < 0 ? 0 : targetIndex;
179
+
180
+ if ( targetIndex !== $nosort.eq( index ).index() ) {
181
+ hasShuffled = true;
182
+ $thisTbody = $nosort.eq( index ).detach();
183
+
184
+ if ( targetIndex >= tbLen ) {
185
+ // Are we trying to be the last tbody?
186
+ $thisTbody.appendTo( $table );
187
+ } else if ( targetIndex === 0 ) {
188
+ // Are we trying to be the first tbody?
189
+ $thisTbody.prependTo( $table );
190
+ } else {
191
+ // No, we want to be somewhere in the middle!
192
+ $thisTbody.insertBefore( $table.children( 'tbody:eq(' + targetIndex + ')' ) );
193
+ }
194
194
 
195
+ }
195
196
  }
197
+ indx++;
196
198
  }
197
- indx++;
198
199
  }
200
+
201
+ $table.show();
199
202
  }
200
203
 
201
- $table.show();
202
- }
203
-
204
- };
205
-
206
- ts.addWidget({
207
- id: 'sortTbody',
208
- // priority < 50 (filter widget), so c.$tbodies has the correct elements
209
- priority: 40,
210
- options: {
211
- // point to a row within the tbody that matches the number of header columns
212
- sortTbody_primaryRow : null,
213
- // sort tbody internal rows
214
- sortTbody_sortRows : false,
215
- // static tbodies (like static rows)
216
- sortTbody_noSort : 'tablesorter-no-sort-tbody'
217
- },
218
- init : function( table, thisWidget, c, wo ) {
219
- ts.sortTbodies.init( c, wo );
220
- },
221
- remove : function( table, c, wo, refreshing ) {
222
- c.$table.unbind( 'sortBegin updateComplete '.split( ' ' ).join( c.namespace + 'sortTbody ' ) );
223
- c.serverSideSorting = wo.sortTbody_original_serverSideSorting;
224
- c.cssInfoBlock = wo.sortTbody_original_cssInfoBlock;
225
- }
226
- });
204
+ };
205
+
206
+ ts.addWidget({
207
+ id: 'sortTbody',
208
+ // priority < 50 (filter widget), so c.$tbodies has the correct elements
209
+ priority: 40,
210
+ options: {
211
+ // point to a row within the tbody that matches the number of header columns
212
+ sortTbody_primaryRow : null,
213
+ // sort tbody internal rows
214
+ sortTbody_sortRows : false,
215
+ // static tbodies (like static rows)
216
+ sortTbody_noSort : 'tablesorter-no-sort-tbody'
217
+ },
218
+ init : function( table, thisWidget, c, wo ) {
219
+ ts.sortTbodies.init( c, wo );
220
+ },
221
+ remove : function( table, c, wo, refreshing ) {
222
+ c.$table.unbind( 'sortBegin updateComplete '.split( ' ' ).join( c.namespace + 'sortTbody ' ) );
223
+ c.serverSideSorting = wo.sortTbody_original_serverSideSorting;
224
+ c.cssInfoBlock = wo.sortTbody_original_cssInfoBlock;
225
+ }
226
+ });
227
227
 
228
228
  })( jQuery );