mirror of
https://github.com/Mottie/tablesorter.git
synced 2024-11-15 23:54:22 +00:00
235 lines
28 KiB
JavaScript
235 lines
28 KiB
JavaScript
/*! Widget: Pager - updated 10/31/2015 (v2.24.0) */
|
|
/* Requires tablesorter v2.8+ and jQuery 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); |