Partial and Dynamic data loading using pagination in React Bootstrap Table

I would like to update the data partially/dynamically using the pagination click.

codesandbox

On the initial load, I would like to render 100 records(DB has more data) and the pagination has to work normally without calling the API.

Once it user reaches the last page, at that time I would like to hit an API call to get another set of 100 data from the database to replace the existing.

From the above example, I can do either. Either by displaying the Static data with pagination on the initial loading of the application nor calling API on either of the pagination clicks.

Table.js

import React, { useState, useEffect } from "react";
import { BootstrapTable, TableHeaderColumn } from "react-bootstrap-table";
import Axios from "axios";
// import { products } from "./products";
import { PHOTOS } from "./constants";
import BSTable from "./BSTable";

function Table() {
  /* Varibale Declaration */
  const [userData, setUserData] = useState([]);
  const [childData, setChildData] = useState();
  const [currentPage, setCurrentPage] = useState();
  const [sizePerPage, setSizePerPage] = useState();

  /* Fetch User Data */
  const fetchUserData = async (start = 0, limit = 50) => {
    console.log("fetchUserData", start, limit);
    var res = await Axios.get(
      `https://jsonplaceholder.typicode.com/photos?_start=${start}&_limit=${limit}`
    );
    console.log("res", res);
    setUserData(res.data);
  };

  /* React Hooks */
  useEffect(() => {
    fetchUserData();
  }, []);

  /* Functional Declaration */
  let expandedRows = {};

  const renderShowsTotal = (start, to, total) => {
    return (
      <p style={{ color: "blue" }}>
        From {start} to {to}, totals is {total}&nbsp;&nbsp;(its a customize
        text)
      </p>
    );
  };

  const handleExpand = async (rowKey, isExpand) => {
    expandedRows = Object.assign(
      expandedRows,
      (expandedRows[rowKey] = isExpand)
    );
    var res = await Axios.get(
      `https://jsonplaceholder.typicode.com/photos?_start=${0}&_limit=${1}`
    );
    console.log(res);
    setChildData(res.data);
    // expandedRows[rowKey] = isExpand;
    // console.log(expandedRows[rowKey], Object.keys(expandedRows).length);
    // if (!(Object.keys(expandedRows).length === 0)) {
    //   expandedRows = Object.assign({}, expandedRows[rowKey] = isExpand);
    // } else {
    //   expandedRows[rowKey] = isExpand;
    // }
    console.log(rowKey, isExpand, expandedRows);
    console.log("handleClick", isExpandableRow({ id: 4 }));
  };

  const onPageChange = (page, sizePerPage) => {
    // setCurrentPage(page);
    console.log("onPageChange", page, sizePerPage, userData);
    // return false;
    // fetchUserData((page - 1) * 10, sizePerPage);
    // fetchUserData();
  };

  // const onSizePerPageList = sizePerPage => {
  //   console.log("onSizePerPageList", currentPage, sizePerPage);
  //   // const currentIndex = (currentPage - 1) * sizePerPage;
  //   // setUserData(userData.slice(currentIndex, currentIndex + sizePerPage));
  //   // setSizePerPage(sizePerPage);
  // };

  const onSortChange = (sortName, sortOrder) => {
    console.log(sortName, sortOrder);
    if (sortOrder === "asc") {
      userData.sort((a, b) => {
        if (parseInt(a[sortName], 10) > parseInt(b[sortName], 10)) {
          return 1;
        } else if (parseInt(b[sortName], 10) > parseInt(a[sortName], 10)) {
          return -1;
        }
        return 0;
      });
    } else {
      userData.sort((a, b) => {
        if (parseInt(a[sortName], 10) > parseInt(b[sortName], 10)) {
          return -1;
        } else if (parseInt(b[sortName], 10) > parseInt(a[sortName], 10)) {
          return 1;
        }
        return 0;
      });
    }
  };

  const options = {
    onlyOneExpanding: true,
    // onSizePerPageList: onSizePerPageList,
    //hideSizePerPage: true,
    paginationSize: 1,
    onExpand: handleExpand,
    sizePerPageList: [15, 10],
    // sizePerPageList: [
    //   {
    //     text: "5",
    //     value: 5
    //   },
    //   {
    //     text: "10",
    //     value: 10
    //   },
    //   {
    //     text: "All",
    //     value: userData.length
    //   }
    // ],
    onPageChange: onPageChange,
    sizePerPage: 15, // which size per page you want to locate as default
    // pageStartIndex: 0, // where to start counting the pages
    // paginationSize: 3,  // the pagination bar size.
    prePage: "Prev", // Previous page button text
    nextPage: "Next", // Next page button text
    firstPage: "First", // First page button text
    lastPage: "Last", // Last page button text
    totalSize: 100,
    paginationShowsTotal: renderShowsTotal, // Accept bool or function
    paginationPosition: "top", // default is bottom, top and both is all available
    //hideSizePerPage: true, // You can hide the dropdown for sizePerPage
    alwaysShowAllBtns: true, // Always show next and previous button
    withFirstAndLast: currentPage === 4 ? true : false, // Hide the going to First and Last page button
    expandRowBgColor: "rgb(242, 255, 163)",
    expandBy: "column", // Currently, available value is row and column, default is row
    expandBodyClass: function(row, rowIndex, isExpanding) {
      if (!isExpanding) {
        return "current-is-hidden";
      } else {
        if (rowIndex > 1) {
          return "custom-expand-body-1";
        } else {
          return "custom-expand-body-0";
        }
      }
    },
    expandParentClass: function(row, rowIndex, isExpanding) {
      return isExpandableRow(row);
    },
    onSortChange: onSortChange
  };

  const isExpandableRow = row => {
    // console.log("isExpandableRow", row);
    if (row.id < 3) return true;
    else return false;
  };

  const expandComponent = (row, e) => {
    console.log("expandComponent", row, e);
    if (row.id === true) {
      return <BSTable data={childData} />;
    }
  };

  const expandColumnComponent = ({ isExpandableRow, isExpanded }) => {
    let content = "";
    console.log("expandColumnComponent", isExpandableRow, isExpanded);
    if (isExpandableRow) {
      content = isExpanded ? "(-)" : "(+)";
    } else {
      content = " ";
    }
    return <div> {content} </div>;
  };

  const expandedColumnHeaderComponent = ({ anyExpand }) => {
    const content = anyExpand ? "(-)" : "(+)";
    return <div>{content}</div>;
  };

  const trClassFormat = (rowData, rIndex) => {
    return !isExpandableRow(rowData) ? "disable-row-cell" : "";
  };

  return (
    <div className="react-bootstrap-table container mt-4">
      <h2>React Bootstrap Table with pagination</h2>
      {userData.length > 0 ? (
        <BootstrapTable
          dataSort={true}
          hover
          // remote={true}
          fetchInfo={{ dataTotalSize: 1000 }}
          trClassName={trClassFormat}
          data={userData}
          pagination
          options={options}
          expandableRow={isExpandableRow}
          expandComponent={expandComponent}
          expandColumnOptions={{
            expandColumnVisible: true,
            expandColumnComponent: expandColumnComponent,
            columnWidth: 50,
            expandedColumnHeaderComponent: expandedColumnHeaderComponent
          }}
          autoCollapse={{ sort: true, search: true, filter: true }}
          search
        >
          <TableHeaderColumn expandable={false} dataField="id" isKey={true}>
            User ID
          </TableHeaderColumn>
          <TableHeaderColumn expandable={false} dataField="title">
            User Title
          </TableHeaderColumn>
          <TableHeaderColumn expandable={false} dataField="url">
            User URL
          </TableHeaderColumn>
        </BootstrapTable>
      ) : (
        <i className="fa fa-spinner fa-3x fa-spin" />
      )}
    </div>
  );
}

export default Table;

Thanks in advance.

Answers:

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.