2015-10-31 16:06:09 +00:00
/*! Widget: Pager - updated 10/31/2015 (v2.24.0) */
2015-10-31 15:08:21 +00:00
/ * R e q u i r e s t a b l e s o r t e r v 2 . 8 + a n d j Q u e r y 1 . 7 +
* by Rob Garrison
* /
/*jshint browser:true, jquery:true, unused:false */
! function ( a ) { "use strict" ; var b , c = a . tablesorter ; c . addWidget ( { id : "pager" , priority : 55 , // load pager after filter widget
options : {
// output default: '{page}/{totalPages}'
// possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
pager _output : "{startRow} to {endRow} of {totalRows} rows" , // '{page}/{totalPages}'
// apply disabled classname to the pager arrows when the rows at either extreme is visible
pager _updateArrows : ! 0 ,
// starting page of the pager (zero based index)
pager _startPage : 0 ,
// reset pager after filtering; set to desired page #
// set to false to not change page at filter start
pager _pageReset : 0 ,
// Number of visible rows
pager _size : 10 ,
// Number of options to include in the pager number selector
pager _maxOptionSize : 20 ,
// Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
pager _savePages : ! 0 ,
// defines custom storage key
pager _storageKey : "tablesorter-pager" ,
// if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
// table row set to a height to compensate; default is false
pager _fixedHeight : ! 1 ,
// count child rows towards the set page size? (set true if it is a visible table row within the pager)
// if true, child row(s) may not appear to be attached to its parent row, may be split across pages or
// may distort the table if rowspan or cellspans are included.
pager _countChildRows : ! 1 ,
// remove rows from the table to speed up the sort of large tables.
// setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
pager _removeRows : ! 1 , // removing rows in larger tables speeds up the sort
// use this format: 'http://mydatabase.com?page={page}&size={size}&{sortList:col}&{filterList:fcol}'
// where {page} is replaced by the page number, {size} is replaced by the number of records to show,
// {sortList:col} adds the sortList to the url into a 'col' array, and {filterList:fcol} adds
// the filterList to the url into an 'fcol' array.
// So a sortList = [[2,0],[3,0]] becomes '&col[2]=0&col[3]=0' in the url
// and a filterList = [[2,Blue],[3,13]] becomes '&fcol[2]=Blue&fcol[3]=13' in the url
pager _ajaxUrl : null ,
// modify the url after all processing has been applied
pager _customAjaxUrl : function ( a , b ) { return b } ,
// ajax error callback from $.tablesorter.showError function
// pager_ajaxError: function( config, xhr, settings, exception ){ return exception; };
// returning false will abort the error message
pager _ajaxError : null ,
// modify the $.ajax object to allow complete control over your ajax requests
pager _ajaxObject : { dataType : "json" } ,
// set this to false if you want to block ajax loading on init
pager _processAjaxOnInit : ! 0 ,
// process ajax so that the following information is returned:
// [ total_rows (number), rows (array of arrays), headers (array; optional) ]
// example:
// [
// 100, // total rows
// [
// [ "row1cell1", "row1cell2", ... "row1cellN" ],
// [ "row2cell1", "row2cell2", ... "row2cellN" ],
// ...
// [ "rowNcell1", "rowNcell2", ... "rowNcellN" ]
// ],
// [ "header1", "header2", ... "headerN" ] // optional
// ]
pager _ajaxProcessing : function ( a ) { return [ 0 , [ ] , null ] } ,
// css class names of pager arrows
pager _css : { container : "tablesorter-pager" , errorRow : "tablesorter-errorRow" , // error information row (don't include period at beginning)
disabled : "disabled" } ,
// jQuery selectors
pager _selectors : { container : ".pager" , // target the pager markup
first : ".first" , // go to first page arrow
prev : ".prev" , // previous page arrow
next : ".next" , // next page arrow
last : ".last" , // go to last page arrow
gotoPage : ".gotoPage" , // go to page selector - select dropdown that sets the current page
pageDisplay : ".pagedisplay" , // location of where the 'output' is displayed
pageSize : ".pagesize" } } , init : function ( a ) { b . init ( a ) } ,
// only update to complete sorter initialization
format : function ( a , c ) { return c . pager && c . pager . initialized ? void b . moveToPage ( a , c . pager , ! 1 ) : b . initComplete ( a , c ) } , remove : function ( a , c , d , e ) { b . destroyPager ( a , c , e ) } } ) , b = c . pager = { init : function ( d ) {
// check if tablesorter has initialized
if ( ! ( d . hasInitialized && d . config . pager && d . config . pager . initialized ) ) { var e , f = d . config , g = f . widgetOptions , h = g . pager _selectors ,
// save pager variables
i = f . pager = a . extend ( { totalPages : 0 , filteredRows : 0 , filteredPages : 0 , currentFilters : [ ] , page : g . pager _startPage , startRow : 0 , endRow : 0 , ajaxCounter : 0 , $size : null , last : { } ,
// save original pager size
setSize : g . pager _size , setPage : g . pager _startPage } , f . pager ) ;
// pager initializes multiple times before table has completed initialization
i . isInitializing || ( i . isInitializing = ! 0 , f . debug && console . log ( "Pager: Initializing" ) , i . size = a . data ( d , "pagerLastSize" ) || g . pager _size ,
// added in case the pager is reinitialized after being destroyed.
i . $container = a ( h . container ) . addClass ( g . pager _css . container ) . show ( ) ,
// goto selector
i . $goto = i . $container . find ( h . gotoPage ) , // goto is a reserved word #657
// page size selector
i . $size = i . $container . find ( h . pageSize ) , i . totalRows = f . $tbodies . eq ( 0 ) . children ( "tr" ) . not ( g . pager _countChildRows ? "" : "." + f . cssChildRow ) . length , i . oldAjaxSuccess = i . oldAjaxSuccess || g . pager _ajaxObject . success , f . appender = b . appender , i . initializing = ! 0 , g . pager _savePages && c . storage && ( e = c . storage ( d , g . pager _storageKey ) || { } , i . page = ( isNaN ( e . page ) ? i . page : e . page ) || i . setPage || 0 , i . size = ( isNaN ( e . size ) ? i . size : e . size ) || i . setSize || 10 , a . data ( d , "pagerLastSize" , i . size ) ) ,
// skipped rows
i . regexRows = new RegExp ( "(" + ( g . filter _filteredRow || "filtered" ) + "|" + f . selectorRemove . slice ( 1 ) + "|" + f . cssChildRow + ")" ) ,
// clear initialized flag
i . initialized = ! 1 ,
// before initialization event
f . $table . trigger ( "pagerBeforeInitialized" , f ) , b . enablePager ( d , f , ! 1 ) ,
// p must have ajaxObject
i . ajaxObject = g . pager _ajaxObject , // $.extend({}, wo.pager_ajaxObject );
i . ajaxObject . url = g . pager _ajaxUrl , "string" == typeof g . pager _ajaxUrl ? (
// ajax pager; interact with database
i . ajax = ! 0 ,
// When filtering with ajax, allow only custom filtering function, disable default filtering since it will be done server side.
g . filter _serversideFiltering = ! 0 , f . serverSideSorting = ! 0 , b . moveToPage ( d , i ) ) : ( i . ajax = ! 1 ,
// Regular pager; all rows stored in memory
c . appendCache ( f , ! 0 ) ) ) } } , initComplete : function ( a , d ) { var e = d . pager ; b . bindEvents ( a , d ) , b . setPageSize ( d , 0 ) , // page size 0 is ignored
e . ajax || b . hideRowsSetup ( a , d ) ,
// pager initialized
e . initialized = ! 0 , e . initializing = ! 1 , e . isInitializing = ! 1 , d . debug && console . log ( "Pager: Triggering pagerInitialized" ) , d . $table . trigger ( "pagerInitialized" , d ) ,
// filter widget not initialized; it will update the output display & fire off the pagerComplete event
d . widgetOptions . filter _initialized && c . hasWidget ( a , "filter" ) ||
// if ajax, then don't fire off pagerComplete
b . updatePageDisplay ( a , d , ! e . ajax ) } , bindEvents : function ( d , e ) { var f , g , h = e . pager , i = e . widgetOptions , j = e . namespace + "pager" , k = i . pager _selectors ; e . $table . off ( j ) . on ( "filterInit filterStart " . split ( " " ) . join ( j + " " ) , function ( b , c ) { h . currentFilters = a . isArray ( c ) ? c : e . $table . data ( "lastSearch" ) ,
// don't change page if filters are the same (pager updating, etc)
"filterStart" === b . type && i . pager _pageReset !== ! 1 && ( e . lastCombinedFilter || "" ) !== ( h . currentFilters || [ ] ) . join ( "" ) && ( h . page = i . pager _pageReset ) } ) . on ( "filterEnd sortEnd " . split ( " " ) . join ( j + " " ) , function ( ) { h . currentFilters = e . $table . data ( "lastSearch" ) , ( h . initialized || h . initializing ) && ( e . delayInit && e . rowsCopy && 0 === e . rowsCopy . length &&
// make sure we have a copy of all table rows once the cache has been built
b . updateCache ( d ) , b . updatePageDisplay ( d , e , ! 1 ) ,
// tsp.moveToPage(table, p, false); <-- called when applyWidgets is triggered
c . applyWidget ( d ) ) } ) . on ( "disablePager" + j , function ( a ) { a . stopPropagation ( ) , b . showAllRows ( d , e ) } ) . on ( "enablePager" + j , function ( a ) { a . stopPropagation ( ) , b . enablePager ( d , e , ! 0 ) } ) . on ( "destroyPager" + j , function ( a , b ) { a . stopPropagation ( ) ,
// call removeWidget to make sure internal flags are modified.
c . removeWidget ( d , "pager" , ! 1 ) } ) . on ( "updateComplete" + j , function ( a , d , f ) {
// table can be unintentionally undefined in tablesorter v2.17.7 and earlier
// don't recalculate total rows/pages if using ajax
if ( a . stopPropagation ( ) , d && ! f && ! h . ajax ) { var g = e . $tbodies . eq ( 0 ) . children ( "tr" ) . not ( e . selectorRemove ) ; h . totalRows = g . length - ( i . pager _countChildRows ? 0 : g . filter ( "." + e . cssChildRow ) . length ) , h . totalPages = Math . ceil ( h . totalRows / h . size ) , g . length && e . rowsCopy && 0 === e . rowsCopy . length &&
// make a copy of all table rows once the cache has been built
b . updateCache ( d ) , h . page >= h . totalPages && b . moveToLastPage ( d , h ) , b . hideRows ( d , e ) , b . changeHeight ( d , e ) ,
// update without triggering pagerComplete
b . updatePageDisplay ( d , e , ! 1 ) ,
// make sure widgets are applied - fixes #450
c . applyWidget ( d ) , b . updatePageDisplay ( d , e ) } } ) . on ( "pageSize refreshComplete " . split ( " " ) . join ( j + " " ) , function ( a , c ) { a . stopPropagation ( ) , b . setPageSize ( e , b . parsePageSize ( e , c , "get" ) ) , b . hideRows ( d , e ) , b . updatePageDisplay ( d , e , ! 1 ) } ) . on ( "pageSet pagerUpdate " . split ( " " ) . join ( j + " " ) , function ( a , c ) { a . stopPropagation ( ) , "pagerUpdate" === a . type && ( c = "undefined" == typeof c ? h . page + 1 : c , h . last . page = ! 0 ) , h . page = ( parseInt ( c , 10 ) || 1 ) - 1 , b . moveToPage ( d , h , ! 0 ) , b . updatePageDisplay ( d , e , ! 1 ) } ) . on ( "pageAndSize" + j , function ( a , c , f ) { a . stopPropagation ( ) , h . page = ( parseInt ( c , 10 ) || 1 ) - 1 , b . setPageSize ( e , b . parsePageSize ( e , f , "get" ) ) , b . moveToPage ( d , h , ! 0 ) , b . hideRows ( d , e ) , b . updatePageDisplay ( d , e , ! 1 ) } ) , f = [ k . first , k . prev , k . next , k . last ] , g = [ "moveToFirstPage" , "moveToPrevPage" , "moveToNextPage" , "moveToLastPage" ] , e . debug && ! h . $container . length && console . warn ( "Pager: >> Container not found" ) , h . $container . find ( f . join ( "," ) ) . attr ( "tabindex" , 0 ) . off ( "click" + j ) . on ( "click" + j , function ( c ) { c . stopPropagation ( ) ; var e , j = a ( this ) , k = f . length ; if ( ! j . hasClass ( i . pager _css . disabled ) ) for ( e = 0 ; k > e ; e ++ ) if ( j . is ( f [ e ] ) ) { b [ g [ e ] ] ( d , h ) ; break } } ) , h . $goto . length ? h . $goto . off ( "change" + j ) . on ( "change" + j , function ( ) { h . page = a ( this ) . val ( ) - 1 , b . moveToPage ( d , h , ! 0 ) , b . updatePageDisplay ( d , e , ! 1 ) } ) : e . debug && console . warn ( "Pager: >> Goto selector not found" ) , h . $size . length ? ( h . $size . find ( "option" ) . removeAttr ( "selected" ) , h . $size . off ( "change" + j ) . on ( "change" + j , function ( ) { if ( ! a ( this ) . hasClass ( i . pager _css . disabled ) ) { var c = a ( this ) . val ( ) ; h . $size . val ( c ) , b . setPageSize ( e , c ) , b . changeHeight ( d , e ) } return ! 1 } ) ) : e . debug && console . warn ( "Pager: >> Size selector not found" ) } ,
// hide arrows at extremes
pagerArrows : function ( a , b ) { var c = a . pager , d = ! ! b , e = d || 0 === c . page , f = Math . min ( c . totalPages , c . filteredPages ) , g = d || c . page === f - 1 || 0 === f , h = a . widgetOptions , i = h . pager _selectors ; h . pager _updateArrows && ( c . $container . find ( i . first + "," + i . prev ) . toggleClass ( h . pager _css . disabled , e ) . attr ( "aria-disabled" , e ) , c . $container . find ( i . next + "," + i . last ) . toggleClass ( h . pager _css . disabled , g ) . attr ( "aria-disabled" , g ) ) } , calcFilters : function ( b , c ) { var d , e , f , g = c . widgetOptions , h = c . pager , i = c . $table . hasClass ( "hasFilters" ) ; if ( i && ! g . pager _ajaxUrl ) if ( a . isEmptyObject ( c . cache ) )
// delayInit: true so nothing is in the cache
h . filteredRows = h . totalRows = c . $tbodies . eq ( 0 ) . children ( "tr" ) . not ( g . pager _countChildRows ? "" : "." + c . cssChildRow ) . length ; else for ( h . filteredRows = 0 , d = c . cache [ 0 ] . normalized , f = d . length , e = 0 ; f > e ; e ++ ) h . filteredRows += h . regexRows . test ( d [ e ] [ c . columns ] . $row [ 0 ] . className ) ? 0 : 1 ; else i || ( h . filteredRows = h . totalRows ) } , updatePageDisplay : function ( d , e , f ) { if ( ! e . pager . initializing ) { var g , h , i , j , k , l , m = e . widgetOptions , n = e . pager , o = e . namespace + "pager" , p = b . parsePageSize ( e , n . size , "get" ) ; if ( // don't allow dividing by zero
m . pager _countChildRows && h . push ( e . cssChildRow ) , n . $size . add ( n . $goto ) . removeClass ( m . pager _css . disabled ) . removeAttr ( "disabled" ) . attr ( "aria-disabled" , "false" ) , n . totalPages = Math . ceil ( n . totalRows / p ) , // needed for 'pageSize' method
e . totalRows = n . totalRows , b . parsePageNumber ( n ) , b . calcFilters ( d , e ) , e . filteredRows = n . filteredRows , n . filteredPages = Math . ceil ( n . filteredRows / p ) || 0 , Math . min ( n . totalPages , n . filteredPages ) >= 0 ) { if ( h = n . size * n . page > n . filteredRows && f , n . page = h ? m . pager _pageReset || 0 : n . page , n . startRow = h ? n . size * n . page + 1 : 0 === n . filteredRows ? 0 : n . size * n . page + 1 , n . endRow = Math . min ( n . filteredRows , n . totalRows , n . size * ( n . page + 1 ) ) , i = n . $container . find ( m . pager _selectors . pageDisplay ) , g = ( n . ajaxData && n . ajaxData . output ? n . ajaxData . output || m . pager _output : m . pager _output ) . replace ( /\{page([\-+]\d+)?\}/gi , function ( a , b ) { return n . totalPages ? n . page + ( b ? parseInt ( b , 10 ) : 1 ) : 0 } ) . replace ( /\{\w+(\s*:\s*\w+)?\}/gi , function ( a ) { var b , c , d = a . replace ( /[{}\s]/g , "" ) , e = d . split ( ":" ) , f = n . ajaxData , g = /(rows?|pages?)$/i . test ( d ) ? 0 : "" ; return /(startRow|page)/ . test ( e [ 0 ] ) && "input" === e [ 1 ] ? ( b = ( "" + ( "page" === e [ 0 ] ? n . totalPages : n . totalRows ) ) . length , c = "page" === e [ 0 ] ? n . page + 1 : n . startRow , '<input type="text" class="ts-' + e [ 0 ] + '" style="max-width:' + b + 'em" value="' + c + '"/>' ) : e . length > 1 && f && f [ e [ 0 ] ] ? f [ e [ 0 ] ] [ e [ 1 ] ] : n [ d ] || ( f ? f [ d ] : g ) || g } ) , n . $goto . length ) { for ( h = "" , j = b . buildPageSelect ( n , e ) , l = j . length , k = 0 ; l > k ; k ++ ) h += '<option value="' + j [ k ] + '">' + j [ k ] + "</option>" ;
// innerHTML doesn't work in IE9 - http://support2.microsoft.com/kb/276228
n . $goto . html ( h ) . val ( n . page + 1 ) } i . length && ( i [ "INPUT" === i [ 0 ] . nodeName ? "val" : "html" ] ( g ) ,
// rebind startRow/page inputs
i . find ( ".ts-startRow, .ts-page" ) . off ( "change" + o ) . on ( "change" + o , function ( ) { var b = a ( this ) . val ( ) , c = a ( this ) . hasClass ( "ts-startRow" ) ? Math . floor ( b / n . size ) + 1 : b ; e . $table . trigger ( "pageSet" + o , [ c ] ) } ) ) } b . pagerArrows ( e ) , b . fixHeight ( d , e ) , n . initialized && f !== ! 1 && ( e . debug && console . log ( "Pager: Triggering pagerComplete" ) , e . $table . trigger ( "pagerComplete" , e ) ,
// save pager info to storage
m . pager _savePages && c . storage && c . storage ( d , m . pager _storageKey , { page : n . page , size : n . size } ) ) } } , buildPageSelect : function ( b , c ) {
// Filter the options page number link array if it's larger than 'pager_maxOptionSize'
// as large page set links will slow the browser on large dom inserts
var d , e , f , g , h , i , j = c . widgetOptions , k = Math . min ( b . totalPages , b . filteredPages ) || 1 ,
// make skip set size multiples of 5
l = 5 * Math . ceil ( k / j . pager _maxOptionSize / 5 ) , m = k > j . pager _maxOptionSize , n = b . page + 1 , o = l , p = k - l , q = [ 1 ] ,
// construct default options pages array
r = m ? l : 1 ; for ( d = r ; k >= d ; ) q . push ( d ) , d += m ? l : 1 ; if ( q . push ( k ) , m ) {
// construct an array to get a focus set around the current page
for ( f = [ ] , e = Math . max ( Math . floor ( j . pager _maxOptionSize / l ) - 1 , 5 ) , o = n - e , 1 > o && ( o = 1 ) , p = n + e , p > k && ( p = k ) , d = o ; p >= d ; d ++ ) f . push ( d ) ;
// keep unique values
q = a . grep ( q , function ( b , c ) { return a . inArray ( b , q ) === c } ) , h = q . length , i = f . length ,
// make sure at all option_pages aren't replaced
h - i > l / 2 && h + i > j . pager _maxOptionSize && ( g = Math . floor ( h / 2 ) - Math . floor ( i / 2 ) , Array . prototype . splice . apply ( q , [ g , i ] ) ) , q = q . concat ( f ) }
// keep unique values again
return q = a . grep ( q , function ( b , c ) { return a . inArray ( b , q ) === c } ) . sort ( function ( a , b ) { return a - b } ) } , fixHeight : function ( b , c ) { var d , e , f = c . pager , g = c . widgetOptions , h = c . $tbodies . eq ( 0 ) ; h . find ( "tr.pagerSavedHeightSpacer" ) . remove ( ) , g . pager _fixedHeight && ! f . isDisabled && ( e = a . data ( b , "pagerSavedHeight" ) , e && ( d = e - h . height ( ) , d > 5 && a . data ( b , "pagerLastSize" ) === f . size && h . children ( "tr:visible" ) . length < f . size && h . append ( '<tr class="pagerSavedHeightSpacer ' + c . selectorRemove . slice ( 1 ) + '" style="height:' + d + 'px;"></tr>' ) ) ) } , changeHeight : function ( c , d ) { var e , f = d . $tbodies . eq ( 0 ) ; f . find ( "tr.pagerSavedHeightSpacer" ) . remove ( ) , f . children ( "tr:visible" ) . length || f . append ( '<tr class="pagerSavedHeightSpacer ' + d . selectorRemove . slice ( 1 ) + '"><td> </td></tr>' ) , e = f . children ( "tr" ) . eq ( 0 ) . height ( ) * d . pager . size , a . data ( c , "pagerSavedHeight" , e ) , b . fixHeight ( c , d ) , a . data ( c , "pagerLastSize" , d . pager . size ) } , hideRows : function ( a , b ) { if ( ! b . widgetOptions . pager _ajaxUrl ) { var d , e , f , g , h , i = b . pager , j = b . widgetOptions , k = b . $tbodies . length , l = i . page * i . size , m = l + i . size , n = j && j . filter _filteredRow || "filtered" , o = 0 , // for cache indexing
p = 0 ; for ( // size counter
i . cacheIndex = [ ] , d = 0 ; k > d ; d ++ ) { // size counter
for ( f = b . $tbodies . eq ( d ) . children ( "tr" ) , g = f . length , h = 0 , o = 0 , p = 0 , e = 0 ; g > e ; e ++ ) f [ e ] . className . match ( n ) || ( p === l && f [ e ] . className . match ( b . cssChildRow ) ?
// hide child rows @ start of pager (if already visible)
f [ e ] . style . display = "none" : ( f [ e ] . style . display = p >= l && m > p ? "" : "none" , o !== p && p >= l && m > p && ( i . cacheIndex . push ( e ) , o = p ) , p += f [ e ] . className . match ( b . cssChildRow + "|" + b . selectorRemove . slice ( 1 ) ) && ! j . pager _countChildRows ? 0 : 1 , p === m && "none" !== f [ e ] . style . display && f [ e ] . className . match ( c . css . cssHasChild ) && ( h = e ) ) ) ;
// add any attached child rows to last row of pager. Fixes part of issue #396
if ( h > 0 && f [ h ] . className . match ( c . css . cssHasChild ) ) for ( ; ++ h < g && f [ h ] . className . match ( b . cssChildRow ) ; ) f [ h ] . style . display = "" } } } , hideRowsSetup : function ( c , d ) { var e = d . pager , f = d . namespace + "pager" , g = e . $size . val ( ) ; e . size = b . parsePageSize ( d , g , "get" ) , e . $size . val ( b . parsePageSize ( d , e . size , "set" ) ) , a . data ( c , "pagerLastSize" , e . size ) , b . pagerArrows ( d ) , d . widgetOptions . pager _removeRows || ( b . hideRows ( c , d ) , d . $table . on ( "sortEnd filterEnd " . split ( " " ) . join ( f + " " ) , function ( ) { b . hideRows ( c , d ) } ) ) } , renderAjax : function ( d , e , f , g , h , i ) { var j = f . pager , k = f . widgetOptions ;
// process data
if ( a . isFunction ( k . pager _ajaxProcessing ) ) {
// ajaxProcessing result: [ total, rows, headers ]
var l , m , n , o , p , q , r , s , t , u , v , w , x , y , z = f . $table , A = "" , B = k . pager _ajaxProcessing ( d , e , g ) || [ 0 , [ ] ] , C = z . find ( "thead th" ) . length ; if (
// Clean up any previous error.
c . showError ( e ) , i ) f . debug && console . error ( "Pager: >> Ajax Error" , g , h , i ) , c . showError ( e , g , h , i ) , f . $tbodies . eq ( 0 ) . children ( "tr" ) . detach ( ) , j . totalRows = 0 ; else { if (
// process ajax object
a . isArray ( B ) ? ( n = isNaN ( B [ 0 ] ) && ! isNaN ( B [ 1 ] ) , x = B [ n ? 1 : 0 ] , j . totalRows = isNaN ( x ) ? j . totalRows || 0 : x , f . totalRows = f . filteredRows = j . filteredRows = j . totalRows , v = 0 === j . totalRows ? [ ] : B [ n ? 0 : 1 ] || [ ] , u = B [ 2 ] ) : ( j . ajaxData = B , f . totalRows = j . totalRows = B . total , f . filteredRows = j . filteredRows = "undefined" != typeof B . filteredRows ? B . filteredRows : B . total , u = B . headers , v = B . rows || [ ] ) , w = v && v . length , v instanceof jQuery ) k . pager _processAjaxOnInit && (
// append jQuery object
f . $tbodies . eq ( 0 ) . empty ( ) , f . $tbodies . eq ( 0 ) . append ( v ) ) ; else if ( w ) {
// build table from array
for ( l = 0 ; w > l ; l ++ ) { for ( A += "<tr>" , m = 0 ; m < v [ l ] . length ; m ++ )
// build tbody cells; watch for data containing HTML markup - see #434
A += /^\s*<td/ . test ( v [ l ] [ m ] ) ? a . trim ( v [ l ] [ m ] ) : "<td>" + v [ l ] [ m ] + "</td>" ; A += "</tr>" }
// add rows to first tbody
k . pager _processAjaxOnInit && f . $tbodies . eq ( 0 ) . html ( A ) } else
// nothing returned by ajax, empty out the table; see #1032
f . $tbodies . eq ( 0 ) . empty ( ) ;
// only add new header text if the length matches
if ( k . pager _processAjaxOnInit = ! 0 , u && u . length === C ) for ( o = z . hasClass ( "hasStickyHeaders" ) , q = o ? k . $sticky . children ( "thead:first" ) . children ( "tr" ) . children ( ) : "" , p = z . find ( "tfoot tr:first" ) . children ( ) , r = f . $headers . filter ( "th " ) , y = r . length , m = 0 ; y > m ; m ++ ) s = r . eq ( m ) , s . find ( "." + c . css . icon ) . length ? ( t = s . find ( "." + c . css . icon ) . clone ( ! 0 ) , s . find ( ".tablesorter-header-inner" ) . html ( u [ m ] ) . append ( t ) , o && q . length && ( t = q . eq ( m ) . find ( "." + c . css . icon ) . clone ( ! 0 ) , q . eq ( m ) . find ( ".tablesorter-header-inner" ) . html ( u [ m ] ) . append ( t ) ) ) : ( s . find ( ".tablesorter-header-inner" ) . html ( u [ m ] ) , o && q . length && q . eq ( m ) . find ( ".tablesorter-header-inner" ) . html ( u [ m ] ) ) , p . eq ( m ) . html ( u [ m ] ) } f . showProcessing && c . isProcessing ( e ) ,
// make sure last pager settings are saved, prevents multiple server side calls with
// the same parameters
j . totalPages = Math . ceil ( j . totalRows / b . parsePageSize ( f , j . size , "get" ) ) , j . last . totalRows = j . totalRows , j . last . currentFilters = j . currentFilters , j . last . sortList = ( f . sortList || [ ] ) . join ( "," ) , j . initializing = ! 1 ,
// update display without triggering pager complete... before updating cache
b . updatePageDisplay ( e , f , ! 1 ) ,
// tablesorter core updateCache (not pager)
c . updateCache ( f , function ( ) { j . initialized &&
// apply widgets after table has rendered & after a delay to prevent
// multiple applyWidget blocking code from blocking this trigger
setTimeout ( function ( ) { f . debug && console . log ( "Pager: Triggering pagerChange" ) , z . trigger ( "pagerChange" , j ) , c . applyWidget ( e ) , b . updatePageDisplay ( e , f ) } , 0 ) } ) } j . initialized || c . applyWidget ( e ) } , getAjax : function ( d , e ) { var f , g = b . getAjaxUrl ( d , e ) , h = a ( document ) , i = e . namespace + "pager" , j = e . pager ; "" !== g && ( e . showProcessing && c . isProcessing ( d , ! 0 ) , h . on ( "ajaxError" + i , function ( a , c , f , g ) { b . renderAjax ( null , d , e , c , f , g ) , h . off ( "ajaxError" + i ) } ) , f = ++ j . ajaxCounter , j . last . ajaxUrl = g , j . ajaxObject . url = g , j . ajaxObject . success = function ( a , c , g ) { f < j . ajaxCounter || ( b . renderAjax ( a , d , e , g ) , h . off ( "ajaxError" + i ) , "function" == typeof j . oldAjaxSuccess && j . oldAjaxSuccess ( a ) ) } , e . debug && console . log ( "Pager: Ajax initialized" , j . ajaxObject ) , a . ajax ( j . ajaxObject ) ) } , getAjaxUrl : function ( b , c ) { var d , e , f = c . pager , g = c . widgetOptions , h = g . pager _ajaxUrl ? g . pager _ajaxUrl . replace ( /\{page([\-+]\d+)?\}/ , function ( a , b ) { return f . page + ( b ? parseInt ( b , 10 ) : 0 ) } ) . replace ( /\{size\}/g , f . size ) : "" , i = c . sortList , j = f . currentFilters || a ( b ) . data ( "lastSearch" ) || [ ] , k = h . match ( /\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/ ) , l = h . match ( /\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/ ) , m = [ ] ; if ( k ) { for ( k = k [ 1 ] , e = i . length , d = 0 ; e > d ; d ++ ) m . push ( k + "[" + i [ d ] [ 0 ] + "]=" + i [ d ] [ 1 ] ) ;
// if the arry is empty, just add the col parameter... '&{sortList:col}' becomes '&col'
h = h . replace ( /\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/g , m . length ? m . join ( "&" ) : k ) , m = [ ] } if ( l ) { for ( l = l [ 1 ] , e = j . length , d = 0 ; e > d ; d ++ ) j [ d ] && m . push ( l + "[" + d + "]=" + encodeURIComponent ( j [ d ] ) ) ;
// if the arry is empty, just add the fcol parameter... '&{filterList:fcol}' becomes '&fcol'
h = h . replace ( /\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/g , m . length ? m . join ( "&" ) : l ) , f . currentFilters = j } return a . isFunction ( g . pager _customAjaxUrl ) && ( h = g . pager _customAjaxUrl ( b , h ) ) , c . debug && console . log ( "Pager: Ajax url = " + h ) , h } , renderTable : function ( a , d ) { var e , f , g , h , i = a . config , j = i . pager , k = i . widgetOptions , l = i . $table . hasClass ( "hasFilters" ) , m = d && d . length || 0 , // rows may be undefined
n = j . page * j . size , o = j . size ; if ( 1 > m )
// empty table, abort!
return void ( i . debug && console . warn ( "Pager: >> No rows for pager to render" ) ) ; if ( j . page >= j . totalPages )
// lets not render the table more than once
return b . moveToLastPage ( a , j ) ; if ( j . cacheIndex = [ ] , j . isDisabled = ! 1 , // needed because sorting will change the page and re-enable the pager
j . initialized && ( i . debug && console . log ( "Pager: Triggering pagerChange" ) , i . $table . trigger ( "pagerChange" , i ) ) , k . pager _removeRows ) { for ( c . clearTableBody ( a ) , e = c . processTbody ( a , i . $tbodies . eq ( 0 ) , ! 0 ) ,
// not filtered, start from the calculated starting point (s)
// if filtered, start from zero
f = l ? 0 : n , g = l ? 0 : n , h = 0 ; o > h && f < d . length ; ) l && /filtered/ . test ( d [ f ] [ 0 ] . className ) || ( g ++ , g > n && o >= h && ( h ++ , j . cacheIndex . push ( f ) , e . append ( d [ f ] ) ) ) , f ++ ; c . processTbody ( a , e , ! 1 ) } else b . hideRows ( a , i ) ; b . updatePageDisplay ( a , i ) , k . pager _startPage = j . page , k . pager _size = j . size , a . isUpdating && ( i . debug && console . log ( "Pager: Triggering updateComplete" ) , i . $table . trigger ( "updateComplete" , [ a , ! 0 ] ) ) } , showAllRows : function ( d , e ) { var f , g , h , i = e . pager , j = e . widgetOptions ; for ( i . ajax ? b . pagerArrows ( e , ! 0 ) : ( a . data ( d , "pagerLastPage" , i . page ) , a . data ( d , "pagerLastSize" , i . size ) , i . page = 0 , i . size = i . totalRows , i . totalPages = 1 , e . $table . addClass ( "pagerDisabled" ) . removeAttr ( "aria-describedby" ) . find ( "tr.pagerSavedHeightSpacer" ) . remove ( ) , b . renderTable ( d , e . rowsCopy ) , i . isDisabled = ! 0 , c . applyWidget ( d ) , e . debug && console . log ( "Pager: Disabled" ) ) , g = i . $size . add ( i . $goto ) . add ( i . $container . find ( ".ts-startRow, .ts-page " ) ) , h = g . length , f = 0 ; h > f ; f ++ ) g . eq ( f ) . attr ( "aria-disabled" , "true" ) . addClass ( j . pager _css . disabled ) [ 0 ] . disabled = ! 0 } ,
// updateCache if delayInit: true
// this is normally done by 'appendToTable' function in the tablesorter core AFTER a sort
updateCache : function ( d ) { var e = d . config , f = e . pager ;
// tablesorter core updateCache (not pager)
c . updateCache ( e , function ( ) { if ( ! a . isEmptyObject ( d . config . cache ) ) { var c , g = [ ] , h = d . config . cache [ 0 ] . normalized ; for ( f . totalRows = h . length , c = 0 ; c < f . totalRows ; c ++ ) g . push ( h [ c ] [ e . columns ] . $row ) ; e . rowsCopy = g , b . moveToPage ( d , f , ! 0 ) ,
// clear out last search to force an update
f . last . currentFilters = [ " " ] } } ) } , moveToPage : function ( d , e , f ) { if ( ! e . isDisabled ) { if ( f !== ! 1 && e . initialized && a . isEmptyObject ( d . config . cache ) ) return b . updateCache ( d ) ; var g = d . config , h = g . widgetOptions , i = e . last ;
// abort page move if the table has filters and has not been initialized
e . ajax && ! h . filter _initialized && c . hasWidget ( d , "filter" ) || ( b . parsePageNumber ( e ) , b . calcFilters ( d , g ) ,
// fixes issue where one current filter is [] and the other is [ '', '', '' ],
// making the next if comparison think the filters as different. Fixes #202.
i . currentFilters = "" === ( i . currentFilters || [ ] ) . join ( "" ) ? [ ] : i . currentFilters , e . currentFilters = "" === ( e . currentFilters || [ ] ) . join ( "" ) ? [ ] : e . currentFilters ,
// don't allow rendering multiple times on the same page/size/totalRows/filters/sorts
( i . page !== e . page || i . size !== e . size || i . totalRows !== e . totalRows || ( i . currentFilters || [ ] ) . join ( "," ) !== ( e . currentFilters || [ ] ) . join ( "," ) || ( i . ajaxUrl || "" ) !== ( e . ajaxObject . url || "" ) || ( i . optAjaxUrl || "" ) !== ( h . pager _ajaxUrl || "" ) || i . sortList !== ( g . sortList || [ ] ) . join ( "," ) ) && ( g . debug && console . log ( "Pager: Changing to page " + e . page ) , e . last = { page : e . page , size : e . size ,
// fixes #408; modify sortList otherwise it auto-updates
sortList : ( g . sortList || [ ] ) . join ( "," ) , totalRows : e . totalRows , currentFilters : e . currentFilters || [ ] , ajaxUrl : e . ajaxObject . url || "" , optAjaxUrl : h . pager _ajaxUrl } , e . ajax ? b . getAjax ( d , g ) : e . ajax || b . renderTable ( d , g . rowsCopy ) , a . data ( d , "pagerLastPage" , e . page ) , e . initialized && f !== ! 1 && ( g . debug && console . log ( "Pager: Triggering pageMoved" ) , g . $table . trigger ( "pageMoved" , g ) , c . applyWidget ( d ) , ! e . ajax && d . isUpdating && ( g . debug && console . log ( "Pager: Triggering updateComplete" ) , g . $table . trigger ( "updateComplete" , [ d , ! 0 ] ) ) ) ) ) } } ,
// set to either set or get value
parsePageSize : function ( a , b , c ) { var d = a . pager , e = parseInt ( b , 10 ) || d . size || a . widgetOptions . pager _size || 10 ,
// if select does not contain an "all" option, use size
f = d . $size . find ( 'option[value="all"]' ) . length ? "all" : d . totalRows ;
// "get" to set `p.size` or "set" to set `p.$size.val()`
return /all/i . test ( b ) || e === d . totalRows ? "get" === c ? d . totalRows : f : "get" === c ? e : d . size } , parsePageNumber : function ( a ) { var b = Math . min ( a . totalPages , a . filteredPages ) - 1 ; return a . page = parseInt ( a . page , 10 ) , ( a . page < 0 || isNaN ( a . page ) ) && ( a . page = 0 ) , a . page > b && 0 !== a . page && ( a . page = b ) , a . page } , setPageSize : function ( c , d ) { var e = c . pager , f = c . table ; e . size = b . parsePageSize ( c , d , "get" ) , e . $size . val ( b . parsePageSize ( c , e . size , "set" ) ) , a . data ( f , "pagerLastPage" , b . parsePageNumber ( e ) ) , a . data ( f , "pagerLastSize" , e . size ) , e . totalPages = Math . ceil ( e . totalRows / e . size ) , e . filteredPages = Math . ceil ( e . filteredRows / e . size ) , b . moveToPage ( f , e , ! 0 ) } , moveToFirstPage : function ( a , c ) { c . page = 0 , b . moveToPage ( a , c , ! 0 ) } , moveToLastPage : function ( a , c ) { c . page = Math . min ( c . totalPages , c . filteredPages ) - 1 , b . moveToPage ( a , c , ! 0 ) } , moveToNextPage : function ( a , c ) { c . page ++ , c . page >= Math . min ( c . totalPages , c . filteredPages ) - 1 && ( c . page = Math . min ( c . totalPages , c . filteredPages ) - 1 ) , b . moveToPage ( a , c , ! 0 ) } , moveToPrevPage : function ( a , c ) { c . page -- , c . page <= 0 && ( c . page = 0 ) , b . moveToPage ( a , c , ! 0 ) } , destroyPager : function ( a , d , e ) { var f = d . pager , g = d . widgetOptions . pager _selectors , h = [ g . first , g . prev , g . next , g . last , g . gotoPage , g . pageSize ] . join ( "," ) , i = d . namespace + "pager" ; f . initialized = ! 1 , d . $table . off ( i ) , f . $container . hide ( ) . find ( h ) . off ( i ) , e || ( b . showAllRows ( a , d ) , d . appender = null , // remove pager appender function
c . storage && c . storage ( a , d . widgetOptions . pager _storageKey , "" ) , delete a . config . pager , delete a . config . rowsCopy ) } , enablePager : function ( d , e , f ) { var g , h , i = e . pager ; i . isDisabled = ! 1 , i . page = a . data ( d , "pagerLastPage" ) || i . page || 0 , h = i . $size . find ( "option[selected]" ) . val ( ) , i . size = a . data ( d , "pagerLastSize" ) || b . parsePageSize ( e , h , "get" ) , i . $size . val ( b . parsePageSize ( e , i . size , "set" ) ) , i . totalPages = Math . ceil ( Math . min ( i . totalRows , i . filteredRows ) / i . size ) , e . $table . removeClass ( "pagerDisabled" ) , d . id && ( g = d . id + "_pager_info" , i . $container . find ( e . widgetOptions . pager _selectors . pageDisplay ) . attr ( "id" , g ) , e . $table . attr ( "aria-describedby" , g ) ) , b . changeHeight ( d , e ) , f && ( c . update ( e ) , b . setPageSize ( e , i . size ) , b . hideRowsSetup ( d , e ) , e . debug && console . log ( "Pager: Enabled" ) ) } , appender : function ( c , d ) { var e = c . config , f = e . widgetOptions , g = e . pager ; g . ajax ? b . moveToPage ( c , g , ! 0 ) : ( e . rowsCopy = d , g . totalRows = f . pager _countChildRows ? e . $tbodies . eq ( 0 ) . children ( "tr" ) . length : d . length , g . size = a . data ( c , "pagerLastSize" ) || g . size || f . pager _size || g . setSize || 10 , g . totalPages = Math . ceil ( g . totalRows / g . size ) , b . moveToPage ( c , g ) ,
// update display here in case all rows are removed
b . updatePageDisplay ( c , e , ! 1 ) ) } } , c . showError = function ( b , c , d , e ) { var f , g = a ( b ) , h = g [ 0 ] . config , i = h && h . widgetOptions , j = h . pager && h . pager . cssErrorRow || i && i . pager _css && i . pager _css . errorRow || "tablesorter-errorRow" , k = typeof c , l = ! 0 , m = "" , n = function ( ) { h . $table . find ( "thead" ) . find ( "." + j ) . remove ( ) } ; if ( ! g . length ) return void console . error ( "tablesorter showError: no table parameter passed" ) ; if ( "function" == typeof h . pager . ajaxError ) { if ( l = h . pager . ajaxError ( h , c , d , e ) , l === ! 1 ) return n ( ) ; m = l } else if ( "function" == typeof i . pager _ajaxError ) { if ( l = i . pager _ajaxError ( h , c , d , e ) , l === ! 1 ) return n ( ) ; m = l } if ( "" === m ) if ( "object" === k ) m = 0 === c . status ? "Not connected, verify Network" : 404 === c . status ? "Requested page not found [404]" : 500 === c . status ? "Internal Server Error [500]" : "parsererror" === e ? "Requested JSON parse failed" : "timeout" === e ? "Time out error" : "abort" === e ? "Ajax Request aborted" : "Uncaught error: " + c . statusText + " [" + c . status + "]" ; else { if ( "string" !== k ) return n ( ) ; m = c } f = a ( /tr\>/ . test ( m ) ? m : '<tr><td colspan="' + h . columns + '">' + m + "</td></tr>" ) . click ( function ( ) { a ( this ) . remove ( ) } ) . appendTo ( h . $table . find ( "thead:first" ) ) . addClass ( j + " " + h . selectorRemove . slice ( 1 ) ) . attr ( { role : "alert" , "aria-live" : "assertive" } ) } } ( jQuery ) ;