jquery-tablesorter 1.15.0 → 1.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (22) 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 +71 -30
  5. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +109 -65
  6. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +83 -62
  7. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-range.js +93 -0
  8. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +6 -4
  9. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-metric.js +1 -1
  10. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +4 -2
  11. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-html5.js +2 -2
  12. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-jui.js +2 -3
  13. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-select2.js +1 -1
  14. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-type-insideRange.js +42 -0
  15. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +57 -45
  16. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-formatter.js +1 -1
  17. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +9 -7
  18. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +9 -1
  19. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +68 -30
  20. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +41 -41
  21. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +25 -16
  22. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 434be6c4bd88f3d84bbfaa574aa004a6db18abdb
4
- data.tar.gz: 21eb848f7fd16cfb5642470af727a6fc858438c9
3
+ metadata.gz: cf80f7e8c0500b21e4c526fd87d688eb6d45d067
4
+ data.tar.gz: b6395dc3b8886d12002caa44c097c6ccd4efb8bc
5
5
  SHA512:
6
- metadata.gz: cb3b3737c7de96e57b09385a612d5c1100125ffbd5c31007e1df38b563c7dbc7bc177dfcd958c8ffdb01a6a5ea24b857e8eacbe930d52547c80206b11fdf0b2f
7
- data.tar.gz: 68cd1f4205072697210c3cacc18e078666bd9b1144b13968b944d30912f957530925f6d2a315cd7db2b2ec3475dccbb12931cfe8f030c150b21b35065c1847eb
6
+ metadata.gz: c8cb6023d3e61aa0e6184124c38642835d876e52da9eb2d5647b4e86b478f2c20669561db9e4a5ce8918c2c46ce1d0a6826aba2d061ca2b77e7f2b178a9f36b1
7
+ data.tar.gz: d79e33105295d8fa121b04d8068c27cf897594eb2e4ea8d6cb25f672d901956aa522ffb1d285607c89c3c9a0e16485668a0a67b83b1d7f89bb2d0018f20919ac
data/README.md 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.20.1 (2/20/2015), [documentation]
7
+ Current tablesorter version: 2.21.0 (3/5/2015), [documentation]
8
8
 
9
9
  Any issue associated with the js/css files, please report to [Mottie's fork].
10
10
 
@@ -1,3 +1,3 @@
1
1
  module JqueryTablesorter
2
- VERSION = '1.15.0'
2
+ VERSION = '1.16.0'
3
3
  end
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * tablesorter (FORK) pager plugin
3
- * updated 2/9/2015 (v2.19.1)
3
+ * updated 3/5/2015 (v2.21.0)
4
4
  */
5
5
  /*jshint browser:true, jquery:true, unused:false */
6
6
  ;(function($) {
@@ -135,7 +135,8 @@
135
135
  },
136
136
 
137
137
  calcFilters = function(table, p) {
138
- var c = table.config,
138
+ var normalized, indx, len,
139
+ c = table.config,
139
140
  hasFilters = c.$table.hasClass('hasFilters');
140
141
  if (hasFilters && !p.ajaxUrl) {
141
142
  if ($.isEmptyObject(c.cache)) {
@@ -143,9 +144,11 @@
143
144
  p.filteredRows = p.totalRows = c.$tbodies.eq(0).children('tr').not( p.countChildRows ? '' : '.' + c.cssChildRow ).length;
144
145
  } else {
145
146
  p.filteredRows = 0;
146
- $.each(c.cache[0].normalized, function(i, el) {
147
- p.filteredRows += p.regexRows.test(el[c.columns].$row[0].className) ? 0 : 1;
148
- });
147
+ normalized = c.cache[0].normalized;
148
+ len = normalized.length;
149
+ for (indx = 0; indx < len; indx++) {
150
+ p.filteredRows += p.regexRows.test(normalized[indx][c.columns].$row[0].className) ? 0 : 1;
151
+ }
149
152
  }
150
153
  } else if (!hasFilters) {
151
154
  p.filteredRows = p.totalRows;
@@ -154,7 +157,7 @@
154
157
 
155
158
  updatePageDisplay = function(table, p, completed) {
156
159
  if ( p.initializing ) { return; }
157
- var s, t, $out,
160
+ var s, t, $out, indx, len, options,
158
161
  c = table.config,
159
162
  sz = p.size || p.settings.size || 10; // don't allow dividing by zero
160
163
  if (p.countChildRows) { t.push(c.cssChildRow); }
@@ -192,9 +195,11 @@
192
195
  });
193
196
  if ( p.$goto.length ) {
194
197
  t = '';
195
- $.each(buildPageSelect(p), function(i, opt){
196
- t += '<option value="' + opt + '">' + opt + '</option>';
197
- });
198
+ options = buildPageSelect(p);
199
+ len = options.length;
200
+ for (indx = 0; indx < len; indx++) {
201
+ t += '<option value="' + options[indx] + '">' + options[indx] + '</option>';
202
+ }
198
203
  // innerHTML doesn't work in IE9 - http://support2.microsoft.com/kb/276228
199
204
  p.$goto.html(t).val( p.page + 1 );
200
205
  }
@@ -211,6 +216,9 @@
211
216
  pagerArrows(p);
212
217
  fixHeight(table, p);
213
218
  if (p.initialized && completed !== false) {
219
+ if (c.debug) {
220
+ ts.log('Pager: Triggering pagerComplete');
221
+ }
214
222
  c.$table.trigger('pagerComplete', p);
215
223
  // save pager info to storage
216
224
  if (p.savePages && ts.storage) {
@@ -381,7 +389,7 @@
381
389
 
382
390
  if ( exception ) {
383
391
  if (c.debug) {
384
- ts.log('Ajax Error', xhr, exception);
392
+ ts.log('Pager: >> Ajax Error', xhr, exception);
385
393
  }
386
394
  ts.showError(table,
387
395
  xhr.status === 0 ? 'Not connected, verify Network' :
@@ -476,6 +484,9 @@
476
484
  // apply widgets after table has rendered & after a delay to prevent
477
485
  // multiple applyWidget blocking code from blocking this trigger
478
486
  setTimeout(function(){
487
+ if (c.debug) {
488
+ ts.log('Pager: Triggering pagerChange');
489
+ }
479
490
  $t
480
491
  .trigger('applyWidgets')
481
492
  .trigger('pagerChange', p);
@@ -488,6 +499,9 @@
488
499
  if (!p.initialized) {
489
500
  p.initialized = true;
490
501
  p.initializing = false;
502
+ if (table.config.debug) {
503
+ ts.log('Pager: Triggering pagerInitialized');
504
+ }
491
505
  $(table)
492
506
  .trigger('applyWidgets')
493
507
  .trigger('pagerInitialized', p);
@@ -525,48 +539,51 @@
525
539
  }
526
540
  };
527
541
  if (c.debug) {
528
- ts.log('ajax initialized', p.ajaxObject);
542
+ ts.log('Pager: Ajax initialized', p.ajaxObject);
529
543
  }
530
544
  $.ajax(p.ajaxObject);
531
545
  }
532
546
  },
533
547
 
534
548
  getAjaxUrl = function(table, p) {
535
- var c = table.config,
549
+ var indx, len,
550
+ c = table.config,
536
551
  url = (p.ajaxUrl) ? p.ajaxUrl
537
552
  // allow using "{page+1}" in the url string to switch to a non-zero based index
538
553
  .replace(/\{page([\-+]\d+)?\}/, function(s,n){ return p.page + (n ? parseInt(n, 10) : 0); })
539
554
  .replace(/\{size\}/g, p.size) : '',
540
- sl = c.sortList,
541
- fl = p.currentFilters || $(table).data('lastSearch') || [],
555
+ sortList = c.sortList,
556
+ filterList = p.currentFilters || $(table).data('lastSearch') || [],
542
557
  sortCol = url.match(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/),
543
558
  filterCol = url.match(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/),
544
559
  arry = [];
545
560
  if (sortCol) {
546
561
  sortCol = sortCol[1];
547
- $.each(sl, function(i,v){
548
- arry.push(sortCol + '[' + v[0] + ']=' + v[1]);
549
- });
562
+ len = sortList.length;
563
+ for (indx = 0; indx < len; indx++) {
564
+ arry.push(sortCol + '[' + sortList[indx][0] + ']=' + sortList[indx][1]);
565
+ }
550
566
  // if the arry is empty, just add the col parameter... "&{sortList:col}" becomes "&col"
551
567
  url = url.replace(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : sortCol );
552
568
  arry = [];
553
569
  }
554
570
  if (filterCol) {
555
571
  filterCol = filterCol[1];
556
- $.each(fl, function(i,v){
557
- if (v) {
558
- arry.push(filterCol + '[' + i + ']=' + encodeURIComponent(v));
572
+ len = filterList.length;
573
+ for (indx = 0; indx < len; indx++) {
574
+ if (filterList[indx]) {
575
+ arry.push(filterCol + '[' + indx + ']=' + encodeURIComponent(filterList[indx]));
559
576
  }
560
- });
577
+ }
561
578
  // if the arry is empty, just add the fcol parameter... "&{filterList:fcol}" becomes "&fcol"
562
579
  url = url.replace(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : filterCol );
563
- p.currentFilters = fl;
580
+ p.currentFilters = filterList;
564
581
  }
565
582
  if ( typeof(p.customAjaxUrl) === "function" ) {
566
583
  url = p.customAjaxUrl(table, url);
567
584
  }
568
585
  if (c.debug) {
569
- ts.log('Pager ajax url: ' + url);
586
+ ts.log('Pager: Ajax url = ' + url);
570
587
  }
571
588
  return url;
572
589
  },
@@ -581,7 +598,7 @@
581
598
  e = p.size;
582
599
  if ( l < 1 ) {
583
600
  if (c.debug) {
584
- ts.log('Pager: no rows for pager to render');
601
+ ts.log('Pager: >> No rows for pager to render');
585
602
  }
586
603
  // empty table, abort!
587
604
  return;
@@ -592,7 +609,12 @@
592
609
  }
593
610
  p.cacheIndex = [];
594
611
  p.isDisabled = false; // needed because sorting will change the page and re-enable the pager
595
- if (p.initialized) { $t.trigger('pagerChange', p); }
612
+ if (p.initialized) {
613
+ if (c.debug) {
614
+ ts.log('Pager: Triggering pagerChange');
615
+ }
616
+ $t.trigger('pagerChange', p);
617
+ }
596
618
 
597
619
  if ( !p.removeRows ) {
598
620
  hideRows(table, p);
@@ -619,6 +641,9 @@
619
641
  }
620
642
  updatePageDisplay(table, p);
621
643
  if (table.isUpdating) {
644
+ if (c.debug) {
645
+ ts.log('Pager: Triggering updateComplete');
646
+ }
622
647
  $t.trigger('updateComplete', [ table, true ]);
623
648
  }
624
649
  },
@@ -640,7 +665,7 @@
640
665
  renderTable(table, table.config.rowsCopy, p);
641
666
  $(table).trigger('applyWidgets');
642
667
  if (table.config.debug) {
643
- ts.log('pager disabled');
668
+ ts.log('Pager: Disabled');
644
669
  }
645
670
  }
646
671
  // disable size selector
@@ -694,7 +719,7 @@
694
719
  (l.optAjaxUrl || '') === (p.ajaxUrl || '') &&
695
720
  l.sortList === (c.sortList || []).join(',') ) { return; }
696
721
  if (c.debug) {
697
- ts.log('Pager changing to page ' + p.page);
722
+ ts.log('Pager: Changing to page ' + p.page);
698
723
  }
699
724
  p.last = {
700
725
  page : p.page,
@@ -713,10 +738,16 @@
713
738
  }
714
739
  $.data(table, 'pagerLastPage', p.page);
715
740
  if (p.initialized && pageMoved !== false) {
741
+ if (c.debug) {
742
+ ts.log('Pager: Triggering pageMoved');
743
+ }
716
744
  $t
717
745
  .trigger('pageMoved', p)
718
746
  .trigger('applyWidgets');
719
747
  if (table.isUpdating) {
748
+ if (c.debug) {
749
+ ts.log('Pager: Triggering updateComplete');
750
+ }
720
751
  $t.trigger('updateComplete', [ table, true ]);
721
752
  }
722
753
  }
@@ -794,7 +825,7 @@
794
825
  setPageSize(table, p.size, p);
795
826
  hideRowsSetup(table, p);
796
827
  if (c.debug) {
797
- ts.log('pager enabled');
828
+ ts.log('Pager: Enabled');
798
829
  }
799
830
  }
800
831
  };
@@ -828,7 +859,7 @@
828
859
  // save a copy of the original settings
829
860
  p.settings = $.extend( true, {}, $.tablesorterPager.defaults, settings );
830
861
  if (c.debug) {
831
- ts.log('Pager initializing');
862
+ ts.log('Pager: Initializing');
832
863
  }
833
864
  p.oldAjaxSuccess = p.oldAjaxSuccess || p.ajaxObject.success;
834
865
  c.appender = $this.appender;
@@ -921,6 +952,9 @@
921
952
  // clicked controls
922
953
  ctrls = [ p.cssFirst, p.cssPrev, p.cssNext, p.cssLast ];
923
954
  fxn = [ moveToFirstPage, moveToPrevPage, moveToNextPage, moveToLastPage ];
955
+ if (c.debug && !pager.length) {
956
+ ts.log('Pager: >> Container not found');
957
+ }
924
958
  pager.find(ctrls.join(','))
925
959
  .attr("tabindex", 0)
926
960
  .unbind('click.pager')
@@ -947,6 +981,8 @@
947
981
  moveToPage(table, p, true);
948
982
  updatePageDisplay(table, p, false);
949
983
  });
984
+ } else if (c.debug) {
985
+ ts.log('Pager: >> Goto selector not found');
950
986
  }
951
987
 
952
988
  // page size selector
@@ -962,6 +998,8 @@
962
998
  }
963
999
  return false;
964
1000
  });
1001
+ } else if (c.debug) {
1002
+ ts.log('Pager: >> Size selector not found');
965
1003
  }
966
1004
 
967
1005
  // clear initialized flag
@@ -989,7 +1027,10 @@
989
1027
  p.initializing = false;
990
1028
  p.initialized = true;
991
1029
  moveToPage(table, p);
992
- $(table).trigger('pagerInitialized', p);
1030
+ if (c.debug) {
1031
+ ts.log('Pager: Triggering pagerInitialized');
1032
+ }
1033
+ c.$table.trigger('pagerInitialized', p);
993
1034
  if ( !( c.widgetOptions.filter_initialized && ts.hasWidget(table, 'filter') ) ) {
994
1035
  updatePageDisplay(table, p, false);
995
1036
  }
@@ -1,4 +1,4 @@
1
- /*! TableSorter (FORK) v{{version}} *//*
1
+ /*! TableSorter (FORK) v2.21.0 *//*
2
2
  * Client-side table sorting with ease!
3
3
  * @requires jQuery v1.2.6+
4
4
  *
@@ -34,7 +34,7 @@
34
34
 
35
35
  var ts = this;
36
36
 
37
- ts.version = '{{version}}';
37
+ ts.version = '2.21.0';
38
38
 
39
39
  ts.parsers = [];
40
40
  ts.widgets = [];
@@ -154,6 +154,9 @@
154
154
  nextNone : 'activate to remove the sort'
155
155
  };
156
156
 
157
+ // These methods can be applied on table.config instance
158
+ ts.instanceMethods = {};
159
+
157
160
  /* debuging utils */
158
161
  function log() {
159
162
  var a = arguments[0],
@@ -256,7 +259,7 @@
256
259
  if (rows.length) {
257
260
  l = c.columns; // rows[j].cells.length;
258
261
  for (i = 0; i < l; i++) {
259
- h = c.$headers.filter('[data-column="' + i + '"]:last');
262
+ h = c.$headerIndexed[i];
260
263
  // get column indexed table cell
261
264
  ch = ts.getColumnData( table, c.headers, i );
262
265
  // get column parser/extractor
@@ -445,8 +448,7 @@
445
448
  }
446
449
 
447
450
  function buildHeaders(table) {
448
- var ch, $t,
449
- h, i, t, lock, time,
451
+ var ch, $t, h, i, t, lock, time, indx,
450
452
  c = table.config;
451
453
  c.headerList = [];
452
454
  c.headerContent = [];
@@ -495,6 +497,13 @@
495
497
  if (c.tabIndex) { $t.attr('tabindex', 0); }
496
498
  return elem;
497
499
  }));
500
+ // cache headers per column
501
+ c.$headerIndexed = [];
502
+ for (indx = 0; indx < c.columns; indx++) {
503
+ $t = c.$headers.filter('[data-column="' + indx + '"]');
504
+ // target sortable column cells, unless there are none, then use non-sortable cells
505
+ c.$headerIndexed[indx] = $t.not('.sorter-false').length ? $t.not('.sorter-false').last() : $t.last();
506
+ }
498
507
  $(table).find(c.selectorHeaders).attr({
499
508
  scope: 'col',
500
509
  role : 'columnheader'
@@ -592,49 +601,51 @@
592
601
  });
593
602
  }
594
603
 
595
- function updateHeaderSortCount(table, list) {
596
- var s, t, o, col, primary,
604
+ function updateHeaderSortCount( table, list ) {
605
+ var col, dir, group, header, indx, primary, temp, val,
597
606
  c = table.config,
598
- sl = list || c.sortList;
607
+ sortList = list || c.sortList,
608
+ len = sortList.length;
599
609
  c.sortList = [];
600
- $.each(sl, function(i,v){
610
+ for (indx = 0; indx < len; indx++) {
611
+ val = sortList[indx];
601
612
  // ensure all sortList values are numeric - fixes #127
602
- col = parseInt(v[0], 10);
613
+ col = parseInt(val[0], 10);
603
614
  // make sure header exists
604
- o = c.$headers.filter('[data-column="' + col + '"]:last')[0];
605
- if (o) { // prevents error if sorton array is wrong
615
+ header = c.$headerIndexed[col][0];
616
+ if (header) { // prevents error if sorton array is wrong
606
617
  // o.count = o.count + 1;
607
- t = ('' + v[1]).match(/^(1|d|s|o|n)/);
608
- t = t ? t[0] : '';
618
+ dir = ('' + val[1]).match(/^(1|d|s|o|n)/);
619
+ dir = dir ? dir[0] : '';
609
620
  // 0/(a)sc (default), 1/(d)esc, (s)ame, (o)pposite, (n)ext
610
- switch(t) {
621
+ switch(dir) {
611
622
  case '1': case 'd': // descending
612
- t = 1;
623
+ dir = 1;
613
624
  break;
614
625
  case 's': // same direction (as primary column)
615
626
  // if primary sort is set to 's', make it ascending
616
- t = primary || 0;
627
+ dir = primary || 0;
617
628
  break;
618
629
  case 'o':
619
- s = o.order[(primary || 0) % (c.sortReset ? 3 : 2)];
630
+ temp = header.order[(primary || 0) % (c.sortReset ? 3 : 2)];
620
631
  // opposite of primary column; but resets if primary resets
621
- t = s === 0 ? 1 : s === 1 ? 0 : 2;
632
+ dir = temp === 0 ? 1 : temp === 1 ? 0 : 2;
622
633
  break;
623
634
  case 'n':
624
- o.count = o.count + 1;
625
- t = o.order[(o.count) % (c.sortReset ? 3 : 2)];
635
+ header.count = header.count + 1;
636
+ dir = header.order[(header.count) % (c.sortReset ? 3 : 2)];
626
637
  break;
627
638
  default: // ascending
628
- t = 0;
639
+ dir = 0;
629
640
  break;
630
641
  }
631
- primary = i === 0 ? t : primary;
632
- s = [ col, parseInt(t, 10) || 0 ];
633
- c.sortList.push(s);
634
- t = $.inArray(s[1], o.order); // fixes issue #167
635
- o.count = t >= 0 ? t : s[1] % (c.sortReset ? 3 : 2);
642
+ primary = indx === 0 ? dir : primary;
643
+ group = [ col, parseInt(dir, 10) || 0 ];
644
+ c.sortList.push(group);
645
+ dir = $.inArray(group[1], header.order); // fixes issue #167
646
+ header.count = dir >= 0 ? dir : group[1] % (c.sortReset ? 3 : 2);
636
647
  }
637
- });
648
+ }
638
649
  }
639
650
 
640
651
  function getCachedSortType(parsers, i) {
@@ -705,7 +716,7 @@
705
716
  // reverse the sorting direction
706
717
  for (col = 0; col < c.sortList.length; col++) {
707
718
  s = c.sortList[col];
708
- order = c.$headers.filter('[data-column="' + s[0] + '"]:last')[0];
719
+ order = c.$headerIndexed[ s[0] ][0];
709
720
  if (s[0] === indx) {
710
721
  // order.count seems to be incorrect when compared to cell.count
711
722
  s[1] = order.order[cell.count];
@@ -1051,7 +1062,7 @@
1051
1062
  return this.each(function() {
1052
1063
  var table = this,
1053
1064
  // merge & extend config options
1054
- c = $.extend(true, {}, ts.defaults, settings);
1065
+ c = $.extend(true, {}, ts.defaults, settings, ts.instanceMethods);
1055
1066
  // save initial settings
1056
1067
  c.originalSettings = settings;
1057
1068
  // create a table from data (build table widget)
@@ -1129,6 +1140,8 @@
1129
1140
  // fixate columns if the users supplies the fixedWidth option
1130
1141
  // do this after theme has been applied
1131
1142
  ts.fixColumnWidth(table);
1143
+ // add widget options before parsing (e.g. grouping widget has parser settings)
1144
+ ts.applyWidgetOptions(table, c);
1132
1145
  // try to auto detect column type, and store in tables config
1133
1146
  buildParserCache(table);
1134
1147
  // start total row count at zero
@@ -1600,6 +1613,12 @@
1600
1613
  }
1601
1614
  };
1602
1615
 
1616
+ // Use it to add a set of methods to table.config which will be available for all tables.
1617
+ // This should be done before table initialization
1618
+ ts.addInstanceMethods = function(methods) {
1619
+ $.extend(ts.instanceMethods, methods);
1620
+ };
1621
+
1603
1622
  ts.getParserById = function(name) {
1604
1623
  /*jshint eqeqeq:false */
1605
1624
  if (name == 'false') { return false; }
@@ -1631,9 +1650,24 @@
1631
1650
  }
1632
1651
  };
1633
1652
 
1653
+ ts.applyWidgetOptions = function( table, c ){
1654
+ var indx, widget,
1655
+ len = c.widgets.length,
1656
+ wo = c.widgetOptions;
1657
+ if (len) {
1658
+ for (indx = 0; indx < len; indx++) {
1659
+ widget = ts.getWidgetById( c.widgets[indx] );
1660
+ if ( widget && 'options' in widget ) {
1661
+ wo = table.config.widgetOptions = $.extend( true, {}, widget.options, wo );
1662
+ }
1663
+ }
1664
+ }
1665
+ };
1666
+
1634
1667
  ts.applyWidget = function(table, init, callback) {
1635
1668
  table = $(table)[0]; // in case this is called externally
1636
- var c = table.config,
1669
+ var indx, len, name,
1670
+ c = table.config,
1637
1671
  wo = c.widgetOptions,
1638
1672
  tableClass = ' ' + c.table.className + ' ',
1639
1673
  widgets = [],
@@ -1648,9 +1682,10 @@
1648
1682
  // extract out the widget id from the table class (widget id's can include dashes)
1649
1683
  w = tableClass.match( wd );
1650
1684
  if ( w ) {
1651
- $.each( w, function( i,n ){
1652
- c.widgets.push( n.replace( wd, '$1' ) );
1653
- });
1685
+ len = w.length;
1686
+ for (indx = 0; indx < len; indx++) {
1687
+ c.widgets.push( w[indx].replace( wd, '$1' ) );
1688
+ }
1654
1689
  }
1655
1690
  }
1656
1691
  if (c.widgets.length) {
@@ -1659,41 +1694,45 @@
1659
1694
  c.widgets = $.grep(c.widgets, function(v, k){
1660
1695
  return $.inArray(v, c.widgets) === k;
1661
1696
  });
1697
+ name = c.widgets || [];
1698
+ len = name.length;
1662
1699
  // build widget array & add priority as needed
1663
- $.each(c.widgets || [], function(i,n){
1664
- wd = ts.getWidgetById(n);
1700
+ for (indx = 0; indx < len; indx++) {
1701
+ wd = ts.getWidgetById(name[indx]);
1665
1702
  if (wd && wd.id) {
1666
1703
  // set priority to 10 if not defined
1667
1704
  if (!wd.priority) { wd.priority = 10; }
1668
- widgets[i] = wd;
1705
+ widgets[indx] = wd;
1669
1706
  }
1670
- });
1707
+ }
1671
1708
  // sort widgets by priority
1672
1709
  widgets.sort(function(a, b){
1673
1710
  return a.priority < b.priority ? -1 : a.priority === b.priority ? 0 : 1;
1674
1711
  });
1675
1712
  // add/update selected widgets
1676
- $.each(widgets, function(i,w){
1677
- if (w) {
1678
- if (init || !(c.widgetInit[w.id])) {
1713
+ len = widgets.length;
1714
+ for (indx = 0; indx < len; indx++) {
1715
+ if (widgets[indx]) {
1716
+ if ( init || !( c.widgetInit[ widgets[indx].id ] ) ) {
1679
1717
  // set init flag first to prevent calling init more than once (e.g. pager)
1680
- c.widgetInit[w.id] = true;
1681
- if (w.hasOwnProperty('options')) {
1682
- wo = table.config.widgetOptions = $.extend( true, {}, w.options, wo );
1718
+ c.widgetInit[ widgets[indx].id ] = true;
1719
+ if (table.hasInitialized) {
1720
+ // don't reapply widget options on tablesorter init
1721
+ ts.applyWidgetOptions( table, c );
1683
1722
  }
1684
- if (w.hasOwnProperty('init')) {
1723
+ if ( 'init' in widgets[indx] ) {
1685
1724
  if (c.debug) { time2 = new Date(); }
1686
- w.init(table, w, c, wo);
1687
- if (c.debug) { ts.benchmark('Initializing ' + w.id + ' widget', time2); }
1725
+ widgets[indx].init(table, widgets[indx], c, wo);
1726
+ if (c.debug) { ts.benchmark('Initializing ' + widgets[indx].id + ' widget', time2); }
1688
1727
  }
1689
1728
  }
1690
- if (!init && w.hasOwnProperty('format')) {
1729
+ if ( !init && 'format' in widgets[indx] ) {
1691
1730
  if (c.debug) { time2 = new Date(); }
1692
- w.format(table, c, wo, false);
1693
- if (c.debug) { ts.benchmark( ( init ? 'Initializing ' : 'Applying ' ) + w.id + ' widget', time2); }
1731
+ widgets[indx].format(table, c, wo, false);
1732
+ if (c.debug) { ts.benchmark( ( init ? 'Initializing ' : 'Applying ' ) + widgets[indx].id + ' widget', time2); }
1694
1733
  }
1695
1734
  }
1696
- });
1735
+ }
1697
1736
  // callback executed on init only
1698
1737
  if (!init && typeof callback === 'function') {
1699
1738
  callback(table);
@@ -1711,29 +1750,31 @@
1711
1750
 
1712
1751
  ts.removeWidget = function(table, name, refreshing){
1713
1752
  table = $(table)[0];
1753
+ var i, widget, indx, len,
1754
+ c = table.config;
1714
1755
  // if name === true, add all widgets from $.tablesorter.widgets
1715
1756
  if (name === true) {
1716
1757
  name = [];
1717
- $.each( ts.widgets, function(i, w){
1718
- if (w && w.id) {
1719
- name.push( w.id );
1758
+ len = ts.widgets.length;
1759
+ for (indx = 0; indx < len; indx++) {
1760
+ widget = ts.widgets[indx];
1761
+ if (widget && widget.id) {
1762
+ name.push( widget.id );
1720
1763
  }
1721
- });
1764
+ }
1722
1765
  } else {
1723
1766
  // name can be either an array of widgets names,
1724
1767
  // or a space/comma separated list of widget names
1725
1768
  name = ( $.isArray(name) ? name.join(',') : name || '' ).toLowerCase().split( /[\s,]+/ );
1726
1769
  }
1727
- var i, widget, indx,
1728
- c = table.config,
1729
- len = name.length;
1770
+ len = name.length;
1730
1771
  for (i = 0; i < len; i++) {
1731
1772
  widget = ts.getWidgetById(name[i]);
1732
1773
  indx = $.inArray( name[i], c.widgets );
1733
1774
  if ( widget && 'remove' in widget ) {
1734
1775
  if (c.debug && indx >= 0) { log( 'Removing "' + name[i] + '" widget' ); }
1735
1776
  widget.remove(table, c, c.widgetOptions, refreshing);
1736
- c.widgetInit[name[i]] = false;
1777
+ c.widgetInit[ name[i] ] = false;
1737
1778
  }
1738
1779
  // don't remove the widget from config.widget if refreshing
1739
1780
  if (indx >= 0 && refreshing !== true) {
@@ -1744,18 +1785,21 @@
1744
1785
 
1745
1786
  ts.refreshWidgets = function(table, doAll, dontapply) {
1746
1787
  table = $(table)[0]; // see issue #243
1747
- var c = table.config,
1788
+ var indx,
1789
+ c = table.config,
1748
1790
  cw = c.widgets,
1791
+ widgets = ts.widgets,
1792
+ len = widgets.length,
1749
1793
  list = [],
1750
1794
  callback = function(table){
1751
1795
  $(table).trigger('refreshComplete');
1752
1796
  };
1753
1797
  // remove widgets not defined in config.widgets, unless doAll is true
1754
- $.each( ts.widgets, function(i, w){
1755
- if (w && w.id && (doAll || $.inArray( w.id, cw ) < 0)) {
1756
- list.push( w.id );
1798
+ for (indx = 0; indx < len; indx++) {
1799
+ if (widgets[indx] && widgets[indx].id && (doAll || $.inArray( widgets[indx].id, cw ) < 0)) {
1800
+ list.push( widgets[indx].id );
1757
1801
  }
1758
- });
1802
+ }
1759
1803
  ts.removeWidget( table, list.join(','), true );
1760
1804
  if (dontapply !== true) {
1761
1805
  // call widget init if
@@ -1955,7 +1999,7 @@
1955
1999
  if (s) {
1956
2000
  var date, d,
1957
2001
  c = table.config,
1958
- ci = c.$headers.filter('[data-column="' + cellIndex + '"]:last'),
2002
+ ci = c.$headerIndexed[ cellIndex ],
1959
2003
  format = ci.length && ci[0].dateFormat || ts.getData( ci, ts.getColumnData( table, c.headers, cellIndex ), 'dateFormat') || c.dateFormat;
1960
2004
  d = s.replace(/\s+/g, ' ').replace(/[\-.,]/g, '/'); // escaped - because JSHint in Firefox was showing it as an error
1961
2005
  if (format === 'mmddyyyy') {