Skip to content

Data grid - Editing (legacy)

The data grid has built-in edit capabilities that you can customize to your needs.

Cell editing

To enable cell editing within a column, set the editable property in the GridColDef object to true to allow editing cells of this column.

<DataGrid columns={[{ field: 'name', editable: true }]} />
Name
Age
Date Created
Last Login
Pauline Lawson
25
11/15/2024
3/28/2025, 4:22:43 PM
Randall Rowe
36
8/24/2024
3/29/2025, 6:25:11 AM
Mason Reid
19
9/12/2024
3/28/2025, 11:13:49 PM
Austin Burgess
28
2/26/2025
3/28/2025, 7:48:16 PM
Carl Bates
23
7/19/2024
3/29/2025, 8:46:43 AM

Rows per page:

1–5 of 5

Start editing

If a cell is editable and has focus, any of the following interactions will start the edit mode:

  • A Enter keydown

  • A Backspace or Delete keydown. It will also delete the value and stops the edit mode instantly.

  • A keydown of any printable key, for instance a, E, 0, or $

  • A double click on the cell

  • A call to apiRef.current.setCellMode(id, field, 'edit').

    /**
      * Set the cellMode of a cell.
      * @param GridRowId
      * @param string
      * @param 'edit' | 'view'
      */
    setCellMode: (id: GridRowId, field: string, mode: GridCellMode) => void;
    

Stop editing

If a cell is in edit mode and has focus, any of the following interactions will stop the edit mode:

  • A Escape keydown. It will also roll back changes done in the value of the cell.
  • A Tab keydown. It will also save and goes to the next cell on the same row.
  • A Enter keydown. It will also save and goes to the next cell on the same column.
  • A mousedown outside the cell
  • A call to apiRef.current.setCellMode(id, field, 'view').

Control cell editability

In addition to the editable flag on columns, you can enable or disable editing of individual cells using the isCellEditable prop.

In this demo, only the rows with an even Age value are editable. The editable cells have a green background for better visibility.

Name
Age
Date Created
Last Login
Allen Dunn
25
2/2/2025
3/28/2025, 8:49:17 PM
Rosa Erickson
36
7/3/2024
3/29/2025, 10:57:58 AM
Margaret Griffin
19
11/7/2024
3/28/2025, 4:57:58 PM
Eugene Horton
28
12/5/2024
3/28/2025, 6:51:29 PM
Steve Caldwell
23
1/2/2025
3/29/2025, 10:28:23 AM

Rows per page:

1–5 of 5

Press Enter to start editing

Controlled editing

The editRowsModel prop lets you control the editing state. You can use the onEditRowsModelChange callback to control the GridEditRowsModel state.

Name
Age
Date Created
Last Login
Cora Webb
25
2/21/2025
3/29/2025, 2:31:20 AM
Minerva Roberson
36
5/9/2024
3/28/2025, 4:44:25 PM
Lottie Rowe
19
6/20/2024
3/28/2025, 6:56:49 PM
Steve Barber
28
6/24/2024
3/29/2025, 8:12:32 AM
Kevin Elliott
23
4/21/2024
3/28/2025, 3:59:56 PM

Rows per page:

1–5 of 5

Saving nested structures

If you are using a valueGetter to extract the value from a nested object, then you must also provides a valueSetter. The valueGetter receives the row object and must return the value to be displayed in the cell. The valueSetter, in turn, receives the new value and returns the updated row.

The following demo shows how these two functions can be used:

First name
Last name
Full name
Jon
Snow
Jon Snow
Cersei
Lannister
Cersei Lannister
Jaime
Lannister
Jaime Lannister
Arya
Stark
Arya Stark
Daenerys
Targaryen
Daenerys Targaryen

Rows per page:

1–5 of 5

Press Enter to start editing

Calling the valueSetter is the last step in the saving process. The validation will still be called with the values before they pass through the setter.

Client-side validation

To validate the value of a cell, add the preProcessEditCellProps callback to the column definition of the field you wish to validate. Once it is called, you can validate the value provided in params.props.value. Then, return a new object containing params.props along with error attribute set to true or false. If the error attribute is true, the value will never be committed.

const columns: GridColDef[] = [
  {
    field: 'firstName',
    preProcessEditCellProps: (params: GridPreProcessEditCellProps) => {
      const hasError = params.props.value.length < 3;
      return { ...params.props, error: hasError };
    },
  },
];

Here is an example implementing an email validation:

No rows
Name
Email
Date Created
Last Login

Rows per page:

0–0 of 0

Press Enter to start editing

Alternatively, you can use the GridEditRowsModel state mentioned in the Controlled editing section. However, one limitation of this approach is that it does not work with the singleSelect column type.

Server-side validation

Server-side validation works like client-side validation. The only difference is that when you call preProcessEditCellProps, you must return a promise. Once the value is validated in the server, the promise should be resolved with a new object containing the error attribute set to true or false. The grid will wait for the promise to be resolved before exiting the edit mode.

By default, preProcessEditCellProps is called on each value change and during commit. With column types that automatically commit the value after a selection (e.g. singleSelect) this means that the callback will be called twice and with the wrong value in the second call. To avoid this inconsistency, enable the preventCommitWhileValidating flag available in the experimental features.

<DataGrid experimentalFeatures={{ preventCommitWhileValidating: true }} />

It's labeled as experimental because in v6 this flag will become the default behavior.

This demo shows how you can validate a username asynchronously and prevent the user from committing the value while validating. It's using DataGridPro but the same approach can be used with DataGrid.

MUI Contributor
Damien
Olivier
Danail
Matheus
You?
Total Rows: 5

Server-side persistence

If you want to send the updated data to your server, you can use the onCellEditCommit which is fired just before committing the new cell value to the grid.

You can then decide if you want to send the whole row or only the modified fields.

Name
Age
Date Created
Last Login
Leon Hansen
25
12/9/2024
3/29/2025, 6:19:49 AM
Bertha Rodriquez
36
2/5/2025
3/29/2025, 7:50:40 AM
Jeanette Shelton
19
12/10/2024
3/29/2025, 9:09:26 AM
Lucille Morrison
28
1/19/2025
3/29/2025, 11:35:52 AM
Eric Figueroa
23
10/25/2024
3/28/2025, 4:23:20 PM
Total Rows: 5

Custom edit component

To customize the edit component of a column, use the renderEditCell attribute available in the GridColDef.

The demo lets you edit the ratings by double-clicking the cell.

Places
Rating
Barcelona
Rio de Janeiro
London
New York

Rows per page:

1–4 of 4

Edit using external button

You can override the default start editing triggers using the event.defaultMuiPrevented on the synthetic React events.

Name
Age
Date Created
Last Login
Carl Washington
25
1/7/2025
3/29/2025, 4:51:01 AM
Hettie Murray
36
4/19/2024
3/29/2025, 12:37:44 PM
Keith Hart
19
9/13/2024
3/28/2025, 5:03:10 PM
Lucinda Richards
28
11/20/2024
3/29/2025, 8:53:38 AM
Henry Franklin
23
12/7/2024
3/28/2025, 4:51:34 PM
Total Rows: 5

Events

The editing feature leverages the event capability of the grid and the apiRef. You can import the following events to customize the editing experience:

  • cellEditStart: triggered when a cell enters edit mode.
  • cellEditStop: triggered when a cell returns to view mode.
  • cellEditCommit: triggered when a new value is committed.
  • editCellPropsChange: triggered when a props passed to the edit cell component are changed.

You can use event catching to add a callback after an event while ignoring its triggers.

The demo shows how to catch the start and end edit events in order to log which cell has been edited in an info message:

Name
Age
Date Created
Last Login
Tyler Flores
25
1/29/2025
3/28/2025, 11:37:25 PM
Total Rows: 1
Press Enter to start editing

Row editing

Row editing lets you edit all cells in a given row simultaneously. It supports most of the same features as those available for cell editing. To enable it, change the edit mode to "row" using the editMode prop, then set to true the editable property in the GridColDef object of those columns that should be editable.

<DataGrid editMode="row" columns={[{ field: 'name', editable: true }]} />
Name
Age
Date Created
Last Login
Mabel Gonzalez
25
6/8/2024
3/28/2025, 7:13:12 PM
Ryan Goodman
36
12/27/2024
3/28/2025, 7:00:14 PM
Olive Reeves
19
5/21/2024
3/29/2025, 1:12:42 PM
Elmer Price
28
10/4/2024
3/28/2025, 9:05:17 PM
Cody Mathis
23
8/25/2024
3/29/2025, 9:25:49 AM

Rows per page:

1–5 of 5

Start editing

You can start editing a cell using any of the following interactions:

  • A Enter keydown

  • A double click on the cell

  • A call to apiRef.current.setRowMode(id, 'edit').

    /**
      * Sets the mode of a row.
      * @param {GridRowId} id The id of the row.
      * @param {GridRowMode} mode Can be: `"edit"`, `"view"`.
      */
    setRowMode: (id: GridRowId, mode: GridRowMode) => void;
    

Stop editing

You can stop editing a cell using any of the following interactions:

  • A Escape keydown. This will also roll back any changes made to the row.
  • A Enter keydown. This will also save the value and move the focus to the cell in the next row of the same column.
  • A mouse click outside the row
  • A call to apiRef.current.setRowMode(id, 'view').

Controlled editing

The editRowsModel prop lets you control the editing state. You can handle the onEditRowsModelChange callback to control the GridEditRowsModel state.

Name
Age
Date Created
Last Login
Jayden Barber
25
10/4/2024
3/29/2025, 3:59:42 AM
Dustin Barnett
36
4/9/2024
3/29/2025, 2:11:42 AM
Seth Barber
19
8/23/2024
3/29/2025, 11:50:11 AM
Seth Russell
28
8/4/2024
3/28/2025, 5:28:37 PM
Mamie Henry
23
3/14/2025
3/29/2025, 8:55:54 AM

Rows per page:

1–5 of 5

Conditional validation

Having all cells of a row in edit mode allows validating a field based on the value of another one To do this, you will first need to add a preProcessEditCellProps callback to the column definition. When all cells in a row are in edit mode, you can validate fields by comparing their values. Return a new object contaning params.props and the error attribute with the validation status. Once at the least one field has the error attribute equals to true no new value will be committed.

The following demo requires a value for the Payment method column if the Is paid? column is checked.

Expense
Price
Due at
Is paid?
Payment method
Light bill
600.41
7/8/2021
no
Rent
884.78
8/1/2021
no
Car insurance
634.39
8/4/2021
yes
Wire transfer
Total Rows: 3

The conditional validation can also be implemented with the controlled editing. This approach can be used in the free version of the DataGrid. The only limitation is that it does not work with the singleSelect column type.

Control with external buttons

You can disable the default behavior of the grid and control the row edit using external buttons.

Here is how you can create a full-featured CRUD:

Name
Age
Date Created
Last Login
Actions
Nettie Hoffman
25
8/3/2024
3/28/2025, 6:36:56 PM
Lilly Roberts
36
4/5/2024
3/29/2025, 11:48:49 AM
Lily Pena
19
3/29/2025
3/28/2025, 3:38:07 PM
Norman Adams
28
6/20/2024
3/28/2025, 4:21:41 PM
Martha Grant
23
4/13/2024
3/28/2025, 7:01:32 PM
Total Rows: 5
Press Enter to start editing

Saving rows with nested structures

You can save columns that make use of valueGetter by adding a valueSetter. The same approach from the cell editing mode can be used here. Note that the valueSetter will be called for each field.

Server-side persistence

If you want to send the updated data to your server, you can use onRowEditCommit which is fired just before committing the new cell value to the grid.

To access the new values for the row, use apiRef.current.getEditRowsModel to enable edit mode on all rows, then use the ID provided to get only the values for the row that was committed.

You can then decide if you want to send the whole row or only the modified fields by checking them against the previous row values.

Name
Age
Date Created
Last Login
Lenora Walsh
25
5/13/2024
3/28/2025, 10:22:31 PM
Martha Hill
36
4/9/2024
3/29/2025, 2:25:48 AM
Ora Underwood
19
6/28/2024
3/28/2025, 9:39:53 PM
Maude Wood
28
6/24/2024
3/28/2025, 6:26:16 PM
Calvin Perry
23
2/13/2025
3/28/2025, 7:20:58 PM
Total Rows: 5

Events

You can import the following events to customize the editing experience:

  • rowEditStart: triggered when a row enters edit mode.
  • rowEditStop: triggered when a row returns to view mode.
  • rowEditCommit: triggered when new row values are committed.
  • editCellPropsChange: triggered when the props passed to the edit cell component are changed.

apiRef

Signature:
commitCellChange: (params: GridCommitCellChangeParams, event?: MuiBaseEvent) => boolean | Promise<boolean>
Signature:
commitRowChange: (id: GridRowId, event?: MuiBaseEvent) => boolean | Promise<boolean>
Signature:
getCellMode: (id: GridRowId, field: string) => GridCellMode
Signature:
getEditRowsModel: () => GridEditRowsModel
Signature:
getRowMode: (id: GridRowId) => GridRowMode
Signature:
isCellEditable: (params: GridCellParams) => boolean
Signature:
setCellMode: (id: GridRowId, field: string, mode: GridCellMode) => void
Signature:
setEditCellValue: (params: GridEditCellValueParams, event?: MuiBaseEvent) => Promise<boolean> | void
Signature:
setEditRowsModel: (model: GridEditRowsModel) => void
Signature:
setRowMode: (id: GridRowId, mode: GridRowMode) => void