<EditInDialogButton>

This Enterprise Edition component offers a way to open an <Edit> view inside a dialog, hence allowing to edit a record without leaving the current view.

It can be useful in case you want the ability to edit a record linked by a reference to the currently edited record, or if you have a nested <Datagrid> inside a <Show> or an <Edit> view.

Note that this component doesn’t use routing, so it doesn’t change the URL. It’s therefore not possible to bookmark the edit dialog, or to link to it from another page. If you need that functionality, use <EditDialog> instead.

Usage

Put <EditInDialogButton> wherever you would put an <EditButton>, and use the same children as you would for an <Edit> component (e.g. a <SimpleForm>):

import {
  Datagrid,
  ReferenceManyField,
  Show,
  SimpleForm,
  SimpleShowLayout,
  TextField,
  TextInput,
} from "react-admin";
import { EditInDialogButton } from "@react-admin/ra-form-layout";

const CompanyShow = () => (
    <Show>
        <SimpleShowLayout>
            <TextField source="name" />
            <TextField source="address" />
            <TextField source="city" />
            <ReferenceManyField target="company_id" reference="employees">
                <Datagrid>
                    <TextField source="first_name" />
                    <TextField source="last_name" />
                    <EditInDialogButton>
                        <SimpleForm>
                            <TextInput source="first_name" />
                            <TextInput source="last_name" />
                        </SimpleForm>
                    </EditInDialogButton>
                </Datagrid>
            </ReferenceManyField>
        </SimpleShowLayout>
    </Show>
);

It accepts the following props:

  • inline: set to true to display only an Material UI <IconButton> instead of the full <Button>. The label will still be available as a <Tooltip> though.
  • icon: allows to override the default icon.
  • label: allows to override the default button label. I18N is supported.
  • ButtonProps: object containing props to pass to Material UI’s <Button>.
  • remaining props will be passed to the <EditDialog> dialog component.

Check out the ra-form-layout documentation for more details.

Combining With <CreateInDialogButton>

Below is an example of an <Edit> view, inside which is a nested <Datagrid>, offering the ability to create, edit and show the rows thanks to <CreateInDialogButton>, <EditInDialogButton> and <ShowInDialogButton>:

import {
  Datagrid,
  DateField,
  DateInput,
  Edit,
  ReferenceManyField,
  required,
  SelectField,
  SelectInput,
  SimpleForm,
  SimpleShowLayout,
  TextField,
  TextInput,
  useRecordContext,
} from "react-admin";
import {
  CreateInDialogButton,
  EditInDialogButton,
  ShowInDialogButton,
} from "@react-admin/ra-form-layout";

const sexChoices = [
  { id: "male", name: "Male" },
  { id: "female", name: "Female" },
];

const CustomerForm = (props) => (
  <SimpleForm defaultValues={{ firstname: "John", name: "Doe" }} {...props}>
    <TextInput source="first_name" validate={required()} fullWidth />
    <TextInput source="last_name" validate={required()} fullWidth />
    <DateInput source="dob" label="born" validate={required()} fullWidth />
    <SelectInput source="sex" choices={sexChoices} fullWidth />
  </SimpleForm>
);

const CustomerLayout = (props) => (
  <SimpleShowLayout {...props}>
    <TextField source="first_name" fullWidth />
    <TextField source="last_name" fullWidth />
    <DateField source="dob" label="born" fullWidth />
    <SelectField source="sex" choices={sexChoices} fullWidth />
  </SimpleShowLayout>
);

// helper component to add actions buttons in a column (children),
// and also in the header (label) of a Datagrid
const DatagridActionsColumn = ({ label, children }) => <>{children}</>;

const NestedCustomersDatagrid = () => {
  const record = useRecordContext();

  const createButton = (
    <CreateInDialogButton
      inline
      fullWidth
      maxWidth="md"
      record={{ employer_id: record?.id }} // pre-populates the employer_id to link the new customer to the current employer
    >
      <CustomerForm />
    </CreateInDialogButton>
  );

  const editButton = (
    <EditInDialogButton fullWidth maxWidth="md">
      <CustomerForm />
    </EditInDialogButton>
  );

  const showButton = (
    <ShowInDialogButton fullWidth maxWidth="md">
      <CustomerLayout />
    </ShowInDialogButton>
  );

  return (
    <ReferenceManyField
      label="Customers"
      reference="customers"
      target="employer_id"
    >
      <Datagrid>
        <TextField source="id" />
        <TextField source="first_name" />
        <TextField source="last_name" />
        <DateField source="dob" label="born" />
        <SelectField source="sex" choices={sexChoices} />
        {/* Using a component as label is a trick to render it in the Datagrid header */}
        <DatagridActionsColumn label={createButton}>
          {editButton}
          {showButton}
        </DatagridActionsColumn>
      </Datagrid>
    </ReferenceManyField>
  );
};

const EmployerEdit = () => (
  <Edit>
    <SimpleForm>
      <TextInput source="name" validate={required()} />
      <TextInput source="address" validate={required()} />
      <TextInput source="city" validate={required()} />
      <NestedCustomersDatagrid />
    </SimpleForm>
  </Edit>
);