Skip to content

Instantly share code, notes, and snippets.

@chrisgfortes
Last active October 25, 2022 16:33
Show Gist options
  • Save chrisgfortes/a890df2d1870b38225e570cef98aafec to your computer and use it in GitHub Desktop.
Save chrisgfortes/a890df2d1870b38225e570cef98aafec to your computer and use it in GitHub Desktop.
Pagination JS
const pagination = {
list: [],
generateListBySize: (size, predicate) => Array.from({ length: size }).map(predicate),
generatePageList: (size, range, total) => pagination.generateListBySize(size, (_, i) => range.start + i).filter(page => page <= total),
generateMapRange: (totalRange, size) => (
pagination
.generateListBySize(totalRange, (_) => ({}))
.reduce((acc, _, i) => {
const lastItem = acc?.[i - 1];
const index = i + 1;
const start = lastItem ? lastItem.end : index;
const end = lastItem ? lastItem.end + size : (index * size) + 1;
return [...acc, { start, end }];
}, [])
),
generate: (listSize, rowsPerPage, paginationSize, currentPage) => {
const pagesTotal = Math.ceil(listSize / rowsPerPage);
const paginatorTotalRange = Math.ceil(pagesTotal / paginationSize);
const list = (
pagination.list.length === 0
? pagination.generateMapRange(paginatorTotalRange, paginationSize, pagesTotal)
: pagination.list
);
const rangeIndex = list.findIndex(range => currentPage >= range.start && currentPage <= range.end);
const rangePage = list[rangeIndex];
const shouldMoveRange = rangePage.end === currentPage && rangeIndex < (list.length - 1);
const pages = pagination.generatePageList(
paginationSize,
list?.[shouldMoveRange ? rangeIndex + 1 : rangeIndex],
pagesTotal
);
return {
next: currentPage < pagesTotal ? currentPage + 1 : undefined,
prev: currentPage <= pagesTotal && currentPage !== 1 ? currentPage - 1 : undefined,
total: pagesTotal,
page: {
current: currentPage,
first: 1,
last: pagesTotal
},
perPage: rowsPerPage,
pages: pages
};
},
generateMoveOneByOne: (listSize, rowsPerPage, paginationSize, currentPage) => {
const pagesTotal = Math.ceil(listSize / rowsPerPage);
const regularNumbersPredicate = (_, index) => index === 0 ? currentPage : currentPage + index;
const lastNumbersPredicate = (_, index) => ((pagesTotal - paginationSize) + 1) + index;
const pages = pagination.generateListBySize(paginationSize, (
currentPage < ((pagesTotal - paginationSize) + 1)
? regularNumbersPredicate
: lastNumbersPredicate
));
return {
next: currentPage < pagesTotal ? currentPage + 1 : undefined,
prev: currentPage <= pagesTotal && currentPage !== 1 ? currentPage - 1 : undefined,
total: pagesTotal,
page: {
current: currentPage,
first: 1,
last: pagesTotal
},
perPage: rowsPerPage,
pages
};
}
};
// How to use
const paginationConfig = {
countTotalList: 100,
itemsPerPage: 5,
paginationSize: 5,
currentPage: 1
};
pagination.generate(
paginationConfig.countTotalList,
paginationConfig.itemsPerPage,
paginationConfig.paginationSize,
paginationConfig.currentPage // Change page number based on button actions
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment