Search code examples
javascriptcssreactjsmaterial-table

How can I add/override Footer component in React material-table?


I'm using react material-table. I'm having trouble in adding/overriding default footer component. By default, pagination component is rendered in footer. So, I tried overriding Pagination component to make it a simple footer like this

<MaterialTable
    // other props
    options={{           
            search: true,
            selection: true,
            sorting: true,
            actionsColumnIndex: -1,
            paging: false,   // true cause the rows truncation... i.e., paging anabled.
            showSelectAllCheckbox: true,
            toolbarButtonAlignment: "right",
            searchFieldAlignment: "right",
            searchAutoFocus: true,
            tableLayout:"auto",
            headerStyle: {              
              fontSize: "small"
            }
          }}
    components={{
            .
            .
            .
            .
            Pagination: props =>(
              <div>
                <h4>{"Total Users: " + users.length}</h4>                
              </div>
            )
            
          }}
/>

I don't want pagination at all as I'm using scrollbar as mentioned in this SO thread. So, in my case options.paging:false but I have to make it true to show up my overridden pagination/footer component. But making it true enable paging under the hood and rows after 6 are truncated.

I want to remove pagination and place a custom footer component. Let's say a span showing the total rows count at the table bottom. <span>{"Total Users: " + users.length}</span>

Material-table is Great! but I'm surprised why material-table don't have a footer component? If it's based on material-ui, it should have a footer component as material-ui table have it.


Solution

  • If you want to override pagination's icons and add your custom, you can install @material-ui/icons.

    npm i --save @material-ui/icons.

    Then you can override pagination without removing your scroll in this way:

    import React, { forwardRef } from 'react';
    
    import MaterialTable, { MTableToolbar, MTableBody, MTableHeader } from 'material-table';
    
    import { Grid, TablePagination } from '@material-ui/core';
    import { Scrollbars } from 'react-custom-scrollbars';
    
    import AddBox from '@material-ui/icons/AddBox';
    import ArrowDownward from '@material-ui/icons/ArrowDownward';
    import Check from '@material-ui/icons/Check';
    import ChevronRight from '@material-ui/icons/ChevronRight';
    import Clear from '@material-ui/icons/Clear';
    import DeleteOutline from '@material-ui/icons/DeleteOutline';
    import Edit from '@material-ui/icons/Edit';
    import FilterList from '@material-ui/icons/FilterList';
    import Remove from '@material-ui/icons/Remove';
    import SaveAlt from '@material-ui/icons/SaveAlt';
    import Search from '@material-ui/icons/Search';
    import ViewColumn from '@material-ui/icons/ViewColumn';
    import ArrowForward from '@material-ui/icons/ArrowForward';
    import ArrowBack from '@material-ui/icons/ArrowBack';
    import Bathtub from '@material-ui/icons/Bathtub';
    import BatteryCharging20 from '@material-ui/icons/BatteryCharging20';
    
    const tableIcons = {
      Add: forwardRef((props, ref) => <AddBox {...props} ref={ref} />),
      Check: forwardRef((props, ref) => <Check {...props} ref={ref} />),
      Clear: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
      Delete: forwardRef((props, ref) => <DeleteOutline {...props} ref={ref} />),
      DetailPanel: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
      Edit: forwardRef((props, ref) => <Edit {...props} ref={ref} />),
      Export: forwardRef((props, ref) => <SaveAlt {...props} ref={ref} />),
      Filter: forwardRef((props, ref) => <FilterList {...props} ref={ref} />),
      FirstPage: forwardRef((props, ref) => <BatteryCharging20 {...props} ref={ref} />),
      LastPage: forwardRef((props, ref) => <Bathtub {...props} ref={ref} />),
      NextPage: forwardRef((props, ref) => <ArrowForward {...props} ref={ref} />),
      PreviousPage: forwardRef((props, ref) => <ArrowBack {...props} ref={ref} />),
      ResetSearch: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
      Search: forwardRef((props, ref) => <Search {...props} ref={ref} />),
      SortArrow: forwardRef((props, ref) => <ArrowDownward {...props} ref={ref} />),
      ThirdStateCheck: forwardRef((props, ref) => <Remove {...props} ref={ref} />),
      ViewColumn: forwardRef((props, ref) => <ViewColumn {...props} ref={ref} />)
    };
    
    const renderThumb = ({ style, ...props }) => {
      const thumbStyle = {
        borderRadius: 6,
        backgroundColor: 'rgba(35, 49, 86, 0.8)'
      };
      return <div style={{ ...style, ...thumbStyle }} {...props} />;
    };
    
    const CustomScrollbars = props => (
      <Scrollbars
        renderThumbHorizontal={renderThumb}
        renderThumbVertical={renderThumb}
        {...props}
      />
    );
    
    export default function App() {
    
      return (
    
        <MaterialTable
    
          options={{
            search: true,
            paging: false,
            toolbarButtonAlignment: "left",
            searchAutoFocus: true,
            cellStyle: { minWidth: '100px', maxWidth: '100px' },
          }}
          title="Toolbar Overriding Preview"
          columns={[
            { title: 'Name', field: 'name' },
            { title: 'Surname', field: 'surname' },
            { title: 'Birth Year', field: 'birthYear', type: 'numeric' },
            { title: 'Birth City', field: 'birthCity', type: 'numeric' }
          ]}
          data={[
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
          ]}
          localization={{
            pagination: {
              labelDisplayedRows: '{from}-{to} of {count} rows',
              labelRowsSelect: 'Custom Label Rows Select',
              labelRowsPerPage: 'Custom Label Rows Per Page',
              firstAriaLabel: 'Custom First Page Label',
              firstTooltip: 'Custom First Page Tooltip',
              previousAriaLabel: 'Custom Previous Page Label',
              previousTooltip: 'Custom Previous Page Tooltip',
              nextAriaLabel: 'Custom Next Pabe',
              nextTooltip: 'Custom Next Page Tooltip',
              lastAriaLabel: 'Custom Last Page Label',
              lastTooltip: 'Custom Last Page Tooltip'
            },
          }}
          icons={tableIcons}
          components={{
            Toolbar: props => {
              // This will let you use your own Title while keeping the search
              const propsCopy = { ...props };
              // Hide default title
              propsCopy.showTitle = false;
              return (
                <Grid container direction="row">
                  <Grid item xs={6}>
                    <h2>Your Own Title</h2>
                  </Grid>
                  <Grid item xs={6}>
                    <MTableToolbar {...propsCopy} />
                  </Grid>
                </Grid>
              );
            },
            Body: props => {
    
              return (
                <div>
                  <CustomScrollbars style={{ height: '250px' }}>
                    <MTableBody {...props} />
    
                  </CustomScrollbars>
    
                  <h2 style={{
                    textAlign: "center"
                  }}>Custom Footer</h2>
                </div>
    
              )
            },
            Header: props => (
              <div>
                <MTableHeader {...props} />
              </div>
            ),
            // Pagination: props => (
            //   <TablePagination
            //     {...props}
            //     rowsPerPageOptions={[]}
            //     rowsPerPage={7}
            //   />
            // )
          }}
        />
      )
    }