jquery-tablesorter 1.17.2 → 1.17.3

Sign up to get free protection for your applications and to get access to all the features.
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);