Skip to content

Instantly share code, notes, and snippets.

@kottenator
Created July 13, 2015 20:44
Show Gist options
  • Save kottenator/9d936eb3e4e3c3e02598 to your computer and use it in GitHub Desktop.
Save kottenator/9d936eb3e4e3c3e02598 to your computer and use it in GitHub Desktop.
Simple pagination algorithm
// Implementation in ES6
function pagination(c, m) {
var current = c,
last = m,
delta = 2,
left = current - delta,
right = current + delta + 1,
range = [],
rangeWithDots = [],
l;
for (let i = 1; i <= last; i++) {
if (i == 1 || i == last || i >= left && i < right) {
range.push(i);
}
}
for (let i of range) {
if (l) {
if (i - l === 2) {
rangeWithDots.push(l + 1);
} else if (i - l !== 1) {
rangeWithDots.push('...');
}
}
rangeWithDots.push(i);
l = i;
}
return rangeWithDots;
}
/*
Test it:
for (let i = 1, l = 20; i <= l; i++)
console.log(`Selected page ${i}:`, pagination(i, l));
Expected output:
Selected page 1: [1, 2, 3, "...", 20]
Selected page 2: [1, 2, 3, 4, "...", 20]
Selected page 3: [1, 2, 3, 4, 5, "...", 20]
Selected page 4: [1, 2, 3, 4, 5, 6, "...", 20]
Selected page 5: [1, 2, 3, 4, 5, 6, 7, "...", 20]
Selected page 6: [1, "...", 4, 5, 6, 7, 8, "...", 20]
Selected page 7: [1, "...", 5, 6, 7, 8, 9, "...", 20]
Selected page 8: [1, "...", 6, 7, 8, 9, 10, "...", 20]
Selected page 9: [1, "...", 7, 8, 9, 10, 11, "...", 20]
Selected page 10: [1, "...", 8, 9, 10, 11, 12, "...", 20]
Selected page 11: [1, "...", 9, 10, 11, 12, 13, "...", 20]
Selected page 12: [1, "...", 10, 11, 12, 13, 14, "...", 20]
Selected page 13: [1, "...", 11, 12, 13, 14, 15, "...", 20]
Selected page 14: [1, "...", 12, 13, 14, 15, 16, "...", 20]
Selected page 15: [1, "...", 13, 14, 15, 16, 17, "...", 20]
Selected page 16: [1, "...", 14, 15, 16, 17, 18, 19, 20]
Selected page 17: [1, "...", 15, 16, 17, 18, 19, 20]
Selected page 18: [1, "...", 16, 17, 18, 19, 20]
Selected page 19: [1, "...", 17, 18, 19, 20]
Selected page 20: [1, "...", 18, 19, 20]
*/
@pk936
Copy link

pk936 commented Aug 7, 2024

Another Pagination which ensures a fixed number of items in the pagination array, including ellipses as necessary same as material UI pagination.

function range(start, end) {
  return Array.from({ length: end - start + 1 }, (_, i) => i + start);
}

function pagination(currentPage, totalPages) {
  const leftSiblingIndex = Math.max(currentPage - 1, 1);
  const rightSiblingIndex = Math.min(currentPage + 1, totalPages);

  const shouldShowLeftEllipsis = leftSiblingIndex > 2;
  const shouldShowRightEllipsis = rightSiblingIndex < totalPages - 2;

  const firstPageIndex = 1;
  const lastPageIndex = totalPages;

  if (!shouldShowLeftEllipsis && shouldShowRightEllipsis) {
    const leftItemCount = 3;
    const leftRange = range(1, leftItemCount + 2);

    return [...leftRange, '...', totalPages];
  }

  if (shouldShowLeftEllipsis && !shouldShowRightEllipsis) {
    const rightItemCount = 3;
    const rightRange = range(totalPages - rightItemCount - 1, totalPages);

    return [firstPageIndex, '...', ...rightRange];
  }

  if (shouldShowLeftEllipsis && shouldShowRightEllipsis) {
    const middleRange = range(leftSiblingIndex, rightSiblingIndex);

    return [firstPageIndex, '...', ...middleRange, '...', lastPageIndex];
  }

  return range(1, totalPages);
}


// pagination(1,20) : [1, 2, 3, 4, 5, '...', 20]
// pagination(5,20) : [1, '...', 4, 5, 6, '...', 20]
// pagination(10,20) : [1, '...', 9, 10, 11, '...', 20]
// pagination(18,20) : [1, '...', 16, 17, 18, 19, 20]

@troyere
Copy link

troyere commented Jan 15, 2025

After testing one of these great codes, I think that having the same number of elements is indeed very important, in terms of user experience

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