Closed benbagley closed 6 years ago
FYI here is the route
router.get('/dashboard/users', ensureAuthenticated, (req, res) => {
User.find({}, function(err, users) {
res.render('dashboard/users/index.hbs', {
pageTitle: 'Users',
users: users,
pagination: {
page: 6,
pageCount: 10
}
});
})
});
I should document the options better, but I believe what you're looking for is the limit
option, which controls how many pages are displayed at a time. For example:
{
pagination: {
page: 6,
pageCount: 10,
limit: 5
}
}
limit
behaves like a moving window, so once you start getting into the middle ranges, rather than displaying the next n, it displays pages before and after the current page.
I'll give it a shot, thanks @jimf
Ok here's what I get now @jimf https://gyazo.com/546071207377595a763acb49f92c2dd0 so see how 10 pages are still showing, obviously there is only one page of records here not 10.
So as more users are added the pagination should ideally be able to look at the amount of records in the collection (in this case users) and change the pagination accordingly i.e if there are 12 records two pages should show in the pagination not 10.
Okay, if you can provide the pagination portion of your Handlebars template, as well as the exact behavior you're trying to achieve, I'll try to see if we can figure this out. I'm pretty confident that what you want can be achieved.
Ok here's what I have in the pagination so far @jimf
<nav aria-label="Page navigation">
<ul class="pagination">
{{#paginate pagination type="first"}}
<li class="page-item{{#if disabled}} disabled{{/if}}">
<a class="page-link" href="?page={{n}}" aria-label="First">
<span aria-hidden="true">«</span>
<span class="sr-only">First</span>
</a>
</li>
{{/paginate}}
{{#paginate pagination type="middle" limit="10"}}
<li class="page-item"><a class="page-link{{#if disabled}} disabled{{/if}}" href="?page={{n}}">{{n}}</a></li>
{{/paginate}}
{{#paginate pagination type="last"}}
<li class="page-item{{#if disabled}} disabled{{/if}}">
<a class="page-link" href="?page={{n}}" aria-label="Last">
<span aria-hidden="true">»</span>
<span class="sr-only">Last</span>
</a>
</li>
{{/paginate}}
</ul>
</nav>
The behaviour I'm trying to accomplish here is explained in previous posts.
Sorry, I had a bit of a brainfart with what you were asking. I believe I have this working, but admittedly it's not entirely baked into this library. I got it working by decorating the plugin:
const Handlebars = require('handlebars');
const paginateHelper = require('handlebars-paginate');
function paginateWithDynamicLimit(origPaginateHelper) {
return function(paginate, options) {
if (options.hash.maxlimit) {
options.hash.limit = Math.min(Number(options.hash.maxlimit), paginate.pageCount);
}
return origPaginateHelper(paginate, options);
};
}
Handlebars.registerHelper('paginate', paginateWithDynamicLimit(paginateHelper));
This adds a new option maxlimit
, which behaves similarly to limit (it in fact uses limit
under the hood), but will use the lesser value of pagination.pageCount
and whatever you set maxlimit
to. You may need to adjust as needed.
Does this achieve what you're trying to do?
Slightly shorter/less noisy version if you aren't gaining anything with the extra function:
const Handlebars = require('handlebars');
const paginateHelper = require('handlebars-paginate');
Handlebars.registerHelper('paginate', function(paginate, options) {
if (options.hash.maxlimit) {
options.hash.limit = Math.min(Number(options.hash.maxlimit), paginate.pageCount);
}
return paginateHelper(paginate, options);
});
Looks good @jimf I'll give it a shot. Just so I'm not confusing myself should I now have something like this?
Route
// /users
router.get('/dashboard/users', ensureAuthenticated, (req, res) => {
User.find({}, function(err, users) {
res.render('dashboard/users/index.hbs', {
pageTitle: 'Users',
users: users,
pagination: {
page: 6,
pageCount: 10,
limit: 5
}
});
})
});
view
<nav aria-label="Page navigation">
<ul class="pagination">
{{#paginate pagination type="first"}}
<li class="page-item{{#if disabled}} disabled{{/if}}">
<a class="page-link" href="?page={{n}}" aria-label="First">
<span aria-hidden="true">«</span>
<span class="sr-only">First</span>
</a>
</li>
{{/paginate}}
{{#paginate pagination type="middle" limit="10"}}
<li class="page-item"><a class="page-link{{#if disabled}} disabled{{/if}}" href="?page={{n}}">{{n}}</a></li>
{{/paginate}}
{{#paginate pagination type="last"}}
<li class="page-item{{#if disabled}} disabled{{/if}}">
<a class="page-link" href="?page={{n}}" aria-label="Last">
<span aria-hidden="true">»</span>
<span class="sr-only">Last</span>
</a>
</li>
{{/paginate}}
</ul>
</nav>
app.js
hbs .registerHelper('paginate', function(paginate, options) {
if (options.hash.maxlimit) {
options.hash.limit = Math.min(Number(options.hash.maxlimit), paginate.pageCount);
}
return paginateHelper(paginate, options);
});
Do I need to change the route options at all?
Should only require 2 changes:
limit
in your Handlebars template(s) with maxlimit
(feel free to rename this)Ok so I now have the following
// /users
router.get('/dashboard/users', ensureAuthenticated, (req, res) => {
User.find({}, function(err, users) {
res.render('dashboard/users/index.hbs', {
pageTitle: 'Users',
users: users,
pagination: {
page: 6,
pageCount: 10,
maxlimit: 5
}
});
})
});
and
const hbs = require('hbs'); // Handlebars
const paginateHelper = require('handlebars-paginate');
hbs.registerHelper('paginate', function(paginate, options) {
if (options.hash.maxlimit) {
options.hash.limit = Math.min(Number(options.hash.maxlimit), paginate.pageCount);
}
return paginateHelper(paginate, options);
});
I'm getting the following https://gyazo.com/518a681f21db96e13f6d2c9311ba24f2
If I'm missing something obvious let me know, still new to express and node 👍
maxlimit
is a template option. Try removing it from the pagination
object and adding it in your template:
// /users
router.get('/dashboard/users', ensureAuthenticated, (req, res) => {
User.find({}, function(err, users) {
res.render('dashboard/users/index.hbs', {
pageTitle: 'Users',
users: users,
pagination: {
page: 6,
pageCount: 10
}
});
})
});
<snip>
{{#paginate pagination type="middle" maxlimit="10"}}
<li class="page-item"><a class="page-link{{#if disabled}} disabled{{/if}}" href="?page={{n}}">{{n}}</a></li>
{{/paginate}}
<snip>
That said, you are still saying you have 10 pages worth of users. Just so I'm clear, are you trying to effectively limit the number of pages displayed to 10, but if you have less than 10 pages, to stop at whatever that number is? If so, then so long as pageCount
is >= 10, I would expect 10 page numbers to get rendered.
Actually, I'm now realizing that the wrapper I wrote above isn't even achieving anything. handlebars-paginate shouldn't be rendering page numbers for pages that don't exist. I think you might be misusing one or more of the options. For reference:
context.pagination.page
is the current page you're oncontext.pagination.pageCount
is the total number of pages availablehandlebars-paginate is actually completely agnostic to the number of items you have per page. It's only concerned with what the current page is, and now many there are in total.
Ok so I'm still getting the same here.
That said, you are still saying you have 10 pages worth of users. Just so I'm clear, are you trying to effectively limit the number of pages displayed to 10, but if you have less than 10 pages, to stop at whatever that number is? If so, then so long as pageCount is >= 10, I would expect 10 page numbers to get rendered.
Yes that's what I'm trying to do here, so for an example let's say I limit to 6 records per page.
So in theory the output should look like this:
6 records = 1 page in the pagination 12 records = 2 pages in the pagination 18 records = 3 pages in the pagination
etc...
What I'm trying to do here is only have the right amount of pages listed in the pagination, if there aren't 10 pages of records, then a pagination of 10 shouldn't show.
See my most recent comment. I believe your context.pagination
options are incorrect. { page: 6, pageCount: 10 }
translates to I'm on page 6 of 10.
Yes but I don't want 10 pagination links when there aren't 10 pages of records.
If there is three pages of records only three pagination links should show. Not 10.
When there are 3 pages of records, you need to set pageCount
to 3.
So have to set it manually? Anyway to make this dynamic?
You're getting into the realm of your template rendering lifecycle, which is out of the scope of this library. If your collection changes after initial render, you need to render your pagination template again if you want that state to be reflected in your UI.
Here is my users page
https://gyazo.com/981af3a4c3c065ba4f31c055c2fd5977
As you can see I only have two users here so ideally only one button in the pagination should show here.
In the production app I have 20 users and I have limited the page to only show 6 records in the using the page prefix in the pagination settings however I am still getting 10 pages in the pagination.
Can this be dynamic so the right about of pages in the pagination given the amount of records created?