Skip to content

Instantly share code, notes, and snippets.

@nestorrente
Last active February 13, 2020 07:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nestorrente/25a20913fe6b5da36ea2d0131c79b63c to your computer and use it in GitHub Desktop.
Save nestorrente/25a20913fe6b5da36ea2d0131c79b63c to your computer and use it in GitHub Desktop.
This function allows you to generate a fully-customizable pagination
function customizablePaginationAlgorithm(currentPage, totalPages, options = {}) {
const {
margin = 2,
outerMargin = margin,
afterFirst = outerMargin,
beforeLast = outerMargin,
innerMargin = margin,
beforeCurrent = innerMargin,
afterCurrent = innerMargin,
showPageNumberOnSingleElementEllipsis = true,
ellipsis = '\u2026'
} = options;
const result = [];
const boundedAfterFirst = Math.min(1 + afterFirst, totalPages);
for(let i = 1; i <= boundedAfterFirst; ++i) {
result.push({ page: i, ellipsis: false, current: i === currentPage });
}
if(boundedAfterFirst === totalPages) {
return result;
}
const boundedBeforeCurrent = Math.max(currentPage - beforeCurrent, boundedAfterFirst + 1);
const boundedAfterCurrent = Math.min(currentPage + afterCurrent, totalPages);
if(boundedBeforeCurrent > boundedAfterFirst + 1) {
if(showPageNumberOnSingleElementEllipsis && boundedBeforeCurrent === boundedAfterFirst + 2) {
result.push({ page: boundedAfterFirst + 1, ellipsis: false, current: false });
} else {
result.push({ page: ellipsis, ellipsis: true, current: false });
}
}
for(let i = boundedBeforeCurrent; i <= boundedAfterCurrent; ++i) {
result.push({ page: i, ellipsis: false, current: i === currentPage });
}
if(boundedAfterCurrent === totalPages) {
return result;
}
const boundedBeforeLast = Math.max(totalPages - beforeLast, boundedAfterCurrent + 1);
if(boundedBeforeLast > boundedAfterCurrent + 1) {
if(showPageNumberOnSingleElementEllipsis && boundedBeforeLast === boundedAfterCurrent + 2) {
result.push({ page: boundedAfterCurrent + 1, ellipsis: false, current: false });
} else {
result.push({ page: ellipsis, ellipsis: true, current: false });
}
}
for(let i = boundedBeforeLast; i <= totalPages; ++i) {
result.push({ page: i, ellipsis: false, current: i === currentPage });
}
return result;
}
@nestorrente
Copy link
Author

Usage:

customizablePaginationAlgorithm(12, 20, {
    innerMargin: 3,
    outerMargin: 1,
    ellipsis: '...'
});

Output:

[
    {   page: 1,       ellipsis: false,   current: false   },
    {   page: 2,       ellipsis: false,   current: false   },
    {   page: '...',   ellipsis: true,    current: false   },
    {   page: 9,       ellipsis: false,   current: false   },
    {   page: 10,      ellipsis: false,   current: false   },
    {   page: 11,      ellipsis: false,   current: false   },
    {   page: 12,      ellipsis: false,   current: true    },
    {   page: 13,      ellipsis: false,   current: false   },
    {   page: 14,      ellipsis: false,   current: false   },
    {   page: 15,      ellipsis: false,   current: false   },
    {   page: '...',   ellipsis: true,    current: false   },
    {   page: 19,      ellipsis: false,   current: false   },
    {   page: 20,      ellipsis: false,   current: false   }
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment