Building Reusable Pagination Component

JavaScriptJavaScriptBeginner
Practice Now

Introduction

In this project, you will learn how to build a pagination component, which is a commonly used component in web applications. The pagination component helps reduce the query time on the backend and does not affect the performance of page rendering due to too much data loading.

👀 Preview

Image

🎯 Tasks

In this project, you will learn:

  • How to implement the ajax function to handle data requests and retrieve the data for the current page and the total number of pages.
  • How to implement the initEvents function to bind events to the buttons of the pagination component.
  • How to implement the createPaginationIndexArr function to generate a pagination array based on the function arguments.
  • How to implement the renderPagination function to generate the string template for the pagination component.
  • How to render the content based on the current page.

🏆 Achievements

After completing this project, you will be able to:

  • Build a reusable pagination component in JavaScript.
  • Use Axios to make HTTP requests and handle the response data.
  • Generate a pagination array based on the current page, total pages, and the maximum number of page buttons to display.
  • Update the pagination component and the content based on the current page.

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL javascript(("`JavaScript`")) -.-> javascript/BasicConceptsGroup(["`Basic Concepts`"]) javascript(("`JavaScript`")) -.-> javascript/AdvancedConceptsGroup(["`Advanced Concepts`"]) javascript(("`JavaScript`")) -.-> javascript/NetworkingGroup(["`Networking`"]) javascript/BasicConceptsGroup -.-> javascript/functions("`Functions`") javascript/BasicConceptsGroup -.-> javascript/array_methods("`Array Methods`") javascript/AdvancedConceptsGroup -.-> javascript/es6("`ES6 Features`") javascript/NetworkingGroup -.-> javascript/http_req("`HTTP Requests`") subgraph Lab Skills javascript/functions -.-> lab-299875{{"`Building Reusable Pagination Component`"}} javascript/array_methods -.-> lab-299875{{"`Building Reusable Pagination Component`"}} javascript/es6 -.-> lab-299875{{"`Building Reusable Pagination Component`"}} javascript/http_req -.-> lab-299875{{"`Building Reusable Pagination Component`"}} end

Set Up the Project Structure

In this step, you will set up the project files and structure. Follow the steps below to complete this step:

Open the project folder. The directory structure is as follows:

├── css
│   └── index.css
├── index.html
└── js
    ├── data.json
    ├── axios.min.js
    ├── util.js
    └── index.js

Where:

  • css/index.css is the CSS style file.
  • index.html is the main page.
  • js/data.json is the JSON file that stores the data.
  • js/axios.min.js is the axios file.
  • js/index.js is the file to be completed.
  • js/util.js is the file that stores utility functions.

Click on Go Live button in the bottom right corner of WebIDE, to run the project.

Next, open "Web 8080" on the top of the VM and manually refresh it to see the page.

Initial Effect

Implement the ajax Function

In this step, you will implement the ajax function in the js/index.js file to handle the data request.

  1. Open the js/index.js file.
  2. Locate the ajax function and complete the implementation.
  3. The ajax function should retrieve the data for the current page and the total number of pages based on the function arguments, and return them.
  4. You can use the provided Axios library to make the HTTP request to the ./js/data.json file.

Here's the completed ajax function:

async function ajax({
  url,
  method = "get",
  data,
  query: { currentPage, pageSize }
}) {
  // TODO: Get the data of the current page according to the function parameters `query` object `currentPage, pageSize`.
  let result = {
    data: [],
    total: 0
  };

  let resData = [];
  let res = await axios[method](url, data);
  if (res.status === 200) {
    resData = res.data.data;
    result.total = res.data.total;
  }
  result.data = resData.slice(
    (currentPage - 1) * pageSize,
    currentPage * pageSize
  );

  return result;
}

Implement the initEvents Function

In this step, you will implement the initEvents function in the js/index.js file, which binds events to the buttons of the pagination component.

  1. Open the js/index.js file.
  2. Locate the initEvents function and complete the implementation.
  3. When the "<" button is clicked, the this.currentPage value should be reduced by 1, with a minimum of 1.
  4. When the ">" button is clicked, the this.currentPage value should be increased by 1, with a maximum of this.totalPages.
  5. When the this.currentPage value changes, the pagination component on the page should be updated accordingly.

Here's the completed initEvents function:

initEvents() {
    this.root.querySelector("#btn-prev").addEventListener("click", () => {
      // TODO: Click event for the "<" button, this.currentPage - 1 when clicked.
      if (this.currentPage > 1) {
        this.currentPage--;
        this.initPagination();
      }
    });
    this.root.querySelector("#btn-next").addEventListener("click", () => {
      // TODO: Click event for the ">" button, this.currentPage + 1 when clicked.
      if (this.currentPage < this.totalPages) {
        this.currentPage++;
        this.initPagination();
      }
    });
    this.root.querySelector(".pager").addEventListener("click", (e) => {
      if (e.target.nodeName.toLowerCase() === "li") {
        if (this.currentPage === e.target.innerText) return;
        if (e.target.classList.contains("more")) return;
        this.currentPage = Number(e.target.innerText);
      }
      this.initPagination();
    });
  }

Implement the createPaginationIndexArr Function

In this step, you will implement the createPaginationIndexArr function in the js/util.js file, which generates a pagination array (indexArr) based on the function arguments following certain rules.

  1. Open the js/util.js file.

  2. Locate the createPaginationIndexArr function and complete the implementation.

  3. The function should generate the pagination array (indexArr) based on the passed parameters currentPage, totalPages, and pagerCount.

  4. The rules for generating the pagination array are as follows:

    • Special case: totalPages <= pagerCount
    • Normal case: totalPages > pagerCount
  5. The generated indexArr should follow the examples provided in the challenge description.

Here's the completed createPaginationIndexArr function:

const createPaginationIndexArr = (currentPage, totalPages, pagerCount) => {
  let indexArr = [];
  // TODO: Generate paging array based on passed parameters indexArr.
  indexArr[0] = 1;
  if (totalPages <= pagerCount) {
    for (let i = 1; i < totalPages; i++) {
      indexArr.push(i + 1);
    }
  } else {
    indexArr[pagerCount - 1] = totalPages;
    if (currentPage <= pagerCount - 2) {
      for (let i = 1; i < pagerCount - 1; i++) {
        indexArr[i] = i + 1;
      }
    } else if (currentPage <= totalPages - pagerCount + 2) {
      let j = 1;
      for (
        let i = -Math.ceil((pagerCount - 3) / 2);
        i <= Math.floor((pagerCount - 3) / 2);
        i++
      ) {
        indexArr[j++] = currentPage + i;
      }
    } else {
      let j = 1;
      for (let i = totalPages - pagerCount + 2; i < totalPages; i++) {
        indexArr[j++] = i;
      }
    }
  }

  return indexArr;
};

Implement the renderPagination Function

In this step, you will implement the renderPagination function in the js/index.js file, which generates the string template template for the pagination component based on the indexArr array.

  1. Open the js/index.js file.
  2. Locate the renderPagination function and complete the implementation.
  3. The function should generate the string template template for the pagination component based on the indexArr array, following the rules described in the challenge description.
  4. The generated template should be inserted into the pagination component's HTML structure using this.root.innerHTML.

Here's the completed renderPagination function:

renderPagination(indexArr) {
  let template = "";
  // TODO: Generates a string template template for the paging component based on the indexArr array.
  template = indexArr.reduce((prev, next, index) => {
    if (indexArr[index] - indexArr[index - 1] > 1) {
      prev += `<li class="number more">...</li>`;
      prev += `<li class="number ${
        this.currentPage == next ? "active" : ""
      }">${next}</li>`;
    } else {
      prev += `<li class="number ${
        this.currentPage == next ? "active" : ""
      }">${next}</li>`;
    }
    return prev;
  }, "");

  this.root.innerHTML = `
      <div class="pagination">
          <div class="btn btn-left" id="btn-prev">&lt;</div>
          <ul class="pager">${template} </ul>
          <div class="btn btn-right" id="btn-next">&gt;</div>
      </div>`;
}

Test the Pagination Component

In this step, you will test the final result of the paging component.

  1. Save the js/index.js and js/util.js files.
  2. Refresh the web page in the browser.
  3. Check the page effect.

Congratulations! You have completed the implementation of the Pagination Component. The final page effect should be as follows:

Image Description
✨ Check Solution and Practice

Summary

Congratulations! You have completed this project. You can practice more labs in LabEx to improve your skills.

Other JavaScript Tutorials you may like