I have some pagination logic working just fine, only issue is I can only get it to show and fixed number of pages to choose from. Right now I have put it to 5 pages, but I would like it to change dynamically based on total records..
So lets say I have 100 records and the limit per page is 10 . There will be 10 pages. Right now I can only get it to show this way
First Prev 1 2 3 4 5 6 7 8 9 10 Next Last
But what I want is the paging to change dynamically based on records and based on what page you are at.
So it looks more like this:
At page 1: 1 2 3 4 5 Next Last
At page 5: First Prev 3 4 5 6 7 Next Last
At page 3: First Prev 1 2 3 4 5 Next Last
I have tried a lot of things, but can not seem to find the right solution. Can someone tell me how to do on current code I have ?
Help would be really appreciated.
Link to the sandbox: https://codesandbox.io/s/react-typescript-nvffv
import * as React from "react";
import Pagination from "./Pagination";
import * as ReactDOM from "react-dom";
const NO_OF_RECORDS_PER_PAGE = 10;
interface IState {
length: number;
currentPage: number;
}
interface IProps {}
export default class App extends React.Component<IProps, IState> {
constructor(props: any) {
super(props);
this.state = {
length: 0,
currentPage: 1
};
}
componentDidMount() {
this.setState({ length: 98 });
}
handlePagination = (fromIndex: number, noOfRecords: number) => {
//Pagination logic here
//console.log(fromIndex, noOfRecords);
};
render() {
return (
<Pagination
dataCount={this.state.length}
currentPage={this.state.currentPage}
handlePagination={this.handlePagination}
perPageCount={NO_OF_RECORDS_PER_PAGE}
/>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
import * as React from "react";
interface IProps {
dataCount: number;
handlePagination(fromIndex: number, noOfRecords: number): any;
perPageCount: number;
}
interface IState {
pages: number;
fromIndex: number;
currentPage: number;
}
export default class PaginationComponent extends React.Component<
IProps,
IState
> {
constructor(props: any) {
super(props);
this.state = {
pages: this.findNumberOfPages(),
fromIndex: 0,
currentPage: 1
};
}
componentDidUpdate(prevProps: any) {
if (prevProps.dataCount !== this.props.dataCount) {
this.setState({ pages: this.findNumberOfPages() });
}
}
findNumberOfPages = () => {
return Math.ceil(this.props.dataCount / this.props.perPageCount);
};
setOffset = (value: number) => {
let fromIndex = this.getFromIndex(
value,
this.props.perPageCount,
this.props.dataCount
);
this.setState({ fromIndex, currentPage: value }, () =>
this.props.handlePagination(this.state.fromIndex, this.props.perPageCount)
);
};
getFromIndex = (page_no: number, per_page: number, total_length: number) => {
return (
+page_no &&
+page_no <= Math.ceil(total_length / per_page) &&
per_page * --page_no
);
};
renderPageNumbers = () => {
const numberOfPages = this.findNumberOfPages();
let pages = [];
for (let i = 1; i <= numberOfPages; i++) {
pages.push(
<span
key={i}
className="margin-wd-10"
onClick={() => this.setOffset(i)}
style={{ cursor: "pointer" }}
>
{i}
</span>
);
}
return pages;
};
renderPrevButton = () => {
return (
<>
{this.state.currentPage > 1 ? (
<button
style={{ cursor: "pointer" }}
onClick={() => this.setOffset(this.state.currentPage - 1)}
>
<
</button>
) : (
<button style={{ cursor: "pointer" }} disabled>
<
</button>
)}
</>
);
};
renderNextButton = () => {
return (
<>
{this.state.currentPage < this.state.pages ? (
<button
style={{ cursor: "pointer" }}
onClick={() => this.setOffset(this.state.currentPage + 1)}
>
>
</button>
) : (
<button style={{ cursor: "pointer" }} disabled>
>
</button>
)}
</>
);
};
renderFirstButton = () => {
return (
<>
{this.state.currentPage > 1 ? (
<button
style={{ cursor: "pointer" }}
onClick={() => this.setOffset(1)}
>
First
</button>
) : (
<button style={{ cursor: "pointer" }} disabled>
First
</button>
)}
</>
);
};
renderLastButton = () => {
return (
<>
{this.state.currentPage < this.state.pages ? (
<button
style={{ cursor: "pointer" }}
onClick={() => this.setOffset(this.state.pages)}
>
Last
</button>
) : (
<button style={{ cursor: "pointer" }} disabled>
Last
</button>
)}
</>
);
};
render() {
return (
<>
<div>
{this.renderFirstButton()}
{this.renderPrevButton()}
{this.renderPageNumbers()}
{this.renderNextButton()}
{this.renderLastButton()}
</div>
</>
);
}
}
Check if this works for you. I've changed the renderPageNumbers
so that it only displays from currentPage
to currentPage + 5
. The 5
here is random. You can choose any window. Or pass it from a prop to make it more dynamic.
renderPageNumbers = () => {
const numberOfPages = this.findNumberOfPages();
let pages = [];
const {currentPage} = this.state;
for (
let i = currentPage;
(i <= currentPage + 4) && (i < numberOfPages);
i++
) {
pages.push(
<span
key={i}
className="margin-wd-10"
onClick={() => this.setOffset(i)}
style={{ cursor: "pointer" }}
>
{i}
</span>
);
}
return pages;
};
The link to sand box. I don't know if it's saved or not. https://codesandbox.io/s/react-typescript-b220b