Material-table - if no data show message
Asked Answered
C

3

7

I am using material-table https://material-table.com/#/docs/get-started. However I can't seem to find any information about showing a default message if no data is returned?

I am wondering if anyone knows how I would go about this. Below is the test table I have created (with fake data). Now if that data is empty I want a message to show where the table data would be saying "create your ad now", with a button.

import React from 'react';
import { forwardRef } from 'react';
import MaterialTable from 'material-table';
import AddBox from '@material-ui/icons/AddBox';
import ArrowDownward from '@material-ui/icons/ArrowDownward';
import Check from '@material-ui/icons/Check';
import ChevronLeft from '@material-ui/icons/ChevronLeft';
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 FirstPage from '@material-ui/icons/FirstPage';
import LastPage from '@material-ui/icons/LastPage';
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';

export default function MaterialTableDemo() {

    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) => <FirstPage {...props} ref={ref} />),
        LastPage: forwardRef((props, ref) => <LastPage {...props} ref={ref} />),
        NextPage: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
        PreviousPage: forwardRef((props, ref) => <ChevronLeft {...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 columns = {columns: [
        { title: 'Ad Name', field: 'name' },
        { title: 'Status', field: 'status' },
        { title: 'Formate', field: 'formate'},
        { title: 'Cost Type', field: 'costtype'},
        { title: 'Ad Listens', field: 'adlistens',  type: "numeric" },
        { title: 'Ads Served', field: 'adserved',  type: "numeric" },
        { title: 'Budget', field: 'budget',  type: "numeric" },
        { title: 'End Date', field: 'enddate',  type: "date" },
       
      ]};
   
  const data = { data: [
    { name: 'Test Ad', status: 'Pending', formate: 'Radio/Podcast', costtype: 'PPL', adlistens:0, adserved:0, budget:'$100', enddate:'02-02-2025' },
    { name: 'ZTest Ad', status: 'Pending', formate: 'Radio/Podcast', costtype: 'PPL', adlistens:0, adserved:0, budget:'$100', enddate:'02-05-2025' },
    { name: 'DTest Ad', status: 'Pending', formate: 'Radio/Podcast', costtype: 'PPL', adlistens:0, adserved:0, budget:'$100', enddate:'02-01-2025' },
  
]};

  
  return (
    <div style={{ maxWidth: "90%", margin:'5vh auto' }}>
    <MaterialTable
      title="Your Ads"
      icons={tableIcons}
      columns={columns.columns}
      data={data.data}
      /*editable={{
        onRowAdd: (newData) =>
          new Promise((resolve) => {
            setTimeout(() => {
              resolve();
              setState((prevState) => {
                const data = [...prevState.data];
                data.push(newData);
                return { ...prevState, data };
              });
            }, 600);
          }),
        onRowUpdate: (newData, oldData) =>
          new Promise((resolve) => {
            setTimeout(() => {
              resolve();
              if (oldData) {
                setState((prevState) => {
                  const data = [...prevState.data];
                  data[data.indexOf(oldData)] = newData;
                  return { ...prevState, data };
                });
              }
            }, 600);
          }),
        onRowDelete: (oldData) =>
          new Promise((resolve) => {
            setTimeout(() => {
              resolve();
              setState((prevState) => {
                const data = [...prevState.data];
                data.splice(data.indexOf(oldData), 1);
                return { ...prevState, data };
              });
            }, 600);
          }),
      }}*/
    />
    </div>
  );
}
Carrelli answered 8/8, 2020 at 2:20 Comment(1)
a minimal reproducible example on codesandbox will be better for other to catch up with your problemNonesuch
T
1

You'll need to use material table's component overriding to achieve this. Here's an example of overriding the body to put a button in the table (I didn't add any CSS so it's ugly).

https://codesandbox.io/s/goofy-moore-h2fkg?file=/src/Table.jsx

Toothy answered 8/8, 2020 at 3:26 Comment(3)
But what about the if statement I take it I need one of those?Carrelli
Do you mean you want the table to do something like if data { show data } else { show button }? If so, I'm sure there's a more elegant way of doing this, but this is the best I can come up with right now. Basically create a function that has the if statement. If data, display table with data. Else, display table with the button. codesandbox.io/s/hungry-leftpad-hmnye?file=/src/Table.jsxToothy
thank you so very much. I don't understand why the developer of this plugin has not made it easier to do this.Carrelli
H
8

You could achieve this with a more elegant way, by using the localization prop like this:

<MaterialTable
    localization={{
        body: {
            emptyDataSourceMessage: (
                <Button color="primary" className={classes.button}>
                    Create your ad now
                </Button>
            ),
        },
    }}
    {...otherProps}
/>;

Hillary answered 17/11, 2020 at 14:57 Comment(5)
As a note for those that came after -- if you pass 'undefined' into the data prop, then this applies. if you pass anything esle (null, etc), you will get an error.Clive
It is saying only string can be passed to emptyDataSourceMessagePerceivable
@PrathameshMore do you mean Typescript is complaining?Hillary
Yeah, TypeScript is complaining @HillaryPerceivable
The material-table library is quite abandoned and types are not always correct. You can just put // @ts-ignore comment on top and that should do it.Hillary
T
1

You'll need to use material table's component overriding to achieve this. Here's an example of overriding the body to put a button in the table (I didn't add any CSS so it's ugly).

https://codesandbox.io/s/goofy-moore-h2fkg?file=/src/Table.jsx

Toothy answered 8/8, 2020 at 3:26 Comment(3)
But what about the if statement I take it I need one of those?Carrelli
Do you mean you want the table to do something like if data { show data } else { show button }? If so, I'm sure there's a more elegant way of doing this, but this is the best I can come up with right now. Basically create a function that has the if statement. If data, display table with data. Else, display table with the button. codesandbox.io/s/hungry-leftpad-hmnye?file=/src/Table.jsxToothy
thank you so very much. I don't understand why the developer of this plugin has not made it easier to do this.Carrelli
S
0

Material table has built in functionality for this:

In options object you can add the showEmptyDataSourceMessage: true property that will enable a default message saying: "No records to display" if the data is missing and the table is empty.

Shaunshauna answered 16/1, 2022 at 20:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.