jquery-tablesorter 1.10.10 → 1.11.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.
@@ -0,0 +1,82 @@
1
+ /*!
2
+ * Extract out date parsers
3
+ */
4
+ /*jshint jquery:true */
5
+ ;(function($){
6
+ "use strict";
7
+
8
+ /*! extract US Long Date (ignore any other text)
9
+ * e.g. "Sue's Birthday! Jun 26, 2004 7:22 AM (8# 2oz)"
10
+ * demo: http://jsfiddle.net/abkNM/2293/
11
+ */
12
+ $.tablesorter.addParser({
13
+ id: "extractUSLongDate",
14
+ is: function (s) {
15
+ // don't auto detect this parser
16
+ return false;
17
+ },
18
+ format: function (s, table) {
19
+ var date = s.match(/[A-Z]{3,10}\.?\s+\d{1,2},?\s+(?:\d{4})(?:\s+\d{1,2}:\d{2}(?::\d{2})?(?:\s+[AP]M)?)?/i);
20
+ return date ? $.tablesorter.formatFloat((new Date(date[0]).getTime() || ''), table) || s : s;
21
+ },
22
+ type: "numeric"
23
+ });
24
+
25
+ /*! extract MMDDYYYY (ignore any other text)
26
+ * demo: http://jsfiddle.net/Mottie/abkNM/2418/
27
+ */
28
+ $.tablesorter.addParser({
29
+ id: "extractMMDDYYYY",
30
+ is: function (s) {
31
+ // don't auto detect this parser
32
+ return false;
33
+ },
34
+ format: function (s, table) {
35
+ var date = s.replace(/\s+/g," ").replace(/[\-.,]/g, "/").match(/(\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4}(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?)/i);
36
+ return date ? $.tablesorter.formatFloat((new Date(date[0]).getTime() || ''), table) || s : s;
37
+ },
38
+ type: "numeric"
39
+ });
40
+
41
+ /*! extract DDMMYYYY (ignore any other text)
42
+ * demo: http://jsfiddle.net/Mottie/abkNM/2419/
43
+ */
44
+ $.tablesorter.addParser({
45
+ id: "extractDDMMYYYY",
46
+ is: function (s) {
47
+ // don't auto detect this parser
48
+ return false;
49
+ },
50
+ format: function (s, table) {
51
+ var date = s.replace(/\s+/g," ").replace(/[\-.,]/g, "/").match(/(\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4}(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?)/i);
52
+ if (date) {
53
+ date = date[0].replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/, "$2/$1/$3");
54
+ return $.tablesorter.formatFloat((new Date(date).getTime() || ''), table) || s;
55
+ }
56
+ return s;
57
+ },
58
+ type: "numeric"
59
+ });
60
+
61
+ /*! extract YYYYMMDD (ignore any other text)
62
+ * demo: http://jsfiddle.net/Mottie/abkNM/2420/
63
+ */
64
+ $.tablesorter.addParser({
65
+ id: "extractYYYYMMDD",
66
+ is: function (s) {
67
+ // don't auto detect this parser
68
+ return false;
69
+ },
70
+ format: function (s, table) {
71
+ var date = s.replace(/\s+/g," ").replace(/[\-.,]/g, "/").match(/(\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2}(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?)/i);
72
+ if (date) {
73
+ date = date[0].replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/, "$2/$3/$1");
74
+ console.log(date);
75
+ return $.tablesorter.formatFloat((new Date(date).getTime() || ''), table) || s;
76
+ }
77
+ return s;
78
+ },
79
+ type: "numeric"
80
+ });
81
+
82
+ })(jQuery);
@@ -1,4 +1,6 @@
1
- /*! Build Table widget * by Rob Garrison */
1
+ /*! Build Table widget for tableSorter v2.16.0 (4/23/2014)
2
+ * by Rob Garrison
3
+ */
2
4
  /*jshint browser:true, jquery:true, unused:false */
3
5
  /*global jQuery: false */
4
6
  ;(function($){
@@ -163,8 +165,12 @@ var ts = $.tablesorter = $.tablesorter || {},
163
165
  t = '<tr>' + (wo.build_numbers.addColumn ? '<th' + (wo.build_numbers.sortable ? '' :
164
166
  ' class="sorter-false"') + '>' + wo.build_numbers.addColumn + '</th>' : '');
165
167
  $.each(h1, function(i, h) {
166
- t += '<th' + (cls && cls[i] ? ' class="' + cls[i] + '"' : '') + '>' +
167
- (h2 && h2[i] ? h2[i] : h) + '</th>';
168
+ if (/<\s*\/t(d|h)\s*>/.test(h)) {
169
+ t += h;
170
+ } else {
171
+ t += '<th' + (cls && cls[i] ? ' class="' + cls[i] + '"' : '') + '>' +
172
+ (h2 && h2[i] ? h2[i] : h) + '</th>';
173
+ }
168
174
  });
169
175
  return t + '</tr>';
170
176
  },
@@ -172,8 +178,13 @@ var ts = $.tablesorter = $.tablesorter || {},
172
178
  var h = (ftr ? 'th' : 'td'),
173
179
  t = '<tr>' + (wo.build_numbers.addColumn ? '<' + h + '>' + (ftr ? '' : num) + '</' + h + '>' : '');
174
180
  $.each(items, function(i, item) {
175
- t += '<' + (ftr ? h + (c && c[i] ? ' class="' + c[i] + '"' : '') : h) + '>' +
176
- (ftr && txt && txt.length && txt[i] ? txt[i] : item) + '</' + h + '>';
181
+ // test if HTML is already included; look for closing </td>
182
+ if (/<\s*\/t(d|h)\s*>/.test(item)) {
183
+ t += item;
184
+ } else {
185
+ t += '<' + (ftr ? h + (c && c[i] ? ' class="' + c[i] + '"' : '') : h) + '>' +
186
+ (ftr && txt && txt.length && txt[i] ? txt[i] : item) + '</' + h + '>';
187
+ }
177
188
  });
178
189
  return t + '</tr>';
179
190
  }
@@ -372,6 +383,7 @@ var ts = $.tablesorter = $.tablesorter || {},
372
383
  $tb = $('<tbody>');
373
384
  // Build tbody
374
385
  $.each(r, function(i, d){
386
+ var j;
375
387
  t = $.type(d) === 'object';
376
388
  // add new tbody
377
389
  if (t && d.newTbody) {
@@ -1,7 +1,7 @@
1
1
  /*! tablesorter CSS Sticky Headers widget - updated 12/17/2013 (v2.15.0)
2
2
  * Requires a modern browser, tablesorter v2.8+
3
3
  */
4
- /*global jQuery: false, unused:false */
4
+ /*jshint jquery:true, unused:false */
5
5
  ;(function($){
6
6
  "use strict";
7
7
 
@@ -0,0 +1,359 @@
1
+ /*! tablesorter math widget - beta testing
2
+ * Requires tablesorter v2.16+ and jQuery 1.7+
3
+ * by Rob Garrison
4
+ */
5
+ /*jshint browser:true, jquery:true, unused:false */
6
+ /*global jQuery: false */
7
+ ;(function($){
8
+ "use strict";
9
+
10
+ var ts = $.tablesorter,
11
+ math = {
12
+
13
+ // get all of the row numerical values in an arry
14
+ getRow : function(table, wo, $el, dataAttrib) {
15
+ var txt,
16
+ arry = [],
17
+ $row = $el.closest('tr'),
18
+ $cells = $row.children();
19
+ if (!$row.hasClass(wo.filter_filteredRow || 'filtered')) {
20
+ if (wo.math_ignore.length) {
21
+ $cells = $cells.not('[' + dataAttrib + '=ignore]').not('[data-column=' + wo.math_ignore.join('],[data-column=') + ']');
22
+ }
23
+ arry = $cells.not($el).map(function(){
24
+ txt = this.textContent || $(this).text();
25
+ txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ""), table);
26
+ return isNaN(txt) ? 0 : txt;
27
+ }).get();
28
+ }
29
+ return arry;
30
+ },
31
+
32
+ // get all of the column numerical values in an arry
33
+ getColumn : function(table, wo, $el, type, dataAttrib){
34
+ var i, txt, $t, len, mathAbove,
35
+ arry = [],
36
+ c = table.config,
37
+ filtered = wo.filter_filteredRow || 'filtered',
38
+ cIndex = parseInt( $el.attr('data-column'), 10 ),
39
+ $rows = c.$table.children('tbody').children(),
40
+ $row = $el.closest('tr');
41
+ // make sure tfoot rows are AFTER the tbody rows
42
+ // $rows.add( c.$table.children('tfoot').children() );
43
+ if (type === 'above') {
44
+ len = $rows.index($row);
45
+ i = len;
46
+ while (i >= 0) {
47
+ $t = $rows.eq(i).children().filter('[data-column=' + cIndex + ']');
48
+ mathAbove = $t.filter('[' + dataAttrib + '^=above]').length;
49
+ // ignore filtered rows & rows with data-math="ignore" (and starting row)
50
+ if ( ( !$rows.eq(i).hasClass(filtered) && $rows.eq(i).not('[' + dataAttrib + '=ignore]').length && i !== len ) || mathAbove && i !== len ) {
51
+ // stop calculating "above", when encountering another "above"
52
+ if (mathAbove) {
53
+ i = 0;
54
+ } else if ($t.length) {
55
+ txt = $t[0].textContent || $t.text();
56
+ txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ""), table);
57
+ arry.push(isNaN(txt) ? 0 : txt);
58
+ }
59
+ }
60
+ i--;
61
+ }
62
+ } else {
63
+ $rows.each(function(){
64
+ $t = $(this).children().filter('[data-column=' + cIndex + ']');
65
+ if (!$(this).hasClass(filtered) && $t.not('[' + dataAttrib + '^=above],[' + dataAttrib + '^=col]').length && !$t.is($el)) {
66
+ txt = ($t[0] ? $t[0].textContent : '') || $t.text();
67
+ txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ""), table);
68
+ arry.push(isNaN(txt) ? 0 : txt);
69
+ }
70
+ });
71
+ }
72
+ return arry;
73
+ },
74
+
75
+ // get all of the column numerical values in an arry
76
+ getAll : function(table, wo, dataAttrib){
77
+ var txt, $t, col,
78
+ arry = [],
79
+ c = table.config,
80
+ filtered = wo.filter_filteredRow || 'filtered',
81
+ $rows = c.$table.children('tbody').children();
82
+ $rows.each(function(){
83
+ if (!$(this).hasClass(filtered)) {
84
+ $(this).children().each(function(){
85
+ $t = $(this);
86
+ col = parseInt( $t.attr('data-column'), 10);
87
+ if (!$t.filter('[' + dataAttrib + ']').length && $.inArray(col, wo.math_ignore) < 0) {
88
+ txt = ($t[0] ? $t[0].textContent : '') || $t.text();
89
+ txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ""), table);
90
+ arry.push(isNaN(txt) ? 0 : txt);
91
+ }
92
+ });
93
+ }
94
+ });
95
+ return arry;
96
+ },
97
+
98
+ recalculate : function(table, c, wo, init){
99
+ if (c && !wo.math_isUpdating) {
100
+
101
+ // add data-column attributes to all table cells
102
+ if (init) {
103
+ ts.computeColumnIndex( c.$table.children('tbody').children() );
104
+ }
105
+
106
+ // data-attribute name (defaults to data-math)
107
+ var dataAttrib = 'data-' + (wo.math_data || 'math'),
108
+
109
+ // all non-info tbody cells
110
+ $mathCells = c.$tbodies.find('[' + dataAttrib + ']');
111
+ math.mathType( table, wo, $mathCells, wo.math_priority, dataAttrib );
112
+
113
+ // only info tbody cells
114
+ $mathCells = c.$table.find('.' + c.cssInfoBlock + ', tfoot').find('[' + dataAttrib + ']');
115
+ math.mathType( table, wo, $mathCells, wo.math_priority, dataAttrib );
116
+
117
+ // find the "all" total
118
+ math.mathType( table, wo, c.$table.find('[' + dataAttrib + '^=all]'), ['all'], dataAttrib );
119
+
120
+ wo.math_isUpdating = true;
121
+ c.$table.trigger('update');
122
+ }
123
+ },
124
+
125
+ mathType : function(table, wo, $cells, priority, dataAttrib) {
126
+ if ($cells.length) {
127
+ var formula, t, $t, arry, getAll,
128
+ eq = ts.equations;
129
+ if (priority[0] === 'all') {
130
+ // no need to get all cells more than once
131
+ getAll = math.getAll(table, wo, dataAttrib);
132
+ }
133
+ $.each( priority, function(i, type) {
134
+ $cells.filter('[' + dataAttrib + '^=' + type + ']').each(function(){
135
+ $t = $(this);
136
+ formula = ($t.attr(dataAttrib) || '').replace(type + '-', '');
137
+ arry = (type === "row") ? math.getRow(table, wo, $t, dataAttrib) :
138
+ (type === "all") ? getAll : math.getColumn(table, wo, $t, type, dataAttrib);
139
+ if (eq[formula]) {
140
+ t = eq[formula](arry);
141
+ if (table.config.debug && console && console.log) {
142
+ console.log($t.attr(dataAttrib), arry, '=', t);
143
+ }
144
+ math.output( $t, wo, t, arry );
145
+ }
146
+ });
147
+ });
148
+ }
149
+ },
150
+
151
+ output : function($cell, wo, value, arry) {
152
+ var result = ts.formatMask( wo.math_mask, value );
153
+ if ($.isFunction(wo.math_complete)) {
154
+ result = wo.math_complete($cell, wo, result, value, arry);
155
+ }
156
+ if (result !== false) {
157
+ $cell.html(result);
158
+ }
159
+ }
160
+
161
+ };
162
+
163
+ // Modified from https://code.google.com/p/javascript-number-formatter/
164
+ /**
165
+ * @preserve IntegraXor Web SCADA - JavaScript Number Formatter
166
+ * http:// www.integraxor.com/
167
+ * author: KPL, KHL
168
+ * (c)2011 ecava
169
+ * Dual licensed under the MIT or GPL Version 2 licenses.
170
+ */
171
+ ts.formatMask = function(m, v){
172
+ var isNegative, result, decimal, group, pos_lead_zero, pos_trail_zero, pos_separator, part, szSep,
173
+ integer, str, offset, i, l;
174
+ if ( !m || isNaN(+v) ) {
175
+ return v; // return as it is.
176
+ }
177
+ // convert any string to number according to formation sign.
178
+ v = m.charAt(0) == '-'? -v : +v;
179
+ isNegative = v < 0 ? v = -v : 0; // process only abs(), and turn on flag.
180
+
181
+ // search for separator for grp & decimal, anything not digit, not +/- sign, not #.
182
+ result = m.match(/[^\d\-\+#]/g);
183
+ decimal = (result && result[result.length-1]) || '.'; // treat the right most symbol as decimal
184
+ group = (result && result[1] && result[0]) || ','; // treat the left most symbol as group separator
185
+
186
+ // split the decimal for the format string if any.
187
+ m = m.split( decimal );
188
+ // Fix the decimal first, toFixed will auto fill trailing zero.
189
+ v = v.toFixed( m[1] && m[1].length );
190
+ v = +(v) + ''; // convert number to string to trim off *all* trailing decimal zero(es)
191
+
192
+ // fill back any trailing zero according to format
193
+ pos_trail_zero = m[1] && m[1].lastIndexOf('0'); // look for last zero in format
194
+ part = v.split('.');
195
+ // integer will get !part[1]
196
+ if ( !part[1] || part[1] && part[1].length <= pos_trail_zero ) {
197
+ v = (+v).toFixed( pos_trail_zero + 1 );
198
+ }
199
+ szSep = m[0].split( group ); // look for separator
200
+ m[0] = szSep.join(''); // join back without separator for counting the pos of any leading 0.
201
+
202
+ pos_lead_zero = m[0] && m[0].indexOf('0');
203
+ if ( pos_lead_zero > -1 ) {
204
+ while ( part[0].length < ( m[0].length - pos_lead_zero ) ) {
205
+ part[0] = '0' + part[0];
206
+ }
207
+ } else if ( +part[0] === 0 ) {
208
+ part[0] = '';
209
+ }
210
+
211
+ v = v.split('.');
212
+ v[0] = part[0];
213
+
214
+ // process the first group separator from decimal (.) only, the rest ignore.
215
+ // get the length of the last slice of split result.
216
+ pos_separator = ( szSep[1] && szSep[ szSep.length - 1 ].length );
217
+ if (pos_separator) {
218
+ integer = v[0];
219
+ str = '';
220
+ offset = integer.length % pos_separator;
221
+ l = integer.length;
222
+ for ( i = 0; i < l; i++ ) {
223
+ str += integer.charAt(i); // ie6 only support charAt for sz.
224
+ // -pos_separator so that won't trail separator on full length
225
+ if ( !(( i - offset + 1 ) % pos_separator) && i < l - pos_separator ) {
226
+ str += group;
227
+ }
228
+ }
229
+ v[0] = str;
230
+ }
231
+
232
+ v[1] = ( m[1] && v[1] ) ? decimal + v[1] : "";
233
+ return ( isNegative ? '-' : '' ) + v[0] + v[1]; // put back any negation and combine integer and fraction.
234
+ };
235
+
236
+ ts.equations = {
237
+ count : function(arry) {
238
+ return arry.length;
239
+ },
240
+ sum : function(arry) {
241
+ var total = 0;
242
+ $.each( arry, function(i) {
243
+ total += arry[i];
244
+ });
245
+ return total;
246
+ },
247
+ mean : function(arry) {
248
+ var total = ts.equations.sum( arry );
249
+ return total / arry.length;
250
+ },
251
+ median : function(arry) {
252
+ // https://gist.github.com/caseyjustus/1166258
253
+ arry.sort( function(a,b){ return a - b; } );
254
+ var half = Math.floor( arry.length / 2 );
255
+ return (arry.length % 2) ? arry[half] : ( arry[half - 1] + arry[half] ) / 2.0;
256
+ },
257
+ mode : function(arry) {
258
+ // http://stackoverflow.com/a/3451640/145346
259
+ if ( arry.length === 0 ) { return 'none'; }
260
+ var i, el,
261
+ modeMap = {},
262
+ maxCount = 1,
263
+ modes = [arry[0]];
264
+ for (i = 0; i < arry.length; i++) {
265
+ el = arry[i];
266
+ modeMap[el] = modeMap[el] ? modeMap[el] + 1 : 1;
267
+ if ( modeMap[el] > maxCount ) {
268
+ modes = [el];
269
+ maxCount = modeMap[el];
270
+ } else if (modeMap[el] === maxCount) {
271
+ modes.push(el);
272
+ maxCount = modeMap[el];
273
+ }
274
+ }
275
+ // returns arry of modes if there is a tie
276
+ return modes.sort( function(a,b){ return a - b; } );
277
+ },
278
+ max : function(arry) {
279
+ return Math.max.apply( Math, arry );
280
+ },
281
+ min : function(arry) {
282
+ return Math.min.apply( Math, arry );
283
+ },
284
+ range: function(arry) {
285
+ var v = arry.sort(function(a,b){ return a - b; });
286
+ return v[ arry.length - 1 ] - v[0];
287
+ },
288
+ // common variance equation
289
+ // (not accessible via data-attribute setting)
290
+ variance: function(arry, population) {
291
+ var avg = ts.equations.mean( arry ),
292
+ v = 0,
293
+ i = arry.length;
294
+ while (i--) {
295
+ v += Math.pow( ( arry[i] - avg ), 2 );
296
+ }
297
+ v /= ( arry.length - (population ? 0 : 1) );
298
+ return v;
299
+ },
300
+ // variance (population)
301
+ varp : function(arry) {
302
+ return ts.equations.variance(arry, true);
303
+ },
304
+ // variance (sample)
305
+ vars : function(arry) {
306
+ return ts.equations.variance(arry);
307
+ },
308
+ // standard deviation (sample)
309
+ stdevs : function(arry) {
310
+ var vars = ts.equations.variance(arry);
311
+ return Math.sqrt( vars );
312
+ },
313
+ // standard deviation (population)
314
+ stdevp : function(arry){
315
+ var varp = ts.equations.variance(arry, true);
316
+ return Math.sqrt( varp );
317
+ }
318
+ };
319
+
320
+ // add new widget called repeatHeaders
321
+ // ************************************
322
+ ts.addWidget({
323
+ id: "math",
324
+ priority: 100,
325
+ options: {
326
+ math_data : 'math',
327
+ // column index to ignore
328
+ math_ignore : [],
329
+ // mask info: https://code.google.com/p/javascript-number-formatter/
330
+ math_mask : '#,##0.00',
331
+ // complete executed after each fucntion
332
+ math_complete : null, // function($cell, wo, result, value, arry){ return result; },
333
+ // order of calculation; "all" is last
334
+ math_priority : [ 'row', 'above', 'col' ]
335
+ },
336
+ init : function(table, thisWidget, c, wo){
337
+ c.$table
338
+ .bind('tablesorter-initialized update updateRows addRows updateCell filterReset filterEnd '.split(' ').join('.tsmath '), function(e){
339
+ if (!wo.math_isUpdating) {
340
+ math.recalculate(table, c, wo, e.type === 'tablesorter-initialized');
341
+ }
342
+ })
343
+ .bind('updateComplete.tsmath', function(){
344
+ setTimeout(function(){
345
+ wo.math_isUpdating = false;
346
+ }, 500);
347
+ });
348
+ wo.math_isUpdating = false;
349
+ },
350
+ // this remove function is called when using the refreshWidgets method or when destroying the tablesorter plugin
351
+ // this function only applies to tablesorter v2.4+
352
+ remove: function(table, c, wo){
353
+ $(table)
354
+ .unbind('tablesorter-initialized update updateRows addRows updateCell filterReset filterEnd '.split(' ').join('.tsmath '))
355
+ .find('[data-' + wo.math_data + ']').empty();
356
+ }
357
+ });
358
+
359
+ })(jQuery);