Closed dmitryrn closed 6 years ago
Default pageNumber
will always be 1 if totalNumberLocator
is set, see: https://github.com/superRaytin/paginationjs/blob/master/src/pagination.js#L785
This is because Pagination can not know exactly if page N exists.
@fabiofdsantos Then what's the best way to have totalNumberLocator
modify pageNumber
after figuring out how many items are going to be shown?
@dents, What's your scenario? Are you using plugin's ajax implementation?
Here's an example:
$('#pagination').pagination({
dataSource: HTTP_URL
pageSize: 50,
locator: 'results.items',
totalNumberLocator: function(response) {
return response.results.total;
},
alias: {
pageNumber: 'page',
pageSize: 'limit'
},
showPrevious: false,
showNext: false,
ajax: {
beforeSend: function() {
// add a spinner
},
complete: function(jqXHR, textStatus) {
if (jqXHR.status === 200 || jqXHR.readyState == 0 || jqXHR.status == 0) {
return false; // do nothing
} else if (jqXHR && jqXHR.status === 403) {
window.location.href = window.location.href.split('/').slice(0, 3).join('/') + '/login';
} else {
alert('error');
}
},
},
callback: function(data, pagination) {
console.log(data);
}
});
@fabiofdsantos As of the latest version it's ajax: function() { return {beforeSend:...} }
but yeah that is what I am using. The problem is when trying to show a specific page on first load (for example page is specified in a URL in a bookmark), there is no obvious way to do that without caling $('#pagination').pagination(properPageNum)
in callback() and thereby incurring another trip to server.
@dents, A potential workaround is to perform asynchronous HTTP requests outside the plugin's scope. Then, use the following code sample to manipulate attributes dataSource, pageSize and pageNumber:
$('#demo').pagination({
dataSource: [1, 2, 3, 4, 5, 6, 7, ... , 35],
pageSize: 5,
pageNumber: 3,
callback: function(data, pagination) {
// template method of yourself
var html = template(data);
dataContainer.html(html);
}
})
@fabiofdsantos That approach would mean putting the paging logic outside then. It would work fine for the first page loading correctly but ajax
would not be able to handle page changes, right? Because dataSource
would be the static data for initial page.
@dents, Yes, it seems that approach only works for a static dataSource
. As @superRaytin said previously, currently the plugin can not know exactly if page X exists.
The default page number ("1") will be considered as long as totalNumberLocator
is defined and we are using the async
mode: https://github.com/superRaytin/paginationjs/blob/master/src/pagination.js#L75
For anyone reading this later, I made peace with having two trips to server and modified beforeSend
of ajax
to tell server to only return totals on the first trip, and then actual page data on subsequent trips. Not ideal but works for now.
@dents Could you please show your code about this?
I made peace with having two trips to server and modified beforeSend of ajax to tell server to only return totals on the first trip
I am not sure how to set totalNumber in beforeSend.
@dents I think what you want is a regular server side render page at first load, and then using ajax to load other pages. This is very seo friendly. If you want to do that ,I have a solution.
$(function () {
//when you first load this page use server side pagination params
let isFirst = true;
let totalCount = parseInt('<%=totalCount%>');
$('.selector').pagination({
dataSource:'/api/data',
locator: 'data',
pageSize:5,
ajax:{
beforeSend:function(xhr,data){
if(isFirst){
//use a empty api to cheat pagination plugin, just return {data:[],totalCount:1}
data.url = '/api/pagination';
}
}
},
//since you already have the correct total number,just modify it here after a successful empty response
totalNumberLocator: function(resp){
if(isFirst){
resp = {
data:[],
totalCount:totalCount
};
}
return resp.totalCount;
},
callback:function(data,pagination){
if(isFirst){
//then finally erase the first load flag,so the rest page click will always be normal ajax request
isFirst = false;
}else{
$('.content').html(data);
}
}
});
});
I set pageNumber on init, but there is always 1