jquery-tablesorter 1.17.2 → 1.17.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/jquery-tablesorter/version.rb +1 -1
  4. data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +76 -71
  5. data/vendor/assets/javascripts/jquery-tablesorter/extras/jquery.dragtable.mod.js +1 -1
  6. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +2647 -2576
  7. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +174 -119
  8. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +2487 -2471
  9. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-extract.js +15 -15
  10. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-iso8601.js +1 -1
  11. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-month.js +4 -4
  12. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-range.js +1 -1
  13. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-two-digit-year.js +12 -12
  14. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-weekday.js +4 -4
  15. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date.js +1 -1
  16. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-duration.js +1 -1
  17. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-feet-inch-fraction.js +6 -6
  18. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-file-type.js +22 -22
  19. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-globalize.js +1 -1
  20. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-ignore-articles.js +15 -15
  21. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-image.js +3 -3
  22. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +10 -3
  23. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-metric.js +2 -2
  24. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-named-numbers.js +3 -3
  25. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-network.js +1 -1
  26. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-roman.js +4 -4
  27. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-alignChar.js +122 -121
  28. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-build-table.js +13 -13
  29. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-chart.js +2 -2
  30. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +324 -324
  31. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columns.js +60 -60
  32. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +219 -219
  33. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-html5.js +360 -361
  34. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-jui.js +666 -666
  35. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-select2.js +124 -124
  36. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-type-insideRange.js +1 -1
  37. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +1448 -1433
  38. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-formatter.js +1 -1
  39. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +213 -213
  40. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-headerTitles.js +3 -3
  41. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +271 -216
  42. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +339 -320
  43. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +1057 -1045
  44. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-print.js +109 -109
  45. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-reflow.js +114 -115
  46. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-resizable.js +360 -359
  47. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-saveSort.js +59 -59
  48. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +818 -806
  49. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sort2Hash.js +128 -0
  50. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sortTbodies.js +195 -195
  51. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-staticRow.js +90 -90
  52. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +257 -257
  53. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-storage.js +76 -76
  54. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-uitheme.js +170 -170
  55. metadata +3 -3
  56. data/vendor/assets/javascripts/jquery-tablesorter/extras/jquery.quicksearch.js +0 -195
@@ -12,110 +12,110 @@
12
12
  /*jshint browser:true, jquery:true, unused:false */
13
13
  /*global jQuery: false */
14
14
  ;(function($){
15
- "use strict";
16
- var ts = $.tablesorter,
15
+ 'use strict';
16
+ var ts = $.tablesorter,
17
17
 
18
- // add/refresh row indexes
19
- addIndexes = function(table){
20
- var $tr, wo, v, indx, rows,
21
- c = table.config;
22
- // "Index" the static rows, saving their current (starting) position in the
23
- // table inside a data() param on the <tr> element itself for later use.
24
- if (c) {
25
- wo = c.widgetOptions;
26
- c.$tbodies.each(function(){
27
- $tr = $(this).children();
28
- rows = $tr.length;
29
- $tr.filter(wo.staticRow_class).each(function() {
30
- $tr = $(this);
31
- indx = $tr.data(wo.staticRow_index);
32
- if (typeof indx !== "undefined") {
33
- v = parseFloat(indx);
34
- // percentage of total rows
35
- indx = (/%/.test(indx)) ? Math.round(v/100 * rows) : v;
36
- } else {
37
- indx = $tr.index();
38
- }
39
- // row indexing starts over within each tbody
40
- $tr.data( wo.staticRow_data, indx );
18
+ // add/refresh row indexes
19
+ addIndexes = function(table){
20
+ var $tr, wo, v, indx, rows,
21
+ c = table.config;
22
+ // 'Index' the static rows, saving their current (starting) position in the
23
+ // table inside a data() param on the <tr> element itself for later use.
24
+ if (c) {
25
+ wo = c.widgetOptions;
26
+ c.$tbodies.each(function(){
27
+ $tr = $(this).children();
28
+ rows = $tr.length;
29
+ $tr.filter(wo.staticRow_class).each(function() {
30
+ $tr = $(this);
31
+ indx = $tr.data(wo.staticRow_index);
32
+ if (typeof indx !== 'undefined') {
33
+ v = parseFloat(indx);
34
+ // percentage of total rows
35
+ indx = (/%/.test(indx)) ? Math.round(v / 100 * rows) : v;
36
+ } else {
37
+ indx = $tr.index();
38
+ }
39
+ // row indexing starts over within each tbody
40
+ $tr.data( wo.staticRow_data, indx );
41
+ });
41
42
  });
42
- });
43
- }
44
- };
43
+ }
44
+ };
45
45
 
46
- ts.addWidget({
47
- // Give the new Widget an ID to be used in the tablesorter() call, as follows:
48
- // $('#myElement').tablesorter({ widgets: ['zebra', 'staticRow'] });
49
- id: 'staticRow',
46
+ ts.addWidget({
47
+ // Give the new Widget an ID to be used in the tablesorter() call, as follows:
48
+ // $('#myElement').tablesorter({ widgets: ['zebra', 'staticRow'] });
49
+ id: 'staticRow',
50
50
 
51
- options: {
52
- staticRow_class : '.static',
53
- staticRow_data : 'static-index',
54
- staticRow_index : 'row-index',
55
- staticRow_event : 'staticRowsRefresh'
56
- },
51
+ options: {
52
+ staticRow_class : '.static',
53
+ staticRow_data : 'static-index',
54
+ staticRow_index : 'row-index',
55
+ staticRow_event : 'staticRowsRefresh'
56
+ },
57
57
 
58
- init: function(table, thisWidget, c, wo){
59
- addIndexes(table);
60
- // refresh static rows after updates
61
- c.$table
62
- .unbind( ('updateComplete.tsstaticrows ' + wo.staticRow_event).replace(/\s+/g, ' ') )
63
- .bind('updateComplete.tsstaticrows ' + wo.staticRow_event, function(){
64
- addIndexes(table);
65
- c.$table.trigger('applyWidgets');
66
- });
67
- },
58
+ init: function(table, thisWidget, c, wo){
59
+ addIndexes(table);
60
+ // refresh static rows after updates
61
+ c.$table
62
+ .unbind( ('updateComplete.tsstaticrows ' + wo.staticRow_event).replace(/\s+/g, ' ') )
63
+ .bind('updateComplete.tsstaticrows ' + wo.staticRow_event, function(){
64
+ addIndexes(table);
65
+ c.$table.trigger('applyWidgets');
66
+ });
67
+ },
68
68
 
69
- format: function(table, c, wo) {
70
- // Loop thru static rows, moving them to their original "indexed" position,
71
- // & repeat until no more re-shuffling is needed
72
- var targetIndex, $thisRow, indx, numRows, $tbody, hasShuffled, $rows, max;
69
+ format: function(table, c, wo) {
70
+ // Loop thru static rows, moving them to their original 'indexed' position,
71
+ // & repeat until no more re-shuffling is needed
72
+ var targetIndex, $thisRow, indx, numRows, $tbody, hasShuffled, $rows, max;
73
73
 
74
- c.$tbodies.each(function(){
75
- $tbody = $.tablesorter.processTbody(table, $(this), true); // remove tbody
76
- hasShuffled = true;
77
- indx = 0;
78
- $rows = $tbody.children(wo.staticRow_class);
79
- numRows = $tbody.children('tr').length - 1;
80
- max = $rows.length;
74
+ c.$tbodies.each(function(){
75
+ $tbody = $.tablesorter.processTbody(table, $(this), true); // remove tbody
76
+ hasShuffled = true;
77
+ indx = 0;
78
+ $rows = $tbody.children(wo.staticRow_class);
79
+ numRows = $tbody.children('tr').length - 1;
80
+ max = $rows.length;
81
81
 
82
- // don't allow the while loop to cycle more times than the set number of static rows
83
- while (hasShuffled && indx < max) {
84
- hasShuffled = false;
85
- /*jshint loopfunc:true */
86
- $rows.each(function() {
87
- targetIndex = $(this).data(wo.staticRow_data);
88
- // allow setting target index >> num rows to always make a row last
89
- targetIndex = targetIndex >= numRows ? numRows : targetIndex < 0 ? 0 : targetIndex;
90
- if (targetIndex !== $(this).index()) {
91
- hasShuffled = true;
92
- $thisRow = $(this).detach();
82
+ // don't allow the while loop to cycle more times than the set number of static rows
83
+ while (hasShuffled && indx < max) {
84
+ hasShuffled = false;
85
+ /*jshint loopfunc:true */
86
+ $rows.each(function() {
87
+ targetIndex = $(this).data(wo.staticRow_data);
88
+ // allow setting target index >> num rows to always make a row last
89
+ targetIndex = targetIndex >= numRows ? numRows : targetIndex < 0 ? 0 : targetIndex;
90
+ if (targetIndex !== $(this).index()) {
91
+ hasShuffled = true;
92
+ $thisRow = $(this).detach();
93
93
 
94
- if (targetIndex >= numRows) {
95
- // Are we trying to be the last row?
96
- $thisRow.appendTo( $tbody );
97
- } else if (targetIndex === 0) {
94
+ if (targetIndex >= numRows) {
95
+ // Are we trying to be the last row?
96
+ $thisRow.appendTo( $tbody );
97
+ } else if (targetIndex === 0) {
98
98
  // Are we trying to be the first row?
99
99
  $thisRow.prependTo( $tbody );
100
- } else {
101
- // No, we want to be somewhere in the middle!
102
- $thisRow.insertBefore( $tbody.find('tr:eq(' + targetIndex + ')') );
100
+ } else {
101
+ // No, we want to be somewhere in the middle!
102
+ $thisRow.insertBefore( $tbody.find('tr:eq(' + targetIndex + ')') );
103
+ }
103
104
  }
104
- }
105
- });
106
- indx++;
107
- }
105
+ });
106
+ indx++;
107
+ }
108
108
 
109
- $.tablesorter.processTbody(table, $tbody, false); // restore tbody
110
- });
109
+ $.tablesorter.processTbody(table, $tbody, false); // restore tbody
110
+ });
111
111
 
112
- c.$table.trigger('staticRowsComplete', table);
113
- },
112
+ c.$table.trigger('staticRowsComplete', table);
113
+ },
114
114
 
115
- remove : function(table, c, wo){
116
- c.$table.unbind( ('updateComplete.tsstaticrows ' + wo.staticRow_event).replace(/\s+/g, ' ') );
117
- }
115
+ remove : function(table, c, wo){
116
+ c.$table.unbind( ('updateComplete.tsstaticrows ' + wo.staticRow_event).replace(/\s+/g, ' ') );
117
+ }
118
118
 
119
- });
119
+ });
120
120
 
121
- })(jQuery);
121
+ })(jQuery);
@@ -3,286 +3,286 @@
3
3
  * by Rob Garrison
4
4
  */
5
5
  ;(function ($, window) {
6
- 'use strict';
7
- var ts = $.tablesorter || {};
6
+ 'use strict';
7
+ var ts = $.tablesorter || {};
8
8
 
9
- $.extend(ts.css, {
10
- sticky : 'tablesorter-stickyHeader', // stickyHeader
11
- stickyVis : 'tablesorter-sticky-visible',
12
- stickyHide: 'tablesorter-sticky-hidden',
13
- stickyWrap: 'tablesorter-sticky-wrapper'
14
- });
9
+ $.extend(ts.css, {
10
+ sticky : 'tablesorter-stickyHeader', // stickyHeader
11
+ stickyVis : 'tablesorter-sticky-visible',
12
+ stickyHide: 'tablesorter-sticky-hidden',
13
+ stickyWrap: 'tablesorter-sticky-wrapper'
14
+ });
15
15
 
16
- // Add a resize event to table headers
17
- ts.addHeaderResizeEvent = function(table, disable, settings) {
18
- table = $(table)[0]; // make sure we're using a dom element
19
- if ( !table.config ) { return; }
20
- var defaults = {
21
- timer : 250
22
- },
23
- options = $.extend({}, defaults, settings),
24
- c = table.config,
25
- wo = c.widgetOptions,
26
- checkSizes = function( triggerEvent ) {
27
- var index, headers, $header, sizes, width, height,
28
- len = c.$headers.length;
29
- wo.resize_flag = true;
30
- headers = [];
31
- for ( index = 0; index < len; index++ ) {
32
- $header = c.$headers.eq( index );
33
- sizes = $header.data( 'savedSizes' ) || [ 0,0 ]; // fixes #394
34
- width = $header[0].offsetWidth;
35
- height = $header[0].offsetHeight;
36
- if ( width !== sizes[0] || height !== sizes[1] ) {
37
- $header.data( 'savedSizes', [ width, height ] );
38
- headers.push( $header[0] );
16
+ // Add a resize event to table headers
17
+ ts.addHeaderResizeEvent = function(table, disable, settings) {
18
+ table = $(table)[0]; // make sure we're using a dom element
19
+ if ( !table.config ) { return; }
20
+ var defaults = {
21
+ timer : 250
22
+ },
23
+ options = $.extend({}, defaults, settings),
24
+ c = table.config,
25
+ wo = c.widgetOptions,
26
+ checkSizes = function( triggerEvent ) {
27
+ var index, headers, $header, sizes, width, height,
28
+ len = c.$headers.length;
29
+ wo.resize_flag = true;
30
+ headers = [];
31
+ for ( index = 0; index < len; index++ ) {
32
+ $header = c.$headers.eq( index );
33
+ sizes = $header.data( 'savedSizes' ) || [ 0, 0 ]; // fixes #394
34
+ width = $header[0].offsetWidth;
35
+ height = $header[0].offsetHeight;
36
+ if ( width !== sizes[0] || height !== sizes[1] ) {
37
+ $header.data( 'savedSizes', [ width, height ] );
38
+ headers.push( $header[0] );
39
+ }
39
40
  }
40
- }
41
- if ( headers.length && triggerEvent !== false ) {
42
- c.$table.trigger( 'resize', [ headers ] );
43
- }
41
+ if ( headers.length && triggerEvent !== false ) {
42
+ c.$table.trigger( 'resize', [ headers ] );
43
+ }
44
+ wo.resize_flag = false;
45
+ };
46
+ checkSizes( false );
47
+ clearInterval(wo.resize_timer);
48
+ if (disable) {
44
49
  wo.resize_flag = false;
45
- };
46
- checkSizes( false );
47
- clearInterval(wo.resize_timer);
48
- if (disable) {
49
- wo.resize_flag = false;
50
- return false;
51
- }
52
- wo.resize_timer = setInterval(function() {
53
- if (wo.resize_flag) { return; }
54
- checkSizes();
55
- }, options.timer);
56
- };
57
-
58
- // Sticky headers based on this awesome article:
59
- // http://css-tricks.com/13465-persistent-headers/
60
- // and https://github.com/jmosbech/StickyTableHeaders by Jonas Mosbech
61
- // **************************
62
- ts.addWidget({
63
- id: "stickyHeaders",
64
- priority: 60, // sticky widget must be initialized after the filter widget!
65
- options: {
66
- stickyHeaders : '', // extra class name added to the sticky header row
67
- stickyHeaders_attachTo : null, // jQuery selector or object to attach sticky header to
68
- stickyHeaders_xScroll : null, // jQuery selector or object to monitor horizontal scroll position (defaults: xScroll > attachTo > window)
69
- stickyHeaders_yScroll : null, // jQuery selector or object to monitor vertical scroll position (defaults: yScroll > attachTo > window)
70
- stickyHeaders_offset : 0, // number or jquery selector targeting the position:fixed element
71
- stickyHeaders_filteredToTop: true, // scroll table top into view after filtering
72
- stickyHeaders_cloneId : '-sticky', // added to table ID, if it exists
73
- stickyHeaders_addResizeEvent : true, // trigger "resize" event on headers
74
- stickyHeaders_includeCaption : true, // if false and a caption exist, it won't be included in the sticky header
75
- stickyHeaders_zIndex : 2 // The zIndex of the stickyHeaders, allows the user to adjust this to their needs
76
- },
77
- format: function(table, c, wo) {
78
- // filter widget doesn't initialize on an empty table. Fixes #449
79
- if ( c.$table.hasClass('hasStickyHeaders') || ($.inArray('filter', c.widgets) >= 0 && !c.$table.hasClass('hasFilters')) ) {
80
- return;
50
+ return false;
81
51
  }
82
- var index, len, $t,
83
- $table = c.$table,
84
- // add position: relative to attach element, hopefully it won't cause trouble.
85
- $attach = $(wo.stickyHeaders_attachTo),
86
- namespace = c.namespace + 'stickyheaders ',
87
- // element to watch for the scroll event
88
- $yScroll = $(wo.stickyHeaders_yScroll || wo.stickyHeaders_attachTo || window),
89
- $xScroll = $(wo.stickyHeaders_xScroll || wo.stickyHeaders_attachTo || window),
90
- $thead = $table.children('thead:first'),
91
- $header = $thead.children('tr').not('.sticky-false').children(),
92
- $tfoot = $table.children('tfoot'),
93
- $stickyOffset = isNaN(wo.stickyHeaders_offset) ? $(wo.stickyHeaders_offset) : '',
94
- stickyOffset = $stickyOffset.length ? $stickyOffset.height() || 0 : parseInt(wo.stickyHeaders_offset, 10) || 0,
95
- // is this table nested? If so, find parent sticky header wrapper (div, not table)
96
- $nestedSticky = $table.parent().closest('.' + ts.css.table).hasClass('hasStickyHeaders') ?
97
- $table.parent().closest('table.tablesorter')[0].config.widgetOptions.$sticky.parent() : [],
98
- nestedStickyTop = $nestedSticky.length ? $nestedSticky.height() : 0,
99
- // clone table, then wrap to make sticky header
100
- $stickyTable = wo.$sticky = $table.clone()
101
- .addClass('containsStickyHeaders ' + ts.css.sticky + ' ' + wo.stickyHeaders + ' ' + c.namespace.slice(1) + '_extra_table' )
102
- .wrap('<div class="' + ts.css.stickyWrap + '">'),
103
- $stickyWrap = $stickyTable.parent()
104
- .addClass(ts.css.stickyHide)
105
- .css({
106
- position : $attach.length ? 'absolute' : 'fixed',
107
- padding : parseInt( $stickyTable.parent().parent().css('padding-left'), 10 ),
108
- top : stickyOffset + nestedStickyTop,
109
- left : 0,
110
- visibility : 'hidden',
111
- zIndex : wo.stickyHeaders_zIndex || 2
112
- }),
113
- $stickyThead = $stickyTable.children('thead:first'),
114
- $stickyCells,
115
- laststate = '',
116
- spacing = 0,
117
- setWidth = function($orig, $clone){
118
- var index, width, border, $cell, $this,
119
- $cells = $orig.filter(':visible'),
120
- len = $cells.length;
121
- for ( index = 0; index < len; index++ ) {
122
- $cell = $clone.filter(':visible').eq(index);
123
- $this = $cells.eq(index);
124
- // code from https://github.com/jmosbech/StickyTableHeaders
125
- if ($this.css('box-sizing') === 'border-box') {
126
- width = $this.outerWidth();
127
- } else {
128
- if ($cell.css('border-collapse') === 'collapse') {
129
- if (window.getComputedStyle) {
130
- width = parseFloat( window.getComputedStyle($this[0], null).width );
52
+ wo.resize_timer = setInterval(function() {
53
+ if (wo.resize_flag) { return; }
54
+ checkSizes();
55
+ }, options.timer);
56
+ };
57
+
58
+ // Sticky headers based on this awesome article:
59
+ // http://css-tricks.com/13465-persistent-headers/
60
+ // and https://github.com/jmosbech/StickyTableHeaders by Jonas Mosbech
61
+ // **************************
62
+ ts.addWidget({
63
+ id: 'stickyHeaders',
64
+ priority: 60, // sticky widget must be initialized after the filter widget!
65
+ options: {
66
+ stickyHeaders : '', // extra class name added to the sticky header row
67
+ stickyHeaders_attachTo : null, // jQuery selector or object to attach sticky header to
68
+ stickyHeaders_xScroll : null, // jQuery selector or object to monitor horizontal scroll position (defaults: xScroll > attachTo > window)
69
+ stickyHeaders_yScroll : null, // jQuery selector or object to monitor vertical scroll position (defaults: yScroll > attachTo > window)
70
+ stickyHeaders_offset : 0, // number or jquery selector targeting the position:fixed element
71
+ stickyHeaders_filteredToTop: true, // scroll table top into view after filtering
72
+ stickyHeaders_cloneId : '-sticky', // added to table ID, if it exists
73
+ stickyHeaders_addResizeEvent : true, // trigger 'resize' event on headers
74
+ stickyHeaders_includeCaption : true, // if false and a caption exist, it won't be included in the sticky header
75
+ stickyHeaders_zIndex : 2 // The zIndex of the stickyHeaders, allows the user to adjust this to their needs
76
+ },
77
+ format: function(table, c, wo) {
78
+ // filter widget doesn't initialize on an empty table. Fixes #449
79
+ if ( c.$table.hasClass('hasStickyHeaders') || ($.inArray('filter', c.widgets) >= 0 && !c.$table.hasClass('hasFilters')) ) {
80
+ return;
81
+ }
82
+ var index, len, $t,
83
+ $table = c.$table,
84
+ // add position: relative to attach element, hopefully it won't cause trouble.
85
+ $attach = $(wo.stickyHeaders_attachTo),
86
+ namespace = c.namespace + 'stickyheaders ',
87
+ // element to watch for the scroll event
88
+ $yScroll = $(wo.stickyHeaders_yScroll || wo.stickyHeaders_attachTo || window),
89
+ $xScroll = $(wo.stickyHeaders_xScroll || wo.stickyHeaders_attachTo || window),
90
+ $thead = $table.children('thead:first'),
91
+ $header = $thead.children('tr').not('.sticky-false').children(),
92
+ $tfoot = $table.children('tfoot'),
93
+ $stickyOffset = isNaN(wo.stickyHeaders_offset) ? $(wo.stickyHeaders_offset) : '',
94
+ stickyOffset = $stickyOffset.length ? $stickyOffset.height() || 0 : parseInt(wo.stickyHeaders_offset, 10) || 0,
95
+ // is this table nested? If so, find parent sticky header wrapper (div, not table)
96
+ $nestedSticky = $table.parent().closest('.' + ts.css.table).hasClass('hasStickyHeaders') ?
97
+ $table.parent().closest('table.tablesorter')[0].config.widgetOptions.$sticky.parent() : [],
98
+ nestedStickyTop = $nestedSticky.length ? $nestedSticky.height() : 0,
99
+ // clone table, then wrap to make sticky header
100
+ $stickyTable = wo.$sticky = $table.clone()
101
+ .addClass('containsStickyHeaders ' + ts.css.sticky + ' ' + wo.stickyHeaders + ' ' + c.namespace.slice(1) + '_extra_table' )
102
+ .wrap('<div class="' + ts.css.stickyWrap + '">'),
103
+ $stickyWrap = $stickyTable.parent()
104
+ .addClass(ts.css.stickyHide)
105
+ .css({
106
+ position : $attach.length ? 'absolute' : 'fixed',
107
+ padding : parseInt( $stickyTable.parent().parent().css('padding-left'), 10 ),
108
+ top : stickyOffset + nestedStickyTop,
109
+ left : 0,
110
+ visibility : 'hidden',
111
+ zIndex : wo.stickyHeaders_zIndex || 2
112
+ }),
113
+ $stickyThead = $stickyTable.children('thead:first'),
114
+ $stickyCells,
115
+ laststate = '',
116
+ spacing = 0,
117
+ setWidth = function($orig, $clone){
118
+ var index, width, border, $cell, $this,
119
+ $cells = $orig.filter(':visible'),
120
+ len = $cells.length;
121
+ for ( index = 0; index < len; index++ ) {
122
+ $cell = $clone.filter(':visible').eq(index);
123
+ $this = $cells.eq(index);
124
+ // code from https://github.com/jmosbech/StickyTableHeaders
125
+ if ($this.css('box-sizing') === 'border-box') {
126
+ width = $this.outerWidth();
127
+ } else {
128
+ if ($cell.css('border-collapse') === 'collapse') {
129
+ if (window.getComputedStyle) {
130
+ width = parseFloat( window.getComputedStyle($this[0], null).width );
131
+ } else {
132
+ // ie8 only
133
+ border = parseFloat( $this.css('border-width') );
134
+ width = $this.outerWidth() - parseFloat( $this.css('padding-left') ) - parseFloat( $this.css('padding-right') ) - border;
135
+ }
131
136
  } else {
132
- // ie8 only
133
- border = parseFloat( $this.css('border-width') );
134
- width = $this.outerWidth() - parseFloat( $this.css('padding-left') ) - parseFloat( $this.css('padding-right') ) - border;
137
+ width = $this.width();
135
138
  }
136
- } else {
137
- width = $this.width();
138
139
  }
140
+ $cell.css({
141
+ 'width': width,
142
+ 'min-width': width,
143
+ 'max-width': width
144
+ });
139
145
  }
140
- $cell.css({
141
- 'width': width,
142
- 'min-width': width,
143
- 'max-width': width
146
+ },
147
+ resizeHeader = function() {
148
+ stickyOffset = $stickyOffset.length ? $stickyOffset.height() || 0 : parseInt(wo.stickyHeaders_offset, 10) || 0;
149
+ spacing = 0;
150
+ $stickyWrap.css({
151
+ left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
152
+ $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft() - spacing,
153
+ width: $table.outerWidth()
144
154
  });
145
- }
146
- },
147
- resizeHeader = function() {
148
- stickyOffset = $stickyOffset.length ? $stickyOffset.height() || 0 : parseInt(wo.stickyHeaders_offset, 10) || 0;
149
- spacing = 0;
150
- $stickyWrap.css({
151
- left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
152
- $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft() - spacing,
153
- width: $table.outerWidth()
154
- });
155
- setWidth( $table, $stickyTable );
156
- setWidth( $header, $stickyCells );
157
- },
158
- scrollSticky = function( resizing ) {
159
- if (!$table.is(':visible')) { return; } // fixes #278
160
- // Detect nested tables - fixes #724
161
- nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
162
- var offset = $table.offset(),
163
- yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
164
- xWindow = $.isWindow( $xScroll[0] ),
165
- // scrollTop = ( $attach.length ? $attach.offset().top : $yScroll.scrollTop() ) + stickyOffset + nestedStickyTop,
166
- scrollTop = ( $attach.length ? ( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) : $yScroll.scrollTop() ) + stickyOffset + nestedStickyTop,
167
- tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)),
168
- isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
169
- cssSettings = { visibility : isVisible };
155
+ setWidth( $table, $stickyTable );
156
+ setWidth( $header, $stickyCells );
157
+ },
158
+ scrollSticky = function( resizing ) {
159
+ if (!$table.is(':visible')) { return; } // fixes #278
160
+ // Detect nested tables - fixes #724
161
+ nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
162
+ var offset = $table.offset(),
163
+ yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
164
+ xWindow = $.isWindow( $xScroll[0] ),
165
+ // scrollTop = ( $attach.length ? $attach.offset().top : $yScroll.scrollTop() ) + stickyOffset + nestedStickyTop,
166
+ scrollTop = ( $attach.length ? ( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) : $yScroll.scrollTop() ) + stickyOffset + nestedStickyTop,
167
+ tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)),
168
+ isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
169
+ cssSettings = { visibility : isVisible };
170
170
 
171
- if ($attach.length) {
172
- cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
173
- }
174
- if (xWindow) {
175
- // adjust when scrolling horizontally - fixes issue #143
176
- cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft() - spacing;
177
- }
178
- if ($nestedSticky.length) {
179
- cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
180
- }
181
- $stickyWrap
182
- .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
183
- .addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
184
- .css(cssSettings);
185
- if (isVisible !== laststate || resizing) {
186
- // make sure the column widths match
171
+ if ($attach.length) {
172
+ cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
173
+ }
174
+ if (xWindow) {
175
+ // adjust when scrolling horizontally - fixes issue #143
176
+ cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft() - spacing;
177
+ }
178
+ if ($nestedSticky.length) {
179
+ cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
180
+ }
181
+ $stickyWrap
182
+ .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
183
+ .addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
184
+ .css(cssSettings);
185
+ if (isVisible !== laststate || resizing) {
186
+ // make sure the column widths match
187
+ resizeHeader();
188
+ laststate = isVisible;
189
+ }
190
+ };
191
+ // only add a position relative if a position isn't already defined
192
+ if ($attach.length && !$attach.css('position')) {
193
+ $attach.css('position', 'relative');
194
+ }
195
+ // fix clone ID, if it exists - fixes #271
196
+ if ($stickyTable.attr('id')) { $stickyTable[0].id += wo.stickyHeaders_cloneId; }
197
+ // clear out cloned table, except for sticky header
198
+ // include caption & filter row (fixes #126 & #249) - don't remove cells to get correct cell indexing
199
+ $stickyTable.find('thead:gt(0), tr.sticky-false').hide();
200
+ $stickyTable.find('tbody, tfoot').remove();
201
+ $stickyTable.find('caption').toggle(wo.stickyHeaders_includeCaption);
202
+ // issue #172 - find td/th in sticky header
203
+ $stickyCells = $stickyThead.children().children();
204
+ $stickyTable.css({ height:0, width:0, margin: 0 });
205
+ // remove resizable block
206
+ $stickyCells.find('.' + ts.css.resizer).remove();
207
+ // update sticky header class names to match real header after sorting
208
+ $table
209
+ .addClass('hasStickyHeaders')
210
+ .bind('pagerComplete' + namespace, function() {
187
211
  resizeHeader();
188
- laststate = isVisible;
189
- }
190
- };
191
- // only add a position relative if a position isn't already defined
192
- if ($attach.length && !$attach.css('position')) {
193
- $attach.css('position', 'relative');
194
- }
195
- // fix clone ID, if it exists - fixes #271
196
- if ($stickyTable.attr('id')) { $stickyTable[0].id += wo.stickyHeaders_cloneId; }
197
- // clear out cloned table, except for sticky header
198
- // include caption & filter row (fixes #126 & #249) - don't remove cells to get correct cell indexing
199
- $stickyTable.find('thead:gt(0), tr.sticky-false').hide();
200
- $stickyTable.find('tbody, tfoot').remove();
201
- $stickyTable.find('caption').toggle(wo.stickyHeaders_includeCaption);
202
- // issue #172 - find td/th in sticky header
203
- $stickyCells = $stickyThead.children().children();
204
- $stickyTable.css({ height:0, width:0, margin: 0 });
205
- // remove resizable block
206
- $stickyCells.find('.' + ts.css.resizer).remove();
207
- // update sticky header class names to match real header after sorting
208
- $table
209
- .addClass('hasStickyHeaders')
210
- .bind('pagerComplete' + namespace, function() {
211
- resizeHeader();
212
- });
212
+ });
213
213
 
214
- ts.bindEvents(table, $stickyThead.children().children('.' + ts.css.header));
214
+ ts.bindEvents(table, $stickyThead.children().children('.' + ts.css.header));
215
215
 
216
- // add stickyheaders AFTER the table. If the table is selected by ID, the original one (first) will be returned.
217
- $table.after( $stickyWrap );
216
+ // add stickyheaders AFTER the table. If the table is selected by ID, the original one (first) will be returned.
217
+ $table.after( $stickyWrap );
218
218
 
219
- // onRenderHeader is defined, we need to do something about it (fixes #641)
220
- if (c.onRenderHeader) {
221
- $t = $stickyThead.children('tr').children();
222
- len = $t.length;
223
- for ( index = 0; index < len; index++ ) {
224
- // send second parameter
225
- c.onRenderHeader.apply( $t.eq( index ), [ index, c, $stickyTable ] );
219
+ // onRenderHeader is defined, we need to do something about it (fixes #641)
220
+ if (c.onRenderHeader) {
221
+ $t = $stickyThead.children('tr').children();
222
+ len = $t.length;
223
+ for ( index = 0; index < len; index++ ) {
224
+ // send second parameter
225
+ c.onRenderHeader.apply( $t.eq( index ), [ index, c, $stickyTable ] );
226
+ }
226
227
  }
227
- }
228
228
 
229
- // make it sticky!
230
- $xScroll.add($yScroll)
231
- .unbind( ('scroll resize '.split(' ').join( namespace )).replace(/\s+/g, ' ') )
232
- .bind('scroll resize '.split(' ').join( namespace ), function( event ) {
233
- scrollSticky( event.type === 'resize' );
234
- });
235
- c.$table
236
- .unbind('stickyHeadersUpdate' + namespace)
237
- .bind('stickyHeadersUpdate' + namespace, function(){
238
- scrollSticky( true );
239
- });
229
+ // make it sticky!
230
+ $xScroll.add($yScroll)
231
+ .unbind( ('scroll resize '.split(' ').join( namespace )).replace(/\s+/g, ' ') )
232
+ .bind('scroll resize '.split(' ').join( namespace ), function( event ) {
233
+ scrollSticky( event.type === 'resize' );
234
+ });
235
+ c.$table
236
+ .unbind('stickyHeadersUpdate' + namespace)
237
+ .bind('stickyHeadersUpdate' + namespace, function(){
238
+ scrollSticky( true );
239
+ });
240
240
 
241
- if (wo.stickyHeaders_addResizeEvent) {
242
- ts.addHeaderResizeEvent(table);
243
- }
241
+ if (wo.stickyHeaders_addResizeEvent) {
242
+ ts.addHeaderResizeEvent(table);
243
+ }
244
244
 
245
- // look for filter widget
246
- if ($table.hasClass('hasFilters') && wo.filter_columnFilters) {
247
- // scroll table into view after filtering, if sticky header is active - #482
248
- $table.bind('filterEnd' + namespace, function() {
249
- // $(':focus') needs jQuery 1.6+
250
- var $td = $(document.activeElement).closest('td'),
251
- column = $td.parent().children().index($td);
252
- // only scroll if sticky header is active
253
- if ($stickyWrap.hasClass(ts.css.stickyVis) && wo.stickyHeaders_filteredToTop) {
254
- // scroll to original table (not sticky clone)
255
- window.scrollTo(0, $table.position().top);
256
- // give same input/select focus; check if c.$filters exists; fixes #594
257
- if (column >= 0 && c.$filters) {
258
- c.$filters.eq(column).find('a, select, input').filter(':visible').focus();
245
+ // look for filter widget
246
+ if ($table.hasClass('hasFilters') && wo.filter_columnFilters) {
247
+ // scroll table into view after filtering, if sticky header is active - #482
248
+ $table.bind('filterEnd' + namespace, function() {
249
+ // $(':focus') needs jQuery 1.6+
250
+ var $td = $(document.activeElement).closest('td'),
251
+ column = $td.parent().children().index($td);
252
+ // only scroll if sticky header is active
253
+ if ($stickyWrap.hasClass(ts.css.stickyVis) && wo.stickyHeaders_filteredToTop) {
254
+ // scroll to original table (not sticky clone)
255
+ window.scrollTo(0, $table.position().top);
256
+ // give same input/select focus; check if c.$filters exists; fixes #594
257
+ if (column >= 0 && c.$filters) {
258
+ c.$filters.eq(column).find('a, select, input').filter(':visible').focus();
259
+ }
259
260
  }
261
+ });
262
+ ts.filter.bindSearch( $table, $stickyCells.find('.' + ts.css.filter) );
263
+ // support hideFilters
264
+ if (wo.filter_hideFilters) {
265
+ ts.filter.hideFilters($stickyTable, c);
260
266
  }
261
- });
262
- ts.filter.bindSearch( $table, $stickyCells.find('.' + ts.css.filter) );
263
- // support hideFilters
264
- if (wo.filter_hideFilters) {
265
- ts.filter.hideFilters($stickyTable, c);
266
267
  }
267
- }
268
268
 
269
- $table.trigger('stickyHeadersInit');
269
+ $table.trigger('stickyHeadersInit');
270
270
 
271
- },
272
- remove: function(table, c, wo) {
273
- var namespace = c.namespace + 'stickyheaders ';
274
- c.$table
275
- .removeClass('hasStickyHeaders')
276
- .unbind( ('pagerComplete filterEnd stickyHeadersUpdate '.split(' ').join(namespace)).replace(/\s+/g, ' ') )
277
- .next('.' + ts.css.stickyWrap).remove();
278
- if (wo.$sticky && wo.$sticky.length) { wo.$sticky.remove(); } // remove cloned table
279
- $(window)
280
- .add(wo.stickyHeaders_xScroll)
281
- .add(wo.stickyHeaders_yScroll)
282
- .add(wo.stickyHeaders_attachTo)
283
- .unbind( ('scroll resize '.split(' ').join(namespace)).replace(/\s+/g, ' ') );
284
- ts.addHeaderResizeEvent(table, false);
285
- }
286
- });
271
+ },
272
+ remove: function(table, c, wo) {
273
+ var namespace = c.namespace + 'stickyheaders ';
274
+ c.$table
275
+ .removeClass('hasStickyHeaders')
276
+ .unbind( ('pagerComplete filterEnd stickyHeadersUpdate '.split(' ').join(namespace)).replace(/\s+/g, ' ') )
277
+ .next('.' + ts.css.stickyWrap).remove();
278
+ if (wo.$sticky && wo.$sticky.length) { wo.$sticky.remove(); } // remove cloned table
279
+ $(window)
280
+ .add(wo.stickyHeaders_xScroll)
281
+ .add(wo.stickyHeaders_yScroll)
282
+ .add(wo.stickyHeaders_attachTo)
283
+ .unbind( ('scroll resize '.split(' ').join(namespace)).replace(/\s+/g, ' ') );
284
+ ts.addHeaderResizeEvent(table, false);
285
+ }
286
+ });
287
287
 
288
288
  })(jQuery, window);