How to limit the number of pages shown in pagination in React?

Viewed 3201

I am developing a web application using MERN stack. I have implemented pagination using React & Bootstrap. enter image description here enter image description here

WHAT DO I WANT? Currently, I have a limited data set. So, the number of pages shown in the pagination are manageable. But with a larger data set, I should be able to limit the number of pages shown in the pagination. The result I am looking for is the pagination implemented at the site www.flanker.net. enter image description here

The following are my code snippets. components/Movies.js

import React, { useState, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import MoviesTable from "./MoviesTable";
import { fetchMovies } from "./moviesSlice";
import "./Movies.css";
import Pagination from "./common/Pagination";
import { paginate } from "./../utils/paginate";

const Movies = () => {
  const [pageSize, setPageSize] = useState(4);
  const [currentPage, setCurrentPage] = useState(1);

  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(fetchMovies());
  }, [dispatch]);

  const handlePageChange = (page) => {
    setCurrentPage(page);
  };
  const handlePreviousClick = () => {
    setCurrentPage(currentPage - 1);
  };
  const handleNextClick = () => {
    setCurrentPage(currentPage + 1);
  };

  const { status, movies } = useSelector((state) => state.movies);

  const paginatedMovies = paginate(movies, currentPage, pageSize);

  let content;

  if (status === "loading") {
    content = (
      <div className="spinner">
        <div className="spinner-border text-success">
          <span class="sr-only">Loading...</span>
        </div>
      </div>
    );
  } else {
    content = (
      <div className="row">
        <div className="col-xs-10 col-md-8 mx-auto mt-3">
          {paginatedMovies.length > 0 ? (
            <MoviesTable movies={paginatedMovies} />
          ) : null}
          <Pagination
            itemsCount={movies.length}
            pageSize={pageSize}
            currentPage={currentPage}
            onPageChange={handlePageChange}
            onPreviousClick={handlePreviousClick}
            onNextClick={handleNextClick}
          />
        </div>
      </div>
    );
  }

  return <>{content}</>;
};

export default Movies;

components/pagination.js

import React from "react";
import _ from "lodash";

const Pagination = ({
  itemsCount,
  pageSize,
  onPageChange,
  currentPage,
  onPreviousClick,
  onNextClick,
}) => {
  const pageCount = Math.ceil(itemsCount / pageSize);
  if (pageCount === 1) return null;
  const pages = _.range(1, pageCount + 1);

  return (
    <nav aria-label="Page navigation example">
      <ul className="pagination">
        {currentPage !== 1 && (
          <li class="page-item">
            <a
              className="page-link"
              style={{ cursor: "pointer" }}
              onClick={onPreviousClick}
            >
              Previous
            </a>
          </li>
        )}
        {pages.map((page) => (
          <li
            key={page}
            className={page === currentPage ? "page-item active" : "page-item"}
          >
            <a
              style={{ cursor: "pointer" }}
              className="page-link"
              onClick={() => onPageChange(page)}
            >
              {page}
            </a>
          </li>
        ))}
        {currentPage !== pageCount && (
          <li class="page-item">
            <a
              className="page-link"
              style={{ cursor: "pointer" }}
              onClick={onNextClick}
            >
              Next
            </a>
          </li>
        )}
      </ul>
    </nav>
  );
};

export default Pagination;

src/utils/paginate.js

import _ from "lodash";

export function paginate(items, pageNumber, pageSize) {
  const startIndex = (pageNumber - 1) * pageSize;
  return _(items).slice(startIndex).take(pageSize).value();
}

I did some research in the internet, but could not find a solution. I don't know where to start. I would appreciate any help.

1 Answers

I had the same problems and I resolved them with this algorithm :

     handleClick(event) {
            this.TotalPage();
            this.setState({
                currentPage: Number(event.target.id)
            });
        }

 const pageNumbers = 10;
 ShowPaginationNumbers(pageNumbers) {

    let paginationNumbers = [];

    if (pageNumbers) {
        let showMax = 3;
        let endPage;
        let startPage;

        if (pageNumbers <= showMax) {
            startPage = 1;
            endPage = pageNumbers.length;
        }
        else {
            startPage = this.state.currentPage;
            if (startPage != pageNumbers.length && (startPage + 1) != pageNumbers.length) {
                endPage = this.state.currentPage + showMax - 1;
            }
            else {
                endPage = pageNumbers.length;
            }
        }
        for (let i = startPage; i <= endPage; i++) {
            paginationNumbers.push(i);
        }
        return this.ShowRenderPageNumbers(paginationNumbers); 
    }
}


    ShowRenderPageNumbers(paginationNumbers) {

        if (paginationNumbers) {
          let result = paginationNumbers.map(number => {
                return (
                    <li className="page-item" >
                        <a className={(this.state.currentPage === number ? ' active' : '') + ' page-link'} key={number} id={number} onClick={this.handleClick}>{number}</a>
                    </li>
                );
          });
            return result;
        }
    }
Related