Skip to content

Commit

Permalink
Fixed initial filter settings when using pager ajax #388 & ajax pager…
Browse files Browse the repository at this point in the history
… not recognizing column sorting #408
  • Loading branch information
Mottie committed Nov 9, 2013
1 parent 8888879 commit e6696b0
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 93 deletions.
111 changes: 71 additions & 40 deletions addons/pager/jquery.tablesorter.pager.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*!
* tablesorter pager plugin
* updated 10/30/2013
* updated 11/8/2013
*/
/*jshint browser:true, jquery:true, unused:false */
;(function($) {
Expand Down Expand Up @@ -236,6 +236,9 @@
$t.find('thead tr.' + p.cssErrorRow).remove(); // Clean up any previous error.

if ( exception ) {
if (c.debug) {
ts.log('Ajax Error', xhr, exception);
}
$err = $('<tr class="' + p.cssErrorRow + '"><td style="text-align:center;" colspan="' + hl + '">' + (
xhr.status === 0 ? 'Not connected, verify Network' :
xhr.status === 404 ? 'Requested page not found [404]' :
Expand Down Expand Up @@ -272,15 +275,13 @@
c.$tbodies.eq(0).empty().append(d);
} else if (l) {
// build table from array
if ( l > 0 ) {
for ( i = 0; i < l; i++ ) {
tds += '<tr>';
for ( j = 0; j < d[i].length; j++ ) {
// build tbody cells
tds += '<td>' + d[i][j] + '</td>';
}
tds += '</tr>';
for ( i = 0; i < l; i++ ) {
tds += '<tr>';
for ( j = 0; j < d[i].length; j++ ) {
// build tbody cells
tds += '<td>' + d[i][j] + '</td>';
}
tds += '</tr>';
}
// add rows to first tbody
c.$tbodies.eq(0).html( tds );
Expand Down Expand Up @@ -314,9 +315,15 @@
if (c.showProcessing) {
ts.isProcessing(table); // remove loading icon
}
p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
// make sure last pager settings are saved, prevents multiple server side calls with
// the same parameters
p.last.totalPages = p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
p.last.currentFilters = p.currentFilters;
p.last.sortList = (c.sortList || []).join(',');
updatePageDisplay(table, p);
fixHeight(table, p);
// apply widgets after table has rendered
$t.trigger('applyWidgets');
if (p.initialized) {
$t.trigger('pagerChange', p);
$t.trigger('updateComplete');
Expand Down Expand Up @@ -350,17 +357,21 @@
p.oldAjaxSuccess(data);
}
};
if (c.debug) {
ts.log('ajax initialized', p.ajaxObject);
}
$.ajax(p.ajaxObject);
}
},

getAjaxUrl = function(table, p) {
var url = (p.ajaxUrl) ? p.ajaxUrl
var c = table.config,
url = (p.ajaxUrl) ? p.ajaxUrl
// allow using "{page+1}" in the url string to switch to a non-zero based index
.replace(/\{page([\-+]\d+)?\}/, function(s,n){ return p.page + (n ? parseInt(n, 10) : 0); })
.replace(/\{size\}/g, p.size) : '',
sl = table.config.sortList,
fl = p.currentFilters || [],
sl = c.sortList,
fl = p.currentFilters || $(table).data('lastSearch') || [],
sortCol = url.match(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/),
filterCol = url.match(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/),
arry = [];
Expand All @@ -382,10 +393,14 @@
});
// if the arry is empty, just add the fcol parameter... "&{filterList:fcol}" becomes "&fcol"
url = url.replace(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : filterCol );
p.currentFilters = fl;
}
if ( typeof(p.customAjaxUrl) === "function" ) {
url = p.customAjaxUrl(table, url);
}
if (c.debug) {
ts.log('Pager ajax url: ' + url);
}
return url;
},

Expand Down Expand Up @@ -433,6 +448,9 @@
p.totalPages = 1;
$(table).addClass('pagerDisabled').find('tr.pagerSavedHeightSpacer').remove();
renderTable(table, table.config.rowsCopy, p);
if (table.config.debug) {
ts.log('pager disabled');
}
}
// disable size selector
p.$size.add(p.$goto).each(function(){
Expand All @@ -442,36 +460,44 @@

moveToPage = function(table, p, flag) {
if ( p.isDisabled ) { return; }
var l = p.last,
var c = table.config,
l = p.last,
pg = Math.min( p.totalPages, p.filteredPages );
if ( p.page < 0 ) { p.page = 0; }
if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; }
// don't allow rendering multiple times on the same page/size/totalpages/filters
if (l.page === p.page && l.size === p.size && l.total === p.totalPages && l.filters === p.currentFilters ) { return; }
// don't allow rendering multiple times on the same page/size/totalpages/filters/sorts
if ( l.page === p.page && l.size === p.size && l.totalPages === p.totalPages &&
(l.currentFilters || []).join(',') === (p.currentFilters || []).join(',') &&
l.sortList === (c.sortList || []).join(',') ) { return; }
if (c.debug) {
ts.log('Pager changing to page ' + p.page);
}
p.last = {
page : p.page,
size : p.size,
// fixes #408; modify sortList otherwise it auto-updates
sortList : (c.sortList || []).join(','),
totalPages : p.totalPages,
currentFilters : p.currentFilters
currentFilters : p.currentFilters || []
};
if (p.ajax) {
getAjax(table, p);
} else if (!p.ajax) {
renderTable(table, table.config.rowsCopy, p);
}
$.data(table, 'pagerLastPage', p.page);
$.data(table, 'pagerUpdateTriggered', true);
if (p.initialized && flag !== false) {
$(table).trigger('pageMoved', p);
c.$table.trigger('pageMoved', p);
c.$table.trigger('applyWidgets');
}
},

setPageSize = function(table, size, p) {
p.size = size;
p.$size.val(size);
p.size = size || p.size || 10;
p.$size.val(p.size);
$.data(table, 'pagerLastPage', p.page);
$.data(table, 'pagerLastSize', p.size);
p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
p.totalPages = Math.ceil( p.totalRows / p.size );
moveToPage(table, p);
},

Expand Down Expand Up @@ -517,14 +543,17 @@
p.$goto.removeClass(p.cssDisabled).removeAttr('disabled');
p.isDisabled = false;
p.page = $.data(table, 'pagerLastPage') || p.page || 0;
p.size = $.data(table, 'pagerLastSize') || parseInt(pg.find('option[selected]').val(), 10) || p.size;
p.size = $.data(table, 'pagerLastSize') || parseInt(pg.find('option[selected]').val(), 10) || p.size || 10;
pg.val(p.size); // set page size
p.totalPages = Math.ceil( Math.min( p.totalPages, p.filteredPages ) / ( p.size || 10 ) );
p.totalPages = Math.ceil( Math.min( p.totalPages, p.filteredPages ) / p.size );
if ( triggered ) {
$(table).trigger('update');
setPageSize(table, p.size, p);
hideRowsSetup(table, p);
fixHeight(table, p);
if (table.config.debug) {
ts.log('pager enabled');
}
}
};

Expand All @@ -534,8 +563,8 @@
if ( !p.ajax ) {
c.rowsCopy = rows;
p.totalRows = p.countChildRows ? c.$tbodies.eq(0).children().length : rows.length;
p.size = $.data(table, 'pagerLastSize') || p.size;
p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
p.size = $.data(table, 'pagerLastSize') || p.size || 10;
p.totalPages = Math.ceil( p.totalRows / p.size );
renderTable(table, rows, p);
}
};
Expand All @@ -551,34 +580,36 @@
$t = c.$table,
// added in case the pager is reinitialized after being destroyed.
pager = p.$container = $(p.container).addClass('tablesorter-pager').show();
if (c.debug) {
ts.log('Pager initializing');
}
p.oldAjaxSuccess = p.oldAjaxSuccess || p.ajaxObject.success;
c.appender = $this.appender;

if (ts.filter && c.widgets.indexOf('filter') >= 0) {
// get any default filter settings (data-value attribute) fixes #388
p.currentFilters = c.$table.data('lastSearch') || ts.filter.setDefaults(table, c, c.widgetOptions) || [];
// set, but don't apply current filters
ts.setFilters(table, p.currentFilters, false);
}
if (p.savePages && ts.storage) {
t = ts.storage(table, 'tablesorter-pager') || {}; // fixes #387
p.page = isNaN(t.page) ? p.page : t.page;
p.size = ( isNaN(t.size) ? p.size : t.size ) || 10;
$.data(table, 'pagerLastSize', p.size);
}

$t
.unbind('filterStart.pager filterEnd.pager sortEnd.pager disable.pager enable.pager destroy.pager update.pager pageSize.pager')
.unbind('filterStart filterEnd sortEnd disable enable destroy update pageSize '.split(' ').join('.pager '))
.bind('filterStart.pager', function(e, filters) {
$.data(table, 'pagerUpdateTriggered', false);
p.currentFilters = filters;
})
// update pager after filter widget completes
.bind('filterEnd.pager sortEnd.pager', function(e) {
//Prevent infinite event loops from occuring by setting this in all moveToPage calls and catching it here.
if ($.data(table, 'pagerUpdateTriggered')) {
$.data(table, 'pagerUpdateTriggered', false);
return;
}
//only run the server side sorting if it has been enabled
if (e.type === "filterEnd" || (e.type === "sortEnd" && c.serverSideSorting)) {
.bind('filterEnd.pager sortEnd.pager', function() {
if (p.initialized) {
moveToPage(table, p, false);
updatePageDisplay(table, p, false);
fixHeight(table, p);
}
updatePageDisplay(table, p, false);
fixHeight(table, p);
})
.bind('disable.pager', function(e){
e.stopPropagation();
Expand Down Expand Up @@ -617,6 +648,7 @@
pager.find(ctrls.join(','))
.unbind('click.pager')
.bind('click.pager', function(e){
e.stopPropagation();
var i, $t = $(this), l = ctrls.length;
if ( !$t.hasClass(p.cssDisabled) ) {
for (i = 0; i < l; i++) {
Expand All @@ -626,7 +658,6 @@
}
}
}
return false;
});

// goto selector
Expand Down
11 changes: 5 additions & 6 deletions docs/example-pager-ajax.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
theme: 'blue',
widthFixed: true,
sortLocaleCompare: true, // needed for accented characters in the data
sortList: [ [0,1] ],
widgets: ['zebra', 'filter']
})

Expand Down Expand Up @@ -180,6 +181,7 @@ <h3>Flexible client-side table sorting</h3>
<h3><a href="#">Notes</a></h3>
<div>
<ul>
<li>In <span class="version">v2.13.3</span>, the "ID" column has a default filter setting of "&gt;30" and a descending sort, but neither is applied as this demo is not connected a server (just a basic JSON file).</li>
<li>In <span class="version">v2.11</span>, the pager now stores any object returned by the `ajaxProcessing` function in `table.config.pager.ajaxData` (see the ajaxProcessing section below for more details).</li>
<li>In <span class="version updated">v2.10</span>, the <code>ajaxProcessing</code> function was updated to only require a total number of rows to be returned, also instead of returning an array of table rows, you can build the table yourself and just return the jQuery object containing those rows. The addon triggers an update.</li>
<li><code>{filterList:fcol}</code> was added to the <code>ajaxUrl</code> in version 2.6.</li>
Expand Down Expand Up @@ -268,9 +270,6 @@ <h3>ARRAY returned</h3>
</ul>
</div>




</div>

<h1>Demo</h1>
Expand All @@ -292,7 +291,7 @@ <h1>Demo</h1>
</td>
</tr>
<tr>
<th>1</th>
<th data-value="&gt;30">1</th>
<th>2</th>
<th>3</th>
<th>4</th>
Expand Down Expand Up @@ -389,7 +388,7 @@ <h1>HTML</h1>
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;1&lt;/th&gt; &lt;!-- thead text will be updated from the JSON; make sure the number of columns matches the JSON data --&gt;
&lt;th&gt;1 data-value=&quot;&amp;gt;30&quot;&lt;/th&gt; &lt;!-- thead text will be updated from the JSON; make sure the number of columns matches the JSON data --&gt;
&lt;th&gt;2&lt;/th&gt;
&lt;th&gt;3&lt;/th&gt;
&lt;th&gt;4&lt;/th&gt;
Expand Down Expand Up @@ -439,7 +438,7 @@ <h1>HTML</h1>
$url.html(url);
})

.on('pagerInitialized', function(){ console.log('pager init');
.on('pagerInitialized', function(){
// allow THIS demo to sort the content; this variable is automatically set to true when ajax
// is used as there isn't any way to sort the server side data from the client side.
this.config.serverSideSorting = false;
Expand Down
Loading

0 comments on commit e6696b0

Please sign in to comment.