diff --git a/dist/js/parsers/parser-input-select.min.js b/dist/js/parsers/parser-input-select.min.js index 758fe94c..eda604f5 100644 --- a/dist/js/parsers/parser-input-select.min.js +++ b/dist/js/parsers/parser-input-select.min.js @@ -1,2 +1,2 @@ /*! Parser: input & select - updated 11/22/2015 (v2.24.6) */ -!function(a){"use strict";var b=function(a,b,c){};a.tablesorter.addParser({id:"inputs",is:function(){return!1},format:function(b,c,d){var e=a(d).find("input");return e.length?e.val():b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"inputs-numeric",is:function(){return!1},format:function(b,c,d){var e=a(d).find("input"),f=e.length?e.val():b,g=a.tablesorter.formatFloat((f||"").replace(/[^\w,. \-()]/g,""),c);return b&&"number"==typeof g?g:b?a.trim(b&&c.config.ignoreCase?b.toLocaleLowerCase():b):b},parsed:!0,type:"numeric"}),a.tablesorter.addParser({id:"checkbox",is:function(){return!1},format:function(b,c,d,e){var f=a(d),g=f.closest("tr"),h=c.config.widgetOptions,i=c.config.checkboxClass||"checked",j=h.group_checkbox?h.group_checkbox:["checked","unchecked"],k=f.find('input[type="checkbox"]'),l=k.length?k[0].checked:"";return g.toggleClass(i+"-"+e,l),l?g.addClass(i):g.length&&!(g[0].className||"").match(i+"-")&&g.removeClass(i),k.length?j[l?0:1]:b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"select",is:function(){return!1},format:function(b,c,d){var e=a(d).find("select");return e.length?e.val():b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"select-text",is:function(){return!1},format:function(b,c,d){var e=a(d).find("select");return e.length?e.find("option:selected").text()||"":b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"textarea",is:function(){return!1},format:function(b,c,d){var e=a(d).find("textarea");return e.length?e.val():b},parsed:!0,type:"text"}),a(function(){a.fn.on&&a("table").on("tablesorter-initialized updateComplete",function(){this.tablesorterBusy=!1;var c=".parser-forms";a(this).children("tbody").off(c).on("mouseleave"+c,function(b){"TBODY"===b.target.nodeName&&a(":focus").blur()}).on("focus"+c,"select, input, textarea",function(){a(this).data("ts-original-value",this.value)}).on("blur"+c,"input, textarea",function(){this.value=a(this).data("ts-original-value")}).on("change keyup ".split(" ").join(c+" "),"select, input, textarea",function(c){if(27===c.which)return void(this.value=a(this).data("ts-original-value"));if("change"===c.type||"keyup"===c.type&&13===c.which&&("INPUT"===c.target.nodeName||"TEXTAREA"===c.target.nodeName&&c.altKey)){var d,e=a(c.target),f="checkbox"===c.target.type,g=e.closest("td"),h=g.closest("table"),i=g[0].cellIndex,j=h[0].config||!1,k=h.length&&h[0].tablesorterBusy,l=j&&j.$headerIndexed&&j.$headerIndexed[i]||[],m=f?c.target.checked:e.val();if(a.isEmptyObject(j)||k!==!1||l.length&&(l.hasClass("parser-false")||l.hasClass("sorter-false")&&l.hasClass("filter-false"))||"change"===c.type&&j.table.isUpdating)return;(j&&m!==e.data("ts-original-value")||f)&&(e.data("ts-original-value",m),h[0].tablesorterBusy=!0,a.tablesorter.updateCell(j,g,d,function(){b(c,h,e),h[0].tablesorterBusy=!1}))}}),a(this).children("thead").find('input[type="checkbox"]')&&a(this).off(c).on("tablesorter-ready"+c,function(){var b,c,d,e=a(this),f=e.length&&e[0].config;a.isEmptyObject(f)||(this.tablesorterBusy=!0,b=f&&f.checkboxClass||"checked",c=e.children("tbody").children(":visible"),d=c.length,a(this).children("thead").find('input[type="checkbox"]').each(function(){var e=a(this).closest("td, th").attr("data-column"),f=c.filter("."+b+"-"+e).length,g=f===d;0===f||g?(this.checked=g,this.indeterminate=!1):this.indeterminate=!0}),this.tablesorterBusy=!1)}).children("thead").off(c).on("change"+c,'input[type="checkbox"]',function(c){var d,e,f,g,h=a(this),i=h.closest("table"),j=i.length&&i[0].config,k=this.checked;return i.length&&j&&!i[0].tablesorterBusy&&(f=parseInt(h.closest("td, th").attr("data-column"),10),e=i.length&&j.checkboxVisible,i[0].tablesorterBusy=!0,g=i.children("tbody").children("tr"+("undefined"==typeof e||e===!0?":visible":"")).children(":nth-child("+(f+1)+")").find('input[type="checkbox"]').prop("checked",k),a.tablesorter.update(j,d,function(){b(c,i,g),i[0].tablesorterBusy=!1})),!1})})})}(jQuery); \ No newline at end of file +!function(a){"use strict";var b=function(a,b,c){};a.tablesorter.addParser({id:"inputs",is:function(){return!1},format:function(b,c,d){var e=a(d).find("input");return e.length?e.val():b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"inputs-numeric",is:function(){return!1},format:function(b,c,d){var e=a(d).find("input"),f=e.length?e.val():b,g=a.tablesorter.formatFloat((f||"").replace(/[^\w,. \-()]/g,""),c);return b&&"number"==typeof g?g:b?a.trim(b&&c.config.ignoreCase?b.toLocaleLowerCase():b):b},parsed:!0,type:"numeric"}),a.tablesorter.addParser({id:"checkbox",is:function(){return!1},format:function(b,c,d,e){var f=a(d),g=c.config.widgetOptions,h=g.group_checkbox?g.group_checkbox:["checked","unchecked"],i=f.find('input[type="checkbox"]'),j=i.length?i[0].checked:"";return i.length?h[j?0:1]:b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"select",is:function(){return!1},format:function(b,c,d){var e=a(d).find("select");return e.length?e.val():b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"select-text",is:function(){return!1},format:function(b,c,d){var e=a(d).find("select");return e.length?e.find("option:selected").text()||"":b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"textarea",is:function(){return!1},format:function(b,c,d){var e=a(d).find("textarea");return e.length?e.val():b},parsed:!0,type:"text"}),a(function(){if(a.fn.on){var c=function(a,b,c,d){a.toggleClass(b+"-"+c,d),(a[0].className||"").match(b+"-")?a.addClass(b):a.removeClass(b)},d=function(b,c){var d=b.children("tbody").children(":visible"),e=d.length;b.children("thead").find('input[type="checkbox"]').each(function(){var b=a(this).closest("td, th").attr("data-column"),f=d.filter("."+c+"-"+b).length,g=f===e;0===f||g?(this.checked=g,this.indeterminate=!1):this.indeterminate=!0})};a("table").on("tablesorter-initialized updateComplete",function(){this.tablesorterBusy=!1;var e=".parser-forms";a(this).children("tbody").off(e).on("mouseleave"+e,function(b){"TBODY"===b.target.nodeName&&a(":focus").blur()}).on("focus"+e,"select, input, textarea",function(){a(this).data("ts-original-value",this.value)}).on("blur"+e,"input, textarea",function(){this.value=a(this).data("ts-original-value")}).on("change keyup ".split(" ").join(e+" "),"select, input, textarea",function(e){if(27===e.which)return void(this.value=a(this).data("ts-original-value"));if("change"===e.type||"keyup"===e.type&&13===e.which&&("INPUT"===e.target.nodeName||"TEXTAREA"===e.target.nodeName&&e.altKey)){var f,g,h=a(e.target),i="checkbox"===e.target.type,j=h.closest("td"),k=j.closest("table"),l=j[0].cellIndex,m=k[0].config||!1,n=k.length&&k[0].tablesorterBusy,o=m&&m.$headerIndexed&&m.$headerIndexed[l]||[],p=i?e.target.checked:h.val();if(a.isEmptyObject(m)||n!==!1)return;if(i&&(g=m.checkboxClass||"checked",c(j.closest("tr"),g,l,p),d(k,g)),o.length&&(o.hasClass("parser-false")||o.hasClass("sorter-false")&&o.hasClass("filter-false"))||"change"===e.type&&m.table.isUpdating)return;(m&&p!==h.data("ts-original-value")||i)&&(h.data("ts-original-value",p),k[0].tablesorterBusy=!0,a.tablesorter.updateCell(m,j,f,function(){b(e,k,h),k[0].tablesorterBusy=!1}))}}),a(this).children("thead").find('input[type="checkbox"]')&&a(this).off(e).on("tablesorter-ready"+e,function(){var b,c=a(this),e=c.length&&c[0].config;a.isEmptyObject(e)||(this.tablesorterBusy=!0,b=e&&e.checkboxClass||"checked",d(c,b),this.tablesorterBusy=!1)}).children("thead").off(e).on("change"+e,'input[type="checkbox"]',function(e){var f,g,h,i,j,k,l,m=a(this),n=m.closest("table"),o=n.length&&n[0].config,p=this.checked;return n.length&&o&&!n[0].tablesorterBusy&&(h=parseInt(m.closest("td, th").attr("data-column"),10),j="checkbox"===o.parsers[h].id,g=n.length&&o.checkboxVisible,n[0].tablesorterBusy=!0,i=n.children("tbody").children("tr"+("undefined"==typeof g||g===!0?":visible":"")).children(":nth-child("+(h+1)+")").find('input[type="checkbox"]').prop("checked",p),j?a.tablesorter.update(o,f,function(){b(e,n,i),n[0].tablesorterBusy=!1}):(l=o.checkboxClass||"checked",i.each(function(){k=a(this).closest("tr"),c(a(this).closest("tr"),l,h,p)}),d(n,l),b(e,n,i),n[0].tablesorterBusy=!1)),!1})})}})}(jQuery); \ No newline at end of file diff --git a/js/parsers/parser-input-select.js b/js/parsers/parser-input-select.js index bcddafa6..44d0288b 100644 --- a/js/parsers/parser-input-select.js +++ b/js/parsers/parser-input-select.js @@ -54,23 +54,12 @@ }, format : function( txt, table, cell, cellIndex ) { var $cell = $( cell ), - $row = $cell.closest( 'tr' ), wo = table.config.widgetOptions, - checkedClass = table.config.checkboxClass || 'checked', // returning plain language here because this is what is shown in the // group headers - change it as desired status = wo.group_checkbox ? wo.group_checkbox : [ 'checked', 'unchecked' ], $input = $cell.find( 'input[type="checkbox"]' ), isChecked = $input.length ? $input[ 0 ].checked : ''; - // adding class to row, indicating that a checkbox is checked; includes - // a column index in case more than one checkbox happens to be in a row - $row.toggleClass( checkedClass + '-' + cellIndex, isChecked ); - if ( isChecked ) { - $row.addClass( checkedClass ); - } else if ( $row.length && !( $row[0].className || '' ).match( checkedClass + '-' ) ) { - // don't remove checked class if other columns have a check - $row.removeClass( checkedClass ); - } return $input.length ? status[ isChecked ? 0 : 1 ] : txt; }, parsed : true, // filter widget flag @@ -127,6 +116,34 @@ // if this code interferes somehow, target the specific table $('#mytable'), instead of $('table') $( function() { if ( !$.fn.on ) { return; } + var toggleRowClass = function( $row, checkboxClass, indx, isChecked ) { + // adding class to row, indicating that a checkbox is checked; includes + // a column index in case more than one checkbox happens to be in a row + $row.toggleClass( checkboxClass + '-' + indx, isChecked ); + // don't remove checked class if other columns have a check + if ( ( $row[0].className || '' ).match( checkboxClass + '-' ) ) { + $row.addClass( checkboxClass ); + } else { + $row.removeClass( checkboxClass ); + } + }, + updateHeaderCheckbox = function( $table, checkboxClass ) { + var $rows = $table.children( 'tbody' ).children( ':visible' ), // (include child rows?) + len = $rows.length; + // set indeterminate state on header checkbox + $table.children( 'thead' ).find( 'input[type="checkbox"]' ).each( function() { + var column = $( this ).closest( 'td, th' ).attr( 'data-column' ), + vis = $rows.filter( '.' + checkboxClass + '-' + column ).length, + allChecked = vis === len; + if ( vis === 0 || allChecked ) { + this.checked = allChecked; + this.indeterminate = false; + } else { + this.indeterminate = true; + } + }); + }; + $( 'table' ).on( 'tablesorter-initialized updateComplete', function() { this.tablesorterBusy = false; var namespace = '.parser-forms'; @@ -159,7 +176,7 @@ if ( event.type === 'change' || ( event.type === 'keyup' && event.which === 13 && ( event.target.nodeName === 'INPUT' || event.target.nodeName === 'TEXTAREA' && event.altKey ) ) ) { - var undef, + var undef, checkboxClass, $target = $( event.target ), isCheckbox = event.target.type === 'checkbox', $cell = $target.closest( 'td' ), @@ -169,9 +186,18 @@ busy = $table.length && $table[ 0 ].tablesorterBusy, $hdr = c && c.$headerIndexed && c.$headerIndexed[ indx ] || [], val = isCheckbox ? event.target.checked : $target.val(); - // abort if not a tablesorter table, or busy, or don't use updateCell if column is set - // to 'sorter-false' and 'filter-false', or column is set to 'parser-false' - if ( $.isEmptyObject( c ) || busy !== false || $hdr.length && ( $hdr.hasClass( 'parser-false' ) || + // abort if not a tablesorter table, or busy + if ( $.isEmptyObject( c ) || busy !== false ) { + return; + } + if ( isCheckbox ) { + checkboxClass = c.checkboxClass || 'checked'; + toggleRowClass( $cell.closest( 'tr' ), checkboxClass, indx, val ); + updateHeaderCheckbox( $table, checkboxClass ); + } + // don't use updateCell if column is set to 'sorter-false' and 'filter-false', + // or column is set to 'parser-false' + if ( $hdr.length && ( $hdr.hasClass( 'parser-false' ) || ( $hdr.hasClass( 'sorter-false' ) && $hdr.hasClass( 'filter-false' ) ) ) || // table already updating; get out of here, we might be in an endless loop (in IE)! See #971 ( event.type === 'change' && c.table.isUpdating ) ) { @@ -201,20 +227,8 @@ if ( !$.isEmptyObject( c ) ) { this.tablesorterBusy = true; checkboxClass = c && c.checkboxClass || 'checked'; - $rows = $table.children( 'tbody' ).children( ':visible' ); // (include child rows?) - len = $rows.length; // set indeterminate state on header checkbox - $( this ).children( 'thead' ).find( 'input[type="checkbox"]' ).each( function() { - var column = $( this ).closest( 'td, th' ).attr( 'data-column' ), - vis = $rows.filter( '.' + checkboxClass + '-' + column ).length, - allChecked = vis === len; - if ( vis === 0 || allChecked ) { - this.checked = allChecked; - this.indeterminate = false; - } else { - this.indeterminate = true; - } - }); + updateHeaderCheckbox( $table, checkboxClass ); this.tablesorterBusy = false; } }) @@ -222,13 +236,14 @@ .off( namespace ) // modified from http://jsfiddle.net/abkNM/6163/ .on( 'change' + namespace, 'input[type="checkbox"]', function( event ) { - var undef, onlyVisible, column, $target, + var undef, onlyVisible, column, $target, isParsed, $row, checkboxClass, $checkbox = $( this ), $table = $checkbox.closest( 'table' ), c = $table.length && $table[ 0 ].config, isChecked = this.checked; if ( $table.length && c && !$table[ 0 ].tablesorterBusy ) { column = parseInt( $checkbox.closest( 'td, th' ).attr( 'data-column' ), 10 ); + isParsed = c.parsers[ column ].id === 'checkbox'; onlyVisible = $table.length && c.checkboxVisible; $table[ 0 ].tablesorterBusy = true; // prevent "change" event from calling updateCell numerous times (see #971) $target = $table @@ -237,10 +252,23 @@ .children( ':nth-child(' + ( column + 1 ) + ')' ) .find( 'input[type="checkbox"]' ) .prop( 'checked', isChecked ); - $.tablesorter.update( c, undef, function() { + if ( !isParsed ) { + // add checkbox class names + checkboxClass = c.checkboxClass || 'checked'; + $target.each(function(){ + $row = $(this).closest('tr'); + toggleRowClass( $(this).closest( 'tr' ), checkboxClass, column, isChecked ); + }); + updateHeaderCheckbox( $table, checkboxClass ); updateServer( event, $table, $target ); $table[ 0 ].tablesorterBusy = false; - }); + } else { + // only update cache if checkboxes are being sorted + $.tablesorter.update( c, undef, function() { + updateServer( event, $table, $target ); + $table[ 0 ].tablesorterBusy = false; + }); + } } // update already going on, don't do anything! return false;