diff --git a/README.md b/README.md index 35c7cef8..97de5023 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,45 @@ If you would like to contribute, please... View the [complete change log here](https://github.com/Mottie/tablesorter/wiki/Changes). +#### Version 2.29.0 (9/27/2017) + +* Core: + * Include callback method for ["applyWidgets"](https://mottie.github.io/tablesorter/docs/index.html#applywidgets). + * Add ["widgetRemoveEnd" event](https://mottie.github.io/tablesorter/docs/index.html#widgetremoveend). Fixes [issue #1430](https://github.com/Mottie/tablesorter/issues/1430). + * Clarify warning message (widget enabled but code not loaded). + * Target header cells for data-column. Fixes [issue #1459](https://github.com/Mottie/tablesorter/issues/1459). +* ColumnSelector: + * Add [`classHasSpan` option](https://mottie.github.io/tablesorter/docs/example-widget-column-selector.html#column-selector-class-has-span). + * Fix compatibility with grouping widget. +* Grouping: + * Fix compatibility with columnSelector widget. +* Output: + * Modify internal `process` function to allow outputting of data without adding it to the table. +* Resizable: + * Add resizableComplete event. Fixes [issue #1444](https://github.com/Mottie/tablesorter/issues/1444). +* Scroller: + * Save position to fix `scroller_upAfterSort: false`; See [PR #1441](https://github.com/Mottie/tablesorter/pull/1441). This should fix [issue #1297](https://github.com/Mottie/tablesorter/issues/1297) - The current position is now saved on scroll so it can be restored after sorting; thanks [@lbodtke](https://github.com/lbodtke)! + * Update scroll position after fixing columns. +* Sort2Hash: + * Prevent sort2Hash from adding extraneous entries to browser history. Use `window.location.replace` to update the browser URL only, rather than `window.location.hash`, which modifies the browser history. See [PR #1447](https://github.com/Mottie/tablesorter/pull/1447); thanks [@alexweissman](https://github.com/alexweissman)! +* StickyHeaders: + * Only update class as needed. See [issue #1018](https://github.com/Mottie/tablesorter/issues/1018). + * Check horizontal scrolling. Fixes [issue #1455](https://github.com/Mottie/tablesorter/issues/1455). +* UITheme: + * Remove bootstrap v2 refs & fix docs. See [issue #1432](https://github.com/Mottie/tablesorter/issues/1432). +* Docs: + * Miscellaneous fixes and updates. + * Add more info about zebra widget when the table is not visible. See [PR #1438](https://github.com/Mottie/tablesorter/pull/1438); thanks [@Federico-G](https://github.com/Federico-G)! + * Fix alignCharacter widget reference to css4. + * Update userfrosting link in the readme. + * Update to Bootstrap v4.0.0-beta. + * Fix colspan demo. +* Themes: + * Rename `icon-white` to `bootstrap-icon-white`. Fixes [issue #1432](https://github.com/Mottie/tablesorter/issues/1432). +* Meta: + * Update dependencies. + * Build: maintain ie8 support to fix [issue #1431](https://github.com/Mottie/tablesorter/issues/1431). + #### Version 2.28.15 (7/4/2017) * Core: @@ -137,15 +176,3 @@ View the [complete change log here](https://github.com/Mottie/tablesorter/wiki/C * Use selectorRemove to remove error rows. Removes error rows with dynamically changed class names. * Meta: * Added [AUTHORS](https://github.com/Mottie/tablesorter/blob/master/AUTHORS) file. - -#### Version 2.28.13 (6/2/2017) - -* Core: - * Add cssIconDisabled option. See [issue #1409](https://github.com/Mottie/tablesorter/issues/1409). - * Coerce sort natural elements into strings. See [issue #1415](https://github.com/Mottie/tablesorter/issues/1415). -* StickyHeaders: - * Fix dynamic updating of offset. Fixes [issue #1412](https://github.com/Mottie/tablesorter/issues/1412). - * Init with visible headers on partial scroll -* Meta: - * Set jQuery dependency back to >=1.2.6. Fixes [issue #1411](https://github.com/Mottie/tablesorter/issues/1411). - * Add `package-lock.json` file. diff --git a/dist/js/jquery.tablesorter.combined.js b/dist/js/jquery.tablesorter.combined.js index 56b4859e..457b76fb 100644 --- a/dist/js/jquery.tablesorter.combined.js +++ b/dist/js/jquery.tablesorter.combined.js @@ -1,4 +1,4 @@ -/*! tablesorter (FORK) - updated 07-04-2017 (v2.28.15)*/ +/*! tablesorter (FORK) - updated 09-27-2017 (v2.29.0)*/ /* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */ (function(factory) { if (typeof define === 'function' && define.amd) { @@ -10,7 +10,7 @@ } }(function(jQuery) { -/*! TableSorter (FORK) v2.28.15 *//* +/*! TableSorter (FORK) v2.29.0 *//* * Client-side table sorting with ease! * @requires jQuery v1.2.6+ * @@ -34,7 +34,7 @@ 'use strict'; var ts = $.tablesorter = { - version : '2.28.15', + version : '2.29.0', parsers : [], widgets : [], @@ -433,10 +433,10 @@ e.stopPropagation(); ts.applyWidgetId( this, id ); }) - .bind( 'applyWidgets' + namespace, function( e, init ) { + .bind( 'applyWidgets' + namespace, function( e, callback ) { e.stopPropagation(); - // apply widgets - ts.applyWidget( this, init ); + // apply widgets (false = not initializing) + ts.applyWidget( this, false, callback ); }) .bind( 'refreshWidgets' + namespace, function( e, all, dontapply ) { e.stopPropagation(); @@ -473,9 +473,9 @@ downTarget = null; if ( core !== true ) { $headers.addClass( namespace.slice( 1 ) + '_extra_headers' ); - tmp = $.fn.closest ? $headers.closest( 'table' )[ 0 ] : $headers.parents( 'table' )[ 0 ]; - if ( tmp && tmp.nodeName === 'TABLE' && tmp !== table ) { - $( tmp ).addClass( namespace.slice( 1 ) + '_extra_table' ); + tmp = ts.getClosest( $headers, 'table' ); + if ( tmp.length && tmp[ 0 ].nodeName === 'TABLE' && tmp[ 0 ] !== table ) { + $( tmp[ 0 ] ).addClass( namespace.slice( 1 ) + '_extra_table' ); } } tmp = ( c.pointerDown + ' ' + c.pointerUp + ' ' + c.pointerClick + ' sort keyup ' ) @@ -527,8 +527,7 @@ ts.buildCache( c ); } // jQuery v1.2.6 doesn't have closest() - $cell = $.fn.closest ? $( this ).closest( 'th, td' ) : - /TH|TD/.test( this.nodeName ) ? $( this ) : $( this ).parents( 'th, td' ); + $cell = ts.getHeaderCell( $( this ) ); // reference original table headers and find the same cell // don't use $headers or IE8 throws an error - see #987 temp = $headers.index( $cell ); @@ -568,7 +567,7 @@ ''; // redefine c.$headers here in case of an updateAll that replaces or adds an entire header cell - see #683 c.$headers = $( $.map( c.$table.find( c.selectorHeaders ), function( elem, index ) { - var configHeaders, header, column, template, tmp, + var configHeaders, header, column, template, tmp, $th, $elem = $( elem ); // ignore cell (don't add it to c.$headers) if row has ignoreRow class if ( $elem.parent().hasClass( c.cssIgnoreRow ) ) { return; } @@ -594,7 +593,9 @@ if ( c.onRenderHeader ) { c.onRenderHeader.apply( $elem, [ index, c, c.$table ] ); } - column = parseInt( $elem.attr( 'data-column' ), 10 ); + // data-column stored on th or td only + $th = ts.getHeaderCell( $elem ); + column = parseInt( $th.attr( 'data-column' ), 10 ); elem.column = column; tmp = ts.getOrder( ts.getData( $elem, configHeaders, 'sortInitialOrder' ) || c.sortInitialOrder ); // this may get updated numerous times if there are multiple rows @@ -612,10 +613,9 @@ } // add cell to headerList c.headerList[ index ] = elem; + $elem.addClass( ts.css.header + ' ' + c.cssHeader ); // add to parent in case there are multiple rows - $elem - .addClass( ts.css.header + ' ' + c.cssHeader ) - .parent() + ts.getClosest( $elem, 'tr' ) .addClass( ts.css.headerRow + ' ' + c.cssHeaderRow ) .attr( 'role', 'row' ); // allow keyboard cursor to focus on element @@ -1173,10 +1173,29 @@ } }, + // This function does NOT return closest if the $el matches the selector + getClosest : function( $el, selector ) { + return $.fn.closest ? + $el.closest( selector ) : + $el.parents( selector ).filter( ':first' ); + }, + + getHeaderCell : function( $el ) { + // jQuery v1.2.6 doesn't have closest() + if ( $.fn.closest ) { + return $el.closest( 'th, td' ); + } + return /TH|TD/.test( $el[0].nodeName ) ? + $el : + $el.parents( 'th, td' ).filter( ':first' ); + }, + // nextSort (optional), lets you disable next sort text setColumnAriaLabel : function( c, $header, nextSort ) { if ( $header.length ) { - var column = parseInt( $header.attr( 'data-column' ), 10 ), + var $th = ts.getHeaderCell( $header ), + // data-column always stored on the th/td + column = parseInt( $th.attr( 'data-column' ), 10 ), vars = c.sortVars[ column ], tmp = $header.hasClass( ts.css.sortAsc ) ? 'sortAsc' : @@ -1334,10 +1353,9 @@ $cell = $( cell ), // update cache - format: function( s, table, cell, cellIndex ) // no closest in jQuery v1.2.6 - tbodyIndex = $tbodies - .index( $.fn.closest ? $cell.closest( 'tbody' ) : $cell.parents( 'tbody' ).filter( ':first' ) ), + tbodyIndex = $tbodies.index( ts.getClosest( $cell, 'tbody' ) ), tbcache = c.cache[ tbodyIndex ], - $row = $.fn.closest ? $cell.closest( 'tr' ) : $cell.parents( 'tr' ).filter( ':first' ); + $row = ts.getClosest( $cell, 'tr' ); cell = $cell[ 0 ]; // in case cell is a jQuery object // tbody may not exist if update is initialized while tbody is removed for processing if ( $tbodies.length && tbodyIndex >= 0 ) { @@ -1392,11 +1410,13 @@ if ( valid ) { $row = $( $row ); c.$tbodies.append( $row ); - } else if ( !$row || + } else if ( + !$row || // row is a jQuery object? !( $row instanceof jQuery ) || // row contained in the table? - ( $.fn.closest ? $row.closest( 'table' )[ 0 ] : $row.parents( 'table' )[ 0 ] ) !== c.table ) { + ( ts.getClosest( $row, 'table' )[ 0 ] !== c.table ) + ) { if ( c.debug ) { console.error( 'addRows method requires (1) a jQuery selector reference to rows that have already ' + 'been added to the table, or (2) row HTML string to be added to a table with only one tbody' ); @@ -1543,10 +1563,10 @@ notMultiSort = !event[ c.sortMultiSortKey ], table = c.table, len = c.$headers.length, - // get current column index - col = parseInt( $( cell ).attr( 'data-column' ), 10 ), + // get current column index; *always* stored on th/td + $th = ts.getHeaderCell( $( cell ) ), + col = parseInt( $th.attr( 'data-column' ), 10 ), order = c.sortVars[ col ].order; - // Only call sortStart if sorting is enabled c.$table.triggerHandler( 'sortStart', table ); // get current column sort order @@ -2070,7 +2090,7 @@ if ( !widget.priority ) { widget.priority = 10; } widgets[ indx ] = widget; } else if ( c.debug ) { - console.warn( '"' + names[ indx ] + '" widget code does not exist!' ); + console.warn( '"' + names[ indx ] + '" was enabled, but the widget code has not been loaded!' ); } } // sort widgets by priority @@ -2142,6 +2162,7 @@ c.widgetInit[ name[ index ] ] = false; } } + c.$table.triggerHandler( 'widgetRemoveEnd', table ); }, refreshWidgets : function( table, doAll, dontapply ) { @@ -2993,7 +3014,7 @@ })(jQuery, window, document); -/*! Widget: uitheme - updated 12/8/2016 (v2.28.1) */ +/*! Widget: uitheme - updated 9/27/2017 (v2.29.0) */ ;(function ($) { 'use strict'; var ts = $.tablesorter || {}; @@ -5196,7 +5217,7 @@ })( jQuery ); -/*! Widget: stickyHeaders - updated 6/2/2017 (v2.28.13) *//* +/*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) *//* * Requires tablesorter v2.8+ and jQuery 1.4.3+ * by Rob Garrison */ @@ -5348,10 +5369,14 @@ }); } }, + getLeftPosition = function() { + return $attach.length ? + parseInt($attach.css('padding-left'), 10) || 0 : + $table.offset().left - parseInt($table.css('margin-left'), 10) - $(window).scrollLeft(); + }, resizeHeader = function() { $stickyWrap.css({ - left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 : - $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft(), + left : getLeftPosition(), width: $table.outerWidth() }); setWidth( $table, $stickyTable ); @@ -5361,10 +5386,10 @@ if (!$table.is(':visible')) { return; } // fixes #278 // Detect nested tables - fixes #724 nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0; - var offset = $table.offset(), + var tmp, + offset = $table.offset(), stickyOffset = getStickyOffset(c, wo), yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3 - xWindow = $.isWindow( $xScroll[0] ), attachTop = $attach.length ? ( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) : $yScroll.scrollTop(), @@ -5372,19 +5397,27 @@ scrollTop = attachTop + stickyOffset + nestedStickyTop - captionHeight, tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)) - captionHeight, isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden', + state = isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide, + needsUpdating = !$stickyWrap.hasClass( state ), cssSettings = { visibility : isVisible }; if ($attach.length) { + // attached sticky headers always need updating + needsUpdating = true; cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop(); } - if (xWindow) { - // adjust when scrolling horizontally - fixes issue #143 - cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft(); + // adjust when scrolling horizontally - fixes issue #143 + tmp = getLeftPosition(); + if (tmp !== parseInt($stickyWrap.css('left'), 10)) { + needsUpdating = true; + cssSettings.left = tmp; } cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop; - $stickyWrap - .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide ) - .addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide ) - .css(cssSettings); + if (needsUpdating) { + $stickyWrap + .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide ) + .addClass( state ) + .css(cssSettings); + } if (isVisible !== laststate || resizing) { // make sure the column widths match resizeHeader(); @@ -5503,7 +5536,7 @@ })(jQuery, window); -/*! Widget: resizable - updated 4/18/2017 (v2.28.8) */ +/*! Widget: resizable - updated 9/27/2017 (v2.29.0) */ /*jshint browser:true, jquery:true, unused:false */ ;(function ($, window) { 'use strict'; @@ -5830,6 +5863,7 @@ vars.$target = vars.$next = null; // will update stickyHeaders, just in case, see #912 c.$table.triggerHandler('stickyHeadersUpdate'); + c.$table.triggerHandler('resizableComplete'); } }; diff --git a/dist/js/jquery.tablesorter.combined.min.js b/dist/js/jquery.tablesorter.combined.min.js index 4187f8d5..19672e32 100644 --- a/dist/js/jquery.tablesorter.combined.min.js +++ b/dist/js/jquery.tablesorter.combined.min.js @@ -1,2 +1,2 @@ -/*! tablesorter (FORK) - updated 07-04-2017 (v2.28.15)*/ -!function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&"object"==typeof module.exports?module.exports=e(require("jquery")):e(jQuery)}(function(e){return function(t){"use strict";var r=t.tablesorter={version:"2.28.15",parsers:[],widgets:[],defaults:{theme:"default",widthFixed:!1,showProcessing:!1,headerTemplate:"{content}",onRenderTemplate:null,onRenderHeader:null,cancelSelection:!0,tabIndex:!0,dateFormat:"mmddyyyy",sortMultiSortKey:"shiftKey",sortResetKey:"ctrlKey",usNumberFormat:!0,delayInit:!1,serverSideSorting:!1,resort:!0,headers:{},ignoreCase:!0,sortForce:null,sortList:[],sortAppend:null,sortStable:!1,sortInitialOrder:"asc",sortLocaleCompare:!1,sortReset:!1,sortRestart:!1,emptyTo:"bottom",stringTo:"max",duplicateSpan:!0,textExtraction:"basic",textAttribute:"data-text",textSorter:null,numberSorter:null,initWidgets:!0,widgetClass:"widget-{name}",widgets:[],widgetOptions:{zebra:["even","odd"]},initialized:null,tableClass:"",cssAsc:"",cssDesc:"",cssNone:"",cssHeader:"",cssHeaderRow:"",cssProcessing:"",cssChildRow:"tablesorter-childRow",cssInfoBlock:"tablesorter-infoOnly",cssNoSort:"tablesorter-noSort",cssIgnoreRow:"tablesorter-ignoreRow",cssIcon:"tablesorter-icon",cssIconNone:"",cssIconAsc:"",cssIconDesc:"",cssIconDisabled:"",pointerClick:"click",pointerDown:"mousedown",pointerUp:"mouseup",selectorHeaders:"> thead th, > thead td",selectorSort:"th, td",selectorRemove:".remove-me",debug:!1,headerList:[],empties:{},strings:{},parsers:[],globalize:0,imgAttr:0},css:{table:"tablesorter",cssHasChild:"tablesorter-hasChildRow",childRow:"tablesorter-childRow",colgroup:"tablesorter-colgroup",header:"tablesorter-header",headerRow:"tablesorter-headerRow",headerIn:"tablesorter-header-inner",icon:"tablesorter-icon",processing:"tablesorter-processing",sortAsc:"tablesorter-headerAsc",sortDesc:"tablesorter-headerDesc",sortNone:"tablesorter-headerUnSorted"},language:{sortAsc:"Ascending sort applied, ",sortDesc:"Descending sort applied, ",sortNone:"No sort applied, ",sortDisabled:"sorting is disabled",nextAsc:"activate to apply an ascending sort",nextDesc:"activate to apply a descending sort",nextNone:"activate to remove the sort"},regex:{templateContent:/\{content\}/g,templateIcon:/\{icon\}/g,templateName:/\{name\}/i,spaces:/\s+/g,nonWord:/\W/g,formElements:/(input|select|button|textarea)/i,chunk:/(^([+\-]?(?:\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi,chunks:/(^\\0|\\0$)/,hex:/^0x[0-9a-f]+$/i,comma:/,/g,digitNonUS:/[\s|\.]/g,digitNegativeTest:/^\s*\([.\d]+\)/,digitNegativeReplace:/^\s*\(([.\d]+)\)/,digitTest:/^[\-+(]?\d+[)]?$/,digitReplace:/[,.'"\s]/g},string:{max:1,min:-1,emptymin:1,emptymax:-1,zero:0,none:0,null:0,top:!0,bottom:!1},keyCodes:{enter:13},dates:{},instanceMethods:{},setup:function(e,a){if(e&&e.tHead&&0!==e.tBodies.length&&!0!==e.hasInitialized){var i="",s=t(e),o=t.metadata;e.hasInitialized=!1,e.isProcessing=!0,e.config=a,t.data(e,"tablesorter",a),a.debug&&(console[console.group?"group":"log"]("Initializing tablesorter v"+r.version),t.data(e,"startoveralltimer",new Date)),a.supportsDataObject=function(e){return e[0]=parseInt(e[0],10),e[0]>1||1===e[0]&&parseInt(e[1],10)>=4}(t.fn.jquery.split(".")),a.emptyTo=a.emptyTo.toLowerCase(),a.stringTo=a.stringTo.toLowerCase(),a.last={sortList:[],clickedIndex:-1},/tablesorter\-/.test(s.attr("class"))||(i=""!==a.theme?" tablesorter-"+a.theme:""),a.namespace?a.namespace="."+a.namespace.replace(r.regex.nonWord,""):a.namespace=".tablesorter"+Math.random().toString(16).slice(2),a.table=e,a.$table=s.addClass(r.css.table+" "+a.tableClass+i+" "+a.namespace.slice(1)).attr("role","grid"),a.$headers=s.find(a.selectorHeaders),a.$table.children().children("tr").attr("role","row"),a.$tbodies=s.children("tbody:not(."+a.cssInfoBlock+")").attr({"aria-live":"polite","aria-relevant":"all"}),a.$table.children("caption").length&&((i=a.$table.children("caption")[0]).id||(i.id=a.namespace.slice(1)+"caption"),a.$table.attr("aria-labelledby",i.id)),a.widgetInit={},a.textExtraction=a.$table.attr("data-text-extraction")||a.textExtraction||"basic",r.buildHeaders(a),r.fixColumnWidth(e),r.addWidgetFromClass(e),r.applyWidgetOptions(e),r.setupParsers(a),a.totalRows=0,r.validateOptions(a),a.delayInit||r.buildCache(a),r.bindEvents(e,a.$headers,!0),r.bindMethods(a),a.supportsDataObject&&void 0!==s.data().sortlist?a.sortList=s.data().sortlist:o&&s.metadata()&&s.metadata().sortlist&&(a.sortList=s.metadata().sortlist),r.applyWidget(e,!0),a.sortList.length>0?r.sortOn(a,a.sortList,{},!a.initWidgets):(r.setHeadersCss(a),a.initWidgets&&r.applyWidget(e,!1)),a.showProcessing&&s.unbind("sortBegin"+a.namespace+" sortEnd"+a.namespace).bind("sortBegin"+a.namespace+" sortEnd"+a.namespace,function(t){clearTimeout(a.timerProcessing),r.isProcessing(e),"sortBegin"===t.type&&(a.timerProcessing=setTimeout(function(){r.isProcessing(e,!0)},500))}),e.hasInitialized=!0,e.isProcessing=!1,a.debug&&(console.log("Overall initialization time:"+r.benchmark(t.data(e,"startoveralltimer"))),a.debug&&console.groupEnd&&console.groupEnd()),s.triggerHandler("tablesorter-initialized",e),"function"==typeof a.initialized&&a.initialized(e)}else a.debug&&(e.hasInitialized?console.warn("Stopping initialization. Tablesorter has already been initialized"):console.error("Stopping initialization! No table, thead or tbody",e))},bindMethods:function(e){var a=e.$table,i=e.namespace,s="sortReset update updateRows updateAll updateHeaders addRows updateCell updateComplete sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave ".split(" ").join(i+" ");a.unbind(s.replace(r.regex.spaces," ")).bind("sortReset"+i,function(e,t){e.stopPropagation(),r.sortReset(this.config,function(e){e.isApplyingWidgets?setTimeout(function(){r.applyWidget(e,"",t)},100):r.applyWidget(e,"",t)})}).bind("updateAll"+i,function(e,t,a){e.stopPropagation(),r.updateAll(this.config,t,a)}).bind("update"+i+" updateRows"+i,function(e,t,a){e.stopPropagation(),r.update(this.config,t,a)}).bind("updateHeaders"+i,function(e,t){e.stopPropagation(),r.updateHeaders(this.config,t)}).bind("updateCell"+i,function(e,t,a,i){e.stopPropagation(),r.updateCell(this.config,t,a,i)}).bind("addRows"+i,function(e,t,a,i){e.stopPropagation(),r.addRows(this.config,t,a,i)}).bind("updateComplete"+i,function(){this.isUpdating=!1}).bind("sorton"+i,function(e,t,a,i){e.stopPropagation(),r.sortOn(this.config,t,a,i)}).bind("appendCache"+i,function(e,a,i){e.stopPropagation(),r.appendCache(this.config,i),t.isFunction(a)&&a(this)}).bind("updateCache"+i,function(e,t,a){e.stopPropagation(),r.updateCache(this.config,t,a)}).bind("applyWidgetId"+i,function(e,t){e.stopPropagation(),r.applyWidgetId(this,t)}).bind("applyWidgets"+i,function(e,t){e.stopPropagation(),r.applyWidget(this,t)}).bind("refreshWidgets"+i,function(e,t,a){e.stopPropagation(),r.refreshWidgets(this,t,a)}).bind("removeWidget"+i,function(e,t,a){e.stopPropagation(),r.removeWidget(this,t,a)}).bind("destroy"+i,function(e,t,a){e.stopPropagation(),r.destroy(this,t,a)}).bind("resetToLoadState"+i,function(a){a.stopPropagation(),r.removeWidget(this,!0,!1);var i=t.extend(!0,{},e.originalSettings);(e=t.extend(!0,{},r.defaults,i)).originalSettings=i,this.hasInitialized=!1,r.setup(this,e)})},bindEvents:function(e,a,i){var s,o=(e=t(e)[0]).config,n=o.namespace,l=null;!0!==i&&(a.addClass(n.slice(1)+"_extra_headers"),(s=t.fn.closest?a.closest("table")[0]:a.parents("table")[0])&&"TABLE"===s.nodeName&&s!==e&&t(s).addClass(n.slice(1)+"_extra_table")),s=(o.pointerDown+" "+o.pointerUp+" "+o.pointerClick+" sort keyup ").replace(r.regex.spaces," ").split(" ").join(n+" "),a.find(o.selectorSort).add(a.filter(o.selectorSort)).unbind(s).bind(s,function(e,i){var s,n,d,c=t(e.target),f=" "+e.type+" ";if(!(1!==(e.which||e.button)&&!f.match(" "+o.pointerClick+" | sort | keyup ")||" keyup "===f&&e.which!==r.keyCodes.enter||f.match(" "+o.pointerClick+" ")&&void 0!==e.which||f.match(" "+o.pointerUp+" ")&&l!==e.target&&!0!==i)){if(f.match(" "+o.pointerDown+" "))return l=e.target,void("1"===(d=c.jquery.split("."))[0]&&d[1]<4&&e.preventDefault());if(l=null,r.regex.formElements.test(e.target.nodeName)||c.hasClass(o.cssNoSort)||c.parents("."+o.cssNoSort).length>0||c.parents("button").length>0)return!o.cancelSelection;o.delayInit&&r.isEmptyObject(o.cache)&&r.buildCache(o),s=t.fn.closest?t(this).closest("th, td"):/TH|TD/.test(this.nodeName)?t(this):t(this).parents("th, td"),d=a.index(s),o.last.clickedIndex=d<0?s.attr("data-column"):d,(n=o.$headers[o.last.clickedIndex])&&!n.sortDisabled&&r.initSort(o,n,e)}}),o.cancelSelection&&a.attr("unselectable","on").bind("selectstart",!1).css({"user-select":"none",MozUserSelect:"none"})},buildHeaders:function(e){var a,i,s,o;for(e.headerList=[],e.headerContent=[],e.sortVars=[],e.debug&&(s=new Date),e.columns=r.computeColumnIndex(e.$table.children("thead, tfoot").children("tr")),i=e.cssIcon?'':"",e.$headers=t(t.map(e.$table.find(e.selectorHeaders),function(a,s){var o,n,l,d,c,f=t(a);if(!f.parent().hasClass(e.cssIgnoreRow))return o=r.getColumnData(e.table,e.headers,s,!0),e.headerContent[s]=f.html(),""===e.headerTemplate||f.find("."+r.css.headerIn).length||(d=e.headerTemplate.replace(r.regex.templateContent,f.html()).replace(r.regex.templateIcon,f.find("."+r.css.icon).length?"":i),e.onRenderTemplate&&(n=e.onRenderTemplate.apply(f,[s,d]))&&"string"==typeof n&&(d=n),f.html('