jquery-tablesorter 1.18.5 → 1.19.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.
Files changed (31) 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 +68 -46
  5. data/vendor/assets/javascripts/jquery-tablesorter/extras/jquery.dragtable.mod.js +3 -3
  6. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +2383 -2100
  7. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +2298 -2039
  8. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +90 -66
  9. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-month.js +45 -20
  10. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-weekday.js +78 -20
  11. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-globalize.js +37 -15
  12. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +4 -4
  13. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-chart.js +2 -2
  14. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +122 -30
  15. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +8 -6
  16. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +79 -58
  17. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +209 -128
  18. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-headerTitles.js +5 -4
  19. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-lazyload.js +367 -0
  20. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +81 -35
  21. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +3 -3
  22. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +79 -53
  23. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-print.js +25 -14
  24. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-saveSort.js +5 -2
  25. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +11 -7
  26. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sort2Hash.js +149 -50
  27. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sortTbodies.js +7 -7
  28. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-staticRow.js +2 -2
  29. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +2 -2
  30. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-view.js +192 -0
  31. metadata +4 -2
@@ -1,4 +1,4 @@
1
- /*! Widget: grouping - updated 9/1/2015 (v2.23.3) *//*
1
+ /*! Widget: grouping - updated 11/2/2015 (v2.24.1) *//*
2
2
  * Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * by Rob Garrison
4
4
  */
@@ -6,60 +6,97 @@
6
6
  /*global jQuery: false */
7
7
  ;(function($){
8
8
  'use strict';
9
- var ts = $.tablesorter;
9
+ var ts = $.tablesorter,
10
10
 
11
- ts.grouping = {
11
+ tsg = ts.grouping = {
12
12
 
13
13
  types : {
14
- number : function(c, $column, txt, num, group){
15
- var value, word;
16
- if (num > 1 && txt !== '') {
17
- if ($column.hasClass(ts.css.sortAsc)) {
18
- value = Math.floor(parseFloat(txt) / num) * num;
19
- return value > parseFloat(group || 0) ? value : parseFloat(group || 0);
14
+ number : function(c, $column, txt, num) {
15
+ var word, result,
16
+ ascSort = $column.hasClass( ts.css.sortAsc );
17
+ if ( num > 1 && txt !== '' ) {
18
+ if ( ascSort ) {
19
+ result = Math.floor( parseFloat( txt ) / num ) * num;
20
20
  } else {
21
- value = Math.ceil(parseFloat(txt) / num) * num;
22
- return value < parseFloat(group || num) - value ? parseFloat(group || num) - value : value;
21
+ result = Math.ceil( parseFloat( txt ) / num ) * num;
23
22
  }
23
+ // show range
24
+ result += ' - ' + ( result + ( num - 1 ) * ( ascSort ? 1 : -1 ) );
24
25
  } else {
25
- word = (txt + '').match(/\d+/g);
26
- return word && word.length >= num ? word[num - 1] : txt || '';
26
+ result = parseFloat( txt ) || txt;
27
27
  }
28
+ return result;
28
29
  },
29
- separator : function(c, $column, txt, num){
30
+ separator : function(c, $column, txt, num) {
30
31
  var word = (txt + '').split(c.widgetOptions.group_separator);
31
- return $.trim(word && num > 0 && word.length >= num ? word[(num || 1) - 1] : '');
32
+ // return $.trim(word && num > 0 && word.length >= num ? word[(num || 1) - 1] : '');
33
+ return $.trim( word[ num - 1 ] || '' );
32
34
  },
33
- word : function(c, $column, txt, num){
34
- var word = (txt + ' ').match(/\w+/g);
35
- return word && word.length >= num ? word[num - 1] : txt || '';
35
+ text : function( c, $column, txt ) {
36
+ return txt;
36
37
  },
37
- letter : function(c, $column, txt, num){
38
+ word : function(c, $column, txt, num) {
39
+ var word = (txt + ' ').match(/\w+/g) || [];
40
+ // return word && word.length >= num ? word[num - 1] : txt || '';
41
+ return word[ num - 1 ] || '';
42
+ },
43
+ letter : function(c, $column, txt, num) {
38
44
  return txt ? (txt + ' ').substring(0, num) : '';
39
45
  },
40
- date : function(c, $column, txt, part, group){
41
- var wo = c.widgetOptions,
42
- time = new Date(txt || ''),
43
- hours = time.getHours();
44
- return part === 'year' ? time.getFullYear() :
45
- part === 'month' ? wo.group_months[time.getMonth()] :
46
- part === 'monthyear' ? wo.group_months[time.getMonth()] + ' ' + time.getFullYear() :
47
- part === 'day' ? wo.group_months[time.getMonth()] + ' ' + time.getDate() :
48
- part === 'week' ? wo.group_week[time.getDay()] :
49
- part === 'time' ? ('00' + (hours > 12 ? hours - 12 : hours === 0 ? hours + 12 : hours)).slice(-2) + ':' +
50
- ('00' + time.getMinutes()).slice(-2) + ' ' + ('00' + wo.group_time[hours >= 12 ? 1 : 0]).slice(-2) :
51
- wo.group_dateString(time);
46
+ date : function(c, $column, txt, part, group) {
47
+ var year, month,
48
+ wo = c.widgetOptions,
49
+ time = new Date(txt || '');
50
+ // check for valid date
51
+ if ( time instanceof Date && isFinite( time ) ) {
52
+ year = time.getFullYear();
53
+ month = tsg.findMonth( wo, time.getMonth() );
54
+ return part === 'year' ? year :
55
+ part === 'month' ? month :
56
+ part === 'monthyear' ? month + ' ' + year :
57
+ part === 'day' ? month + ' ' + time.getDate() :
58
+ part === 'week' ? tsg.findWeek( wo, time.getDay() ) :
59
+ part === 'time' ? tsg.findTime( wo, time ) :
60
+ wo.group_dateString( time, c, $column );
61
+ } else {
62
+ return wo.group_dateInvalid;
63
+ }
64
+ }
65
+ },
66
+
67
+ // group date type functions to allow using this widget with Globalize
68
+ findMonth : function( wo, month ) {
69
+ // CLDR returns an object { 1: "Jan", 2: "Feb", 3: "Mar", ..., 12: "Dec" }
70
+ return wo.group_months[ month + ( ( wo.group_months[0] || '' ) === '' ? 1 : 0 ) ];
71
+ },
72
+ findWeek : function( wo, day ) {
73
+ if ( $.isArray( wo.group_week ) ) {
74
+ return wo.group_week[ day ];
75
+ } else if ( !$.isEmptyObject( wo.group_week ) ) {
76
+ // CLDR returns { sun: "Sun", mon: "Mon", tue: "Tue", wed: "Wed", thu: "Thu", ... }
77
+ var cldrWeek = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ];
78
+ return wo.group_week[ cldrWeek[ day ] ];
52
79
  }
53
80
  },
81
+ findTime : function( wo, time ) {
82
+ var suffix,
83
+ // CLDR returns { am: "AM", pm: "PM", ... }
84
+ isObj = wo.group_time.am && wo.group_time.pm,
85
+ h = time.getHours(),
86
+ period = h >= 12 ? 1 : 0,
87
+ p24 = wo.group_time24Hour && h > 12 ? h - 12 :
88
+ wo.group_time24Hour && h === 0 ? h + 12 : h,
89
+ hours = ( '00' + p24 ).slice(-2),
90
+ min = ( '00' + time.getMinutes() ).slice(-2);
91
+ suffix = wo.group_time[ isObj ? [ 'am', 'pm' ][ period ] : period ];
92
+ return hours + ':' + min + ( wo.group_time24Hour ? '' : ' ' + ( suffix || '' ) );
93
+ },
54
94
 
55
- update : function(table, c, wo){
95
+ update : function(table, c, wo) {
56
96
  if ($.isEmptyObject(c.cache)) { return; }
57
- var rowIndex, tbodyIndex, currentGroup, $rows, groupClass, grouping, norm_rows, saveName, direction,
58
- hasSort = typeof c.sortList[0] !== 'undefined',
59
- group = '',
60
- groupIndex = 0,
61
- savedGroup = false,
62
- column = typeof wo.group_forceColumn[0] !== 'undefined' ?
97
+ var hasSort = typeof c.sortList[0] !== 'undefined',
98
+ data = {},
99
+ column = $.isArray( wo.group_forceColumn ) && typeof wo.group_forceColumn[0] !== 'undefined' ?
63
100
  ( wo.group_enforceSort && !hasSort ? -1 : wo.group_forceColumn[0] ) :
64
101
  ( hasSort ? c.sortList[0][0] : -1 );
65
102
  c.$table
@@ -70,97 +107,135 @@
70
107
  c.$table.data('pagerSavedHeight', 0);
71
108
  }
72
109
  if (column >= 0 && column < c.columns && !c.$headerIndexed[column].hasClass('group-false')) {
73
- wo.group_currentGroup = ''; // save current groups
74
- wo.group_currentGroups = {};
110
+ wo.group_collapsedGroup = ''; // save current groups
111
+ wo.group_collapsedGroups = {};
75
112
 
113
+ data.column = column;
76
114
  // group class finds 'group-{word/separator/letter/number/date/false}-{optional:#/year/month/day/week/time}'
77
- groupClass = (c.$headerIndexed[column].attr('class') || '').match(/(group-\w+(-\w+)?)/g);
115
+ data.groupClass = (c.$headerIndexed[column].attr('class') || '').match(/(group-\w+(-\w+)?)/g);
78
116
  // grouping = [ 'group', '{word/separator/letter/number/date/false}', '{#/year/month/day/week/time}' ]
79
- grouping = groupClass ? groupClass[0].split('-') : [ 'group', 'letter', 1 ]; // default to letter 1
117
+ data.grouping = data.groupClass ? data.groupClass[0].split('-') : [ 'group', 'letter', 1 ]; // default to letter 1
80
118
 
81
119
  // save current grouping
82
- if (wo.group_collapsible && wo.group_saveGroups && ts.storage) {
83
- wo.group_currentGroups = ts.storage( table, 'tablesorter-groups' ) || {};
84
- // include direction when saving groups (reversed numbers shows different range values)
85
- direction = 'dir' + c.sortList[0][1];
86
- // combine column, sort direction & grouping as save key
87
- saveName = wo.group_currentGroup = '' + c.sortList[0][0] + direction + grouping.join('');
88
- if (!wo.group_currentGroups[saveName]) {
89
- wo.group_currentGroups[saveName] = [];
90
- } else {
91
- savedGroup = true;
92
- }
93
- }
94
- for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++) {
95
- norm_rows = c.cache[tbodyIndex].normalized;
96
- group = ''; // clear grouping across tbodies
97
- $rows = c.$tbodies.eq(tbodyIndex).children('tr').not('.' + c.cssChildRow);
98
- for (rowIndex = 0; rowIndex < $rows.length; rowIndex++) {
99
- if ( $rows.eq(rowIndex).is(':visible') ) {
100
- // fixes #438
101
- if (ts.grouping.types[grouping[1]]) {
102
- currentGroup = norm_rows[rowIndex] ?
103
- ts.grouping.types[grouping[1]]( c, c.$headerIndexed[column], norm_rows[rowIndex][column], /date/.test(groupClass) ?
104
- grouping[2] : parseInt(grouping[2] || 1, 10) || 1, group ) : currentGroup;
105
- if (group !== currentGroup) {
106
- group = currentGroup;
107
- // show range if number > 1
108
- if (grouping[1] === 'number' && grouping[2] > 1 && currentGroup !== '') {
109
- currentGroup += ' - ' + (parseInt(currentGroup, 10) +
110
- ((parseInt(grouping[2], 10) - 1) * (c.$headerIndexed[column].hasClass(ts.css.sortAsc) ? 1 : -1)));
111
- }
112
- if ($.isFunction(wo.group_formatter)) {
113
- currentGroup = wo.group_formatter((currentGroup || '').toString(), column, table, c, wo) || currentGroup;
114
- }
115
- $rows.eq(rowIndex).before('<tr class="group-header ' + c.selectorRemove.slice(1) +
116
- '" unselectable="on" ' + ( c.tabIndex ? 'tabindex="0" ' : '' ) + 'data-group-index="' +
117
- ( groupIndex++ ) + '"><td colspan="' + c.columns + '">' +
118
- ( wo.group_collapsible ? '<i/>' : '' ) +
119
- '<span class="group-name">' + currentGroup + '</span>' +
120
- '<span class="group-count"></span></td></tr>');
121
- if (wo.group_saveGroups && !savedGroup && wo.group_collapsed && wo.group_collapsible) {
122
- // all groups start collapsed
123
- wo.group_currentGroups[wo.group_currentGroup].push(currentGroup);
124
- }
125
- }
126
- }
120
+ data.savedGroup = tsg.saveCurrentGrouping( c, wo, data );
121
+
122
+ // find column groups
123
+ tsg.findColumnGroups( c, wo, data );
124
+ tsg.processHeaders( c, wo, data );
125
+
126
+ c.$table.trigger(wo.group_complete);
127
+ }
128
+ },
129
+
130
+ processHeaders : function( c, wo, data ) {
131
+ var index, isHidden, $label, name, $rows, $row,
132
+ $headers = c.$table.find( 'tr.group-header' ),
133
+ len = $headers.length;
134
+
135
+ $headers.bind( 'selectstart', false );
136
+ for ( index = 0; index < len; index++ ) {
137
+ $row = $headers.eq( index );
138
+ $rows = $row.nextUntil( 'tr.group-header' ).filter( ':visible' );
139
+
140
+ // add group count (only visible rows!)
141
+ if ( wo.group_count || $.isFunction( wo.group_callback ) ) {
142
+ $label = $row.find( '.group-count' );
143
+ if ( $label.length ) {
144
+ if ( wo.group_count ) {
145
+ $label.html( wo.group_count.replace( /\{num\}/g, $rows.length ) );
127
146
  }
128
- }
129
- }
130
- c.$table.find('tr.group-header')
131
- .bind('selectstart', false)
132
- .each(function(){
133
- var isHidden, $label, name,
134
- $row = $(this),
135
- $rows = $row.nextUntil('tr.group-header').filter(':visible');
136
- if (wo.group_count || $.isFunction(wo.group_callback)) {
137
- $label = $row.find('.group-count');
138
- if ($label.length) {
139
- if (wo.group_count) {
140
- $label.html( wo.group_count.replace(/\{num\}/g, $rows.length) );
141
- }
142
- if ($.isFunction(wo.group_callback)) {
143
- wo.group_callback($row.find('td'), $rows, column, table);
144
- }
147
+ if ( $.isFunction( wo.group_callback ) ) {
148
+ wo.group_callback( $row.find( 'td' ), $rows, data.column, c.table );
145
149
  }
146
150
  }
147
- if (wo.group_saveGroups && !$.isEmptyObject(wo.group_currentGroups) && wo.group_currentGroups[wo.group_currentGroup].length) {
148
- name = $row.find('.group-name').text().toLowerCase() + $row.attr('data-group-index');
149
- isHidden = $.inArray( name, wo.group_currentGroups[wo.group_currentGroup] ) > -1;
150
- $row.toggleClass('collapsed', isHidden);
151
- $rows.toggleClass('group-hidden', isHidden);
152
- } else if (wo.group_collapsed && wo.group_collapsible) {
153
- $row.addClass('collapsed');
154
- $rows.addClass('group-hidden');
151
+ }
152
+
153
+ // save collapsed groups
154
+ if ( wo.group_saveGroups &&
155
+ !$.isEmptyObject( wo.group_collapsedGroups ) &&
156
+ wo.group_collapsedGroups[ wo.group_collapsedGroup ].length ) {
157
+
158
+ name = $row.find( '.group-name' ).text().toLowerCase() + $row.attr( 'data-group-index' );
159
+ isHidden = $.inArray( name, wo.group_collapsedGroups[ wo.group_collapsedGroup ] ) > -1;
160
+ $row.toggleClass( 'collapsed', isHidden );
161
+ $rows.toggleClass( 'group-hidden', isHidden );
162
+ } else if ( wo.group_collapsed && wo.group_collapsible ) {
163
+ $row.addClass( 'collapsed' );
164
+ $rows.addClass( 'group-hidden' );
165
+ }
166
+ }
167
+ },
168
+
169
+ groupHeaderHTML : function( c, wo, data ) {
170
+ return '<tr class="group-header ' + c.selectorRemove.slice(1) +
171
+ '" unselectable="on" ' + ( c.tabIndex ? 'tabindex="0" ' : '' ) + 'data-group-index="' +
172
+ ( data.groupIndex++ ) + '">' +
173
+ '<td colspan="' + c.columns + '">' +
174
+ ( wo.group_collapsible ? '<i/>' : '' ) +
175
+ '<span class="group-name">' + data.currentGroup + '</span>' +
176
+ '<span class="group-count"></span>' +
177
+ '</td></tr>';
178
+ },
179
+ saveCurrentGrouping : function( c, wo, data ) {
180
+ // save current grouping
181
+ var saveName, direction,
182
+ savedGroup = false;
183
+ if (wo.group_collapsible && wo.group_saveGroups && ts.storage) {
184
+ wo.group_collapsedGroups = ts.storage( c.table, 'tablesorter-groups' ) || {};
185
+ // include direction when saving groups (reversed numbers shows different range values)
186
+ direction = 'dir' + c.sortList[0][1];
187
+ // combine column, sort direction & grouping as save key
188
+ saveName = wo.group_collapsedGroup = '' + c.sortList[0][0] + direction + data.grouping.join('');
189
+ if (!wo.group_collapsedGroups[saveName]) {
190
+ wo.group_collapsedGroups[saveName] = [];
191
+ } else {
192
+ savedGroup = true;
193
+ }
194
+ }
195
+ return savedGroup;
196
+ },
197
+ findColumnGroups : function( c, wo, data ) {
198
+ var tbodyIndex, norm_rows, $row, rowIndex, end,
199
+ hasPager = ts.hasWidget( c.table, 'pager' );
200
+ data.groupIndex = 0;
201
+ for ( tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++ ) {
202
+ norm_rows = c.cache[ tbodyIndex ].normalized;
203
+ data.group = ''; // clear grouping across tbodies
204
+ rowIndex = hasPager ? c.pager.startRow - 1 : 0;
205
+ end = hasPager ? c.pager.endRow : norm_rows.length;
206
+ for ( ; rowIndex < end; rowIndex++ ) {
207
+ data.rowData = norm_rows[ rowIndex ];
208
+ data.$row = data.rowData[ c.columns ].$row;
209
+ // fixes #438
210
+ if ( data.$row.is( ':visible' ) && tsg.types[ data.grouping[ 1 ] ] ) {
211
+ tsg.insertGroupHeader( c, wo, data );
155
212
  }
156
- });
157
- c.$table.trigger(wo.group_complete);
213
+ }
214
+ }
215
+ },
216
+ insertGroupHeader: function( c, wo, data ) {
217
+ var $header = c.$headerIndexed[ data.column ],
218
+ txt = data.rowData[ data.column ],
219
+ num = /date/.test( data.groupClass ) ? data.grouping[ 2 ] : parseInt( data.grouping[ 2 ] || 1, 10 ) || 1;
220
+ data.currentGroup = data.rowData ?
221
+ tsg.types[ data.grouping[ 1 ] ]( c, $header, txt, num, data.group ) :
222
+ data.currentGroup;
223
+ if ( data.group !== data.currentGroup ) {
224
+ data.group = data.currentGroup;
225
+ if ( $.isFunction( wo.group_formatter ) ) {
226
+ data.currentGroup = wo.group_formatter( ( data.group || '' ).toString(), data.column, c.table, c, wo ) || data.group;
227
+ }
228
+ data.$row.before( tsg.groupHeaderHTML( c, wo, data ) );
229
+ if ( wo.group_saveGroups && !data.savedGroup && wo.group_collapsed && wo.group_collapsible ) {
230
+ // all groups start collapsed
231
+ wo.group_collapsedGroups[ wo.group_collapsedGroup ].push( data.currentGroup );
232
+ }
158
233
  }
159
234
  },
160
235
 
161
236
  bindEvents : function(table, c, wo){
162
237
  if (wo.group_collapsible) {
163
- wo.group_currentGroups = [];
238
+ wo.group_collapsedGroups = [];
164
239
  // .on() requires jQuery 1.7+
165
240
  c.$table.on('click toggleGroup keyup', 'tr.group-header', function(event){
166
241
  event.stopPropagation();
@@ -180,33 +255,33 @@
180
255
  if (wo.group_saveGroups && ts.storage) {
181
256
  $groups = c.$table.find('.group-header');
182
257
  isCollapsed = $this.hasClass('collapsed');
183
- if (!wo.group_currentGroups[wo.group_currentGroup]) {
184
- wo.group_currentGroups[wo.group_currentGroup] = [];
258
+ if (!wo.group_collapsedGroups[wo.group_collapsedGroup]) {
259
+ wo.group_collapsedGroups[wo.group_collapsedGroup] = [];
185
260
  }
186
- if (isCollapsed && wo.group_currentGroup) {
187
- wo.group_currentGroups[wo.group_currentGroup].push( name );
188
- } else if (wo.group_currentGroup) {
189
- indx = $.inArray( name, wo.group_currentGroups[wo.group_currentGroup] );
261
+ if (isCollapsed && wo.group_collapsedGroup) {
262
+ wo.group_collapsedGroups[wo.group_collapsedGroup].push( name );
263
+ } else if (wo.group_collapsedGroup) {
264
+ indx = $.inArray( name, wo.group_collapsedGroups[wo.group_collapsedGroup] );
190
265
  if (indx > -1) {
191
- wo.group_currentGroups[wo.group_currentGroup].splice( indx, 1 );
266
+ wo.group_collapsedGroups[wo.group_collapsedGroup].splice( indx, 1 );
192
267
  }
193
268
  }
194
- ts.storage( table, 'tablesorter-groups', wo.group_currentGroups );
269
+ ts.storage( table, 'tablesorter-groups', wo.group_collapsedGroups );
195
270
  }
196
271
  });
197
272
  }
198
273
  $(wo.group_saveReset).on('click', function(){
199
- ts.grouping.clearSavedGroups(table);
274
+ tsg.clearSavedGroups(table);
200
275
  });
201
276
  c.$table.on('pagerChange.tsgrouping', function(){
202
- ts.grouping.update(table, c, wo);
277
+ tsg.update(table, c, wo);
203
278
  });
204
279
  },
205
280
 
206
281
  clearSavedGroups: function(table){
207
282
  if (table && ts.storage) {
208
283
  ts.storage(table, 'tablesorter-groups', '');
209
- ts.grouping.update(table, table.config, table.config.widgetOptions);
284
+ tsg.update(table, table.config, table.config.widgetOptions);
210
285
  }
211
286
  }
212
287
 
@@ -236,16 +311,22 @@
236
311
  group_months : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
237
312
  group_week : [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
238
313
  group_time : [ 'AM', 'PM' ],
314
+
315
+ // use 12 vs 24 hour time
316
+ group_time24Hour : false,
317
+ // group header text added for invalid dates
318
+ group_dateInvalid : 'Invalid Date',
319
+
239
320
  // this function is used when 'group-date' is set to create the date string
240
321
  // you can just return date, date.toLocaleString(), date.toLocaleDateString() or d.toLocaleTimeString()
241
322
  // reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#Conversion_getter
242
323
  group_dateString : function(date) { return date.toLocaleString(); }
243
324
  },
244
325
  init: function(table, thisWidget, c, wo){
245
- ts.grouping.bindEvents(table, c, wo);
326
+ tsg.bindEvents(table, c, wo);
246
327
  },
247
328
  format: function(table, c, wo) {
248
- ts.grouping.update(table, c, wo);
329
+ tsg.update(table, c, wo);
249
330
  },
250
331
  remove : function(table, c, wo){
251
332
  c.$table
@@ -1,4 +1,4 @@
1
- /*! Widget: headerTitles - updated 3/5/2014 (v2.15.6) *//*
1
+ /*! Widget: headerTitles - updated 10/31/2015 (v2.24.0) *//*
2
2
  * Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * by Rob Garrison
4
4
  */
@@ -54,15 +54,16 @@
54
54
  c.$headers.each(function(){
55
55
  var t = this,
56
56
  $this = $(this),
57
- sortType = wo.headerTitle_type[t.column] || c.parsers[ t.column ].type || 'text',
57
+ col = parseInt( $this.attr( 'data-column' ), 10 ),
58
+ sortType = wo.headerTitle_type[ col ] || c.parsers[ col ].type || 'text',
58
59
  sortDirection = $this.hasClass(ts.css.sortAsc) ? 0 : $this.hasClass(ts.css.sortDesc) ? 1 : 2,
59
- sortNext = t.order[(t.count + 1) % (c.sortReset ? 3 : 2)];
60
+ sortNext = c.sortVars[ col ].order[ ( c.sortVars[ col ].count + 1 ) % ( c.sortReset ? 3 : 2 ) ];
60
61
  if (wo.headerTitle_useAria) {
61
62
  txt = $this.hasClass('sorter-false') ? wo.headerTitle_output_nosort : $this.attr('aria-label') || '';
62
63
  } else {
63
64
  txt = (wo.headerTitle_prefix || '') + // now deprecated
64
65
  ($this.hasClass('sorter-false') ? wo.headerTitle_output_nosort :
65
- ts.isValueInArray( t.column, c.sortList ) >= 0 ? wo.headerTitle_output_sorted : wo.headerTitle_output_unsorted);
66
+ ts.isValueInArray( col, c.sortList ) >= 0 ? wo.headerTitle_output_sorted : wo.headerTitle_output_unsorted);
66
67
  txt = txt.replace(/\{(current|next|name)\}/gi, function(m){
67
68
  return {
68
69
  '{name}' : $this.text(),
@@ -0,0 +1,367 @@
1
+ /*! Widget: lazyload (BETA) - 10/31/2015 (v2.24.0) *//*
2
+ * Requires tablesorter v2.8+ and jQuery 1.7+
3
+ * by Rob Garrison
4
+ */
5
+ /*jshint browser:true, jquery:true, unused:false */
6
+ ;( function( $, window ) {
7
+ 'use strict';
8
+ var ts = $.tablesorter;
9
+
10
+ ts.lazyload = {
11
+ init : function( c, wo ) {
12
+ if ( wo.lazyload_event === 'scrollstop' && !ts.addScrollStopDone ) {
13
+ ts.addScrollStop();
14
+ ts.addScrollStopDone = true;
15
+ $.event.special.scrollstop.latency = wo.lazyload_latency || 250;
16
+ }
17
+ ts.lazyload.update( c, wo );
18
+ var events = [ wo.lazyload_update, 'pagerUpdate', wo.columnSelector_updated || 'columnUpdate', '' ]
19
+ .join( c.namespace + 'lazyload ' );
20
+ c.$table.on( events, function() {
21
+ ts.lazyload.update( c, c.widgetOptions );
22
+ });
23
+ },
24
+ update : function( c, wo ) {
25
+ // add '.' if not already included
26
+ var sel = ( /(\.|#)/.test( wo.lazyload_imageClass ) ? '' : '.' ) + wo.lazyload_imageClass;
27
+ c.$table.find( sel ).lazyload({
28
+ threshold : wo.lazyload_threshold,
29
+ failure_limit : wo.lazyload_failure_limit,
30
+ event : wo.lazyload_event,
31
+ effect : wo.lazyload_effect,
32
+ container : wo.lazyload_container,
33
+ data_attribute : wo.lazyload_data_attribute,
34
+ skip_invisible : wo.lazyload_skip_invisible,
35
+ appear : wo.lazyload_appear,
36
+ load : wo.lazyload_load,
37
+ placeholder : wo.lazyload_placeholder
38
+ });
39
+ },
40
+ remove : function( c, wo ) {
41
+ c.$table.off( c.namespace + 'lazyload' );
42
+ }
43
+ };
44
+
45
+ ts.addWidget({
46
+ id: 'lazyload',
47
+ options: {
48
+ // widget options
49
+ lazyload_imageClass : 'lazy',
50
+ lazyload_update : 'lazyloadUpdate',
51
+ // scrollStop option (https://github.com/ssorallen/jquery-scrollstop)
52
+ lazyload_latency : 250,
53
+ // lazyload options (see http://www.appelsiini.net/projects/lazyload)
54
+ lazyload_threshold : 0,
55
+ lazyload_failure_limit : 0,
56
+ lazyload_event : 'scrollstop',
57
+ lazyload_effect : 'show',
58
+ lazyload_container : window,
59
+ lazyload_data_attribute : 'original',
60
+ lazyload_skip_invisible : false,
61
+ lazyload_appear : null,
62
+ lazyload_load : null,
63
+ lazyload_placeholder : 'data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='
64
+ },
65
+ init: function( table, thisWidget, c, wo ) {
66
+ ts.lazyload.init( c, wo );
67
+ },
68
+ remove : function( table, c, wo ) {
69
+ ts.lazyload.remove( c, wo );
70
+ }
71
+ });
72
+
73
+ // jscs:disable
74
+ ts.addScrollStop = function() {
75
+ // jQuery Scrollstop Plugin v1.2.0
76
+ // https://github.com/ssorallen/jquery-scrollstop
77
+ /*
78
+ (function (factory) {
79
+ // UMD[2] wrapper for jQuery plugins to work in AMD or in CommonJS.
80
+ //
81
+ // [2] https://github.com/umdjs/umd
82
+
83
+ if (typeof define === 'function' && define.amd) {
84
+ // AMD. Register as an anonymous module.
85
+ define(['jquery'], factory);
86
+ } else if (typeof exports === 'object') {
87
+ // Node/CommonJS
88
+ module.exports = factory(require('jquery'));
89
+ } else {
90
+ // Browser globals
91
+ factory(jQuery);
92
+ }
93
+ }(function ($) { */
94
+ // $.event.dispatch was undocumented and was deprecated in jQuery 1.7[1]. It
95
+ // was replaced by $.event.handle in jQuery 1.9.
96
+ //
97
+ // Use the first of the available functions to support jQuery <1.8.
98
+ //
99
+ // [1] https://github.com/jquery/jquery-migrate/blob/master/src/event.js#L25
100
+ var dispatch = $.event.dispatch || $.event.handle;
101
+
102
+ var special = $.event.special,
103
+ uid1 = 'D' + (+new Date()),
104
+ uid2 = 'D' + (+new Date() + 1);
105
+
106
+ special.scrollstart = {
107
+ setup: function(data) {
108
+ var _data = $.extend({
109
+ latency: special.scrollstop.latency
110
+ }, data);
111
+
112
+ var timer,
113
+ handler = function(evt) {
114
+ var _self = this,
115
+ _args = arguments;
116
+ if (timer) {
117
+ clearTimeout(timer);
118
+ } else {
119
+ evt.type = 'scrollstart';
120
+ dispatch.apply(_self, _args);
121
+ }
122
+ timer = setTimeout(function() {
123
+ timer = null;
124
+ }, _data.latency);
125
+ };
126
+ $(this).bind('scroll', handler).data(uid1, handler);
127
+ },
128
+ teardown: function() {
129
+ $(this).unbind('scroll', $(this).data(uid1));
130
+ }
131
+ };
132
+ special.scrollstop = {
133
+ latency: 250,
134
+ setup: function(data) {
135
+ var _data = $.extend({
136
+ latency: special.scrollstop.latency
137
+ }, data);
138
+ var timer,
139
+ handler = function(evt) {
140
+ var _self = this,
141
+ _args = arguments;
142
+ if (timer) {
143
+ clearTimeout(timer);
144
+ }
145
+ timer = setTimeout(function() {
146
+ timer = null;
147
+ evt.type = 'scrollstop';
148
+ dispatch.apply(_self, _args);
149
+ }, _data.latency);
150
+ };
151
+ $(this).bind('scroll', handler).data(uid2, handler);
152
+ },
153
+ teardown: function() {
154
+ $(this).unbind('scroll', $(this).data(uid2));
155
+ }
156
+ };
157
+ /*
158
+ }));
159
+ */
160
+
161
+ };
162
+ // jscs:enable
163
+
164
+ })( jQuery, window );
165
+
166
+ // jscs:disable
167
+ /*!
168
+ * Lazy Load - jQuery plugin for lazy loading images
169
+ *
170
+ * Copyright (c) 2007-2015 Mika Tuupola
171
+ *
172
+ * Licensed under the MIT license:
173
+ * http://www.opensource.org/licenses/mit-license.php
174
+ *
175
+ * Project home:
176
+ * http://www.appelsiini.net/projects/lazyload
177
+ *
178
+ * Version: 1.9.7
179
+ *
180
+ */
181
+ (function($, window, document, undefined) {
182
+ var $window = $(window);
183
+ $.fn.lazyload = function(options) {
184
+ var elements = this;
185
+ var $container;
186
+ var settings = {
187
+ threshold : 0,
188
+ failure_limit : 0,
189
+ event : "scroll",
190
+ effect : "show",
191
+ container : window,
192
+ data_attribute : "original",
193
+ skip_invisible : false,
194
+ appear : null,
195
+ load : null,
196
+ placeholder : "data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
197
+ };
198
+ function update() {
199
+ var counter = 0;
200
+ elements.each(function() {
201
+ var $this = $(this);
202
+ if (settings.skip_invisible && !$this.is(":visible")) {
203
+ return;
204
+ }
205
+ if ($.abovethetop(this, settings) || $.leftofbegin(this, settings)) {
206
+ /* Nothing. */
207
+ } else if (!$.belowthefold(this, settings) && !$.rightoffold(this, settings)) {
208
+ $this.trigger("appear");
209
+ /* if we found an image we'll load, reset the counter */
210
+ counter = 0;
211
+ } else {
212
+ if (++counter > settings.failure_limit) {
213
+ return false;
214
+ }
215
+ }
216
+ });
217
+ }
218
+ if (options) {
219
+ /* Maintain BC for a couple of versions. */
220
+ if (undefined !== options.failurelimit) {
221
+ options.failure_limit = options.failurelimit;
222
+ delete options.failurelimit;
223
+ }
224
+ if (undefined !== options.effectspeed) {
225
+ options.effect_speed = options.effectspeed;
226
+ delete options.effectspeed;
227
+ }
228
+ $.extend(settings, options);
229
+ }
230
+ /* Cache container as jQuery as object. */
231
+ $container = (settings.container === undefined ||
232
+ settings.container === window) ? $window : $(settings.container);
233
+ /* Fire one scroll event per scroll. Not one scroll event per image. */
234
+ if (0 === settings.event.indexOf("scroll")) {
235
+ $container.bind(settings.event, function() {
236
+ return update();
237
+ });
238
+ }
239
+ this.each(function() {
240
+ var self = this;
241
+ var $self = $(self);
242
+ self.loaded = false;
243
+ /* If no src attribute given use data:uri. */
244
+ if ($self.attr("src") === undefined || $self.attr("src") === false) {
245
+ if ($self.is("img")) {
246
+ $self.attr("src", settings.placeholder);
247
+ }
248
+ }
249
+ /* When appear is triggered load original image. */
250
+ $self.one("appear", function() {
251
+ if (!this.loaded) {
252
+ if (settings.appear) {
253
+ var elements_left = elements.length;
254
+ settings.appear.call(self, elements_left, settings);
255
+ }
256
+ $("<img />")
257
+ .bind("load", function() {
258
+ var original = $self.attr("data-" + settings.data_attribute);
259
+ $self.hide();
260
+ if ($self.is("img")) {
261
+ $self.attr("src", original);
262
+ } else {
263
+ $self.css("background-image", "url('" + original + "')");
264
+ }
265
+ $self[settings.effect](settings.effect_speed);
266
+ self.loaded = true;
267
+ /* Remove image from array so it is not looped next time. */
268
+ var temp = $.grep(elements, function(element) {
269
+ return !element.loaded;
270
+ });
271
+ elements = $(temp);
272
+ if (settings.load) {
273
+ var elements_left = elements.length;
274
+ settings.load.call(self, elements_left, settings);
275
+ }
276
+ })
277
+ .attr("src", $self.attr("data-" + settings.data_attribute));
278
+ }
279
+ });
280
+ /* When wanted event is triggered load original image */
281
+ /* by triggering appear. */
282
+ if (0 !== settings.event.indexOf("scroll")) {
283
+ $self.bind(settings.event, function() {
284
+ if (!self.loaded) {
285
+ $self.trigger("appear");
286
+ }
287
+ });
288
+ }
289
+ });
290
+ /* Check if something appears when window is resized. */
291
+ $window.bind("resize", function() {
292
+ update();
293
+ });
294
+ /* With IOS5 force loading images when navigating with back button. */
295
+ /* Non optimal workaround. */
296
+ if ((/(?:iphone|ipod|ipad).*os 5/gi).test(navigator.appVersion)) {
297
+ $window.bind("pageshow", function(event) {
298
+ if (event.originalEvent && event.originalEvent.persisted) {
299
+ elements.each(function() {
300
+ $(this).trigger("appear");
301
+ });
302
+ }
303
+ });
304
+ }
305
+ /* Force initial check if images should appear. */
306
+ $(document).ready(function() {
307
+ update();
308
+ });
309
+ return this;
310
+ };
311
+ /* Convenience methods in jQuery namespace. */
312
+ /* Use as $.belowthefold(element, {threshold : 100, container : window}) */
313
+ $.belowthefold = function(element, settings) {
314
+ var fold;
315
+ if (settings.container === undefined || settings.container === window) {
316
+ fold = (window.innerHeight ? window.innerHeight : $window.height()) + $window.scrollTop();
317
+ } else {
318
+ fold = $(settings.container).offset().top + $(settings.container).height();
319
+ }
320
+ return fold <= $(element).offset().top - settings.threshold;
321
+ };
322
+ $.rightoffold = function(element, settings) {
323
+ var fold;
324
+ if (settings.container === undefined || settings.container === window) {
325
+ fold = $window.width() + $window.scrollLeft();
326
+ } else {
327
+ fold = $(settings.container).offset().left + $(settings.container).width();
328
+ }
329
+ return fold <= $(element).offset().left - settings.threshold;
330
+ };
331
+ $.abovethetop = function(element, settings) {
332
+ var fold;
333
+ if (settings.container === undefined || settings.container === window) {
334
+ fold = $window.scrollTop();
335
+ } else {
336
+ fold = $(settings.container).offset().top;
337
+ }
338
+ return fold >= $(element).offset().top + settings.threshold + $(element).height();
339
+ };
340
+ $.leftofbegin = function(element, settings) {
341
+ var fold;
342
+ if (settings.container === undefined || settings.container === window) {
343
+ fold = $window.scrollLeft();
344
+ } else {
345
+ fold = $(settings.container).offset().left;
346
+ }
347
+ return fold >= $(element).offset().left + settings.threshold + $(element).width();
348
+ };
349
+ $.inviewport = function(element, settings) {
350
+ return !$.rightoffold(element, settings) && !$.leftofbegin(element, settings) &&
351
+ !$.belowthefold(element, settings) && !$.abovethetop(element, settings);
352
+ };
353
+ /* Custom selectors for your convenience. */
354
+ /* Use as $("img:below-the-fold").something() or */
355
+ /* $("img").filter(":below-the-fold").something() which is faster */
356
+ $.extend($.expr[":"], {
357
+ "below-the-fold" : function(a) { return $.belowthefold(a, {threshold : 0}); },
358
+ "above-the-top" : function(a) { return !$.belowthefold(a, {threshold : 0}); },
359
+ "right-of-screen": function(a) { return $.rightoffold(a, {threshold : 0}); },
360
+ "left-of-screen" : function(a) { return !$.rightoffold(a, {threshold : 0}); },
361
+ "in-viewport" : function(a) { return $.inviewport(a, {threshold : 0}); },
362
+ /* Maintain BC for couple of versions. */
363
+ "above-the-fold" : function(a) { return !$.belowthefold(a, {threshold : 0}); },
364
+ "right-of-fold" : function(a) { return $.rightoffold(a, {threshold : 0}); },
365
+ "left-of-fold" : function(a) { return !$.rightoffold(a, {threshold : 0}); }
366
+ });
367
+ })(jQuery, window, document);