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
@@ -1,68 +1,68 @@
1
1
  /*! Widget: saveSort */
2
2
  ;(function ($) {
3
- 'use strict';
4
- var ts = $.tablesorter || {};
3
+ 'use strict';
4
+ var ts = $.tablesorter || {};
5
5
 
6
- // this widget saves the last sort only if the
7
- // saveSort widget option is true AND the
8
- // $.tablesorter.storage function is included
9
- // **************************
10
- ts.addWidget({
11
- id: 'saveSort',
12
- priority: 20,
13
- options: {
14
- saveSort : true
15
- },
16
- init: function(table, thisWidget, c, wo) {
17
- // run widget format before all other widgets are applied to the table
18
- thisWidget.format(table, c, wo, true);
19
- },
20
- format: function(table, c, wo, init) {
21
- var stored, time,
22
- $table = c.$table,
23
- saveSort = wo.saveSort !== false, // make saveSort active/inactive; default to true
24
- sortList = { "sortList" : c.sortList };
25
- if (c.debug) {
26
- time = new Date();
27
- }
28
- if ($table.hasClass('hasSaveSort')) {
29
- if (saveSort && table.hasInitialized && ts.storage) {
30
- ts.storage( table, 'tablesorter-savesort', sortList );
31
- if (c.debug) {
32
- ts.benchmark('saveSort widget: Saving last sort: ' + c.sortList, time);
33
- }
6
+ // this widget saves the last sort only if the
7
+ // saveSort widget option is true AND the
8
+ // $.tablesorter.storage function is included
9
+ // **************************
10
+ ts.addWidget({
11
+ id: 'saveSort',
12
+ priority: 20,
13
+ options: {
14
+ saveSort : true
15
+ },
16
+ init: function(table, thisWidget, c, wo) {
17
+ // run widget format before all other widgets are applied to the table
18
+ thisWidget.format(table, c, wo, true);
19
+ },
20
+ format: function(table, c, wo, init) {
21
+ var stored, time,
22
+ $table = c.$table,
23
+ saveSort = wo.saveSort !== false, // make saveSort active/inactive; default to true
24
+ sortList = { 'sortList' : c.sortList };
25
+ if (c.debug) {
26
+ time = new Date();
34
27
  }
35
- } else {
36
- // set table sort on initial run of the widget
37
- $table.addClass('hasSaveSort');
38
- sortList = '';
39
- // get data
40
- if (ts.storage) {
41
- stored = ts.storage( table, 'tablesorter-savesort' );
42
- sortList = (stored && stored.hasOwnProperty('sortList') && $.isArray(stored.sortList)) ? stored.sortList : '';
43
- if (c.debug) {
44
- ts.benchmark('saveSort: Last sort loaded: "' + sortList + '"', time);
28
+ if ($table.hasClass('hasSaveSort')) {
29
+ if (saveSort && table.hasInitialized && ts.storage) {
30
+ ts.storage( table, 'tablesorter-savesort', sortList );
31
+ if (c.debug) {
32
+ console.log('saveSort widget: Saving last sort: ' + c.sortList + ts.benchmark(time));
33
+ }
34
+ }
35
+ } else {
36
+ // set table sort on initial run of the widget
37
+ $table.addClass('hasSaveSort');
38
+ sortList = '';
39
+ // get data
40
+ if (ts.storage) {
41
+ stored = ts.storage( table, 'tablesorter-savesort' );
42
+ sortList = (stored && stored.hasOwnProperty('sortList') && $.isArray(stored.sortList)) ? stored.sortList : '';
43
+ if (c.debug) {
44
+ console.log('saveSort: Last sort loaded: "' + sortList + '"' + ts.benchmark(time));
45
+ }
46
+ $table.bind('saveSortReset', function(event) {
47
+ event.stopPropagation();
48
+ ts.storage( table, 'tablesorter-savesort', '' );
49
+ });
50
+ }
51
+ // init is true when widget init is run, this will run this widget before all other widgets have initialized
52
+ // this method allows using this widget in the original tablesorter plugin; but then it will run all widgets twice.
53
+ if (init && sortList && sortList.length > 0) {
54
+ c.sortList = sortList;
55
+ } else if (table.hasInitialized && sortList && sortList.length > 0) {
56
+ // update sort change
57
+ $table.trigger('sorton', [ sortList ]);
45
58
  }
46
- $table.bind('saveSortReset', function(event) {
47
- event.stopPropagation();
48
- ts.storage( table, 'tablesorter-savesort', '' );
49
- });
50
- }
51
- // init is true when widget init is run, this will run this widget before all other widgets have initialized
52
- // this method allows using this widget in the original tablesorter plugin; but then it will run all widgets twice.
53
- if (init && sortList && sortList.length > 0) {
54
- c.sortList = sortList;
55
- } else if (table.hasInitialized && sortList && sortList.length > 0) {
56
- // update sort change
57
- $table.trigger('sorton', [sortList]);
58
59
  }
60
+ },
61
+ remove: function(table, c) {
62
+ c.$table.removeClass('hasSaveSort');
63
+ // clear storage
64
+ if (ts.storage) { ts.storage( table, 'tablesorter-savesort', '' ); }
59
65
  }
60
- },
61
- remove: function(table, c) {
62
- c.$table.removeClass('hasSaveSort');
63
- // clear storage
64
- if (ts.storage) { ts.storage( table, 'tablesorter-savesort', '' ); }
65
- }
66
- });
66
+ });
67
67
 
68
68
  })(jQuery);
@@ -1,4 +1,4 @@
1
- /*! Widget: scroller - updated 5/17/2015 (v2.22.0) *//*
1
+ /*! Widget: scroller - updated 7/28/2015 (v2.22.4) *//*
2
2
  Copyright (C) 2011 T. Connell & Associates, Inc.
3
3
 
4
4
  Dual-licensed under the MIT and GPL licenses
@@ -33,873 +33,885 @@
33
33
  */
34
34
  /*jshint browser:true, jquery:true, unused:false */
35
35
  ;( function( $, window ) {
36
- 'use strict';
37
-
38
- var ts = $.tablesorter,
39
- tscss = ts.css;
40
-
41
- $.extend( ts.css, {
42
- scrollerWrap : 'tablesorter-scroller',
43
- scrollerHeader : 'tablesorter-scroller-header',
44
- scrollerTable : 'tablesorter-scroller-table',
45
- scrollerFooter : 'tablesorter-scroller-footer',
46
- scrollerFixed : 'tablesorter-scroller-fixed',
47
- scrollerFixedPanel : 'tablesorter-scroller-fixed-panel',
48
- scrollerHasFix : 'tablesorter-scroller-has-fixed-columns',
49
- scrollerHideColumn : 'tablesorter-scroller-hidden-column',
50
- scrollerHideElement : 'tablesorter-scroller-hidden',
51
- scrollerSpacerRow : 'tablesorter-scroller-spacer',
52
- scrollerBarSpacer : 'tablesorter-scroller-bar-spacer',
53
- scrollerAddedHeight : 'tablesorter-scroller-added-height',
54
- scrollerHack : 'tablesorter-scroller-scrollbar-hack',
55
- // class name on table cannot start with 'tablesorter-' or the
56
- // suffix "scroller-rtl" will match as a theme name
57
- scrollerRtl : 'ts-scroller-rtl'
58
- });
59
-
60
- ts.addWidget({
61
- id : 'scroller',
62
- priority : 60, // run after the filter widget
63
- options : {
64
- scroller_height : 300,
65
- // pop table header into view while scrolling up the page
66
- scroller_jumpToHeader : true,
67
- // scroll tbody to top after sorting
68
- scroller_upAfterSort : true,
69
- // set number of fixed columns
70
- scroller_fixedColumns : 0,
71
- // add hover highlighting to the fixed column (disable if it causes slowing)
72
- scroller_rowHighlight : 'hover',
73
- // add a fixed column overlay for styling
74
- scroller_addFixedOverlay : false,
75
- // In tablesorter v2.19.0 the scroll bar width is auto-detected
76
- // add a value here to override the auto-detected setting
77
- scroller_barWidth : null
78
- },
79
- format : function( table, c, wo ) {
80
- if ( !c.isScrolling ) {
81
- // initialize here instead of in widget init to give the
82
- // filter widget time to finish building the filter row
83
- ts.scroller.setup( c, wo );
84
- }
85
- },
86
- remove : function( table, c, wo ) {
87
- ts.scroller.remove( c, wo );
88
- }
89
- });
90
-
91
- /* Add window resizeEnd event */
92
- ts.window_resize = function() {
93
- if ( ts.timer_resize ) {
94
- clearTimeout( ts.timer_resize );
95
- }
96
- ts.timer_resize = setTimeout( function() {
97
- $( window ).trigger( 'resizeEnd' );
98
- }, 250 );
99
- };
100
-
101
- // Add extra scroller css
102
- $( function() {
103
- var style = '<style>' +
104
- /* overall wrapper & table section wrappers */
105
- '.' + tscss.scrollerWrap + ' { position: relative; overflow: hidden; }' +
106
- /* add border-box sizing to all scroller widget tables; see #135 */
107
- '.' + tscss.scrollerWrap + ' * { box-sizing: border-box; }' +
108
- '.' + tscss.scrollerHeader + ', .' + tscss.scrollerFooter + ' { position: relative; overflow: hidden; }' +
109
- '.' + tscss.scrollerHeader + ' table.' + tscss.table + ' { margin-bottom: 0; }' +
110
- /* always leave the scroll bar visible for tbody, or table overflows into the scrollbar
111
- when height < max height (filtering) */
112
- '.' + tscss.scrollerTable + ' { position: relative; overflow: auto; }' +
113
- '.' + tscss.scrollerTable + ' table.' + tscss.table +
114
- ' { border-top: 0; margin-top: 0; margin-bottom: 0; overflow: hidden; }' +
115
- /* hide footer in original table */
116
- '.' + tscss.scrollerTable + ' tfoot, .' + tscss.scrollerHideElement + ', .' + tscss.scrollerHideColumn +
117
- ' { display: none; }' +
118
-
119
- /*** fixed column ***/
120
- /* disable pointer-events on fixed column wrapper or the user can't interact with the horizontal scrollbar */
121
- '.' + tscss.scrollerFixed + ', .' + tscss.scrollerFixed + ' .' + tscss.scrollerFixedPanel +
122
- ' { pointer-events: none; }' +
123
- /* enable pointer-events for fixed column children; see #135 & #878 */
124
- '.' + tscss.scrollerFixed + ' > div { pointer-events: all; }' +
125
- '.' + tscss.scrollerWrap + ' .' + tscss.scrollerFixed + ' { position: absolute; top: 0; z-index: 1; left: 0 } ' +
126
- '.' + tscss.scrollerWrap + ' .' + tscss.scrollerFixed + '.' + tscss.scrollerRtl + ' { left: auto; right: 0 } ' +
127
- /* add horizontal scroll bar; set to "auto", see #135 */
128
- '.' + tscss.scrollerWrap + '.' + tscss.scrollerHasFix + ' > .' + tscss.scrollerTable + ' { overflow: auto; }' +
129
- /* need to position the tbody & tfoot absolutely to hide the scrollbar & move the footer
130
- below the horizontal scrollbar */
131
- '.' + tscss.scrollerFixed + ' .' + tscss.scrollerFooter + ' { position: absolute; bottom: 0; }' +
132
- /* hide fixed tbody scrollbar - see http://goo.gl/VsLe6n - set overflow to auto here for mousewheel scroll */
133
- '.' + tscss.scrollerFixed + ' .' + tscss.scrollerTable +
134
- ' { position: relative; left: 0; overflow: auto; -ms-overflow-style: none; }' +
135
- '.' + tscss.scrollerFixed + ' .' + tscss.scrollerTable + '::-webkit-scrollbar { display: none; }' +
136
- /*** fixed column panel ***/
137
- '.' + tscss.scrollerWrap + ' .' + tscss.scrollerFixedPanel +
138
- ' { position: absolute; top: 0; bottom: 0; z-index: 2; left: 0; right: 0; } ' +
139
- '</style>';
140
- $( style ).appendTo( 'body' );
141
- });
142
-
143
- ts.scroller = {
144
-
145
- // Ugh.. Firefox misbehaves, so it needs to be detected
146
- isFirefox : navigator.userAgent.toLowerCase().indexOf( 'firefox' ) > -1,
147
- // old IE needs a wrap to hide the fixed column scrollbar; http://stackoverflow.com/a/24408672/145346
148
- isOldIE : document.all && !window.atob,
149
- isIE : ( document.all && !window.atob ) || navigator.appVersion.indexOf( 'Trident/' ) > 0,
150
- // http://stackoverflow.com/questions/7944460/detect-safari-browser - needed to position scrolling body
151
- // when the table is set up in RTL direction
152
- isSafari : navigator.userAgent.toLowerCase().indexOf( 'safari' ) > -1 &&
153
- navigator.userAgent.toLowerCase().indexOf( 'chrome' ) === -1,
154
-
155
- hasScrollBar : function( $target, checkWidth ) {
156
- if ( checkWidth ) {
157
- return $target.get(0).scrollWidth > $target.width();
158
- } else {
159
- return $target.get(0).scrollHeight > $target.height();
36
+ 'use strict';
37
+
38
+ var ts = $.tablesorter,
39
+ tscss = ts.css;
40
+
41
+ $.extend( ts.css, {
42
+ scrollerWrap : 'tablesorter-scroller',
43
+ scrollerHeader : 'tablesorter-scroller-header',
44
+ scrollerTable : 'tablesorter-scroller-table',
45
+ scrollerFooter : 'tablesorter-scroller-footer',
46
+ scrollerFixed : 'tablesorter-scroller-fixed',
47
+ scrollerFixedPanel : 'tablesorter-scroller-fixed-panel',
48
+ scrollerHasFix : 'tablesorter-scroller-has-fixed-columns',
49
+ scrollerHideColumn : 'tablesorter-scroller-hidden-column',
50
+ scrollerHideElement : 'tablesorter-scroller-hidden',
51
+ scrollerSpacerRow : 'tablesorter-scroller-spacer',
52
+ scrollerBarSpacer : 'tablesorter-scroller-bar-spacer',
53
+ scrollerAddedHeight : 'tablesorter-scroller-added-height',
54
+ scrollerHack : 'tablesorter-scroller-scrollbar-hack',
55
+ // class name on table cannot start with 'tablesorter-' or the
56
+ // suffix 'scroller-rtl' will match as a theme name
57
+ scrollerRtl : 'ts-scroller-rtl'
58
+ });
59
+
60
+ ts.addWidget({
61
+ id : 'scroller',
62
+ priority : 60, // run after the filter widget
63
+ options : {
64
+ scroller_height : 300,
65
+ // pop table header into view while scrolling up the page
66
+ scroller_jumpToHeader : true,
67
+ // scroll tbody to top after sorting
68
+ scroller_upAfterSort : true,
69
+ // set number of fixed columns
70
+ scroller_fixedColumns : 0,
71
+ // add hover highlighting to the fixed column (disable if it causes slowing)
72
+ scroller_rowHighlight : 'hover',
73
+ // add a fixed column overlay for styling
74
+ scroller_addFixedOverlay : false,
75
+ // In tablesorter v2.19.0 the scroll bar width is auto-detected
76
+ // add a value here to override the auto-detected setting
77
+ scroller_barWidth : null
78
+ },
79
+ format : function( table, c, wo ) {
80
+ if ( !c.isScrolling ) {
81
+ // initialize here instead of in widget init to give the
82
+ // filter widget time to finish building the filter row
83
+ ts.scroller.setup( c, wo );
84
+ }
85
+ },
86
+ remove : function( table, c, wo ) {
87
+ ts.scroller.remove( c, wo );
160
88
  }
161
- },
89
+ });
162
90
 
163
- setWidth : function( $el, width ) {
164
- $el.css({
165
- 'width' : width,
166
- 'min-width' : width,
167
- 'max-width' : width
168
- });
169
- },
170
-
171
- // modified from http://davidwalsh.name/detect-scrollbar-width
172
- getBarWidth : function() {
173
- var $div = $( '<div>' ).css({
174
- 'position' : 'absolute',
175
- 'top' : '-9999px',
176
- 'left' : 0,
177
- 'width' : '100px',
178
- 'height' : '100px',
179
- 'overflow' : 'scroll',
180
- 'visibility' : 'hidden'
181
- }).appendTo( 'body' ),
182
- div = $div[0],
183
- barWidth = div.offsetWidth - div.clientWidth;
184
- $div.remove();
185
- return barWidth;
186
- },
187
-
188
- setup : function( c, wo ) {
189
- var maxHt, tbHt, $hdr, $t, $hCells, $fCells, $tableWrap, events, tmp,
190
- $win = $( window ),
191
- tsScroller = ts.scroller,
192
- namespace = c.namespace + 'tsscroller',
193
- $foot = $(),
194
- // c.namespace contains a unique tablesorter ID, per table
195
- id = c.namespace.slice( 1 ) + 'tsscroller',
196
- $table = c.$table;
197
-
198
- // force config.widthFixed option - this helps maintain proper alignment across cloned tables
199
- c.widthFixed = true;
200
-
201
- wo.scroller_calcWidths = [];
202
- wo.scroller_saved = [ 0, 0 ];
203
- wo.scroller_isBusy = true;
204
-
205
- // set scrollbar width & allow setting width to zero
206
- wo.scroller_barSetWidth = wo.scroller_barWidth !== null ?
207
- wo.scroller_barWidth :
208
- ( tsScroller.getBarWidth() || 15 );
209
-
210
- maxHt = wo.scroller_height || 300;
211
-
212
- $hdr = $( '<table class="' + $table.attr( 'class' ) + '" cellpadding=0 cellspacing=0>' +
213
- $table.children( 'thead' )[ 0 ].outerHTML + '</table>' );
214
- wo.scroller_$header = $hdr.addClass( c.namespace.slice( 1 ) + '_extra_table' );
215
-
216
- $t = $table.children( 'tfoot' );
217
- if ( $t.length ) {
218
- $foot = $( '<table class="' + $table.attr( 'class' ) +
219
- '" cellpadding=0 cellspacing=0 style="margin-top:0"></table>' )
220
- .addClass( c.namespace.slice( 1 ) + '_extra_table' )
221
- // maintain any bindings on the tfoot cells
222
- .append( $t.clone( true ) )
223
- .wrap( '<div class="' + tscss.scrollerFooter + '"/>' );
224
- $fCells = $foot.children( 'tfoot' ).eq( 0 ).children( 'tr' ).children();
91
+ /* Add window resizeEnd event */
92
+ ts.window_resize = function() {
93
+ if ( ts.timer_resize ) {
94
+ clearTimeout( ts.timer_resize );
225
95
  }
226
- wo.scroller_$footer = $foot;
96
+ ts.timer_resize = setTimeout( function() {
97
+ $( window ).trigger( 'resizeEnd' );
98
+ }, 250 );
99
+ };
100
+
101
+ // Add extra scroller css
102
+ $( function() {
103
+ var style = '<style>' +
104
+ /* overall wrapper & table section wrappers */
105
+ '.' + tscss.scrollerWrap + ' { position: relative; overflow: hidden; }' +
106
+ /* add border-box sizing to all scroller widget tables; see #135 */
107
+ '.' + tscss.scrollerWrap + ' * { box-sizing: border-box; }' +
108
+ '.' + tscss.scrollerHeader + ', .' + tscss.scrollerFooter + ' { position: relative; overflow: hidden; }' +
109
+ '.' + tscss.scrollerHeader + ' table.' + tscss.table + ' { margin-bottom: 0; }' +
110
+ /* always leave the scroll bar visible for tbody, or table overflows into the scrollbar
111
+ when height < max height (filtering) */
112
+ '.' + tscss.scrollerTable + ' { position: relative; overflow: auto; }' +
113
+ '.' + tscss.scrollerTable + ' table.' + tscss.table +
114
+ ' { border-top: 0; margin-top: 0; margin-bottom: 0; overflow: hidden; }' +
115
+ /* hide footer in original table */
116
+ '.' + tscss.scrollerTable + ' tfoot, .' + tscss.scrollerHideElement + ', .' + tscss.scrollerHideColumn +
117
+ ' { display: none; }' +
118
+
119
+ /*** fixed column ***/
120
+ /* disable pointer-events on fixed column wrapper or the user can't interact with the horizontal scrollbar */
121
+ '.' + tscss.scrollerFixed + ', .' + tscss.scrollerFixed + ' .' + tscss.scrollerFixedPanel +
122
+ ' { pointer-events: none; }' +
123
+ /* enable pointer-events for fixed column children; see #135 & #878 */
124
+ '.' + tscss.scrollerFixed + ' > div { pointer-events: all; }' +
125
+ '.' + tscss.scrollerWrap + ' .' + tscss.scrollerFixed + ' { position: absolute; top: 0; z-index: 1; left: 0 } ' +
126
+ '.' + tscss.scrollerWrap + ' .' + tscss.scrollerFixed + '.' + tscss.scrollerRtl + ' { left: auto; right: 0 } ' +
127
+ /* add horizontal scroll bar; set to 'auto', see #135 */
128
+ '.' + tscss.scrollerWrap + '.' + tscss.scrollerHasFix + ' > .' + tscss.scrollerTable + ' { overflow: auto; }' +
129
+ /* need to position the tbody & tfoot absolutely to hide the scrollbar & move the footer
130
+ below the horizontal scrollbar */
131
+ '.' + tscss.scrollerFixed + ' .' + tscss.scrollerFooter + ' { position: absolute; bottom: 0; }' +
132
+ /* hide fixed tbody scrollbar - see http://goo.gl/VsLe6n - set overflow to auto here for mousewheel scroll */
133
+ '.' + tscss.scrollerFixed + ' .' + tscss.scrollerTable +
134
+ ' { position: relative; left: 0; overflow: auto; -ms-overflow-style: none; }' +
135
+ '.' + tscss.scrollerFixed + ' .' + tscss.scrollerTable + '::-webkit-scrollbar { display: none; }' +
136
+ /*** fixed column panel ***/
137
+ '.' + tscss.scrollerWrap + ' .' + tscss.scrollerFixedPanel +
138
+ ' { position: absolute; top: 0; bottom: 0; z-index: 2; left: 0; right: 0; } ' +
139
+ '</style>';
140
+ $( style ).appendTo( 'body' );
141
+ });
142
+
143
+ ts.scroller = {
144
+
145
+ // Ugh.. Firefox misbehaves, so it needs to be detected
146
+ isFirefox : navigator.userAgent.toLowerCase().indexOf( 'firefox' ) > -1,
147
+ // old IE needs a wrap to hide the fixed column scrollbar; http://stackoverflow.com/a/24408672/145346
148
+ isOldIE : document.all && !window.atob,
149
+ isIE : ( document.all && !window.atob ) || navigator.appVersion.indexOf( 'Trident/' ) > 0,
150
+ // http://stackoverflow.com/questions/7944460/detect-safari-browser - needed to position scrolling body
151
+ // when the table is set up in RTL direction
152
+ isSafari : navigator.userAgent.toLowerCase().indexOf( 'safari' ) > -1 &&
153
+ navigator.userAgent.toLowerCase().indexOf( 'chrome' ) === -1,
154
+
155
+ hasScrollBar : function( $target, checkWidth ) {
156
+ if ( checkWidth ) {
157
+ return $target.get(0).scrollWidth > $target.width();
158
+ } else {
159
+ return $target.get(0).scrollHeight > $target.height();
160
+ }
161
+ },
227
162
 
228
- $table
229
- .wrap( '<div id="' + id + '" class="' + tscss.scrollerWrap + '" />' )
230
- .before( $hdr )
231
- // shrink filter row but don't completely hide it because the inputs/selectors may distort the columns
232
- .find( '.' + tscss.filterRow )
233
- .addClass( tscss.filterRowHide );
163
+ setWidth : function( $el, width ) {
164
+ $el.css({
165
+ 'width' : width,
166
+ 'min-width' : width,
167
+ 'max-width' : width
168
+ });
169
+ },
170
+
171
+ // modified from http://davidwalsh.name/detect-scrollbar-width
172
+ getBarWidth : function() {
173
+ var $div = $( '<div>' ).css({
174
+ 'position' : 'absolute',
175
+ 'top' : '-9999px',
176
+ 'left' : 0,
177
+ 'width' : '100px',
178
+ 'height' : '100px',
179
+ 'overflow' : 'scroll',
180
+ 'visibility' : 'hidden'
181
+ }).appendTo( 'body' ),
182
+ div = $div[0],
183
+ barWidth = div.offsetWidth - div.clientWidth;
184
+ $div.remove();
185
+ return barWidth;
186
+ },
187
+
188
+ setup : function( c, wo ) {
189
+ var maxHt, tbHt, $hdr, $t, $hCells, $fCells, $tableWrap, events, tmp,
190
+ $win = $( window ),
191
+ tsScroller = ts.scroller,
192
+ namespace = c.namespace + 'tsscroller',
193
+ $foot = $(),
194
+ // c.namespace contains a unique tablesorter ID, per table
195
+ id = c.namespace.slice( 1 ) + 'tsscroller',
196
+ $table = c.$table;
197
+
198
+ // force config.widthFixed option - this helps maintain proper alignment across cloned tables
199
+ c.widthFixed = true;
200
+
201
+ wo.scroller_calcWidths = [];
202
+ wo.scroller_saved = [ 0, 0 ];
203
+ wo.scroller_isBusy = true;
204
+
205
+ // set scrollbar width & allow setting width to zero
206
+ wo.scroller_barSetWidth = wo.scroller_barWidth !== null ?
207
+ wo.scroller_barWidth :
208
+ ( tsScroller.getBarWidth() || 15 );
209
+
210
+ maxHt = wo.scroller_height || 300;
211
+
212
+ $hdr = $( '<table class="' + $table.attr( 'class' ) + '" cellpadding=0 cellspacing=0>' +
213
+ $table.children( 'thead' )[ 0 ].outerHTML + '</table>' );
214
+ wo.scroller_$header = $hdr.addClass( c.namespace.slice( 1 ) + '_extra_table' );
215
+
216
+ $t = $table.children( 'tfoot' );
217
+ if ( $t.length ) {
218
+ $foot = $( '<table class="' + $table.attr( 'class' ) +
219
+ '" cellpadding=0 cellspacing=0 style="margin-top:0"></table>' )
220
+ .addClass( c.namespace.slice( 1 ) + '_extra_table' )
221
+ // maintain any bindings on the tfoot cells
222
+ .append( $t.clone( true ) )
223
+ .wrap( '<div class="' + tscss.scrollerFooter + '"/>' );
224
+ $fCells = $foot.children( 'tfoot' ).eq( 0 ).children( 'tr' ).children();
225
+ }
226
+ wo.scroller_$footer = $foot;
234
227
 
235
- wo.scroller_$container = $table.parent();
228
+ $table
229
+ .wrap( '<div id="' + id + '" class="' + tscss.scrollerWrap + '" />' )
230
+ .before( $hdr )
231
+ // shrink filter row but don't completely hide it because the inputs/selectors may distort the columns
232
+ .find( '.' + tscss.filterRow )
233
+ .addClass( tscss.filterRowHide );
236
234
 
237
- if ( $foot.length ) {
238
- // $foot.parent() to include <div> wrapper
239
- $table.after( $foot.parent() );
240
- }
235
+ wo.scroller_$container = $table.parent();
241
236
 
242
- $hCells = $hdr
243
- .wrap( '<div class="' + tscss.scrollerHeader + '" />' )
244
- .find( '.' + tscss.header );
237
+ if ( $foot.length ) {
238
+ // $foot.parent() to include <div> wrapper
239
+ $table.after( $foot.parent() );
240
+ }
245
241
 
246
- // use max-height, so the height resizes dynamically while filtering
247
- $table.wrap( '<div class="' + tscss.scrollerTable + '" style="max-height:' + maxHt + 'px;" />' );
248
- $tableWrap = $table.parent();
242
+ $hCells = $hdr
243
+ .wrap( '<div class="' + tscss.scrollerHeader + '" />' )
244
+ .find( '.' + tscss.header );
249
245
 
250
- // make scroller header sortable
251
- ts.bindEvents( c.table, $hCells );
246
+ // use max-height, so the height resizes dynamically while filtering
247
+ $table.wrap( '<div class="' + tscss.scrollerTable + '" style="max-height:' + maxHt + 'px;" />' );
248
+ $tableWrap = $table.parent();
252
249
 
253
- // look for filter widget
254
- if ( $table.hasClass( 'hasFilters' ) ) {
255
- ts.filter.bindSearch( $table, $hdr.find( '.' + tscss.filter ) );
256
- }
250
+ // make scroller header sortable
251
+ ts.bindEvents( c.table, $hCells );
257
252
 
258
- $table
259
- .find( 'thead' )
260
- .addClass( tscss.scrollerHideElement );
253
+ // look for filter widget
254
+ if ( $table.hasClass( 'hasFilters' ) ) {
255
+ ts.filter.bindSearch( $table, $hdr.find( '.' + tscss.filter ) );
256
+ }
261
257
 
262
- tbHt = $tableWrap.parent().height();
258
+ $table
259
+ .find( 'thead' )
260
+ .addClass( tscss.scrollerHideElement );
261
+
262
+ tbHt = $tableWrap.parent().height();
263
+
264
+ // The header will always jump into view if scrolling the table body
265
+ $tableWrap
266
+ .off( 'scroll' + namespace )
267
+ .on( 'scroll' + namespace, function() {
268
+ if ( wo.scroller_jumpToHeader ) {
269
+ var pos = $win.scrollTop() - $hdr.offset().top;
270
+ if ( $( this ).scrollTop() !== 0 && pos < tbHt && pos > 0 ) {
271
+ $win.scrollTop( $hdr.offset().top );
272
+ }
273
+ }
274
+ $hdr
275
+ .parent()
276
+ .add( $foot.parent() )
277
+ .scrollLeft( $( this ).scrollLeft() );
278
+ });
263
279
 
264
- // The header will always jump into view if scrolling the table body
265
- $tableWrap
266
- .off( 'scroll' + namespace )
267
- .on( 'scroll' + namespace, function() {
268
- if ( wo.scroller_jumpToHeader ) {
269
- var pos = $win.scrollTop() - $hdr.offset().top;
270
- if ( $( this ).scrollTop() !== 0 && pos < tbHt && pos > 0 ) {
271
- $win.scrollTop( $hdr.offset().top );
280
+ // resize/update events - filterEnd fires after "tablesorter-initialized" and "updateComplete"
281
+ events = ( ( ts.hasWidget( c.table, 'filter' ) ? 'filterEnd' : 'tablesorter-initialized updateComplete' ) +
282
+ ' sortEnd pagerComplete columnUpdate ' ).split( ' ' ).join( namespace + ' ' );
283
+
284
+ $table
285
+ .off( namespace )
286
+ .on( 'sortEnd filterEnd'.split( ' ' ).join( namespace + ' ' ), function( event ) {
287
+ // Sorting, so scroll to top
288
+ if ( event.type === 'sortEnd' && wo.scroller_upAfterSort ) {
289
+ $tableWrap.animate({
290
+ scrollTop : 0
291
+ }, 'fast' );
292
+ } else if ( wo.scroller_fixedColumns ) {
293
+ setTimeout( function() {
294
+ // restore previous scroll position
295
+ $tableWrap
296
+ .scrollTop( wo.scroller_saved[1] )
297
+ .scrollLeft( wo.scroller_saved[0] );
298
+ tsScroller.updateFixed( c, wo );
299
+ }, 0 );
272
300
  }
273
- }
274
- $hdr
275
- .parent()
276
- .add( $foot.parent() )
277
- .scrollLeft( $( this ).scrollLeft() );
278
- });
301
+ })
302
+ .on( 'setFixedColumnSize' + namespace, function( event, size ) {
303
+ var $wrap = wo.scroller_$container;
304
+ if ( typeof size !== 'undefined' && !isNaN( size ) ) {
305
+ wo.scroller_fixedColumns = parseInt( size, 10 );
306
+ }
307
+ // remove fixed columns
308
+ tsScroller.removeFixed( c, wo );
309
+ size = wo.scroller_fixedColumns;
310
+ if ( size > 0 && size < c.columns - 1 ) {
311
+ tsScroller.updateFixed( c, wo );
312
+ } else if ( $wrap.hasClass( tscss.scrollerHasFix ) ) {
313
+ $wrap.removeClass( tscss.scrollerHasFix );
314
+ // resize needed to make tables full width
315
+ tsScroller.resize( c, wo );
316
+ }
317
+ })
318
+ .on( events, function( event ) {
319
+ // Stop from running twice with pager
320
+ if ( ts.hasWidget( 'pager' ) && event.type === 'updateComplete' ) {
321
+ return;
322
+ }
323
+ if ( wo.scroller_fixedColumns > 0 ) {
324
+ tsScroller.updateFixed( c, wo );
325
+ }
326
+ // adjust column sizes after an update
327
+ tsScroller.resize( c, wo );
328
+ });
279
329
 
280
- // resize/update events
281
- events = ( ( ts.hasWidget( c.table, 'filter' ) ? 'filterEnd' : 'tablesorter-initialized' ) +
282
- ' updateComplete pagerComplete columnUpdate ' ).split( ' ' ).join( namespace + ' ' );
283
-
284
- $table
285
- .off( namespace )
286
- .on( 'sortEnd filterEnd'.split( ' ' ).join( namespace + ' ' ), function( event ) {
287
- // Sorting, so scroll to top
288
- if ( event.type === 'sortEnd' && wo.scroller_upAfterSort ) {
289
- $tableWrap.animate({
290
- scrollTop : 0
291
- }, 'fast' );
292
- } else if ( wo.scroller_fixedColumns ) {
293
- setTimeout( function() {
294
- // restore previous scroll position
295
- $tableWrap
296
- .scrollTop( wo.scroller_saved[1] )
297
- .scrollLeft( wo.scroller_saved[0] );
298
- tsScroller.updateFixed( c, wo, false );
299
- }, 0 );
300
- }
301
- })
302
- .on( 'setFixedColumnSize' + namespace, function( event, size ) {
303
- var $wrap = wo.scroller_$container;
304
- if ( typeof size !== 'undefined' && !isNaN( size ) ) {
305
- wo.scroller_fixedColumns = parseInt( size, 10 );
306
- }
307
- // remove fixed columns
308
- tsScroller.removeFixed( c, wo );
309
- size = wo.scroller_fixedColumns;
310
- if ( size > 0 && size < c.columns - 1 ) {
311
- tsScroller.updateFixed( c, wo );
312
- } else if ( $wrap.hasClass( tscss.scrollerHasFix ) ) {
313
- $wrap.removeClass( tscss.scrollerHasFix );
314
- // resize needed to make tables full width
330
+ // Setup window.resizeEnd event
331
+ $win
332
+ .off( 'resize resizeEnd '.split( ' ' ).join( namespace + ' ' ) )
333
+ .on( 'resize' + namespace, ts.window_resize )
334
+ .on( 'resizeEnd' + namespace, function() {
335
+ // IE calls resize when you modify content, so we have to unbind the resize event
336
+ // so we don't end up with an infinite loop. we can rebind after we're done.
337
+ $win.off( 'resize' + namespace, ts.window_resize );
315
338
  tsScroller.resize( c, wo );
316
- }
317
- })
318
- .on( events, function( event ) {
319
- // Stop from running twice with pager
320
- if ( ts.hasWidget( 'pager' ) && event.type === 'updateComplete' ) {
321
- return;
322
- }
323
- if ( wo.scroller_fixedColumns > 0 ) {
324
- tsScroller.updateFixed( c, wo, false );
325
- }
326
- // adjust column sizes after an update
327
- tsScroller.resize( c, wo );
328
- });
339
+ $win.on( 'resize' + namespace, ts.window_resize );
340
+ $tableWrap.trigger( 'scroll' + namespace );
341
+ });
329
342
 
330
- // Setup window.resizeEnd event
331
- $win
332
- .off( 'resize resizeEnd '.split( ' ' ).join( namespace + ' ' ) )
333
- .on( 'resize' + namespace, ts.window_resize )
334
- .on( 'resizeEnd' + namespace, function() {
335
- // IE calls resize when you modify content, so we have to unbind the resize event
336
- // so we don't end up with an infinite loop. we can rebind after we're done.
337
- $win.off( 'resize' + namespace, ts.window_resize );
338
- tsScroller.resize( c, wo );
339
- $win.on( 'resize' + namespace, ts.window_resize );
340
- $tableWrap.trigger( 'scroll' + namespace );
341
- });
343
+ // initialization flag
344
+ c.isScrolling = true;
342
345
 
343
- // initialization flag
344
- c.isScrolling = true;
345
-
346
- tsScroller.updateFixed( c, wo );
347
-
348
- },
349
-
350
- resize : function( c, wo ) {
351
- if ( wo.scroller_isBusy ) { return; }
352
- var index, borderWidth, setWidth, $hCells, $bCells, $fCells, $headers, $this, temp,
353
- tsScroller = ts.scroller,
354
- $container = wo.scroller_$container,
355
- $table = c.$table,
356
- $tableWrap = $table.parent(),
357
- $hdr = wo.scroller_$header,
358
- $foot = wo.scroller_$footer,
359
- id = c.namespace.slice( 1 ) + 'tsscroller',
360
- // Hide other scrollers so we can resize
361
- $div = $( 'div.' + tscss.scrollerWrap + '[id!="' + id + '"]' )
362
- .addClass( tscss.scrollerHideElement ),
363
- row = '<tr class="' + tscss.scrollerSpacerRow + ' ' + c.selectorRemove.slice(1) + '">';
364
-
365
- wo.scroller_calcWidths = [];
366
-
367
- // Remove fixed so we get proper widths and heights
368
- tsScroller.removeFixed( c, wo );
369
- $container.find( '.' + tscss.scrollerSpacerRow ).remove();
370
- // remove ts added colgroups
371
- $container.find( '.' + ts.css.colgroup ).remove();
372
-
373
- // show original table elements to get proper alignment
374
- $table
375
- .find( '.' + tscss.scrollerHideElement )
376
- .removeClass( tscss.scrollerHideElement );
377
-
378
- // include left & right border widths
379
- borderWidth = parseInt( $table.css( 'border-left-width' ), 10 );
380
-
381
- $headers = c.$headerIndexed;
382
-
383
- for ( index = 0; index < c.columns; index++ ) {
384
- $this = $headers[ index ];
385
- // code from https://github.com/jmosbech/StickyTableHeaders
386
- if ( $this.css( 'box-sizing' ) === 'border-box' ) {
387
- setWidth = $this.outerWidth();
388
- } else {
389
- if ( $hCells.eq( index ).css( 'border-collapse' ) === 'collapse' ) {
390
- if ( $this.length && window.getComputedStyle ) {
391
- setWidth = parseFloat( window.getComputedStyle( $this[ 0 ], null ).width );
346
+ tsScroller.updateFixed( c, wo );
347
+
348
+ // updateAll called - need to give the browser time to adjust the layout
349
+ // before calculating fix column widths
350
+ if ( c.table.hasInitialized && c.isScrolling ) {
351
+ setTimeout(function(){
352
+ ts.scroller.resize( c, wo );
353
+ }, 50);
354
+ }
355
+
356
+ },
357
+
358
+ resize : function( c, wo ) {
359
+ if ( wo.scroller_isBusy ) { return; }
360
+ var index, borderWidth, setWidth, $hCells, $bCells, $fCells, $headers, $this, temp,
361
+ tsScroller = ts.scroller,
362
+ $container = wo.scroller_$container,
363
+ $table = c.$table,
364
+ $tableWrap = $table.parent(),
365
+ $hdr = wo.scroller_$header,
366
+ $foot = wo.scroller_$footer,
367
+ id = c.namespace.slice( 1 ) + 'tsscroller',
368
+ // Hide other scrollers so we can resize
369
+ $div = $( 'div.' + tscss.scrollerWrap + '[id!="' + id + '"]' )
370
+ .addClass( tscss.scrollerHideElement ),
371
+ row = '<tr class="' + tscss.scrollerSpacerRow + ' ' + c.selectorRemove.slice(1) + '">';
372
+
373
+ wo.scroller_calcWidths = [];
374
+
375
+ // Remove fixed so we get proper widths and heights
376
+ tsScroller.removeFixed( c, wo );
377
+ $container.find( '.' + tscss.scrollerSpacerRow ).remove();
378
+ // remove ts added colgroups
379
+ $container.find( '.' + ts.css.colgroup ).remove();
380
+
381
+ // show original table elements to get proper alignment
382
+ $table
383
+ .find( '.' + tscss.scrollerHideElement )
384
+ .removeClass( tscss.scrollerHideElement );
385
+
386
+ // include left & right border widths
387
+ borderWidth = parseInt( $table.css( 'border-left-width' ), 10 );
388
+
389
+ $headers = c.$headerIndexed;
390
+
391
+ for ( index = 0; index < c.columns; index++ ) {
392
+ $this = $headers[ index ];
393
+ // code from https://github.com/jmosbech/StickyTableHeaders
394
+ if ( $this.css( 'box-sizing' ) === 'border-box' ) {
395
+ setWidth = $this.outerWidth();
396
+ } else {
397
+ if ( $this.css( 'border-collapse' ) === 'collapse' ) {
398
+ if ( $this.length && window.getComputedStyle ) {
399
+ setWidth = parseFloat( window.getComputedStyle( $this[ 0 ], null ).width );
400
+ } else {
401
+ // ie8 only
402
+ setWidth = $this.outerWidth() - parseFloat( $this.css( 'padding-left' ) ) -
403
+ parseFloat( $this.css( 'padding-right' ) ) -
404
+ ( parseFloat( $this.css( 'border-width' ) ) || 0 );
405
+ }
392
406
  } else {
393
- // ie8 only
394
- setWidth = $this.outerWidth() - parseFloat( $this.css( 'padding-left' ) ) -
395
- parseFloat( $this.css( 'padding-right' ) ) -
396
- ( parseFloat( $this.css( 'border-width' ) ) || 0 );
407
+ setWidth = $this.width();
397
408
  }
398
- } else {
399
- setWidth = $this.width();
400
409
  }
410
+ row += '<td data-column="' + index + '" style="padding:0;margin:0;border:0;height:0;max-height:0;' +
411
+ 'min-height:0;width:' + setWidth + 'px;min-width:' + setWidth + 'px;max-width:' + setWidth + 'px"></td>';
412
+
413
+ // save current widths
414
+ wo.scroller_calcWidths[ index ] = setWidth;
401
415
  }
402
- row += '<td data-column="' + index + '" style="padding:0;margin:0;border:0;height:0;max-height:0;' +
403
- 'min-height:0;width:' + setWidth + 'px;min-width:' + setWidth + 'px;max-width:' + setWidth + 'px"></td>';
416
+ row += '</tr>';
417
+ c.$tbodies.eq(0).prepend( row ); // tbody
418
+ $hdr.children( 'thead' ).append( row );
419
+ $foot.children( 'tfoot' ).append( row );
420
+
421
+ // include colgroup or alignment is off
422
+ ts.fixColumnWidth( c.table );
423
+ row = c.$table.children( 'colgroup' )[0].outerHTML;
424
+ $hdr.prepend( row );
425
+ $foot.prepend( row );
426
+
427
+ temp = $tableWrap.parent().innerWidth() -
428
+ ( tsScroller.hasScrollBar( $tableWrap ) ? wo.scroller_barSetWidth : 0 );
429
+ $tableWrap.width( temp );
404
430
 
405
- // save current widths
406
- wo.scroller_calcWidths[ index ] = setWidth;
407
- }
408
- row += '</tr>';
409
- c.$tbodies.eq(0).prepend( row ); // tbody
410
- $hdr.children( 'thead' ).append( row );
411
- $foot.children( 'tfoot' ).append( row );
412
-
413
- // include colgroup or alignment is off
414
- ts.fixColumnWidth( c.table );
415
- row = c.$table.children( 'colgroup' )[0].outerHTML;
416
- $hdr.prepend( row );
417
- $foot.prepend( row );
418
-
419
- temp = $tableWrap.parent().innerWidth() -
420
- ( tsScroller.hasScrollBar( $tableWrap ) ? wo.scroller_barSetWidth : 0 );
421
- $tableWrap.width( temp );
422
-
423
- temp = ( tsScroller.hasScrollBar( $tableWrap ) ? wo.scroller_barSetWidth : 0 ) + borderWidth;
424
- setWidth = $tableWrap.innerWidth() - temp;
425
-
426
- $hdr
427
- .parent()
428
- .add( $foot.parent() )
429
- .width( setWidth );
430
-
431
- $tableWrap
432
- .width( setWidth + temp );
433
-
434
- // hide original table thead
435
- $table.children( 'thead' ).addClass( tscss.scrollerHideElement );
436
-
437
- // update fixed column sizes
438
- tsScroller.updateFixed( c, wo );
439
-
440
- $div.removeClass( tscss.scrollerHideElement );
441
-
442
- // restore scrollTop - fixes #926
443
- $tableWrap.scrollTop( wo.scroller_saved[1] );
444
- wo.scroller_$container
445
- .find( '.' + tscss.scrollerFixed )
446
- .find( '.' + tscss.scrollerTable )
447
- .scrollTop( wo.scroller_saved[1] );
448
-
449
- // update resizable widget handles
450
- setTimeout( function() {
451
- c.$table.trigger( 'resizableUpdate' );
452
- }, 100 );
453
-
454
- },
455
-
456
- // Add fixed (frozen) columns (Do not call directly, use updateFixed)
457
- setupFixed : function( c, wo ) {
458
- var index, index2, $el, len, temp, $fixedColumn, $fixedTbody,
459
- $table = c.$table,
460
- $wrapper = wo.scroller_$container,
461
- fixedColumns = wo.scroller_fixedColumns;
462
-
463
- $fixedColumn = $wrapper
464
- .addClass( tscss.scrollerHasFix )
465
- .clone()
466
- .addClass( tscss.scrollerFixed )
467
- .removeClass( tscss.scrollerWrap )
468
- .attr( 'id', '' );
469
-
470
- if ( wo.scroller_addFixedOverlay ) {
471
- $fixedColumn.append( '<div class="' + tscss.scrollerFixedPanel + '">' );
472
- }
431
+ temp = ( tsScroller.hasScrollBar( $tableWrap ) ? wo.scroller_barSetWidth : 0 ) + borderWidth;
432
+ setWidth = $tableWrap.innerWidth() - temp;
473
433
 
474
- $fixedTbody = $fixedColumn.find( '.' + tscss.scrollerTable );
475
- $fixedTbody
476
- .children( 'table' )
477
- .addClass( c.namespace.slice( 1 ) + '_extra_table' )
478
- .attr( 'id', '' )
479
- .children( 'thead, tfoot' )
480
- .remove();
434
+ $hdr
435
+ .parent()
436
+ .add( $foot.parent() )
437
+ .width( setWidth );
481
438
 
482
- wo.scroller_$fixedColumns = $fixedColumn;
439
+ $tableWrap
440
+ .width( setWidth + temp );
483
441
 
484
- // RTL support (fixes column on right)
485
- if ( $table.hasClass( tscss.scrollerRtl ) ) {
486
- $fixedColumn.addClass( tscss.scrollerRtl );
487
- }
442
+ // hide original table thead
443
+ $table.children( 'thead' ).addClass( tscss.scrollerHideElement );
488
444
 
489
- $el = $fixedColumn.find( 'tr' );
490
- len = $el.length;
491
- for ( index = 0; index < len; index++ ) {
492
- $el.eq( index ).children( ':gt(' + ( fixedColumns - 1 ) + ')' ).remove();
493
- }
494
- $fixedColumn
495
- .addClass( tscss.scrollerHideElement )
496
- .prependTo( $wrapper );
497
-
498
- // look for filter widget
499
- if ( c.$table.hasClass( 'hasFilters' ) ) {
500
- // make sure fixed column filters aren't disabled
501
- $el = $fixedColumn
502
- .find( '.' + tscss.filter )
503
- .not( '.' + tscss.filterDisabled )
504
- .prop( 'disabled', false );
505
- ts.filter.bindSearch( $table, $fixedColumn.find( '.' + tscss.filter ) );
506
- // disable/enable filters behind fixed column
507
- $el = $wrapper
508
- .children( '.' + tscss.scrollerHeader )
509
- .find( '.' + tscss.filter );
445
+ // update fixed column sizes
446
+ tsScroller.updateFixed( c, wo );
447
+
448
+ $div.removeClass( tscss.scrollerHideElement );
449
+
450
+ // restore scrollTop - fixes #926
451
+ $tableWrap.scrollTop( wo.scroller_saved[1] );
452
+ wo.scroller_$container
453
+ .find( '.' + tscss.scrollerFixed )
454
+ .find( '.' + tscss.scrollerTable )
455
+ .scrollTop( wo.scroller_saved[1] );
456
+
457
+ // update resizable widget handles
458
+ setTimeout( function() {
459
+ c.$table.trigger( 'resizableUpdate' );
460
+ }, 100 );
461
+
462
+ },
463
+
464
+ // Add fixed (frozen) columns (Do not call directly, use updateFixed)
465
+ setupFixed : function( c, wo ) {
466
+ var index, index2, $el, len, temp, $fixedColumn, $fixedTbody,
467
+ $table = c.$table,
468
+ $wrapper = wo.scroller_$container,
469
+ fixedColumns = wo.scroller_fixedColumns;
470
+
471
+ $fixedColumn = $wrapper
472
+ .addClass( tscss.scrollerHasFix )
473
+ .clone()
474
+ .addClass( tscss.scrollerFixed )
475
+ .removeClass( tscss.scrollerWrap )
476
+ .attr( 'id', '' );
477
+
478
+ if ( wo.scroller_addFixedOverlay ) {
479
+ $fixedColumn.append( '<div class="' + tscss.scrollerFixedPanel + '">' );
480
+ }
481
+
482
+ $fixedTbody = $fixedColumn.find( '.' + tscss.scrollerTable );
483
+ $fixedTbody
484
+ .children( 'table' )
485
+ .addClass( c.namespace.slice( 1 ) + '_extra_table' )
486
+ .attr( 'id', '' )
487
+ .children( 'thead, tfoot' )
488
+ .remove();
489
+
490
+ wo.scroller_$fixedColumns = $fixedColumn;
491
+
492
+ // RTL support (fixes column on right)
493
+ if ( $table.hasClass( tscss.scrollerRtl ) ) {
494
+ $fixedColumn.addClass( tscss.scrollerRtl );
495
+ }
496
+
497
+ $el = $fixedColumn.find( 'tr' );
510
498
  len = $el.length;
511
499
  for ( index = 0; index < len; index++ ) {
512
- // previously disabled filter; don't mess with it! filterDisabled class added by filter widget
513
- if ( !$el.eq( index ).hasClass( tscss.filterDisabled || 'disabled' ) ) {
514
- // disable filters behind fixed column; don't disable visible filters
515
- $el.eq( index ).prop( 'disabled', index < fixedColumns );
500
+ $el.eq( index ).children( ':gt(' + ( fixedColumns - 1 ) + ')' ).remove();
501
+ }
502
+ $fixedColumn
503
+ .addClass( tscss.scrollerHideElement )
504
+ .prependTo( $wrapper );
505
+
506
+ // look for filter widget
507
+ if ( c.$table.hasClass( 'hasFilters' ) ) {
508
+ // make sure fixed column filters aren't disabled
509
+ $el = $fixedColumn
510
+ .find( '.' + tscss.filter )
511
+ .not( '.' + tscss.filterDisabled )
512
+ .prop( 'disabled', false );
513
+ ts.filter.bindSearch( $table, $fixedColumn.find( '.' + tscss.filter ) );
514
+ // disable/enable filters behind fixed column
515
+ $el = $wrapper
516
+ .children( '.' + tscss.scrollerHeader )
517
+ .find( '.' + tscss.filter );
518
+ len = $el.length;
519
+ for ( index = 0; index < len; index++ ) {
520
+ // previously disabled filter; don't mess with it! filterDisabled class added by filter widget
521
+ if ( !$el.eq( index ).hasClass( tscss.filterDisabled || 'disabled' ) ) {
522
+ // disable filters behind fixed column; don't disable visible filters
523
+ $el.eq( index ).prop( 'disabled', index < fixedColumns );
524
+ }
516
525
  }
517
526
  }
518
- }
519
527
 
520
- // disable/enable tab indexes behind fixed column
521
- c.$table
522
- .add( '.' + tscss.scrollerFooter + ' table' )
523
- .children( 'thead' )
524
- .children( 'tr.' + tscss.headerRow )
525
- .children()
526
- .attr( 'tabindex', -1 );
527
-
528
- $el = wo.scroller_$header
529
- .add( $fixedColumn.find( '.' + tscss.scrollerTable + ' table' ) )
530
- .children( 'thead' )
531
- .children( 'tr.' + tscss.headerRow );
532
- len = $el.length;
533
- for ( index = 0; index < len; index++ ) {
534
- temp = $el.eq( index ).children();
535
- for ( index2 = 0; index2 < temp.length; index2++ ) {
536
- temp.eq( index2 ).attr( 'tabindex', index2 < fixedColumns ? -1 : 0 );
528
+ // disable/enable tab indexes behind fixed column
529
+ c.$table
530
+ .add( '.' + tscss.scrollerFooter + ' table' )
531
+ .children( 'thead' )
532
+ .children( 'tr.' + tscss.headerRow )
533
+ .children()
534
+ .attr( 'tabindex', -1 );
535
+
536
+ $el = wo.scroller_$header
537
+ .add( $fixedColumn.find( '.' + tscss.scrollerTable + ' table' ) )
538
+ .children( 'thead' )
539
+ .children( 'tr.' + tscss.headerRow );
540
+ len = $el.length;
541
+ for ( index = 0; index < len; index++ ) {
542
+ temp = $el.eq( index ).children();
543
+ for ( index2 = 0; index2 < temp.length; index2++ ) {
544
+ temp.eq( index2 ).attr( 'tabindex', index2 < fixedColumns ? -1 : 0 );
545
+ }
537
546
  }
538
- }
539
547
 
540
- ts.bindEvents( c.table, $fixedColumn.find( '.' + tscss.header ) );
541
- ts.scroller.bindFixedColumnEvents( c, wo );
548
+ ts.bindEvents( c.table, $fixedColumn.find( '.' + tscss.header ) );
549
+ ts.scroller.bindFixedColumnEvents( c, wo );
542
550
 
543
- /*** Scrollbar hack! Since we can't hide the scrollbar with css ***/
544
- if ( ts.scroller.isFirefox || ts.scroller.isOldIE ) {
545
- $fixedTbody.wrap( '<div class="' + tscss.scrollerHack + '" style="overflow:hidden;">' );
546
- }
551
+ /*** Scrollbar hack! Since we can't hide the scrollbar with css ***/
552
+ if ( ts.scroller.isFirefox || ts.scroller.isOldIE ) {
553
+ $fixedTbody.wrap( '<div class="' + tscss.scrollerHack + '" style="overflow:hidden;">' );
554
+ }
547
555
 
548
- },
549
-
550
- bindFixedColumnEvents : function( c, wo ) {
551
- // update thead & tbody in fixed column
552
- var tsScroller = ts.scroller,
553
- namespace = c.namespace + 'tsscrollerFixed',
554
- events = 'scroll' + namespace,
555
- $fixedTbody = wo.scroller_$fixedColumns.find( '.' + tscss.scrollerTable ),
556
- fixedScroll = true,
557
- tableScroll = true;
558
-
559
- c.$table
560
- .parent()
561
- // *** SCROLL *** scroll fixed column along with main
562
- .off( events )
563
- .on( events, function() {
564
- if ( wo.scroller_isBusy ) { return; }
565
- // using flags to prevent firing the scroll event excessively leading to slow scrolling in Firefox
566
- if ( !wo.scroller_isBusy && ( fixedScroll || !( tsScroller.isFirefox || tsScroller.isIE ) ) ) {
567
- tableScroll = false;
568
- var $this = $( this );
569
- $fixedTbody[0].scrollTop = wo.scroller_saved[1] = $this.scrollTop();
570
- wo.scroller_saved[0] = $this.scrollLeft();
571
- setTimeout( function() {
572
- tableScroll = true;
573
- }, 20 );
574
- }
575
- });
576
- // scroll main along with fixed column
577
- $fixedTbody
578
- .off( events )
579
- .on( events, function() {
580
- // using flags to prevent firing the scroll event excessively leading to slow scrolling in Firefox
581
- if ( !wo.scroller_isBusy && ( tableScroll || !( tsScroller.isFirefox || tsScroller.isIE ) ) ) {
582
- fixedScroll = false;
583
- var $this = $( this );
584
- c.$table.parent()[0].scrollTop = wo.scroller_saved[1] = $this.scrollTop();
585
- setTimeout( function() {
586
- fixedScroll = true;
587
- }, 20 );
588
- }
589
- })
590
- .scroll();
556
+ },
557
+
558
+ bindFixedColumnEvents : function( c, wo ) {
559
+ // update thead & tbody in fixed column
560
+ var tsScroller = ts.scroller,
561
+ namespace = c.namespace + 'tsscrollerFixed',
562
+ events = 'scroll' + namespace,
563
+ $fixedTbody = wo.scroller_$fixedColumns.find( '.' + tscss.scrollerTable ),
564
+ fixedScroll = true,
565
+ tableScroll = true;
591
566
 
592
- // *** ROW HIGHLIGHT ***
593
- if ( wo.scroller_rowHighlight !== '' ) {
594
- events = 'mouseover mouseleave '.split( ' ' ).join( namespace + ' ' );
595
- // can't use c.$tbodies because it doesn't include info-only tbodies
596
567
  c.$table
597
- .off( events, 'tbody > tr' )
598
- .on( events, 'tbody > tr', function( event ) {
599
- var indx = c.$table.children( 'tbody' ).children( 'tr' ).index( this );
600
- $fixedTbody
601
- .children( 'table' )
602
- .children( 'tbody' )
603
- .children( 'tr' )
604
- .eq( indx )
605
- .add( this )
606
- .toggleClass( wo.scroller_rowHighlight, event.type === 'mouseover' );
568
+ .parent()
569
+ // *** SCROLL *** scroll fixed column along with main
570
+ .off( events )
571
+ .on( events, function() {
572
+ if ( wo.scroller_isBusy ) { return; }
573
+ // using flags to prevent firing the scroll event excessively leading to slow scrolling in Firefox
574
+ if ( !wo.scroller_isBusy && ( fixedScroll || !( tsScroller.isFirefox || tsScroller.isIE ) ) ) {
575
+ tableScroll = false;
576
+ var $this = $( this );
577
+ $fixedTbody[0].scrollTop = wo.scroller_saved[1] = $this.scrollTop();
578
+ wo.scroller_saved[0] = $this.scrollLeft();
579
+ setTimeout( function() {
580
+ tableScroll = true;
581
+ }, 20 );
582
+ }
607
583
  });
584
+ // scroll main along with fixed column
608
585
  $fixedTbody
609
- .find( 'table' )
610
- .off( events, 'tbody > tr' )
611
- .on( events, 'tbody > tr', function( event ) {
612
- var $fixed = $fixedTbody.children( 'table' ).children( 'tbody' ).children( 'tr' ),
613
- indx = $fixed.index( this );
614
- c.$table
615
- .children( 'tbody' )
616
- .children( 'tr' )
617
- .eq( indx )
618
- .add( this )
619
- .toggleClass( wo.scroller_rowHighlight, event.type === 'mouseover' );
620
- });
621
- }
622
- },
623
-
624
- adjustWidth : function( c, wo, totalWidth, adj, dir ) {
625
- var $wrapper = wo.scroller_$container;
626
-
627
- // RTL support (fixes column on right)
628
- $wrapper
629
- .children( '.' + tscss.scrollerTable )
630
- .css( dir ? 'right' : 'left', totalWidth );
631
- $wrapper
632
- .children( '.' + tscss.scrollerHeader + ', .' + tscss.scrollerFooter )
633
- // Safari needs a scrollbar width of extra adjusment to align the fixed & scrolling columns
634
- .css( dir ? 'right' : 'left', totalWidth + ( dir && ts.scroller.isSafari ? adj : 0 ) );
635
- },
636
-
637
- updateFixed : function( c, wo ) {
638
- var temp, adj,
639
- $wrapper = wo.scroller_$container,
640
- $hdr = wo.scroller_$header,
641
- $foot = wo.scroller_$footer,
642
- $table = c.$table,
643
- $tableWrap = $table.parent(),
644
- scrollBarWidth = wo.scroller_barSetWidth,
645
- dir = $table.hasClass( tscss.scrollerRtl );
646
-
647
- if ( wo.scroller_fixedColumns === 0 ) {
648
- wo.scroller_isBusy = false;
649
- ts.scroller.removeFixed( c, wo );
650
- temp = $wrapper.width();
651
- $tableWrap.width( temp );
586
+ .off( events )
587
+ .on( events, function() {
588
+ // using flags to prevent firing the scroll event excessively leading to slow scrolling in Firefox
589
+ if ( !wo.scroller_isBusy && ( tableScroll || !( tsScroller.isFirefox || tsScroller.isIE ) ) ) {
590
+ fixedScroll = false;
591
+ var $this = $( this );
592
+ c.$table.parent()[0].scrollTop = wo.scroller_saved[1] = $this.scrollTop();
593
+ setTimeout( function() {
594
+ fixedScroll = true;
595
+ }, 20 );
596
+ }
597
+ })
598
+ .scroll();
599
+
600
+ // *** ROW HIGHLIGHT ***
601
+ if ( wo.scroller_rowHighlight !== '' ) {
602
+ events = 'mouseover mouseleave '.split( ' ' ).join( namespace + ' ' );
603
+ // can't use c.$tbodies because it doesn't include info-only tbodies
604
+ c.$table
605
+ .off( events, 'tbody > tr' )
606
+ .on( events, 'tbody > tr', function( event ) {
607
+ var indx = c.$table.children( 'tbody' ).children( 'tr' ).index( this );
608
+ $fixedTbody
609
+ .children( 'table' )
610
+ .children( 'tbody' )
611
+ .children( 'tr' )
612
+ .eq( indx )
613
+ .add( this )
614
+ .toggleClass( wo.scroller_rowHighlight, event.type === 'mouseover' );
615
+ });
616
+ $fixedTbody
617
+ .find( 'table' )
618
+ .off( events, 'tbody > tr' )
619
+ .on( events, 'tbody > tr', function( event ) {
620
+ var $fixed = $fixedTbody.children( 'table' ).children( 'tbody' ).children( 'tr' ),
621
+ indx = $fixed.index( this );
622
+ c.$table
623
+ .children( 'tbody' )
624
+ .children( 'tr' )
625
+ .eq( indx )
626
+ .add( this )
627
+ .toggleClass( wo.scroller_rowHighlight, event.type === 'mouseover' );
628
+ });
629
+ }
630
+ },
631
+
632
+ adjustWidth : function( c, wo, totalWidth, adj, dir ) {
633
+ var $wrapper = wo.scroller_$container;
634
+
635
+ // RTL support (fixes column on right)
636
+ $wrapper
637
+ .children( '.' + tscss.scrollerTable )
638
+ .css( dir ? 'right' : 'left', totalWidth );
639
+ $wrapper
640
+ .children( '.' + tscss.scrollerHeader + ', .' + tscss.scrollerFooter )
641
+ // Safari needs a scrollbar width of extra adjusment to align the fixed & scrolling columns
642
+ .css( dir ? 'right' : 'left', totalWidth + ( dir && ts.scroller.isSafari ? adj : 0 ) );
643
+ },
644
+
645
+ updateFixed : function( c, wo ) {
646
+ var temp, adj,
647
+ $wrapper = wo.scroller_$container,
648
+ $hdr = wo.scroller_$header,
649
+ $foot = wo.scroller_$footer,
650
+ $table = c.$table,
651
+ $tableWrap = $table.parent(),
652
+ scrollBarWidth = wo.scroller_barSetWidth,
653
+ dir = $table.hasClass( tscss.scrollerRtl );
654
+
655
+ if ( wo.scroller_fixedColumns === 0 ) {
656
+ wo.scroller_isBusy = false;
657
+ ts.scroller.removeFixed( c, wo );
658
+ temp = $wrapper.width();
659
+ $tableWrap.width( temp );
660
+ adj = ts.scroller.hasScrollBar( $tableWrap ) ? scrollBarWidth : 0;
661
+ $hdr
662
+ .parent()
663
+ .add( $foot.parent() )
664
+ .width( temp - adj );
665
+ return;
666
+ }
667
+
668
+ if ( !c.isScrolling ) {
669
+ return;
670
+ }
671
+
672
+ wo.scroller_isBusy = true;
673
+
674
+ // Make sure the wo.scroller_$fixedColumns container exists, if not build it
675
+ if ( !$wrapper.find( '.' + tscss.scrollerFixed ).length ) {
676
+ ts.scroller.setupFixed( c, wo );
677
+ }
678
+
679
+ // scroller_fixedColumns
680
+ var index, tbodyIndex, rowIndex, $tbody, $adjCol, $fb, $fixHead, $fixBody, $fixFoot,
681
+ totalRows, row,
682
+
683
+ // source cells for measurement
684
+ $mainTbodies = wo.scroller_$container
685
+ .children( '.' + tscss.scrollerTable )
686
+ .children( 'table' )
687
+ .children( 'tbody' ),
688
+ // variable gets redefined
689
+ $rows = wo.scroller_$header
690
+ .children( 'thead' )
691
+ .children( '.' + tscss.headerRow ),
692
+
693
+ // hide fixed column during resize, or we get a FOUC
694
+ $fixedColumn = wo.scroller_$fixedColumns
695
+ .addClass( tscss.scrollerHideElement ),
696
+
697
+ // target cells
698
+ $fixedTbodiesTable = $fixedColumn
699
+ .find( '.' + tscss.scrollerTable )
700
+ .children( 'table' ),
701
+ $fixedTbodies = $fixedTbodiesTable
702
+ .children( 'tbody' ),
703
+ // variables
704
+ tsScroller = ts.scroller,
705
+ fixedColumns = wo.scroller_fixedColumns,
706
+ // get dimensions
707
+ $temp = $table.find( 'tbody td' ),
708
+ borderRightWidth = parseInt( $temp.css( 'border-right-width' ), 10 ) || 1,
709
+ borderSpacing = parseInt( ( $temp.css( 'border-spacing' ) || '' ).split( /\s/ )[ 0 ], 10 ) / 2 || 0,
710
+ totalWidth = parseInt( $table.css( 'padding-left' ), 10 ) +
711
+ parseInt( $table.css( 'padding-right' ), 10 ) -
712
+ borderRightWidth,
713
+ widths = wo.scroller_calcWidths;
714
+
715
+ ts.scroller.removeFixed( c, wo, false );
716
+
717
+ // calculate fixed column width
718
+ for ( index = 0; index < fixedColumns; index++ ) {
719
+ totalWidth += widths[ index ] + borderSpacing;
720
+ }
721
+
722
+ // set fixed column width
723
+ totalWidth = totalWidth + borderRightWidth * 2 - borderSpacing;
724
+ tsScroller.setWidth( $fixedColumn.add( $fixedColumn.children() ), totalWidth );
725
+ tsScroller.setWidth( $fixedColumn.children().children( 'table' ), totalWidth );
726
+
727
+ // update fixed column tbody content, set cell widths on hidden row
728
+ for ( tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++ ) {
729
+ $tbody = $mainTbodies.eq( tbodyIndex );
730
+ if ( $tbody.length ) {
731
+ // get tbody
732
+ $rows = $tbody.children();
733
+ totalRows = $rows.length;
734
+ $fb = ts.processTbody( $fixedTbodiesTable, $fixedTbodies.eq( tbodyIndex ), true );
735
+ $fb.empty();
736
+ // update tbody cells after sort/filtering
737
+ for ( rowIndex = 0; rowIndex < totalRows; rowIndex++ ) {
738
+ $adjCol = $( $rows[ rowIndex ].outerHTML );
739
+ $adjCol
740
+ .children( 'td, th' )
741
+ .slice( fixedColumns )
742
+ .remove();
743
+ $fb.append( $adjCol );
744
+ }
745
+
746
+ // restore tbody
747
+ ts.processTbody( $fixedTbodiesTable, $fb, false );
748
+ }
749
+ }
750
+
652
751
  adj = ts.scroller.hasScrollBar( $tableWrap ) ? scrollBarWidth : 0;
752
+
753
+ /*** scrollbar HACK! Since we can't hide the scrollbar with css ***/
754
+ if ( tsScroller.isFirefox || tsScroller.isOldIE ) {
755
+ $fixedTbodiesTable
756
+ .css( 'width', totalWidth )
757
+ .parent()
758
+ .css( 'width', totalWidth + adj );
759
+ }
760
+
761
+ $fixedColumn.removeClass( tscss.scrollerHideElement );
762
+ for ( index = 0; index < fixedColumns; index++ ) {
763
+ $wrapper
764
+ .children( 'div' )
765
+ .children( 'table' )
766
+ .find( 'th:nth-child(' + ( index + 1 ) + '), td:nth-child(' + ( index + 1 ) + ')' )
767
+ .addClass( tscss.scrollerHideColumn );
768
+ }
769
+
770
+ totalWidth = totalWidth - borderRightWidth;
771
+ temp = $tableWrap.parent().innerWidth() - totalWidth;
772
+ $tableWrap.width( temp );
773
+ // RTL support (fixes column on right)
774
+ $wrapper
775
+ .children( '.' + tscss.scrollerTable )
776
+ .css( dir ? 'right' : 'left', totalWidth );
777
+ $wrapper
778
+ .children( '.' + tscss.scrollerHeader + ', .' + tscss.scrollerFooter )
779
+ // Safari needs a scrollbar width of extra adjusment to align the fixed & scrolling columns
780
+ .css( dir ? 'right' : 'left', totalWidth + ( dir && ts.scroller.isSafari ? adj : 0 ) );
781
+
653
782
  $hdr
654
783
  .parent()
655
784
  .add( $foot.parent() )
656
785
  .width( temp - adj );
657
- return;
658
- }
659
786
 
660
- if ( !c.isScrolling ) {
661
- return;
662
- }
787
+ // fix gap under the tbody for the horizontal scrollbar
788
+ temp = ts.scroller.hasScrollBar( $tableWrap, true );
789
+ adj = temp ? scrollBarWidth : 0;
790
+ if ( !$fixedColumn.find( '.' + tscss.scrollerBarSpacer ).length && temp ) {
791
+ $temp = $( '<div class="' + tscss.scrollerBarSpacer + '">' )
792
+ .css( 'height', adj + 'px' );
793
+ $fixedColumn.find( '.' + tscss.scrollerTable ).append( $temp );
794
+ } else if ( !temp ) {
795
+ $fixedColumn.find( '.' + tscss.scrollerBarSpacer ).remove();
796
+ }
663
797
 
664
- wo.scroller_isBusy = true;
798
+ ts.scroller.updateRowHeight( c, wo );
799
+ // set fixed column height (changes with filtering)
800
+ $fixedColumn.height( $wrapper.height() );
665
801
 
666
- // Make sure the wo.scroller_$fixedColumns container exists, if not build it
667
- if ( !$wrapper.find( '.' + tscss.scrollerFixed ).length ) {
668
- ts.scroller.setupFixed( c, wo );
669
- }
802
+ $fixedColumn.removeClass( tscss.scrollerHideElement );
670
803
 
671
- // scroller_fixedColumns
672
- var index, tbodyIndex, rowIndex, $tbody, $adjCol, $fb, $fixHead, $fixBody, $fixFoot,
673
- totalRows, row,
804
+ wo.scroller_isBusy = false;
674
805
 
675
- // source cells for measurement
676
- $mainTbodies = wo.scroller_$container
677
- .children( '.' + tscss.scrollerTable )
678
- .children( 'table' )
679
- .children( 'tbody' ),
680
- // variable gets redefined
681
- $rows = wo.scroller_$header
682
- .children( 'thead' )
683
- .children( '.' + tscss.headerRow ),
806
+ },
684
807
 
685
- // hide fixed column during resize, or we get a FOUC
686
- $fixedColumn = wo.scroller_$fixedColumns
687
- .addClass( tscss.scrollerHideElement ),
808
+ fixHeight : function( $rows, $fixedRows ) {
809
+ var index, heightRow, heightFixed, $r, $f,
810
+ addedHt = tscss.scrollerAddedHeight,
811
+ len = $rows.length;
812
+ for ( index = 0; index < len; index++ ) {
813
+ $r = $rows.eq( index );
814
+ $f = $fixedRows.eq( index );
815
+ heightRow = $r.height();
816
+ heightFixed = $f.height();
817
+ if ( heightRow > heightFixed ) {
818
+ $f.addClass( addedHt ).height( heightRow );
819
+ } else if ( heightRow < heightFixed ) {
820
+ $r.addClass( addedHt ).height( heightFixed );
821
+ }
822
+ }
823
+ },
688
824
 
689
- // target cells
690
- $fixedTbodiesTable = $fixedColumn
691
- .find( '.' + tscss.scrollerTable )
692
- .children( 'table' ),
693
- $fixedTbodies = $fixedTbodiesTable
694
- .children( 'tbody' ),
695
- // variables
696
- tsScroller = ts.scroller,
697
- fixedColumns = wo.scroller_fixedColumns,
698
- // get dimensions
699
- $temp = $table.find( 'tbody td' ),
700
- borderRightWidth = parseInt( $temp.css( 'border-right-width' ), 10 ) || 1,
701
- borderSpacing = parseInt( ( $temp.css( 'border-spacing' ) || '' ).split( /\s/ )[ 0 ], 10 ) / 2 || 0,
702
- totalWidth = parseInt( $table.css( 'padding-left' ), 10 ) +
703
- parseInt( $table.css( 'padding-right' ), 10 ) -
704
- borderRightWidth,
705
- widths = wo.scroller_calcWidths;
706
-
707
- ts.scroller.removeFixed( c, wo, false );
708
-
709
- // calculate fixed column width
710
- for ( index = 0; index < fixedColumns; index++ ) {
711
- totalWidth += widths[ index ] + borderSpacing;
712
- }
825
+ updateRowHeight : function( c, wo ) {
826
+ var $rows, $fixed,
827
+ $fixedColumns = wo.scroller_$fixedColumns;
713
828
 
714
- // set fixed column width
715
- totalWidth = totalWidth + borderRightWidth * 2 - borderSpacing;
716
- tsScroller.setWidth( $fixedColumn.add( $fixedColumn.children() ), totalWidth );
717
- tsScroller.setWidth( $fixedColumn.children().children( 'table' ), totalWidth );
718
-
719
- // update fixed column tbody content, set cell widths on hidden row
720
- for ( tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++ ) {
721
- $tbody = $mainTbodies.eq( tbodyIndex );
722
- if ( $tbody.length ) {
723
- // get tbody
724
- $rows = $tbody.children();
725
- totalRows = $rows.length;
726
- $fb = ts.processTbody( $fixedTbodiesTable, $fixedTbodies.eq( tbodyIndex ), true );
727
- $fb.empty();
728
- // update tbody cells after sort/filtering
729
- for ( rowIndex = 0; rowIndex < totalRows; rowIndex++ ) {
730
- $adjCol = $( $rows[ rowIndex ].outerHTML );
731
- $adjCol
732
- .children( 'td, th' )
733
- .slice( fixedColumns )
734
- .remove();
735
- $fb.append( $adjCol );
736
- }
829
+ wo.scroller_$container
830
+ .find( '.' + tscss.scrollerAddedHeight )
831
+ .removeClass( tscss.scrollerAddedHeight )
832
+ .height( '' );
833
+
834
+ $rows = wo.scroller_$header
835
+ .children( 'thead' )
836
+ .children( 'tr' );
837
+ $fixed = $fixedColumns
838
+ .children( '.' + tscss.scrollerHeader )
839
+ .children( 'table' )
840
+ .children( 'thead' )
841
+ .children( 'tr' );
842
+ ts.scroller.fixHeight( $rows, $fixed );
843
+
844
+ $rows = wo.scroller_$footer
845
+ .children( 'tfoot' )
846
+ .children( 'tr' );
847
+ $fixed = $fixedColumns
848
+ .children( '.' + tscss.scrollerFooter )
849
+ .children( 'table' )
850
+ .children( 'tfoot' )
851
+ .children( 'tr' );
852
+ ts.scroller.fixHeight( $rows, $fixed );
737
853
 
738
- // restore tbody
739
- ts.processTbody( $fixedTbodiesTable, $fb, false );
854
+ if ( ts.scroller.isFirefox || ts.scroller.isOldIE ) {
855
+ // Firefox/Old IE scrollbar hack (wraps table to hide the scrollbar)
856
+ $fixedColumns = $fixedColumns.find( '.' + tscss.scrollerHack );
740
857
  }
741
- }
858
+ $rows = c.$table
859
+ .children( 'tbody' )
860
+ .children( 'tr' );
861
+ $fixed = $fixedColumns
862
+ .children( '.' + tscss.scrollerTable )
863
+ .children( 'table' )
864
+ .children( 'tbody' )
865
+ .children( 'tr' );
866
+ ts.scroller.fixHeight( $rows, $fixed );
742
867
 
743
- adj = ts.scroller.hasScrollBar( $tableWrap ) ? scrollBarWidth : 0;
868
+ },
744
869
 
745
- /*** scrollbar HACK! Since we can't hide the scrollbar with css ***/
746
- if ( tsScroller.isFirefox || tsScroller.isOldIE ) {
747
- $fixedTbodiesTable
748
- .css( 'width', totalWidth )
749
- .parent()
750
- .css( 'width', totalWidth + adj );
751
- }
870
+ removeFixed : function( c, wo, removeIt ) {
871
+ var $table = c.$table,
872
+ $wrapper = wo.scroller_$container,
873
+ dir = $table.hasClass( tscss.scrollerRtl );
752
874
 
753
- $fixedColumn.removeClass( tscss.scrollerHideElement );
754
- for ( index = 0; index < fixedColumns; index++ ) {
755
- $wrapper
756
- .children( 'div' )
757
- .children( 'table' )
758
- .find( 'th:nth-child(' + ( index + 1 ) + '), td:nth-child(' + ( index + 1 ) + ')' )
759
- .addClass( tscss.scrollerHideColumn );
760
- }
875
+ // remove fixed columns
876
+ if ( removeIt || typeof removeIt === 'undefined' ) {
877
+ $wrapper.find( '.' + tscss.scrollerFixed ).remove();
878
+ }
761
879
 
762
- totalWidth = totalWidth - borderRightWidth;
763
- temp = $tableWrap.parent().innerWidth() - totalWidth;
764
- $tableWrap.width( temp );
765
- // RTL support (fixes column on right)
766
- $wrapper
767
- .children( '.' + tscss.scrollerTable )
768
- .css( dir ? 'right' : 'left', totalWidth );
769
- $wrapper
770
- .children( '.' + tscss.scrollerHeader + ', .' + tscss.scrollerFooter )
771
- // Safari needs a scrollbar width of extra adjusment to align the fixed & scrolling columns
772
- .css( dir ? 'right' : 'left', totalWidth + ( dir && ts.scroller.isSafari ? adj : 0 ) );
773
-
774
- $hdr
775
- .parent()
776
- .add( $foot.parent() )
777
- .width( temp - adj );
778
-
779
- // fix gap under the tbody for the horizontal scrollbar
780
- temp = ts.scroller.hasScrollBar( $tableWrap, true );
781
- adj = temp ? scrollBarWidth : 0;
782
- if ( !$fixedColumn.find( '.' + tscss.scrollerBarSpacer ).length && temp ) {
783
- $temp = $( '<div class="' + tscss.scrollerBarSpacer + '">' )
784
- .css( 'height', adj + 'px' );
785
- $fixedColumn.find( '.' + tscss.scrollerTable ).append( $temp );
786
- } else if ( !temp ) {
787
- $fixedColumn.find( '.' + tscss.scrollerBarSpacer ).remove();
788
- }
880
+ $wrapper
881
+ .find( '.' + tscss.scrollerHideColumn )
882
+ .removeClass( tscss.scrollerHideColumn );
789
883
 
790
- ts.scroller.updateRowHeight( c, wo );
791
- // set fixed column height (changes with filtering)
792
- $fixedColumn.height( $wrapper.height() );
793
-
794
- $fixedColumn.removeClass( tscss.scrollerHideElement );
795
-
796
- wo.scroller_isBusy = false;
797
- },
798
-
799
- fixHeight : function( $rows, $fixedRows ) {
800
- var index, heightRow, heightFixed, $r, $f,
801
- len = $rows.length;
802
- for ( index = 0; index < len; index++ ) {
803
- $r = $rows.eq( index );
804
- $f = $fixedRows.eq( index );
805
- heightRow = $r.height();
806
- heightFixed = $f.height();
807
- if ( heightRow > heightFixed ) {
808
- $f.addClass( tscss.scrollerAddedHeight ).height( heightRow );
809
- } else if ( heightRow < heightFixed ) {
810
- $r.addClass( tscss.scrollerAddedHeight ).height( heightFixed );
884
+ // RTL support ( fixes column on right )
885
+ $wrapper
886
+ .children( ':not(.' + tscss.scrollerFixed + ')' )
887
+ .css( dir ? 'right' : 'left', 0 );
888
+ },
889
+
890
+ remove : function( c, wo ) {
891
+ var $wrap = wo.scroller_$container,
892
+ namespace = c.namespace + 'tsscroller';
893
+ c.$table.off( namespace );
894
+ $( window ).off( namespace );
895
+ if ( $wrap ) {
896
+ c.$table
897
+ .insertBefore( $wrap )
898
+ .find( 'thead' )
899
+ .removeClass( tscss.scrollerHideElement )
900
+ .children( 'tr.' + tscss.headerRow )
901
+ .children()
902
+ .attr( 'tabindex', 0 )
903
+ .end()
904
+ .find( '.' + tscss.filterRow )
905
+ .removeClass( tscss.scrollerHideElement + ' ' + tscss.filterRowHide );
906
+ c.$table
907
+ .find( '.' + tscss.filter )
908
+ .not( '.' + tscss.filterDisabled )
909
+ .prop( 'disabled', false );
910
+ $wrap.remove();
911
+ c.isScrolling = false;
811
912
  }
812
913
  }
813
- },
814
-
815
- updateRowHeight : function( c, wo ) {
816
- var $rows, $fixed,
817
- $fixedColumns = wo.scroller_$fixedColumns;
818
-
819
- wo.scroller_$container
820
- .find( '.' + tscss.scrollerAddedHeight )
821
- .removeClass( tscss.scrollerAddedHeight )
822
- .height( '' );
823
-
824
- $rows = wo.scroller_$header
825
- .children( 'thead' )
826
- .children( 'tr' );
827
- $fixed = $fixedColumns
828
- .children( '.' + tscss.scrollerHeader )
829
- .children( 'table' )
830
- .children( 'thead' )
831
- .children( 'tr' );
832
- ts.scroller.fixHeight( $rows, $fixed );
833
-
834
- $rows = wo.scroller_$footer
835
- .children( 'tfoot' )
836
- .children( 'tr' );
837
- $fixed = $fixedColumns
838
- .children( '.' + tscss.scrollerFooter )
839
- .children( 'table' )
840
- .children( 'tfoot' )
841
- .children( 'tr' );
842
- ts.scroller.fixHeight( $rows, $fixed );
843
-
844
- if ( ts.scroller.isFirefox || ts.scroller.isOldIE ) {
845
- // Firefox/Old IE scrollbar hack (wraps table to hide the scrollbar)
846
- $fixedColumns = $fixedColumns.find( '.' + tscss.scrollerHack );
847
- }
848
- $rows = c.$table
849
- .children( 'tbody' )
850
- .children( 'tr' );
851
- $fixed = $fixedColumns
852
- .children( '.' + tscss.scrollerTable )
853
- .children( 'table' )
854
- .children( 'tbody' )
855
- .children( 'tr' );
856
- ts.scroller.fixHeight( $rows, $fixed );
857
-
858
- },
859
-
860
- removeFixed : function( c, wo, removeIt ) {
861
- var $table = c.$table,
862
- $wrapper = wo.scroller_$container,
863
- dir = $table.hasClass( tscss.scrollerRtl );
864
-
865
- // remove fixed columns
866
- if ( removeIt || typeof removeIt === 'undefined' ) {
867
- $wrapper.find( '.' + tscss.scrollerFixed ).remove();
868
- }
869
914
 
870
- $wrapper
871
- .find( '.' + tscss.scrollerHideColumn )
872
- .removeClass( tscss.scrollerHideColumn );
873
-
874
- // RTL support ( fixes column on right )
875
- $wrapper
876
- .children( ':not(.' + tscss.scrollerFixed + ')' )
877
- .css( dir ? 'right' : 'left', 0 );
878
- },
879
-
880
- remove : function( c, wo ) {
881
- var $wrap = wo.scroller_$container,
882
- namespace = c.namespace + 'tsscroller';
883
- c.$table
884
- .off( namespace )
885
- .insertBefore( $wrap )
886
- .find( 'thead' )
887
- .removeClass( tscss.scrollerHideElement )
888
- .children( 'tr.' + tscss.headerRow )
889
- .children()
890
- .attr( 'tabindex', 0 )
891
- .end()
892
- .find( '.' + tscss.filterRow )
893
- .removeClass( tscss.scrollerHideElement + ' ' + tscss.filterRowHide );
894
- c.$table
895
- .find( '.' + tscss.filter )
896
- .not( '.' + tscss.filterDisabled )
897
- .prop( 'disabled', false );
898
- $wrap.remove();
899
- $( window ).off( namespace );
900
- c.isScrolling = false;
901
- }
902
-
903
- };
915
+ };
904
916
 
905
917
  })( jQuery, window );