mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
4.07k stars 1.26k forks source link

[datagrid] Add an event that runs after a cell value is updated #10311

Open AnthonyCerdasAnalisis opened 1 year ago

AnthonyCerdasAnalisis commented 1 year ago

Steps to reproduce 🕹

https://codesandbox.io/s/broken-shadow-y6pqj4

  1. Edit a cell, press enter
  2. The console log shows the old value

Expected behavior 🤔

If i update a cell and press enter key, i would like to see the new value, but it is printing the previous one.

Context 🔦

I am using datagrid. When I edit a cell, i need to make some reviews before api request, so i need to see the updated value.

romgrk commented 1 year ago

Please provide a minimal reproduction test case with the latest version. This would help a lot 👷. A live example would be perfect. This codesandbox.io template may be a good starting point. Thank you!

JBernouli commented 1 year ago

onRowEditStop has the same problem.

AnthonyCerdasAnalisis commented 1 year ago

import * as React from 'react';

import { DataGrid, GridCellParams, GridColDef, GridRowsProp } from '@mui/x-data-grid';

const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', width: 70, editable: true }, { field: 'firstName', headerName: 'First Name', width: 150, editable: true }, { field: 'lastName', headerName: 'Last Name', width: 150, editable: true }, { field: 'age', headerName: 'Age', type: 'number', width: 90, editable: true }, ];

const rows: GridRowsProp = [ { id: 1, firstName: 'John', lastName: 'Doe', age: 25 }, { id: 2, firstName: 'Jane', lastName: 'Doe', age: 22 }, { id: 3, firstName: 'Bob', lastName: 'Smith', age: 30 }, ];

const MyDataGrid: React.FC = () => { const handleKeyDown = (params: GridCellParams, event: React.KeyboardEvent) => { if (event.key === 'Enter') {

console.log(`New cell value: ${params.value}`) //This is currently returning the previous value, without return the newest

//The idea is to return the newest value that has been just added. Why would I like to see the last one?

} };

return ( <div style={{ height: 400, width: '100%' }}> <DataGrid rows={rows} columns={columns} onCellKeyDown={(params, event) => handleKeyDown(params, event as React.KeyboardEvent)} />

); };

export default MyDataGrid;

AnthonyCerdasAnalisis commented 1 year ago

import * as React from 'react';

import { DataGrid, GridCellParams, GridColDef, GridRowsProp } from '@mui/x-data-grid';

const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', width: 70, editable: true }, { field: 'firstName', headerName: 'First Name', width: 150, editable: true }, { field: 'lastName', headerName: 'Last Name', width: 150, editable: true }, { field: 'age', headerName: 'Age', type: 'number', width: 90, editable: true }, ];

const rows: GridRowsProp = [ { id: 1, firstName: 'John', lastName: 'Doe', age: 25 }, { id: 2, firstName: 'Jane', lastName: 'Doe', age: 22 }, { id: 3, firstName: 'Bob', lastName: 'Smith', age: 30 }, ];

const MyDataGrid: React.FC = () => { const handleKeyDown = (params: GridCellParams, event: React.KeyboardEvent) => { if (event.key === 'Enter') {

console.log(`New cell value: ${params.value}`) //This is currently returning the previous value, without return the newest

//The idea is to return the newest value that has been just added. Why would I like to see the last one?

} };

return ( <div style={{ height: 400, width: '100%' }}> <DataGrid rows={rows} columns={columns} onCellKeyDown={(params, event) => handleKeyDown(params, event as React.KeyboardEvent)} />

); };

export default MyDataGrid;

romgrk commented 1 year ago

@AnthonyCerdasAnalisis Can you put that code in a codesandbox live example? You have the link in the message right below, it's already set up properly, you just need to insert your code.

Please provide a minimal reproduction test case with the latest version. This would help a lot 👷. A live example would be perfect. This codesandbox.io template may be a good starting point. Thank you!

AnthonyCerdasAnalisis commented 1 year ago

Done, I just added an example in: https://codesandbox.io/s/7tyjsv?file=/demo.tsx
To reproduce the "error", colocate on a cell, edit it, and press enter. Then, see the value that is printed on the console. Prints the old value, not the new value.

MBilalShafi commented 1 year ago

@AnthonyCerdasAnalisis I tried the codesandbox example you provided, but I couldn't see any console output being printed. Seems like you provided the same codesandbox example provided by @romgrk, you have to provide the URL of the new fork generated after you save your changes.

Thank You!

AnthonyCerdasAnalisis commented 1 year ago

Check it here: https://codesandbox.io/s/broken-shadow-y6pqj4

Thank you!

romgrk commented 1 year ago

We don't seem to have an event that runs after the value is updated. I guess this would be a feature request.

JBernouli commented 1 year ago

I don't think that's right Because the onCellEditStop does run after the edit event is done. But it contains the value from before the edit when it runs.

romgrk commented 1 year ago

The cellEditStop event is the internal event that we use to handle a cell edit stop event. So the cell value is modified by the event handler that responds to that event, but that modification is done asynchronously. Technically, the name is cellEditStop so it makes sense that it runs when the cell edit stops but not necessarily when the cell value is modified. I don't think that event should have been exposed because it probably doesn't do what people want it to do. But we can't modifiy it now to have a different behavior, that would be semver-breaking. That's why I think this is a feature request, we need a new event that runs after a cell has been modified.

@mui/xgrid Thoughts?

michelengelen commented 1 year ago

The cellEditStop event is the internal event that we use to handle a cell edit stop event. So the cell value is modified by the event handler that responds to that event, but that modification is done asynchronously. Technically, the name is cellEditStop so it makes sense that it runs when the cell edit stops but not necessarily when the cell value is modified. I don't think that event should have been exposed because it probably doesn't do what people want it to do. But we can't modifiy it now to have a different behavior, that would be semver-breaking. That's why I think this is a feature request, we need a new event that runs after a cell has been modified.

@mui/xgrid Thoughts?

This makes perfect sense. The separation between cellEditStop and cellValueChange (named only to have one for now) makes perfect sense as well. There are definitely use-cases for both events to be handled separately, so I would also say that this is a feature request.

JBernouli commented 1 year ago

In the meanwhile is there anyway I can get the current value at the row using the index that editStop provides? This could be a good temporary work around?

AnthonyCerdasAnalisis commented 1 year ago

Currently, I am using the "processRowUpdate" function that receives as parameters the old row and the new row. Thanks to this, I can identify which value has changed and in which cell the change occurred. However, a drawback arises when no changes are made, as it is impossible to determine which cell was currently being worked on. There is a functionality gap when the editing mode is per cell.

romgrk commented 1 year ago

However, a drawback arises when no changes are made, as it is impossible to determine which cell was currently being worked on.

Can't you use onCellEditStop for the case where there is no update? What's your use-case and what are you trying to do?

AnthonyCerdasAnalisis commented 1 year ago

Can't you use onCellEditStop for the case where there is no update? What's your use-case and what are you trying to do?

I try the following: 1) Get the new value from cell 2) Get in which cell the change was made. 3) In case of not making any changes, obtain which cell was being edited or in edit mode.

onCellEditStop is used to know the cell, but the value remains the previous one, without showing me the new value.

onRowProcess allows me to see the value and cell, as long as the field is updated. For that reason, onCellEditStop does not help me to perform the whole process. Check it out here: https://codesandbox.io/s/trusting-ives-m8w6sq

romgrk commented 12 months ago

Can you describe the use-case you're trying to fullfill? Not what the code is doing.

Cnordbo commented 9 months ago

Hi, We are currently looking for this feature.

Use case: We have a DataGrid that will default to "edit" mode, which shows all rows in an editable state. Its a Datascience tool, so we want to visually display that it consists of input fields that is ment to be changed. Like a form usually is. The row should never leave the "edit" state.

I can not find any event that would allow me to retrieve the current row values, or any event that triggers after an edit has been made.

romgrk commented 9 months ago

@Cnordbo I would advise to forget about the edit mode and instead simply use renderCell and updateRows. It also won't be possible to use the MUI TextField, as it's too heavy to render that many of them. You should have your .renderCell methods return a simple input element. You don't need an event for this, the value is provided in the params of .renderCell.

If you require further assistance open a separate issue as your use-case doesn't seem strictly related to this feature request.

maxbraeutigam commented 3 months ago

+1