I'm trying to make a function that returns me pagination items, and here is what I tried (based on https://github.com/mui/material-ui/blob/v4.10.2/packages/material-ui-lab/src/Pagination/usePagination.js):
const pagination = (totalPages, siblingCount = 2, pageNumber) => {
const ELLIPSIS = '…';
const siblingsStart = Math.max(
Math.min(
// Natural start
pageNumber - siblingCount,
// Lower boundary when page is high
totalPages - siblingCount * 2 - 2,
),
// Greater than startPage
3,
);
const siblingsEnd = Math.min(
Math.max(
// Natural end
pageNumber + siblingCount,
// Upper boundary when page is low
siblingCount * 2 + 3,
),
// Less than endPages
totalPages - 2,
);
// Basic list of items to render
return [
1,
// Start ellipsis
// eslint-disable-next-line no-nested-ternary
...(siblingsStart > 3
? [ELLIPSIS]
: totalPages - 1 > 2
? [2]
: []),
// Sibling pages
...range(siblingsStart, siblingsEnd),
// End ellipsis
// eslint-disable-next-line no-nested-ternary
...(siblingsEnd < totalPages - 2
? [ELLIPSIS]
: totalPages - 1 > 1
? [totalPages - 1]
: []),
totalPages,
];
};
This function will return a string like the following when (for example) pageNumber = 6 and totalPages = 20:
1 … 4 5 6 7 8 … 20
This is working fine, since I want to always display two numbers before and after the pageNumber.
So when the pageNumber = 1 I want the following:
1 2 3 … 20
But instead I get this:
1 2 3 4 5 6 7 … 20
The same as when the pageNumber = 20, I want to get this:
1 … 18 19 20
How can I solve this ?
There are hard-coded lowest, and highest possible sibling pages in the code provided in the question. For example, the code that determines the siblingsStart value, which is used to begin the sibling pages—list of pages in the center portion—will never be less than three:
const siblingsStart = Math.max( ... , 3); // <-- lowest value returnable is 3
So any current page value less than 6, given a value of 2 siblings before the current page, will return 1 2 3 4 5 6 ..., because the page list always starts with 1, the siblingCount is 2, and 3 is hard-coded as the lowest sibling page number: 1 + 2 + 3 = 6.
Starting with a blank slate... first check to see if current page is close to the first page and if not add first page plus ellipsis to a string. Next start looping before the current page and loop the number of sibling pages, making sure not to go before first page, adding each to the string. After that start at the current page and loop the sibling count forward, making sure not to go beyond the total pages. And finally add the last page if it's not too close to the current page.
const pagination = (pageNumber, totalPages = 40, siblingCount = 2) => {
let pagination_str = "";
// add first page if current page is not too close
if ( 1 < pageNumber - siblingCount ) {
pagination_str += "1 ";
if ( siblingCount + 3 < pageNumber ) { pagination_str += "… "; }
else if ( siblingCount + 2 < pageNumber ) { pagination_str += "2 "; }
}
// get siblingCount before
for (
// is current page to close to first page?
let ii = (0 < (pageNumber - siblingCount)? pageNumber - siblingCount: 1);
ii < (pageNumber);
ii++
) {
pagination_str += ii + " ";
}
// get siblingCount after
for (
let ii = pageNumber;
// is end of increment greater than or equal to the total number of pages?
ii <= ((totalPages >= pageNumber + siblingCount)? (pageNumber + siblingCount): totalPages);
ii++
) {
pagination_str += ii + " ";
}
// add last page if current page is not too close
if ( totalPages > pageNumber + siblingCount ) {
if ( totalPages - siblingCount - 2 > pageNumber ) { pagination_str += "… "; }
else if ( totalPages - siblingCount - 1 > pageNumber ) { pagination_str += (totalPages - 1) + " "; }
pagination_str += totalPages;
}
return pagination_str;
}
console.log("page 1 of 7: ", pagination(1, 7));
console.log("page 5 of 7: ", pagination(5, 7));
console.log("page 6 of 7: ", pagination(6, 7));
console.log("page 5: ", pagination(5, 20));
console.log("page 6: ", pagination(6, 20));
console.log("page 20: ", pagination(20, 20));