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.17k stars 1.3k forks source link

[data grid] Disable submit button if DataGrid is in edit mode #14827

Open alejandrolm96 opened 3 weeks ago

alejandrolm96 commented 3 weeks ago

Related page

https://mui.com/material-ui/

Kind of issue

Unclear explanations

Issue description

Disabling a Button During DataGrid "Edit" Mode

Context

Hi, not sure if I'm posting this in the right section.

I’m working with a DataGrid component in ReactJS and have a "Submit" button below the table for submitting data. I would like to disable this button whenever the DataGrid is in "Edit" mode. Specifically:

Example:

image001

I have read the documentation but I could not find any possible solution for this.

Search keywords: datagrid

Search keywords:

michelengelen commented 3 weeks ago

Hey @alejandrolm96 ... this can be done using the event callbacks we provide as props:

Here is an example of it:

export default function DisableStopEditModeOnFocusOut() {
  const [isEditing, setIsEditing] = React.useState(false);
  const toggleIsEditing = () => {
    setIsEditing((prev) => !prev);
  };
  return (
    <>
      <div style={{ height: 300, width: '100%' }}>
        <DataGrid
          rows={rows}
          columns={columns}
          onCellEditStop={toggleIsEditing}
          onCellEditStart={toggleIsEditing}
        />
      </div>
      <Button disabled={isEditing}>Submit</Button>
    </>
  );
}
alejandrolm96 commented 3 weeks ago

@michelengelen

Thanks for your reply, I will try it, Thanks!

github-actions[bot] commented 2 weeks ago

The issue has been inactive for 7 days and has been automatically closed.

alejandrolm96 commented 1 week ago

Hi, how can I re-open this issue?

alejandrolm96 commented 1 week ago

@michelengelen Hi,

I tested what you mentioned above, and it successfully disables the button. However, I'm not sure how to handle errors properly.

For example, I have a constant variable called columns, and one of the columns uses preProcessEditCellProps to manage errors for a specific field. The issue is that when an error occurs, the button remains enabled.

Additionally, if there is an error in that field, clicking away from the cell does not exit edit mode; the cell remains in edit mode.

const columns: GridColDef[] = [
... other columns
{
      flex: 1,
      align: 'right',
      headerAlign: 'right',
      editable: true,
      type: 'number',
      cellClassName: (params) => {
        const { value, waterQualityTypeId } = params.row;

        const hasError = hasValueError(value, waterQualityTypeId);

        return hasError ? 'cell--warning' : '';
      },
      preProcessEditCellProps: (params: GridPreProcessEditCellProps) => {
        const { value } = params.props;
        const waterQualityTypeId = params.row.waterQualityTypeId;
        const error = hasValueError(value, waterQualityTypeId);

        return { ...params.props, error };
      },
    },
  ] as GridColDef[];

Example video:

https://github.com/user-attachments/assets/4dbd1351-4aec-4983-97b7-d2aa662dc624

As you can see, the error occurs because I have a validation that requires the number to be less than or equal to 20. The goal is to catch this error and disable the button when the validation fails.

michelengelen commented 1 week ago

Hey @alejandrolm96 ... the cell not exiting the edit mode is expected when it got validated with an error. Not sure if we can opt out of that ... @arminmeh?

The other part is a bit harder to do. Your best (but probably perf wise worst) shot would be to introduce a new state (hasError) and set it every time you call preProcessEditCellProps. Example:

// e.g. on `colDef.type === 'number'`
preProcessEditCellProps: (params: GridPreProcessEditCellProps) => {
  const { value } = params.props;
  const error = value < 10;

  setHasError(error);

  return { ...params.props, error };
},

With this you can then update your toggleIsEditing function:

const toggleIsEditing = () => {
  setDisabledButton((prev) => hasError || !prev);
};
michelengelen commented 1 week ago

Ideal would be if we could somehow get the current state of the cell in edit mode from the grid and determine it that way ... can we support something like this @arminmeh?

michelengelen commented 6 days ago

@MBilalShafi do you have any idea how we could implement something like this?

arminmeh commented 6 days ago

the cell not exiting the edit mode is expected when it got validated with an error. Not sure if we can opt out of that

if there is an error, edit state will not be updated (mentioned here as well)

since the requirement is that the submit button changes the state while user is changing the value, I would suggest to customize the edit component and add onChange listeners which will update the error state that will be used by the submit button

would this work @alejandrolm96