How to use a Material UI table showing a single row per page?

Viewed 392

I'm trying to use a material ui table to display content with a single row per page.

I can load the page and show the first row, but the next handler moves to the subsequent pages but does not render the content.

I'm trying to find an example of how to use the table pagination options to show one row per page.

At the moment I have:

import React from 'react';
import PropTypes from 'prop-types';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import TableFooter from '@material-ui/core/TableFooter';
import TablePagination from '@material-ui/core/TablePagination';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';
import IconButton from '@material-ui/core/IconButton';
import FirstPageIcon from '@material-ui/icons/FirstPage';
import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft';
import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight';
import LastPageIcon from '@material-ui/icons/LastPage';
import './styles.css';

const useStyles1 = makeStyles((theme) => ({
  root: {
    flexShrink: 0,
    marginLeft: theme.spacing(2.5),
  },
}));

function TablePaginationActions(props) {
  const classes = useStyles1();
  const theme = useTheme();
  const { count, page, rowsPerPage, onChangePage } = props;

  const handleFirstPageButtonClick = (event) => {
    onChangePage(event, 0);
  };

  const handleBackButtonClick = (event) => {
    onChangePage(event, page - 1);
  };

  const handleNextButtonClick = (event) => {
    onChangePage(event, page + 1);
  };

  const handleLastPageButtonClick = (event) => {
    onChangePage(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
  };

  return (
    <div className={classes.root}>
      <IconButton
        onClick={handleFirstPageButtonClick}
        disabled={page === 0}
        aria-label="first page"
      >
        {theme.direction === 'rtl' ? <LastPageIcon /> : <FirstPageIcon />}
      </IconButton>
      <IconButton onClick={handleBackButtonClick} disabled={page === 0} aria-label="previous page">
        {theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
      </IconButton>
      <IconButton
        onClick={handleNextButtonClick}
        disabled={page >= Math.ceil(count / rowsPerPage) - 1}
        aria-label="next page"
      >
        {theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
      </IconButton>
      <IconButton
        onClick={handleLastPageButtonClick}
        disabled={page >= Math.ceil(count / rowsPerPage) - 1}
        aria-label="last page"
      >
        {theme.direction === 'rtl' ? <FirstPageIcon /> : <LastPageIcon />}
      </IconButton>
    </div>
  );
}

TablePaginationActions.propTypes = {
  count: PropTypes.number.isRequired,
  onChangePage: PropTypes.func.isRequired,
  page: PropTypes.number.isRequired,
  
};

function createData(number, icon, heading, explanation) {
  return { number, icon, heading, explanation };
}

const rows = [
    createData(1, 'Cupcake', 305, 3.7),
    createData(2, 'Donut', 452, 25.0),
    createData(3, 'Eclair', 262, 16.0),
    
  ].sort((a, b) => (a.number < b.number ? -1 : 1));
  
const useStyles2 = makeStyles({
  table: {
    // minWidth: 500,
  },
});

export default function CustomPaginationActionsTable() {
  const classes = useStyles2();
  const [page, setPage] = React.useState(0);
  const [rowsPerPage, setRowsPerPage] = React.useState(1);

//   const emptyRows = rowsPerPage - Math.min(rowsPerPage, rows.length - page * rowsPerPage);

  const handleChangePage = (event, newPage) => {
    setPage(newPage);
  };


  return (
    <TableContainer component={Paper}>
      <Table className={classes.table} aria-label="The design studio supports research">
        <TableBody>
          {(rowsPerPage > 0
            ? rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
            : rows
          ).map((row) => (
            <TableRow key={row.number}>
              <TableCell  align="right">
                {row.icon}
              </TableCell>
              <TableCell component="th" scope="row" style={{ width: "80%" }}>
                {row.heading}
                {row.explanation}
              </TableCell>
              
              
            </TableRow>
          ))}

          
        </TableBody>
        <TableFooter>
          <TableRow>
                <TablePagination
                colSpan={3}
                
                rowsPerPage={rowsPerPage}
                rowsPerPageOptions={[1]} 
                onChangePage={handleChangePage}
                
                ActionsComponent={TablePaginationActions}
                />
          </TableRow>
          </TableFooter>
          </Table>
    </TableContainer>
  );
}

Page 1 renders:

enter image description here

Page 2 renders:

enter image description here

What do I need to do to be able to render the row content in subsequent pages?

1 Answers

I think your issue is with the page changes since when I ran your code, I kept getting NaN for the pages. I think this is messing up your code as you use slicing (which is the correct method) but you slice nonexistent values that messes with your additional row cutting. That is why your code only works for the first page but not the rest.

I would check this out: https://stackoverflow.com/a/60294052/12403162

Related