|
1 |
| -/*! Parser: input & select - updated 11/26/2016 (v2.28.0) *//* |
| 1 | +/*! Parser: input & select - updated 5/16/2017 (v2.28.10) *//* |
2 | 2 | * for jQuery 1.7+ & tablesorter 2.7.11+
|
3 | 3 | * Demo: http://mottie.github.com/tablesorter/docs/example-widget-grouping.html
|
4 | 4 | */
|
|
131 | 131 | $row.removeClass( checkboxClass );
|
132 | 132 | }
|
133 | 133 | },
|
| 134 | + updateCheckbox = function($el, state) { |
| 135 | + if ($el[0].nodeName !== 'INPUT') { |
| 136 | + $el = $el.find( 'input[type="checkbox"]' ); |
| 137 | + } |
| 138 | + if ($el.length) { |
| 139 | + var ua = window.navigator.userAgent; |
| 140 | + if (state === 'indeterminate') { |
| 141 | + // needed for IE |
| 142 | + $el.prop('checked', !(ua.indexOf('Trident/') > -1 || ua.indexOf('Edge/') > -1)); |
| 143 | + $el.prop('indeterminate', true); |
| 144 | + } else { |
| 145 | + $el.prop('checked', state); |
| 146 | + $el.prop('indeterminate', false); |
| 147 | + } |
| 148 | + } |
| 149 | + }, |
134 | 150 | updateHeaderCheckbox = function( $table, checkboxClass ) {
|
135 |
| - var ua = window.navigator.userAgent, |
136 |
| - $rows = $table.children( 'tbody' ).children( ':visible' ), // (include child rows?) |
137 |
| - len = $rows.length; |
| 151 | + var $rows = $table.children( 'tbody' ).children( ':visible' ), // (include child rows?) |
| 152 | + len = $rows.length, |
| 153 | + hasSticky = $table[0].config.widgetOptions.$sticky; |
138 | 154 | // set indeterminate state on header checkbox
|
139 | 155 | $table.children( 'thead' ).find( 'input[type="checkbox"]' ).each( function() {
|
140 | 156 | var column = $( this ).closest( 'td, th' ).attr( 'data-column' ),
|
| 157 | + $sticky = hasSticky.find( '[data-column="' + column + '"]' ), |
141 | 158 | vis = $rows.filter( '.' + checkboxClass + '-' + column ).length,
|
142 | 159 | allChecked = vis === len && len > 0;
|
143 | 160 | if ( vis === 0 || allChecked ) {
|
144 |
| - this.checked = allChecked; |
145 |
| - this.indeterminate = false; |
| 161 | + updateCheckbox($(this), allChecked); |
| 162 | + if ($sticky) { |
| 163 | + updateCheckbox($sticky, allChecked); |
| 164 | + } |
146 | 165 | } else {
|
147 |
| - // needed for IE |
148 |
| - this.checked = !(ua.indexOf('Trident/') > -1 || ua.indexOf('Edge/') > -1); |
149 |
| - this.indeterminate = true; |
| 166 | + updateCheckbox($(this), 'indeterminate'); |
| 167 | + if ($sticky) { |
| 168 | + updateCheckbox($sticky, 'indeterminate'); |
| 169 | + } |
150 | 170 | }
|
151 | 171 | });
|
| 172 | + |
152 | 173 | };
|
153 | 174 |
|
154 | 175 | $( 'table' ).on( 'tablesorter-initialized updateComplete', function() {
|
155 | 176 | this.tablesorterBusy = false;
|
156 | 177 | var namespace = '.parser-forms';
|
157 |
| - // bind to .tablesorter (default class name) |
158 |
| - $( this ).children( 'tbody' ) |
| 178 | + $( this ) |
| 179 | + // add namespace to table in case of version mismatch (v2.28.10) |
| 180 | + .addClass( this.config.namespace.slice(1) ) |
| 181 | + .children( 'tbody' ) |
159 | 182 | .off( namespace )
|
160 | 183 | .on( 'mouseleave' + namespace, function( event ) {
|
161 | 184 | // make sure we restore original values (trigger blur)
|
|
165 | 188 | $( ':focus' ).blur();
|
166 | 189 | }
|
167 | 190 | })
|
168 |
| - .on( 'focus' + namespace, 'select, input:not([type=checkbox]), textarea', function() { |
| 191 | + .on( 'focus' + namespace, 'select, input:not([type=checkbox]), textarea', function( event ) { |
| 192 | + var $row = $( event.target ).closest( 'tr' ), |
| 193 | + c = $row.closest( 'table' )[0].config; |
| 194 | + if ( !c || c && c.ignoreChildRow && $row.hasClass( c.cssChildRow ) ) { |
| 195 | + return; |
| 196 | + } |
169 | 197 | $( this ).data( 'ts-original-value', this.value );
|
170 | 198 | })
|
171 |
| - .on( 'blur' + namespace, 'input:not([type=checkbox]), textarea', function() { |
| 199 | + .on( 'blur' + namespace, 'input:not([type=checkbox]), textarea', function( event ) { |
| 200 | + var $row = $( event.target ).closest( 'tr' ), |
| 201 | + c = $row.closest( 'table' )[0].config; |
| 202 | + if ( !c || c && c.ignoreChildRow && $row.hasClass( c.cssChildRow ) ) { |
| 203 | + return; |
| 204 | + } |
172 | 205 | // restore input value;
|
173 | 206 | // 'change' is triggered before 'blur' so this doesn't replace the new update with the original
|
174 | 207 | this.value = $( this ).data( 'ts-original-value' );
|
175 | 208 | })
|
176 | 209 | .on( 'change keyup '.split( ' ' ).join( namespace + ' ' ), 'select, input, textarea', function( event ) {
|
| 210 | + var $row = $( this ).closest( 'tr' ), |
| 211 | + c = $row.closest( 'table' )[0].config; |
| 212 | + if ( !c || c && c.ignoreChildRow && $row.hasClass( c.cssChildRow ) ) { |
| 213 | + return; |
| 214 | + } |
177 | 215 | if ( event.which === 27 && !( this.nodeName === 'INPUT' && this.type === 'checkbox' ) ) {
|
178 | 216 | // escape: restore original value
|
179 | 217 | this.value = $( this ).data( 'ts-original-value' );
|
|
187 | 225 | $target = $( event.target ),
|
188 | 226 | isCheckbox = event.target.type === 'checkbox',
|
189 | 227 | $cell = $target.closest( 'td' ),
|
190 |
| - $table = $cell.closest( 'table' ), |
191 | 228 | indx = $cell[ 0 ].cellIndex,
|
192 |
| - c = $table[ 0 ].config || false, |
193 |
| - busy = $table.length && $table[ 0 ].tablesorterBusy, |
194 |
| - $hdr = c && c.$headerIndexed && c.$headerIndexed[ indx ] || [], |
| 229 | + busy = c.table.tablesorterBusy, |
| 230 | + $hdr = c.$headerIndexed && c.$headerIndexed[ indx ] || [], |
195 | 231 | val = isCheckbox ? event.target.checked : $target.val();
|
196 | 232 | // abort if not a tablesorter table, or busy
|
197 | 233 | if ( $.isEmptyObject( c ) || busy !== false ) {
|
|
200 | 236 | if ( isCheckbox ) {
|
201 | 237 | checkboxClass = c.checkboxClass || 'checked';
|
202 | 238 | toggleRowClass( $cell.closest( 'tr' ), checkboxClass, indx, val );
|
203 |
| - updateHeaderCheckbox( $table, checkboxClass ); |
| 239 | + updateHeaderCheckbox( c.$table, checkboxClass ); |
204 | 240 | }
|
205 | 241 | // don't use updateCell if column is set to 'sorter-false' and 'filter-false',
|
206 | 242 | // or column is set to 'parser-false'
|
|
213 | 249 | // ignore change event if nothing changed
|
214 | 250 | if ( c && val !== $target.data( 'ts-original-value' ) || isCheckbox ) {
|
215 | 251 | $target.data( 'ts-original-value', val );
|
216 |
| - $table[ 0 ].tablesorterBusy = true; |
| 252 | + c.table.tablesorterBusy = true; |
217 | 253 | // pass undefined resort value so it falls back to config.resort setting
|
218 | 254 | $.tablesorter.updateCell( c, $cell, undef, function() {
|
219 |
| - updateServer( event, $table, $target ); |
220 |
| - $table[ 0 ].tablesorterBusy = false; |
| 255 | + updateServer( event, c.$table, $target ); |
| 256 | + c.table.tablesorterBusy = false; |
221 | 257 | });
|
222 | 258 | }
|
223 | 259 | }
|
|
240 | 276 | }
|
241 | 277 | })
|
242 | 278 | .children( 'thead' )
|
| 279 | + .add( this.config.widgetOptions.$sticky ) |
243 | 280 | .off( namespace )
|
244 | 281 | // modified from http://jsfiddle.net/abkNM/6163/
|
245 | 282 | // click needed for IE; a change isn't fired when going from an indeterminate checkbox to
|
246 | 283 | // either checked or unchecked
|
247 | 284 | .on( 'click' + namespace + ' change' + namespace, 'input[type="checkbox"]', function( event ) {
|
248 |
| - var undef, onlyVisible, column, $target, isParsed, checkboxClass, |
| 285 | + var c, undef, onlyVisible, column, $target, isParsed, checkboxClass, |
249 | 286 | $checkbox = $( this ),
|
| 287 | + isChecked = this.checked, |
250 | 288 | $table = $checkbox.closest( 'table' ),
|
251 |
| - c = $table.length && $table[ 0 ].config, |
252 |
| - isChecked = this.checked; |
| 289 | + isSticky = $table.length && $table[0].className.match(/(tablesorter\w+)_extra_table/); |
| 290 | + if (isSticky) { |
| 291 | + isSticky = isSticky[1]; |
| 292 | + $table = $('.' + isSticky + ':not(.' + isSticky + '_extra_table)'); |
| 293 | + } |
| 294 | + c = $table.length && $table[ 0 ].config; |
253 | 295 | if ( $table.length && c && !$table[ 0 ].tablesorterBusy ) {
|
254 | 296 | column = parseInt( $checkbox.closest( 'td, th' ).attr( 'data-column' ), 10 );
|
255 | 297 | isParsed = c.parsers[ column ].id === 'checkbox';
|
256 |
| - onlyVisible = $table.length && c.checkboxVisible; |
| 298 | + onlyVisible = c.checkboxVisible; |
257 | 299 | $table[ 0 ].tablesorterBusy = true; // prevent "change" event from calling updateCell numerous times (see #971)
|
258 |
| - $target = $table |
259 |
| - .children( 'tbody' ) |
260 |
| - .children( 'tr' + ( typeof onlyVisible === 'undefined' || onlyVisible === true ? ':visible' : '' ) ) |
261 |
| - .children( ':nth-child(' + ( column + 1 ) + ')' ) |
262 |
| - .find( 'input[type="checkbox"]' ) |
263 |
| - .prop( 'checked', isChecked ); |
| 300 | + updateCheckbox( |
| 301 | + $target = $table |
| 302 | + .children( 'tbody' ) |
| 303 | + .children( 'tr' + ( typeof onlyVisible === 'undefined' || onlyVisible === true ? ':visible' : '' ) ) |
| 304 | + .children( ':nth-child(' + ( column + 1 ) + ')' ), |
| 305 | + isChecked |
| 306 | + ); |
264 | 307 | // add checkbox class names to row
|
265 | 308 | checkboxClass = c.checkboxClass || 'checked';
|
266 | 309 | $target.each( function() {
|
267 | 310 | toggleRowClass( $( this ).closest( 'tr' ), checkboxClass, column, isChecked );
|
268 | 311 | });
|
| 312 | + if (isSticky) { |
| 313 | + // make main table checkbox match sticky header checkbox |
| 314 | + updateCheckbox($table.children( 'thead' ).find( '[data-column="' + column + '"]' ), isChecked); |
| 315 | + } else if (c.widgetOptions.$sticky) { |
| 316 | + updateCheckbox(c.widgetOptions.$sticky.find( 'thead' ).find( '[data-column="' + column + '"]' ), isChecked); |
| 317 | + } |
269 | 318 | updateHeaderCheckbox( $table, checkboxClass );
|
270 | 319 | if ( isParsed ) {
|
271 | 320 | // only update cache if checkboxes are being sorted
|
|
0 commit comments