jquery-tablesorter 1.23.15 → 1.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0174cfbb069870781ff7190466a647e1c2adef6d
4
- data.tar.gz: 1c3148a7b59d0668953057219e279d5b4c2613b1
3
+ metadata.gz: fd2f6d679b0523149759cc69b1b95cb25ca39e65
4
+ data.tar.gz: 86b19e6a3167c07baf0d90e3ab2d8993da19c625
5
5
  SHA512:
6
- metadata.gz: 81c10902e944af29caa6b34b187a889212fabe87eb89147562cb8c2ac9472129474acd8d614e8f71eddeac3527d4d3cf73ee062dd4a3c914d621e2f1981660f4
7
- data.tar.gz: ca0b113781b19faf0bab7b4b49a67cd93a76f1bfe89edceebe79ee28c66988009b65e3f169c7a44e947c211022a63811cb8210895803627fc42fabd023194451
6
+ metadata.gz: f26ac12515b165ac9e47c2cefac141a377a48f1d00be50f71bf62afc75a767d0b6ff795e3564f70465de4129119c9d3b81c2136d984edaced5fd2b9695bb6c55
7
+ data.tar.gz: bb9343e62a716614e84c5ba8f450d25af4d1c6e965e02fecc2a35b7ace98654f1e7ab5025a7f9f87421c3ff075d46caa0b630ae8ccf593076394338809bd423a
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Simple integration of jQuery tablesorter ([Mottie's fork]) into the asset pipeline.
6
6
 
7
- Current tablesorter version: 2.28.15 (7/4/2017) [documentation]
7
+ Current tablesorter version: 2.29.0 (9/27/2017) [documentation]
8
8
 
9
9
  Any issue associated with the js/css files, please report to [Mottie's fork].
10
10
 
@@ -1,7 +1,7 @@
1
1
  module JqueryTablesorter
2
2
  MAJOR = 1
3
- MINOR = 23
4
- TINY = 15
3
+ MINOR = 24
4
+ TINY = 0
5
5
 
6
6
  VERSION = [MAJOR, MINOR, TINY].compact.join('.')
7
7
  end
@@ -4,7 +4,7 @@
4
4
  ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██▀▀ ▀▀▀██
5
5
  █████▀ ▀████▀ ██ ██ ▀████▀ ██ ██ ██ ██ ▀████▀ █████▀ ██ ██ █████▀
6
6
  */
7
- /*! tablesorter (FORK) - updated 07-04-2017 (v2.28.15)*/
7
+ /*! tablesorter (FORK) - updated 09-27-2017 (v2.29.0)*/
8
8
  /* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
9
9
  (function(factory) {
10
10
  if (typeof define === 'function' && define.amd) {
@@ -16,7 +16,7 @@
16
16
  }
17
17
  }(function(jQuery) {
18
18
 
19
- /*! TableSorter (FORK) v2.28.15 *//*
19
+ /*! TableSorter (FORK) v2.29.0 *//*
20
20
  * Client-side table sorting with ease!
21
21
  * @requires jQuery v1.2.6+
22
22
  *
@@ -40,7 +40,7 @@
40
40
  'use strict';
41
41
  var ts = $.tablesorter = {
42
42
 
43
- version : '2.28.15',
43
+ version : '2.29.0',
44
44
 
45
45
  parsers : [],
46
46
  widgets : [],
@@ -439,10 +439,10 @@
439
439
  e.stopPropagation();
440
440
  ts.applyWidgetId( this, id );
441
441
  })
442
- .bind( 'applyWidgets' + namespace, function( e, init ) {
442
+ .bind( 'applyWidgets' + namespace, function( e, callback ) {
443
443
  e.stopPropagation();
444
- // apply widgets
445
- ts.applyWidget( this, init );
444
+ // apply widgets (false = not initializing)
445
+ ts.applyWidget( this, false, callback );
446
446
  })
447
447
  .bind( 'refreshWidgets' + namespace, function( e, all, dontapply ) {
448
448
  e.stopPropagation();
@@ -479,9 +479,9 @@
479
479
  downTarget = null;
480
480
  if ( core !== true ) {
481
481
  $headers.addClass( namespace.slice( 1 ) + '_extra_headers' );
482
- tmp = $.fn.closest ? $headers.closest( 'table' )[ 0 ] : $headers.parents( 'table' )[ 0 ];
483
- if ( tmp && tmp.nodeName === 'TABLE' && tmp !== table ) {
484
- $( tmp ).addClass( namespace.slice( 1 ) + '_extra_table' );
482
+ tmp = ts.getClosest( $headers, 'table' );
483
+ if ( tmp.length && tmp[ 0 ].nodeName === 'TABLE' && tmp[ 0 ] !== table ) {
484
+ $( tmp[ 0 ] ).addClass( namespace.slice( 1 ) + '_extra_table' );
485
485
  }
486
486
  }
487
487
  tmp = ( c.pointerDown + ' ' + c.pointerUp + ' ' + c.pointerClick + ' sort keyup ' )
@@ -533,8 +533,7 @@
533
533
  ts.buildCache( c );
534
534
  }
535
535
  // jQuery v1.2.6 doesn't have closest()
536
- $cell = $.fn.closest ? $( this ).closest( 'th, td' ) :
537
- /TH|TD/.test( this.nodeName ) ? $( this ) : $( this ).parents( 'th, td' );
536
+ $cell = ts.getHeaderCell( $( this ) );
538
537
  // reference original table headers and find the same cell
539
538
  // don't use $headers or IE8 throws an error - see #987
540
539
  temp = $headers.index( $cell );
@@ -574,7 +573,7 @@
574
573
  '';
575
574
  // redefine c.$headers here in case of an updateAll that replaces or adds an entire header cell - see #683
576
575
  c.$headers = $( $.map( c.$table.find( c.selectorHeaders ), function( elem, index ) {
577
- var configHeaders, header, column, template, tmp,
576
+ var configHeaders, header, column, template, tmp, $th,
578
577
  $elem = $( elem );
579
578
  // ignore cell (don't add it to c.$headers) if row has ignoreRow class
580
579
  if ( $elem.parent().hasClass( c.cssIgnoreRow ) ) { return; }
@@ -600,7 +599,9 @@
600
599
  if ( c.onRenderHeader ) {
601
600
  c.onRenderHeader.apply( $elem, [ index, c, c.$table ] );
602
601
  }
603
- column = parseInt( $elem.attr( 'data-column' ), 10 );
602
+ // data-column stored on th or td only
603
+ $th = ts.getHeaderCell( $elem );
604
+ column = parseInt( $th.attr( 'data-column' ), 10 );
604
605
  elem.column = column;
605
606
  tmp = ts.getOrder( ts.getData( $elem, configHeaders, 'sortInitialOrder' ) || c.sortInitialOrder );
606
607
  // this may get updated numerous times if there are multiple rows
@@ -618,10 +619,9 @@
618
619
  }
619
620
  // add cell to headerList
620
621
  c.headerList[ index ] = elem;
622
+ $elem.addClass( ts.css.header + ' ' + c.cssHeader );
621
623
  // add to parent in case there are multiple rows
622
- $elem
623
- .addClass( ts.css.header + ' ' + c.cssHeader )
624
- .parent()
624
+ ts.getClosest( $elem, 'tr' )
625
625
  .addClass( ts.css.headerRow + ' ' + c.cssHeaderRow )
626
626
  .attr( 'role', 'row' );
627
627
  // allow keyboard cursor to focus on element
@@ -1179,10 +1179,29 @@
1179
1179
  }
1180
1180
  },
1181
1181
 
1182
+ // This function does NOT return closest if the $el matches the selector
1183
+ getClosest : function( $el, selector ) {
1184
+ return $.fn.closest ?
1185
+ $el.closest( selector ) :
1186
+ $el.parents( selector ).filter( ':first' );
1187
+ },
1188
+
1189
+ getHeaderCell : function( $el ) {
1190
+ // jQuery v1.2.6 doesn't have closest()
1191
+ if ( $.fn.closest ) {
1192
+ return $el.closest( 'th, td' );
1193
+ }
1194
+ return /TH|TD/.test( $el[0].nodeName ) ?
1195
+ $el :
1196
+ $el.parents( 'th, td' ).filter( ':first' );
1197
+ },
1198
+
1182
1199
  // nextSort (optional), lets you disable next sort text
1183
1200
  setColumnAriaLabel : function( c, $header, nextSort ) {
1184
1201
  if ( $header.length ) {
1185
- var column = parseInt( $header.attr( 'data-column' ), 10 ),
1202
+ var $th = ts.getHeaderCell( $header ),
1203
+ // data-column always stored on the th/td
1204
+ column = parseInt( $th.attr( 'data-column' ), 10 ),
1186
1205
  vars = c.sortVars[ column ],
1187
1206
  tmp = $header.hasClass( ts.css.sortAsc ) ?
1188
1207
  'sortAsc' :
@@ -1340,10 +1359,9 @@
1340
1359
  $cell = $( cell ),
1341
1360
  // update cache - format: function( s, table, cell, cellIndex )
1342
1361
  // no closest in jQuery v1.2.6
1343
- tbodyIndex = $tbodies
1344
- .index( $.fn.closest ? $cell.closest( 'tbody' ) : $cell.parents( 'tbody' ).filter( ':first' ) ),
1362
+ tbodyIndex = $tbodies.index( ts.getClosest( $cell, 'tbody' ) ),
1345
1363
  tbcache = c.cache[ tbodyIndex ],
1346
- $row = $.fn.closest ? $cell.closest( 'tr' ) : $cell.parents( 'tr' ).filter( ':first' );
1364
+ $row = ts.getClosest( $cell, 'tr' );
1347
1365
  cell = $cell[ 0 ]; // in case cell is a jQuery object
1348
1366
  // tbody may not exist if update is initialized while tbody is removed for processing
1349
1367
  if ( $tbodies.length && tbodyIndex >= 0 ) {
@@ -1398,11 +1416,13 @@
1398
1416
  if ( valid ) {
1399
1417
  $row = $( $row );
1400
1418
  c.$tbodies.append( $row );
1401
- } else if ( !$row ||
1419
+ } else if (
1420
+ !$row ||
1402
1421
  // row is a jQuery object?
1403
1422
  !( $row instanceof jQuery ) ||
1404
1423
  // row contained in the table?
1405
- ( $.fn.closest ? $row.closest( 'table' )[ 0 ] : $row.parents( 'table' )[ 0 ] ) !== c.table ) {
1424
+ ( ts.getClosest( $row, 'table' )[ 0 ] !== c.table )
1425
+ ) {
1406
1426
  if ( c.debug ) {
1407
1427
  console.error( 'addRows method requires (1) a jQuery selector reference to rows that have already ' +
1408
1428
  'been added to the table, or (2) row HTML string to be added to a table with only one tbody' );
@@ -1549,10 +1569,10 @@
1549
1569
  notMultiSort = !event[ c.sortMultiSortKey ],
1550
1570
  table = c.table,
1551
1571
  len = c.$headers.length,
1552
- // get current column index
1553
- col = parseInt( $( cell ).attr( 'data-column' ), 10 ),
1572
+ // get current column index; *always* stored on th/td
1573
+ $th = ts.getHeaderCell( $( cell ) ),
1574
+ col = parseInt( $th.attr( 'data-column' ), 10 ),
1554
1575
  order = c.sortVars[ col ].order;
1555
-
1556
1576
  // Only call sortStart if sorting is enabled
1557
1577
  c.$table.triggerHandler( 'sortStart', table );
1558
1578
  // get current column sort order
@@ -2076,7 +2096,7 @@
2076
2096
  if ( !widget.priority ) { widget.priority = 10; }
2077
2097
  widgets[ indx ] = widget;
2078
2098
  } else if ( c.debug ) {
2079
- console.warn( '"' + names[ indx ] + '" widget code does not exist!' );
2099
+ console.warn( '"' + names[ indx ] + '" was enabled, but the widget code has not been loaded!' );
2080
2100
  }
2081
2101
  }
2082
2102
  // sort widgets by priority
@@ -2148,6 +2168,7 @@
2148
2168
  c.widgetInit[ name[ index ] ] = false;
2149
2169
  }
2150
2170
  }
2171
+ c.$table.triggerHandler( 'widgetRemoveEnd', table );
2151
2172
  },
2152
2173
 
2153
2174
  refreshWidgets : function( table, doAll, dontapply ) {
@@ -2999,7 +3020,7 @@
2999
3020
 
3000
3021
  })(jQuery, window, document);
3001
3022
 
3002
- /*! Widget: uitheme - updated 12/8/2016 (v2.28.1) */
3023
+ /*! Widget: uitheme - updated 9/27/2017 (v2.29.0) */
3003
3024
  ;(function ($) {
3004
3025
  'use strict';
3005
3026
  var ts = $.tablesorter || {};
@@ -3016,10 +3037,10 @@
3016
3037
  active : '', // applied when column is sorted
3017
3038
  hover : '', // custom css required - a defined bootstrap style may not override other classes
3018
3039
  // icon class names
3019
- icons : '', // add 'icon-white' to make them white; this icon class is added to the <i> in the header
3040
+ icons : '', // add 'bootstrap-icon-white' to make them white; this icon class is added to the <i> in the header
3020
3041
  iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
3021
- iconSortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
3022
- iconSortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
3042
+ iconSortAsc : 'glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
3043
+ iconSortDesc : 'glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
3023
3044
  filterRow : '', // filter row class
3024
3045
  footerRow : '',
3025
3046
  footerCells : '',
@@ -5202,7 +5223,7 @@
5202
5223
 
5203
5224
  })( jQuery );
5204
5225
 
5205
- /*! Widget: stickyHeaders - updated 6/2/2017 (v2.28.13) *//*
5226
+ /*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) *//*
5206
5227
  * Requires tablesorter v2.8+ and jQuery 1.4.3+
5207
5228
  * by Rob Garrison
5208
5229
  */
@@ -5354,10 +5375,14 @@
5354
5375
  });
5355
5376
  }
5356
5377
  },
5378
+ getLeftPosition = function() {
5379
+ return $attach.length ?
5380
+ parseInt($attach.css('padding-left'), 10) || 0 :
5381
+ $table.offset().left - parseInt($table.css('margin-left'), 10) - $(window).scrollLeft();
5382
+ },
5357
5383
  resizeHeader = function() {
5358
5384
  $stickyWrap.css({
5359
- left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
5360
- $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft(),
5385
+ left : getLeftPosition(),
5361
5386
  width: $table.outerWidth()
5362
5387
  });
5363
5388
  setWidth( $table, $stickyTable );
@@ -5367,10 +5392,10 @@
5367
5392
  if (!$table.is(':visible')) { return; } // fixes #278
5368
5393
  // Detect nested tables - fixes #724
5369
5394
  nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
5370
- var offset = $table.offset(),
5395
+ var tmp,
5396
+ offset = $table.offset(),
5371
5397
  stickyOffset = getStickyOffset(c, wo),
5372
5398
  yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
5373
- xWindow = $.isWindow( $xScroll[0] ),
5374
5399
  attachTop = $attach.length ?
5375
5400
  ( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) :
5376
5401
  $yScroll.scrollTop(),
@@ -5378,19 +5403,27 @@
5378
5403
  scrollTop = attachTop + stickyOffset + nestedStickyTop - captionHeight,
5379
5404
  tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)) - captionHeight,
5380
5405
  isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
5406
+ state = isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide,
5407
+ needsUpdating = !$stickyWrap.hasClass( state ),
5381
5408
  cssSettings = { visibility : isVisible };
5382
5409
  if ($attach.length) {
5410
+ // attached sticky headers always need updating
5411
+ needsUpdating = true;
5383
5412
  cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
5384
5413
  }
5385
- if (xWindow) {
5386
- // adjust when scrolling horizontally - fixes issue #143
5387
- cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft();
5414
+ // adjust when scrolling horizontally - fixes issue #143
5415
+ tmp = getLeftPosition();
5416
+ if (tmp !== parseInt($stickyWrap.css('left'), 10)) {
5417
+ needsUpdating = true;
5418
+ cssSettings.left = tmp;
5388
5419
  }
5389
5420
  cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
5390
- $stickyWrap
5391
- .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
5392
- .addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
5393
- .css(cssSettings);
5421
+ if (needsUpdating) {
5422
+ $stickyWrap
5423
+ .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
5424
+ .addClass( state )
5425
+ .css(cssSettings);
5426
+ }
5394
5427
  if (isVisible !== laststate || resizing) {
5395
5428
  // make sure the column widths match
5396
5429
  resizeHeader();
@@ -5509,7 +5542,7 @@
5509
5542
 
5510
5543
  })(jQuery, window);
5511
5544
 
5512
- /*! Widget: resizable - updated 4/18/2017 (v2.28.8) */
5545
+ /*! Widget: resizable - updated 9/27/2017 (v2.29.0) */
5513
5546
  /*jshint browser:true, jquery:true, unused:false */
5514
5547
  ;(function ($, window) {
5515
5548
  'use strict';
@@ -5836,6 +5869,7 @@
5836
5869
  vars.$target = vars.$next = null;
5837
5870
  // will update stickyHeaders, just in case, see #912
5838
5871
  c.$table.triggerHandler('stickyHeadersUpdate');
5872
+ c.$table.triggerHandler('resizableComplete');
5839
5873
  }
5840
5874
  };
5841
5875
 
@@ -1,4 +1,4 @@
1
- /*! TableSorter (FORK) v2.28.15 *//*
1
+ /*! TableSorter (FORK) v2.29.0 *//*
2
2
  * Client-side table sorting with ease!
3
3
  * @requires jQuery v1.2.6+
4
4
  *
@@ -22,7 +22,7 @@
22
22
  'use strict';
23
23
  var ts = $.tablesorter = {
24
24
 
25
- version : '2.28.15',
25
+ version : '2.29.0',
26
26
 
27
27
  parsers : [],
28
28
  widgets : [],
@@ -421,10 +421,10 @@
421
421
  e.stopPropagation();
422
422
  ts.applyWidgetId( this, id );
423
423
  })
424
- .bind( 'applyWidgets' + namespace, function( e, init ) {
424
+ .bind( 'applyWidgets' + namespace, function( e, callback ) {
425
425
  e.stopPropagation();
426
- // apply widgets
427
- ts.applyWidget( this, init );
426
+ // apply widgets (false = not initializing)
427
+ ts.applyWidget( this, false, callback );
428
428
  })
429
429
  .bind( 'refreshWidgets' + namespace, function( e, all, dontapply ) {
430
430
  e.stopPropagation();
@@ -461,9 +461,9 @@
461
461
  downTarget = null;
462
462
  if ( core !== true ) {
463
463
  $headers.addClass( namespace.slice( 1 ) + '_extra_headers' );
464
- tmp = $.fn.closest ? $headers.closest( 'table' )[ 0 ] : $headers.parents( 'table' )[ 0 ];
465
- if ( tmp && tmp.nodeName === 'TABLE' && tmp !== table ) {
466
- $( tmp ).addClass( namespace.slice( 1 ) + '_extra_table' );
464
+ tmp = ts.getClosest( $headers, 'table' );
465
+ if ( tmp.length && tmp[ 0 ].nodeName === 'TABLE' && tmp[ 0 ] !== table ) {
466
+ $( tmp[ 0 ] ).addClass( namespace.slice( 1 ) + '_extra_table' );
467
467
  }
468
468
  }
469
469
  tmp = ( c.pointerDown + ' ' + c.pointerUp + ' ' + c.pointerClick + ' sort keyup ' )
@@ -515,8 +515,7 @@
515
515
  ts.buildCache( c );
516
516
  }
517
517
  // jQuery v1.2.6 doesn't have closest()
518
- $cell = $.fn.closest ? $( this ).closest( 'th, td' ) :
519
- /TH|TD/.test( this.nodeName ) ? $( this ) : $( this ).parents( 'th, td' );
518
+ $cell = ts.getHeaderCell( $( this ) );
520
519
  // reference original table headers and find the same cell
521
520
  // don't use $headers or IE8 throws an error - see #987
522
521
  temp = $headers.index( $cell );
@@ -556,7 +555,7 @@
556
555
  '';
557
556
  // redefine c.$headers here in case of an updateAll that replaces or adds an entire header cell - see #683
558
557
  c.$headers = $( $.map( c.$table.find( c.selectorHeaders ), function( elem, index ) {
559
- var configHeaders, header, column, template, tmp,
558
+ var configHeaders, header, column, template, tmp, $th,
560
559
  $elem = $( elem );
561
560
  // ignore cell (don't add it to c.$headers) if row has ignoreRow class
562
561
  if ( $elem.parent().hasClass( c.cssIgnoreRow ) ) { return; }
@@ -582,7 +581,9 @@
582
581
  if ( c.onRenderHeader ) {
583
582
  c.onRenderHeader.apply( $elem, [ index, c, c.$table ] );
584
583
  }
585
- column = parseInt( $elem.attr( 'data-column' ), 10 );
584
+ // data-column stored on th or td only
585
+ $th = ts.getHeaderCell( $elem );
586
+ column = parseInt( $th.attr( 'data-column' ), 10 );
586
587
  elem.column = column;
587
588
  tmp = ts.getOrder( ts.getData( $elem, configHeaders, 'sortInitialOrder' ) || c.sortInitialOrder );
588
589
  // this may get updated numerous times if there are multiple rows
@@ -600,10 +601,9 @@
600
601
  }
601
602
  // add cell to headerList
602
603
  c.headerList[ index ] = elem;
604
+ $elem.addClass( ts.css.header + ' ' + c.cssHeader );
603
605
  // add to parent in case there are multiple rows
604
- $elem
605
- .addClass( ts.css.header + ' ' + c.cssHeader )
606
- .parent()
606
+ ts.getClosest( $elem, 'tr' )
607
607
  .addClass( ts.css.headerRow + ' ' + c.cssHeaderRow )
608
608
  .attr( 'role', 'row' );
609
609
  // allow keyboard cursor to focus on element
@@ -1161,10 +1161,29 @@
1161
1161
  }
1162
1162
  },
1163
1163
 
1164
+ // This function does NOT return closest if the $el matches the selector
1165
+ getClosest : function( $el, selector ) {
1166
+ return $.fn.closest ?
1167
+ $el.closest( selector ) :
1168
+ $el.parents( selector ).filter( ':first' );
1169
+ },
1170
+
1171
+ getHeaderCell : function( $el ) {
1172
+ // jQuery v1.2.6 doesn't have closest()
1173
+ if ( $.fn.closest ) {
1174
+ return $el.closest( 'th, td' );
1175
+ }
1176
+ return /TH|TD/.test( $el[0].nodeName ) ?
1177
+ $el :
1178
+ $el.parents( 'th, td' ).filter( ':first' );
1179
+ },
1180
+
1164
1181
  // nextSort (optional), lets you disable next sort text
1165
1182
  setColumnAriaLabel : function( c, $header, nextSort ) {
1166
1183
  if ( $header.length ) {
1167
- var column = parseInt( $header.attr( 'data-column' ), 10 ),
1184
+ var $th = ts.getHeaderCell( $header ),
1185
+ // data-column always stored on the th/td
1186
+ column = parseInt( $th.attr( 'data-column' ), 10 ),
1168
1187
  vars = c.sortVars[ column ],
1169
1188
  tmp = $header.hasClass( ts.css.sortAsc ) ?
1170
1189
  'sortAsc' :
@@ -1322,10 +1341,9 @@
1322
1341
  $cell = $( cell ),
1323
1342
  // update cache - format: function( s, table, cell, cellIndex )
1324
1343
  // no closest in jQuery v1.2.6
1325
- tbodyIndex = $tbodies
1326
- .index( $.fn.closest ? $cell.closest( 'tbody' ) : $cell.parents( 'tbody' ).filter( ':first' ) ),
1344
+ tbodyIndex = $tbodies.index( ts.getClosest( $cell, 'tbody' ) ),
1327
1345
  tbcache = c.cache[ tbodyIndex ],
1328
- $row = $.fn.closest ? $cell.closest( 'tr' ) : $cell.parents( 'tr' ).filter( ':first' );
1346
+ $row = ts.getClosest( $cell, 'tr' );
1329
1347
  cell = $cell[ 0 ]; // in case cell is a jQuery object
1330
1348
  // tbody may not exist if update is initialized while tbody is removed for processing
1331
1349
  if ( $tbodies.length && tbodyIndex >= 0 ) {
@@ -1380,11 +1398,13 @@
1380
1398
  if ( valid ) {
1381
1399
  $row = $( $row );
1382
1400
  c.$tbodies.append( $row );
1383
- } else if ( !$row ||
1401
+ } else if (
1402
+ !$row ||
1384
1403
  // row is a jQuery object?
1385
1404
  !( $row instanceof jQuery ) ||
1386
1405
  // row contained in the table?
1387
- ( $.fn.closest ? $row.closest( 'table' )[ 0 ] : $row.parents( 'table' )[ 0 ] ) !== c.table ) {
1406
+ ( ts.getClosest( $row, 'table' )[ 0 ] !== c.table )
1407
+ ) {
1388
1408
  if ( c.debug ) {
1389
1409
  console.error( 'addRows method requires (1) a jQuery selector reference to rows that have already ' +
1390
1410
  'been added to the table, or (2) row HTML string to be added to a table with only one tbody' );
@@ -1531,10 +1551,10 @@
1531
1551
  notMultiSort = !event[ c.sortMultiSortKey ],
1532
1552
  table = c.table,
1533
1553
  len = c.$headers.length,
1534
- // get current column index
1535
- col = parseInt( $( cell ).attr( 'data-column' ), 10 ),
1554
+ // get current column index; *always* stored on th/td
1555
+ $th = ts.getHeaderCell( $( cell ) ),
1556
+ col = parseInt( $th.attr( 'data-column' ), 10 ),
1536
1557
  order = c.sortVars[ col ].order;
1537
-
1538
1558
  // Only call sortStart if sorting is enabled
1539
1559
  c.$table.triggerHandler( 'sortStart', table );
1540
1560
  // get current column sort order
@@ -2058,7 +2078,7 @@
2058
2078
  if ( !widget.priority ) { widget.priority = 10; }
2059
2079
  widgets[ indx ] = widget;
2060
2080
  } else if ( c.debug ) {
2061
- console.warn( '"' + names[ indx ] + '" widget code does not exist!' );
2081
+ console.warn( '"' + names[ indx ] + '" was enabled, but the widget code has not been loaded!' );
2062
2082
  }
2063
2083
  }
2064
2084
  // sort widgets by priority
@@ -2130,6 +2150,7 @@
2130
2150
  c.widgetInit[ name[ index ] ] = false;
2131
2151
  }
2132
2152
  }
2153
+ c.$table.triggerHandler( 'widgetRemoveEnd', table );
2133
2154
  },
2134
2155
 
2135
2156
  refreshWidgets : function( table, doAll, dontapply ) {
@@ -4,7 +4,7 @@
4
4
  ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██▀▀ ▀▀▀██
5
5
  █████▀ ▀████▀ ██ ██ ▀████▀ ██ ██ ██ ██ ▀████▀ █████▀ ██ ██ █████▀
6
6
  */
7
- /*! tablesorter (FORK) - updated 07-04-2017 (v2.28.15)*/
7
+ /*! tablesorter (FORK) - updated 09-27-2017 (v2.29.0)*/
8
8
  /* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
9
9
  (function(factory) {
10
10
  if (typeof define === 'function' && define.amd) {
@@ -133,7 +133,7 @@
133
133
 
134
134
  })(jQuery, window, document);
135
135
 
136
- /*! Widget: uitheme - updated 12/8/2016 (v2.28.1) */
136
+ /*! Widget: uitheme - updated 9/27/2017 (v2.29.0) */
137
137
  ;(function ($) {
138
138
  'use strict';
139
139
  var ts = $.tablesorter || {};
@@ -150,10 +150,10 @@
150
150
  active : '', // applied when column is sorted
151
151
  hover : '', // custom css required - a defined bootstrap style may not override other classes
152
152
  // icon class names
153
- icons : '', // add 'icon-white' to make them white; this icon class is added to the <i> in the header
153
+ icons : '', // add 'bootstrap-icon-white' to make them white; this icon class is added to the <i> in the header
154
154
  iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
155
- iconSortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
156
- iconSortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
155
+ iconSortAsc : 'glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
156
+ iconSortDesc : 'glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
157
157
  filterRow : '', // filter row class
158
158
  footerRow : '',
159
159
  footerCells : '',
@@ -2336,7 +2336,7 @@
2336
2336
 
2337
2337
  })( jQuery );
2338
2338
 
2339
- /*! Widget: stickyHeaders - updated 6/2/2017 (v2.28.13) *//*
2339
+ /*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) *//*
2340
2340
  * Requires tablesorter v2.8+ and jQuery 1.4.3+
2341
2341
  * by Rob Garrison
2342
2342
  */
@@ -2488,10 +2488,14 @@
2488
2488
  });
2489
2489
  }
2490
2490
  },
2491
+ getLeftPosition = function() {
2492
+ return $attach.length ?
2493
+ parseInt($attach.css('padding-left'), 10) || 0 :
2494
+ $table.offset().left - parseInt($table.css('margin-left'), 10) - $(window).scrollLeft();
2495
+ },
2491
2496
  resizeHeader = function() {
2492
2497
  $stickyWrap.css({
2493
- left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
2494
- $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft(),
2498
+ left : getLeftPosition(),
2495
2499
  width: $table.outerWidth()
2496
2500
  });
2497
2501
  setWidth( $table, $stickyTable );
@@ -2501,10 +2505,10 @@
2501
2505
  if (!$table.is(':visible')) { return; } // fixes #278
2502
2506
  // Detect nested tables - fixes #724
2503
2507
  nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
2504
- var offset = $table.offset(),
2508
+ var tmp,
2509
+ offset = $table.offset(),
2505
2510
  stickyOffset = getStickyOffset(c, wo),
2506
2511
  yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
2507
- xWindow = $.isWindow( $xScroll[0] ),
2508
2512
  attachTop = $attach.length ?
2509
2513
  ( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) :
2510
2514
  $yScroll.scrollTop(),
@@ -2512,19 +2516,27 @@
2512
2516
  scrollTop = attachTop + stickyOffset + nestedStickyTop - captionHeight,
2513
2517
  tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)) - captionHeight,
2514
2518
  isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
2519
+ state = isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide,
2520
+ needsUpdating = !$stickyWrap.hasClass( state ),
2515
2521
  cssSettings = { visibility : isVisible };
2516
2522
  if ($attach.length) {
2523
+ // attached sticky headers always need updating
2524
+ needsUpdating = true;
2517
2525
  cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
2518
2526
  }
2519
- if (xWindow) {
2520
- // adjust when scrolling horizontally - fixes issue #143
2521
- cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft();
2527
+ // adjust when scrolling horizontally - fixes issue #143
2528
+ tmp = getLeftPosition();
2529
+ if (tmp !== parseInt($stickyWrap.css('left'), 10)) {
2530
+ needsUpdating = true;
2531
+ cssSettings.left = tmp;
2522
2532
  }
2523
2533
  cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
2524
- $stickyWrap
2525
- .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
2526
- .addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
2527
- .css(cssSettings);
2534
+ if (needsUpdating) {
2535
+ $stickyWrap
2536
+ .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
2537
+ .addClass( state )
2538
+ .css(cssSettings);
2539
+ }
2528
2540
  if (isVisible !== laststate || resizing) {
2529
2541
  // make sure the column widths match
2530
2542
  resizeHeader();
@@ -2643,7 +2655,7 @@
2643
2655
 
2644
2656
  })(jQuery, window);
2645
2657
 
2646
- /*! Widget: resizable - updated 4/18/2017 (v2.28.8) */
2658
+ /*! Widget: resizable - updated 9/27/2017 (v2.29.0) */
2647
2659
  /*jshint browser:true, jquery:true, unused:false */
2648
2660
  ;(function ($, window) {
2649
2661
  'use strict';
@@ -2970,6 +2982,7 @@
2970
2982
  vars.$target = vars.$next = null;
2971
2983
  // will update stickyHeaders, just in case, see #912
2972
2984
  c.$table.triggerHandler('stickyHeadersUpdate');
2985
+ c.$table.triggerHandler('resizableComplete');
2973
2986
  }
2974
2987
  };
2975
2988
 
@@ -1,4 +1,4 @@
1
- /* Widget: columnSelector (responsive table widget) - updated 7/4/2017 (v2.28.15) *//*
1
+ /* Widget: columnSelector (responsive table widget) - updated 9/27/2017 (v2.29.0) *//*
2
2
  * Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * by Justin Hallett & Rob Garrison
4
4
  */
@@ -269,16 +269,16 @@
269
269
  c.$table.triggerHandler(wo.columnSelector_updated);
270
270
  }
271
271
  },
272
- addSelectors: function( prefix, column ) {
272
+ addSelectors: function( wo, prefix, column ) {
273
273
  var array = [],
274
274
  temp = ' col:nth-child(' + column + ')';
275
275
  array.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
276
- temp = ' tr:not(.hasSpan) th[data-column="' + ( column - 1 ) + '"]';
276
+ temp = ' tr:not(.' + wo.columnSelector_classHasSpan + ') th[data-column="' + ( column - 1 ) + '"]';
277
277
  array.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
278
- temp = ' tr:not(.hasSpan) td:nth-child(' + column + ')';
278
+ temp = ' tr:not(.' + wo.columnSelector_classHasSpan + ') td:nth-child(' + column + ')';
279
279
  array.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
280
280
  // for other cells in colspan columns
281
- temp = ' tr td:not(' + prefix + 'HasSpan)[data-column="' + (column - 1) + '"]';
281
+ temp = ' tr td:not(' + prefix + wo.columnSelector_classHasSpan + ')[data-column="' + (column - 1) + '"]';
282
282
  array.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
283
283
  return array;
284
284
  },
@@ -301,7 +301,7 @@
301
301
  isHidden[ column + 1 ] = ts.getData( c.$headerIndexed[ column ], col, 'columnSelector' ) === 'false';
302
302
  if ( isHidden[ column + 1 ] ) {
303
303
  // hide columnSelector false column (in auto mode)
304
- mediaAll = mediaAll.concat( tsColSel.addSelectors( prefix, column + 1 ) );
304
+ mediaAll = mediaAll.concat( tsColSel.addSelectors( wo, prefix, column + 1 ) );
305
305
  }
306
306
  }
307
307
  }
@@ -313,7 +313,7 @@
313
313
  column = parseInt($(this).attr('data-column'), 10) + 1;
314
314
  // don't reveal columnSelector false columns
315
315
  if ( !isHidden[ column ] ) {
316
- breaks = breaks.concat( tsColSel.addSelectors( prefix, column ) );
316
+ breaks = breaks.concat( tsColSel.addSelectors( wo, prefix, column ) );
317
317
  }
318
318
  });
319
319
  if (breaks.length) {
@@ -343,7 +343,7 @@
343
343
  colSel.$container.find('input[data-column]').filter('[data-column!="auto"]').each(function(){
344
344
  if (!this.checked) {
345
345
  column = parseInt( $(this).attr('data-column'), 10 ) + 1;
346
- styles = styles.concat( tsColSel.addSelectors( prefix, column ) );
346
+ styles = styles.concat( tsColSel.addSelectors( wo, prefix, column ) );
347
347
  }
348
348
  $(this).toggleClass( wo.columnSelector_cssChecked, this.checked );
349
349
  });
@@ -373,10 +373,10 @@
373
373
  if ( span > 1 ) {
374
374
  hasSpans = true;
375
375
  $cells.eq( index )
376
- .addClass( c.namespace.slice( 1 ) + 'columnselectorHasSpan' )
376
+ .addClass( c.namespace.slice( 1 ) + 'columnselector' + wo.columnSelector_classHasSpan )
377
377
  .attr( 'data-col-span', span );
378
378
  // add data-column values
379
- ts.computeColumnIndex( $cells.eq( index ).parent().addClass( 'hasSpan' ) );
379
+ ts.computeColumnIndex( $cells.eq( index ).parent().addClass( wo.columnSelector_classHasSpan ) );
380
380
  }
381
381
  }
382
382
  // only add resize end if using media queries
@@ -402,7 +402,9 @@
402
402
  autoModeOn = wo.columnSelector_mediaquery && colSel.auto,
403
403
  // find all header/footer cells in case a regular column follows a colspan; see #1238
404
404
  $headers = c.$table.children( 'thead, tfoot' ).children().children()
405
- .add( $(c.namespace + '_extra_table').children( 'thead, tfoot' ).children().children() ),
405
+ .add( $(c.namespace + '_extra_table').children( 'thead, tfoot' ).children().children() )
406
+ // include grouping widget headers (they have colspans!)
407
+ .add( c.$table.find( '.group-header' ).children() ),
406
408
  len = $headers.length;
407
409
  for ( index = 0; index < len; index++ ) {
408
410
  $cell = $headers.eq(index);
@@ -422,7 +424,7 @@
422
424
  $cell.addClass( filtered );
423
425
  }
424
426
  } else if ( typeof colSel.states[ col ] !== 'undefined' && colSel.states[ col ] !== null ) {
425
- $cell.toggleClass( filtered, !colSel.states[ col ] );
427
+ $cell.toggleClass( filtered, !autoModeOn && !colSel.states[ col ] );
426
428
  }
427
429
  }
428
430
  },
@@ -533,6 +535,8 @@
533
535
  // class name added to checked checkboxes - this fixes an issue with Chrome not updating FontAwesome
534
536
  // applied icons; use this class name (input.checked) instead of input:checked
535
537
  columnSelector_cssChecked : 'checked',
538
+ // class name added to rows that have a span (e.g. grouping widget & other rows inside the tbody)
539
+ columnSelector_classHasSpan : 'hasSpan',
536
540
  // event triggered when columnSelector completes
537
541
  columnSelector_updated : 'columnUpdate'
538
542
  },
@@ -546,10 +550,10 @@
546
550
  if ( csel.$popup ) { csel.$popup.empty(); }
547
551
  csel.$style.remove();
548
552
  csel.$breakpoints.remove();
549
- $( c.namespace + 'columnselectorHasSpan' ).removeClass( wo.filter_filteredRow || 'filtered' );
553
+ $( c.namespace + 'columnselector' + wo.columnSelector_classHasSpan )
554
+ .removeClass( wo.filter_filteredRow || 'filtered' );
550
555
  c.$table.find('[data-col-span]').each(function(indx, el) {
551
556
  var $el = $(el);
552
- console.log($el, $el.attr('data-col-span'));
553
557
  $el.attr('colspan', $el.attr('data-col-span'));
554
558
  });
555
559
  c.$table.off('updateAll' + namespace + ' update' + namespace);
@@ -1,4 +1,4 @@
1
- /*! Widget: grouping - updated 11/26/2016 (v2.28.0) *//*
1
+ /*! Widget: grouping - updated 9/27/2017 (v2.29.0) *//*
2
2
  * Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * by Rob Garrison
4
4
  */
@@ -172,7 +172,10 @@
172
172
 
173
173
  groupHeaderHTML : function( c, wo, data ) {
174
174
  var name = ( data.currentGroup || '' ).toString().replace(/</g, '&lt;').replace(/>/g, '&gt;');
175
- return '<tr class="group-header ' + c.selectorRemove.slice(1) +
175
+ return '<tr class="group-header ' + c.selectorRemove.slice(1) + ' ' +
176
+ // prevent grouping row from being hidden by the columnSelector;
177
+ // classHasSpan option added 2.29.0
178
+ ( wo.columnSelector_classHasSpan || 'hasSpan' ) +
176
179
  '" unselectable="on" ' + ( c.tabIndex ? 'tabindex="0" ' : '' ) + 'data-group-index="' +
177
180
  data.groupIndex + '">' +
178
181
  '<td colspan="' + c.columns + '">' +
@@ -221,6 +224,10 @@
221
224
  }
222
225
  }
223
226
  }
227
+ if ( ts.hasWidget( c.table, 'columnSelector' ) ) {
228
+ // make sure to handle the colspan adjustments of the grouping rows
229
+ ts.columnSelector.setUpColspan( c, wo );
230
+ }
224
231
  },
225
232
  insertGroupHeader: function( c, wo, data ) {
226
233
  var $header = c.$headerIndexed[ data.column ],
@@ -1,4 +1,4 @@
1
- /*! Widget: output - updated 4/2/2017 (v2.28.6) *//*
1
+ /*! Widget: output - updated 9/27/2017 (v2.29.0) *//*
2
2
  * Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * Modified from:
4
4
  * HTML Table to CSV: http://www.kunalbabre.com/projects/table2CSV.php (License unknown?)
@@ -131,8 +131,10 @@
131
131
  return data;
132
132
  },
133
133
 
134
- process : function(c, wo) {
135
- var mydata, $this, $rows, headers, csvData, len, rowsLen, tmp,
134
+ // optional vars $rows and dump added by TheSin to make
135
+ // process callable via callback for ajaxPager
136
+ process : function(c, wo, $rows, dump) {
137
+ var mydata, $this, headers, csvData, len, rowsLen, tmp,
136
138
  hasStringify = window.JSON && JSON.hasOwnProperty('stringify'),
137
139
  indx = 0,
138
140
  tmpData = (wo.output_separator || ',').toLowerCase(),
@@ -162,7 +164,8 @@
162
164
  headers = output.processRow(c, $this, true, outputJSON);
163
165
 
164
166
  // all tbody rows - do not include widget added rows (e.g. grouping widget headers)
165
- $rows = $el.children('tbody').children('tr').not(c.selectorRemove);
167
+ if ( !$rows )
168
+ $rows = $el.children('tbody').children('tr').not(c.selectorRemove);
166
169
 
167
170
  // check for a filter callback function first! because
168
171
  // /^f/.test(function(){ console.log('test'); }) is TRUE! (function is converted to a string)
@@ -210,10 +213,15 @@
210
213
  mydata = outputArray && hasStringify ? JSON.stringify(tmpData) : tmpData.join('\n');
211
214
  }
212
215
 
216
+ if (dump) {
217
+ return mydata;
218
+ }
219
+
213
220
  // callback; if true returned, continue processing
214
221
  if ($.isFunction(wo.output_callback)) {
215
222
  tmp = wo.output_callback(c, mydata, c.pager && c.pager.ajaxObject.url || null);
216
223
  if ( tmp === false ) {
224
+ output.busy = false;
217
225
  return;
218
226
  } else if ( typeof tmp === 'string' ) {
219
227
  mydata = tmp;
@@ -1,4 +1,4 @@
1
- /*! Widget: resizable - updated 4/18/2017 (v2.28.8) */
1
+ /*! Widget: resizable - updated 9/27/2017 (v2.29.0) */
2
2
  /*jshint browser:true, jquery:true, unused:false */
3
3
  ;(function ($, window) {
4
4
  'use strict';
@@ -325,6 +325,7 @@
325
325
  vars.$target = vars.$next = null;
326
326
  // will update stickyHeaders, just in case, see #912
327
327
  c.$table.triggerHandler('stickyHeadersUpdate');
328
+ c.$table.triggerHandler('resizableComplete');
328
329
  }
329
330
  };
330
331
 
@@ -1,4 +1,4 @@
1
- /*! Widget: scroller - updated 4/18/2017 (v2.28.8) *//*
1
+ /*! Widget: scroller - updated 9/27/2017 (v2.29.0) *//*
2
2
  Copyright (C) 2011 T. Connell & Associates, Inc.
3
3
 
4
4
  Dual-licensed under the MIT and GPL licenses
@@ -273,6 +273,9 @@
273
273
  $tableWrap
274
274
  .off( 'scroll' + namespace )
275
275
  .on( 'scroll' + namespace, function() {
276
+ // Save position
277
+ wo.scroller_saved[0] = $tableWrap.scrollLeft();
278
+ wo.scroller_saved[1] = $tableWrap.scrollTop();
276
279
  if ( wo.scroller_jumpToHeader ) {
277
280
  var pos = $win.scrollTop() - $hdr.offset().top;
278
281
  if ( $( this ).scrollTop() !== 0 && pos < tbHt && pos > 0 ) {
@@ -841,6 +844,7 @@
841
844
  // adjust caption height, see #1202
842
845
  $fixedColumn.find('caption').height( wo.scroller_$header.find( 'caption' ).height() );
843
846
 
847
+ $tableWrap.scroll();
844
848
  wo.scroller_isBusy = false;
845
849
 
846
850
  },
@@ -1,4 +1,4 @@
1
- /*! Widget: sort2Hash (BETA) - updated 7/4/2017 (v2.28.15) */
1
+ /*! Widget: sort2Hash (BETA) - updated 9/27/2017 (v2.29.0) */
2
2
  /* Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * by Rob Garrison
4
4
  */
@@ -225,8 +225,27 @@
225
225
  hash = s2h.cleanHash( c, wo, component, hash );
226
226
  str += value;
227
227
  });
228
- // add updated hash
229
- window.location.hash = ( ( window.location.hash || '' ).replace( '#', '' ).length ? hash : wo.sort2Hash_hash ) + str;
228
+
229
+ var hashChar = wo.sort2Hash_hash;
230
+ // Combine new hash with any existing hashes
231
+ var newHash = (
232
+ ( window.location.hash || '' ).replace( hashChar, '' ).length ?
233
+ hash : hashChar
234
+ ) + str;
235
+
236
+ if (wo.sort2Hash_replaceHistory) {
237
+ var baseUrl = window.location.href.split(hashChar)[0];
238
+ // Ensure that there is a leading hash character
239
+ var firstChar = newHash[0];
240
+ if (firstChar != hashChar) {
241
+ newHash = hashChar + newHash;
242
+ }
243
+ // Update URL in browser
244
+ window.location.replace(baseUrl + newHash);
245
+ } else {
246
+ // Add updated hash
247
+ window.location.hash = newHash;
248
+ }
230
249
  }
231
250
  };
232
251
 
@@ -239,6 +258,7 @@
239
258
  sort2Hash_headerTextAttr : 'data-header', // data attribute containing alternate header text
240
259
  sort2Hash_directionText : [ 0, 1 ], // [ 'asc', 'desc' ],
241
260
  sort2Hash_overrideSaveSort : false, // if true, override saveSort widget if saved sort available
261
+ sort2Hash_replaceHistory : false, // if true, hash changes are not saved to browser history
242
262
 
243
263
  // this option > table ID > table index on page
244
264
  sort2Hash_tableId : null,
@@ -1,4 +1,4 @@
1
- /*! Widget: stickyHeaders - updated 6/2/2017 (v2.28.13) *//*
1
+ /*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) *//*
2
2
  * Requires tablesorter v2.8+ and jQuery 1.4.3+
3
3
  * by Rob Garrison
4
4
  */
@@ -150,10 +150,14 @@
150
150
  });
151
151
  }
152
152
  },
153
+ getLeftPosition = function() {
154
+ return $attach.length ?
155
+ parseInt($attach.css('padding-left'), 10) || 0 :
156
+ $table.offset().left - parseInt($table.css('margin-left'), 10) - $(window).scrollLeft();
157
+ },
153
158
  resizeHeader = function() {
154
159
  $stickyWrap.css({
155
- left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
156
- $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft(),
160
+ left : getLeftPosition(),
157
161
  width: $table.outerWidth()
158
162
  });
159
163
  setWidth( $table, $stickyTable );
@@ -163,10 +167,10 @@
163
167
  if (!$table.is(':visible')) { return; } // fixes #278
164
168
  // Detect nested tables - fixes #724
165
169
  nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
166
- var offset = $table.offset(),
170
+ var tmp,
171
+ offset = $table.offset(),
167
172
  stickyOffset = getStickyOffset(c, wo),
168
173
  yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
169
- xWindow = $.isWindow( $xScroll[0] ),
170
174
  attachTop = $attach.length ?
171
175
  ( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) :
172
176
  $yScroll.scrollTop(),
@@ -174,19 +178,27 @@
174
178
  scrollTop = attachTop + stickyOffset + nestedStickyTop - captionHeight,
175
179
  tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)) - captionHeight,
176
180
  isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
181
+ state = isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide,
182
+ needsUpdating = !$stickyWrap.hasClass( state ),
177
183
  cssSettings = { visibility : isVisible };
178
184
  if ($attach.length) {
185
+ // attached sticky headers always need updating
186
+ needsUpdating = true;
179
187
  cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
180
188
  }
181
- if (xWindow) {
182
- // adjust when scrolling horizontally - fixes issue #143
183
- cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft();
189
+ // adjust when scrolling horizontally - fixes issue #143
190
+ tmp = getLeftPosition();
191
+ if (tmp !== parseInt($stickyWrap.css('left'), 10)) {
192
+ needsUpdating = true;
193
+ cssSettings.left = tmp;
184
194
  }
185
195
  cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
186
- $stickyWrap
187
- .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
188
- .addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
189
- .css(cssSettings);
196
+ if (needsUpdating) {
197
+ $stickyWrap
198
+ .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
199
+ .addClass( state )
200
+ .css(cssSettings);
201
+ }
190
202
  if (isVisible !== laststate || resizing) {
191
203
  // make sure the column widths match
192
204
  resizeHeader();
@@ -1,4 +1,4 @@
1
- /*! Widget: uitheme - updated 12/8/2016 (v2.28.1) */
1
+ /*! Widget: uitheme - updated 9/27/2017 (v2.29.0) */
2
2
  ;(function ($) {
3
3
  'use strict';
4
4
  var ts = $.tablesorter || {};
@@ -15,10 +15,10 @@
15
15
  active : '', // applied when column is sorted
16
16
  hover : '', // custom css required - a defined bootstrap style may not override other classes
17
17
  // icon class names
18
- icons : '', // add 'icon-white' to make them white; this icon class is added to the <i> in the header
18
+ icons : '', // add 'bootstrap-icon-white' to make them white; this icon class is added to the <i> in the header
19
19
  iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
20
- iconSortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
21
- iconSortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
20
+ iconSortAsc : 'glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
21
+ iconSortDesc : 'glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
22
22
  filterRow : '', // filter row class
23
23
  footerRow : '',
24
24
  footerCells : '',
@@ -56,8 +56,8 @@
56
56
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAA20lEQVR4AWJABpKSkoxALCstLb0aUAsZaCAMhVEY6B0amx8YZWDDEDSBa2AGe7XeIiAAClYwVGBvsAcIllsf/mvcC9DgOOd8h90fxWvngVEUbZIkuWRZZlE8eQjcisgZMM9zi+LJ6ZfwegmWZflZDugdHMfxTcGqql7TNBlUB/QObtv2VBSFrev6OY7jngzFk9OT/fn73fWYpqnlXNyXDMWT0zuYx/Bvel9ej+LJ6R08DMOu67q7DkTkrSA5vYPneV71fX/QASdTkJwezhs0TfMARn0wMDDGXEPgF4oijqwM5YjNAAAAAElFTkSuQmCC);
57
57
  }
58
58
 
59
- /* white unsorted icon */
60
- .tablesorter-bootstrap .icon-white.bootstrap-icon-unsorted {
59
+ /* white unsorted icon; updated to use bootstrap-icon-white - see #1432 */
60
+ .tablesorter-bootstrap .bootstrap-icon-white.bootstrap-icon-unsorted {
61
61
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAe0lEQVR4AbXQoRWDMBiF0Sh2QLAAQ8SxJGugWSA6A2STW1PxTsnB9cnkfuYvv8OGC1t5G3Y0QMP+Bm857keAdQIzWBP3+Bw4MADQE18B6/etRnCV/w9nnGuLezfAmXhABGtAGIkruvk6auIFRwQJDywllsEAjCecB20GP59BQQ+gtlRLAAAAAElFTkSuQmCC);
62
62
  }
63
63
 
@@ -53,8 +53,8 @@
53
53
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAA20lEQVR4AWJABpKSkoxALCstLb0aUAsZaCAMhVEY6B0amx8YZWDDEDSBa2AGe7XeIiAAClYwVGBvsAcIllsf/mvcC9DgOOd8h90fxWvngVEUbZIkuWRZZlE8eQjcisgZMM9zi+LJ6ZfwegmWZflZDugdHMfxTcGqql7TNBlUB/QObtv2VBSFrev6OY7jngzFk9OT/fn73fWYpqnlXNyXDMWT0zuYx/Bvel9ej+LJ6R08DMOu67q7DkTkrSA5vYPneV71fX/QASdTkJwezhs0TfMARn0wMDDGXEPgF4oijqwM5YjNAAAAAElFTkSuQmCC);
54
54
  }
55
55
 
56
- /* white unsorted icon */
57
- .tablesorter-bootstrap .icon-white.bootstrap-icon-unsorted {
56
+ /* white unsorted icon; updated to use bootstrap-icon-white - see #1432 */
57
+ .tablesorter-bootstrap .bootstrap-icon-white.bootstrap-icon-unsorted {
58
58
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAe0lEQVR4AbXQoRWDMBiF0Sh2QLAAQ8SxJGugWSA6A2STW1PxTsnB9cnkfuYvv8OGC1t5G3Y0QMP+Bm857keAdQIzWBP3+Bw4MADQE18B6/etRnCV/w9nnGuLezfAmXhABGtAGIkruvk6auIFRwQJDywllsEAjCecB20GP59BQQ+gtlRLAAAAAElFTkSuQmCC);
59
59
  }
60
60
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jquery-tablesorter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.23.15
4
+ version: 1.24.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jun Lin
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-07-09 00:00:00.000000000 Z
12
+ date: 2017-10-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: railties
@@ -183,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
183
  version: '0'
184
184
  requirements: []
185
185
  rubyforge_project:
186
- rubygems_version: 2.6.11
186
+ rubygems_version: 2.6.13
187
187
  signing_key:
188
188
  specification_version: 4
189
189
  summary: Simple integration of jquery-tablesorter (Mottie's fork) into the Rails asset