Skip to content

Instantly share code, notes, and snippets.

@hrgui
Created December 5, 2016 01:36
Show Gist options
  • Save hrgui/3ef13b028ffc43ddc77c9d30036f8984 to your computer and use it in GitHub Desktop.
Save hrgui/3ef13b028ffc43ddc77c9d30036f8984 to your computer and use it in GitHub Desktop.
Pagination in react
import React from 'react';
let howManyToShowAtATime = 5;
export default ({elementLength, start, howMany, onPageClicked}) => {
let numberOfPages = Math.ceil(elementLength / howMany);
let pageLinkNodes = [];
let previousNode, nextNode;
let previousTextNode = <span>Prev</span>;
let nextTextNode = <span>Next</span>;
let onPageClickHandler = (start) => {
return () => {
if (onPageClicked) {
onPageClicked(start, howMany);
}
};
};
let renderPageNode = ({children, startIfClicked, isActive, isDisabled}) => {
if (isDisabled) {
return <a className="disabled">{children}</a>
}
return (<a className={isActive ? 'active' : ''}
onClick={onPageClickHandler(startIfClicked)}>{children}
</a>)
};
let firstNode = renderPageNode({children: 'First', startIfClicked: 0, isActive: false, isDisabled: false});
let lastNode = renderPageNode({children: 'Last', startIfClicked: (numberOfPages - 1) * howMany, isActive: false, isDisabled: false});
// calculate the page nodes in between prev, first, next, last
// ideally we want the active node to be in the middle, but when you're at the last/ first node
// you have to let the node be slightly to the left or right
let half = Math.floor(howManyToShowAtATime / 2);
let startPage = (start / howMany) + 1;
let startIndex = startPage - half;
let startDiff = 0;
if (startIndex < 1) {
// this is to pad the lastIndex the difference we lost from thi
startDiff = 1 - startIndex;
startIndex = 1;
}
let lastIndex = startPage + half + startDiff;
if (lastIndex > numberOfPages) {
// pad startIndex the difference
startIndex += lastIndex - numberOfPages;
lastIndex = numberOfPages;
}
for (let i = startIndex; i <= lastIndex; i++) {
let actualPageNumber = (i - 1);
let startIfClicked = actualPageNumber * howMany;
let isActive = start === startIfClicked;
pageLinkNodes.push(renderPageNode({ isActive, children: i, startIfClicked }));
if (isActive) {
previousNode = renderPageNode({
isActive: false,
children: previousTextNode,
startIfClicked: (actualPageNumber - 1) * howMany,
isDisabled: !!!actualPageNumber
});
nextNode = renderPageNode({
isActive: false,
children: nextTextNode,
startIfClicked: (actualPageNumber + 1) * howMany,
isDisabled: i === numberOfPages
});
}
}
return <div className="mobile-pagination">
{firstNode}
{previousNode}
{pageLinkNodes}
{nextNode}
{lastNode}
</div>
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment