I want to show pagination numbers compressed like 1,2,3 ... 56, 57, please see this attached screenshot of my current situation and what I am expecting
below are my API codes and frontend codes which have been done for pictures showing.
// Backend
const totalPages = Math.ceil(totalPages / limit);
res.send({
posts,
totalPages,
});
// Output
totalPages = 107;
posts = 2140;
// Frontend
const pager = () => {
const paginate = [];
for (let i = 1; i <= totalPages; i++) {
// console.log('000')
paginate.push(
<Link href={`?page=${i}`} key={i}>
<a>{i}</a>
</Link>
);
}
return paginate;
};
I think I can explain what I want but if you have any confusion please let me know in the comment.
Thanks in advance.
Update based on answer
Please see this screenshot, after 3 should come 4, 5 then ... and so on.
Based on @Andy
I think it will be easier if you try with the NPM package because you have done the backend fully and for the frontend, you may try with this like the below link
NPM next-pagination
And the demo is here
Code example like below
import React, { Component } from 'react'
import Pagination from 'next-pagination'
class Example extends Component {
render() {
return <Pagination total={1000} />
}
}
and the output is
By the way, you may visit the package manager link for full details.
I think it may help.
Just set your conditions accordingly. And for a better navigation experience, you should probably also consider the current page and add at least the page before and after that to your navigation. Like 1 2 3 ... 56 57 58 ... 100 101 102
const pager = () => {
let pagination = [], i = 1;
while (i <= totalPages) {
if (i <= 3 || //the first three pages
i >= totalPages - 2 || //the last three pages
i >= currentPage - 1 && i <= currentPage + 1) { //the currentPage, the page before and after
pagination.push(
<Link href={`?page=${i}`} key={i}>
<a>{i}</a>
</Link>
);
i++;
} else { //any other page should be represented by ...
pagination.push(<div>...</div>);
//jump to the next page to be linked in the navigation
i = i < currentPage ? currentPage - 1 : totalPages - 2;
}
}
return pagination;
}
Instead of iterating through the whole n of totalPages, do it in stages. First get the first page links using a for...loop, then apply the dots, then use a similar loop to get the last page links.
This example uses a Paginator component to encapsulate the code which you can then import into the component that requires it.
function Paginator({ totalPages }) {
const pagination = [];
function createLink(i) {
const page = `?page=${i}`;
return (
<div className="page">
<a href={page} key={i}>{i}</a>
</div>
);
}
function createDots() {
return <div className="page">...</div>;
}
// If there are no pages return a message
if (!totalPages) return <div>No pages</div>;
// If totalPages is less than seven, iterate
// over that number and return the page links
if (totalPages < 7) {
for (let i = 1; i <= totalPages; i++) {
pagination.push(createLink(i));
}
return pagination;
}
// Otherwise create the first three page links
for (let i = 1; i <= 3; i++) {
pagination.push(createLink(i));
}
// Create the dots
pagination.push(createDots());
// Last three page links
for (let i = totalPages - 2; i <= totalPages; i++) {
pagination.push(createLink(i));
}
return pagination;
}
function Example() {
// Sample array of possible totalPages
// Run the snippet again to see the change in output
const arr = [0, 10, 107, 50, 100, 200, 1000, 45, 9, 3];
// Pick a total
const totalPages = arr[Math.floor(Math.random() * arr.length)];
return <Paginator totalPages={totalPages} />;
};
// Render it
ReactDOM.render(
<Example />,
document.getElementById("react")
);
.page { display: inline-block; padding: 0.5em; margin-left: 0.2em; border: 1px solid #666666; }
.page a { color: black; text-decoration: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>