Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a button to every row in MUI DataGrid

I cant add a button into every row of MUI DataGrid. I have a MUI DataGrid which I render like this:

<DataGrid rows={rows} columns={columns} pageSize={5} checkboxSelection />

I have added into the columns variable 'actions' column where the button should be. rows are just a a data object I get from the props. how can I add a button into every row (for editing the row)? I have tried mapping the data array but it is not possible to add JSX button into every object of data.

like image 917
Ni Tai Avatar asked Oct 13 '20 08:10

Ni Tai


People also ask

What is renderCell?

The renderCell property is a function that returns a React node, not a React component. If you want to use React hooks inside your renderer, you should wrap them inside a component. // ❌ Not valid const column = { // ...other properties, renderCell: () => { const [count, setCount] = React.

How do I install MUI data grid?

Installation. Using your favorite package manager, install @mui/x-data-grid-pro or @mui/x-data-grid-premium for the commercial version, or @mui/x-data-grid for the free community version. Please note that react >= 17.0.0 and react-dom >= 17.0.0 are peer dependencies.


3 Answers

You can add your custom component by overriding GridColDef.renderCell method and return whatever element you want.

The example below displays an action column that renders a single button in each row. When clicking the button, it alerts the current row data in json string:

const columns: GridColDef[] = [
  { field: "id", headerName: "ID", width: 70 },
  {
    field: "action",
    headerName: "Action",
    sortable: false,
    renderCell: (params) => {
      const onClick = (e) => {
        e.stopPropagation(); // don't select this row after clicking

        const api: GridApi = params.api;
        const thisRow: Record<string, GridCellValue> = {};

        api
          .getAllColumns()
          .filter((c) => c.field !== "__check__" && !!c)
          .forEach(
            (c) => (thisRow[c.field] = params.getValue(params.id, c.field))
          );

        return alert(JSON.stringify(thisRow, null, 4));
      };

      return <Button onClick={onClick}>Click</Button>;
    }
  },
];

Edit 64331095/cant-add-a-button-to-every-row-in-material-ui-table

like image 69
NearHuscarl Avatar answered Oct 18 '22 23:10

NearHuscarl


Just came across this.

What you need to do is include a renderCell method in your columns array.

 const columns = [
    {
        field: 'col1',
        headerName: 'Name 1',
        width: 150,
        disableClickEventBubbling: true,
    },
    {
        field: 'col2',
        headerName: 'Name 2',
        width: 300,
        disableClickEventBubbling: true,
    },
    {
        field: 'col3',
        headerName: 'Name 3',
        width: 300,
        disableClickEventBubbling: true,
    },
    {
        field: 'col4',
        headerName: 'Name 4',
        width: 100,
        disableClickEventBubbling: true,
    },
    {
        field: 'col5',
        headerName: 'Name 5',
        width: 150,
        ***renderCell: renderSummaryDownloadButton,***
        disableClickEventBubbling: true,
    },
    {
        field: 'col6',
        headerName: 'Name 6',
        width: 150,
        ***renderCell: renderDetailsButton,***
        disableClickEventBubbling: true,
    },
]

In the above I am rendering a Button inside columns 5 and 6 which will appear on every populated row.

Above that you can have a function which creates and returns a Button from Material-ui.

 const renderDetailsButton = (params) => {
        return (
            <strong>
                <Button
                    variant="contained"
                    color="primary"
                    size="small"
                    style={{ marginLeft: 16 }}
                    onClick={() => {
                        parseName(params.row.col6)
                    }}
                >
                    More Info
                </Button>
            </strong>
        )
    }
like image 30
Zack Amin Avatar answered Oct 18 '22 22:10

Zack Amin


While @NearHuscarl's response answers the question perfectly, I'd like to post a TypeScript example:

  const onClick = () => {
    const api: GridApi = params.api;
    const fields = api
      .getAllColumns()
      .map((c) => c.field)
      .filter((c) => c !== "__check__" && !!c);
    const thisRow: any = {};

    fields.forEach((f) => {
      thisRow[f] = params.getValue(params.id, f);
    });

    return alert(JSON.stringify(thisRow, null, 4));
  };

  return <Button onClick={onClick}>Click</Button>;

Also note, I changed the getValue call. (included the row id)

like image 7
LuvForAirplanes Avatar answered Oct 18 '22 21:10

LuvForAirplanes