Material-table: Dependent columns

Created on 23 May 2019  路  23Comments  路  Source: mbrn/material-table

Hello,

First thank you for your great work :)

I'm interested if it's possible to change the value of a column based on another one. An example: let's say i have 2 columns, A and B, both dropdowns. I would like that the options available in column B change depending on what i select in column A.

I tried using the editComponent and props.rowData, but this rowData doesn't seem to update according to the changes. The values in it are the same from the moment you enter edit mode. So if i change the value in column A, it doesn't update the rowData.

Thank you

bug help wanted

Most helpful comment

After upgrading to version 1.39.0 when start row edit, in browser console it generate warning:

index.js:1437 Warning: Unknown event handler property `onRowDataChange`. It will be ignored.
    in div (created by ForwardRef(FormControl))
    in ForwardRef(FormControl) (created by WithStyles(ForwardRef(FormControl)))
    in WithStyles(ForwardRef(FormControl)) (created by ForwardRef(TextField))
    in ForwardRef(TextField) (created by WithStyles(ForwardRef(TextField)))
    in WithStyles(ForwardRef(TextField)) (created by MTableEditField)
    in MTableEditField (created by MTableEditRow)
    in td (created by ForwardRef(TableCell))
    in ForwardRef(TableCell) (created by WithStyles(ForwardRef(TableCell)))
    in WithStyles(ForwardRef(TableCell)) (created by MTableEditRow)
    in tr (created by ForwardRef(TableRow))
    in ForwardRef(TableRow) (created by WithStyles(ForwardRef(TableRow)))
    in WithStyles(ForwardRef(TableRow)) (created by MTableEditRow)
    in MTableEditRow (created by MTableBody)
    in tbody (created by ForwardRef(TableBody))
    in ForwardRef(TableBody) (created by WithStyles(ForwardRef(TableBody)))
    in WithStyles(ForwardRef(TableBody)) (created by MTableBody)
    in MTableBody (created by Droppable)
    in table (created by ForwardRef(Table))
    in ForwardRef(Table) (created by WithStyles(ForwardRef(Table)))
    in WithStyles(ForwardRef(Table)) (created by Droppable)
    in div (created by Droppable)
    in div (created by Droppable)
    in Droppable (created by ConnectFunction)
    in ConnectFunction
    in ConnectFunction (created by MaterialTable)
    in div (created by ScrollBar)
    in ScrollBar (created by MaterialTable)
    in div (created by ForwardRef(Paper))
    in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper)))
    in WithStyles(ForwardRef(Paper)) (created by Container)
    in Container (created by MaterialTable)
    in Provider (created by App)
    in App (created by ErrorBoundary)
    in ErrorBoundary (created by DragDropContext)
    in DragDropContext (created by MaterialTable)
    in MaterialTable
    in Unknown (created by WithStyles(Component))
    in WithStyles(Component) (at Applications/index.tsx:116)
    in div (at Applications/index.tsx:114)
    in ApplicationsComponent (created by WithStyles(ApplicationsComponent))
    in WithStyles(ApplicationsComponent) (created by Context.Consumer)
    in Route (created by PrivateRoute)
    in PrivateRoute (at App.tsx:65)
    in Switch (at App.tsx:57)
    in Router (created by BrowserRouter)
    in BrowserRouter (at App.tsx:48)
    in App (at src/index.tsx:12)

All 23 comments

I've figured it out. In case anybody is interested: in the onChange of my custom select defined for the editComponent of column A, i check the selected value and then update the state accordingly for the lookup of column B. Maybe no the best solution, but it works for my case :)

Hi, sorry, i'm still having problems with this for some cases. For example, if i have column A as dropdown and column B as a text field. Depending on what i select in column A, i would like to automatically fill in column B. Is this possible?

Thank you

if you use editComponent for both A and B you can. You will call onChange of B when value of A changed.

Thank you for the help, but i can't get it right. How can i access the props of B in the onChange of A. I mean, when A changes, i have to call the onChange of B, but with B's props, otherwise i can't update the B field, right?

Thank you

It tried set props of B to component (this.propsB). But when i call double onChange in for A one of them is not working properly.

So i added onRowDataChange to props of editComponent. This is usage. You can use it for next release. I will publish it tomorrow.

 columns: [
      {
        title: 'Ad谋', field: 'name', editComponent: props => {
          return (
            <input
              value={props.value}
              onChange={e => {
                var data = { ...props.rowData };
                data.name = e.target.value;
                data.surname = e.target.value.toLocaleUpperCase();
                props.onRowDataChange(data);
              }}
            />
          )
        }
      },
      {
        title: 'Soyad谋', field: 'surname', editComponent: props => {
          this.inputBProps = props;
          return (
            <input
              value={props.value}
              onChange={e => props.onChange(e.target.value)}
            />
          )
        }
      },

This is done with version 1.39.0

After upgrading to version 1.39.0 when start row edit, in browser console it generate warning:

index.js:1437 Warning: Unknown event handler property `onRowDataChange`. It will be ignored.
    in div (created by ForwardRef(FormControl))
    in ForwardRef(FormControl) (created by WithStyles(ForwardRef(FormControl)))
    in WithStyles(ForwardRef(FormControl)) (created by ForwardRef(TextField))
    in ForwardRef(TextField) (created by WithStyles(ForwardRef(TextField)))
    in WithStyles(ForwardRef(TextField)) (created by MTableEditField)
    in MTableEditField (created by MTableEditRow)
    in td (created by ForwardRef(TableCell))
    in ForwardRef(TableCell) (created by WithStyles(ForwardRef(TableCell)))
    in WithStyles(ForwardRef(TableCell)) (created by MTableEditRow)
    in tr (created by ForwardRef(TableRow))
    in ForwardRef(TableRow) (created by WithStyles(ForwardRef(TableRow)))
    in WithStyles(ForwardRef(TableRow)) (created by MTableEditRow)
    in MTableEditRow (created by MTableBody)
    in tbody (created by ForwardRef(TableBody))
    in ForwardRef(TableBody) (created by WithStyles(ForwardRef(TableBody)))
    in WithStyles(ForwardRef(TableBody)) (created by MTableBody)
    in MTableBody (created by Droppable)
    in table (created by ForwardRef(Table))
    in ForwardRef(Table) (created by WithStyles(ForwardRef(Table)))
    in WithStyles(ForwardRef(Table)) (created by Droppable)
    in div (created by Droppable)
    in div (created by Droppable)
    in Droppable (created by ConnectFunction)
    in ConnectFunction
    in ConnectFunction (created by MaterialTable)
    in div (created by ScrollBar)
    in ScrollBar (created by MaterialTable)
    in div (created by ForwardRef(Paper))
    in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper)))
    in WithStyles(ForwardRef(Paper)) (created by Container)
    in Container (created by MaterialTable)
    in Provider (created by App)
    in App (created by ErrorBoundary)
    in ErrorBoundary (created by DragDropContext)
    in DragDropContext (created by MaterialTable)
    in MaterialTable
    in Unknown (created by WithStyles(Component))
    in WithStyles(Component) (at Applications/index.tsx:116)
    in div (at Applications/index.tsx:114)
    in ApplicationsComponent (created by WithStyles(ApplicationsComponent))
    in WithStyles(ApplicationsComponent) (created by Context.Consumer)
    in Route (created by PrivateRoute)
    in PrivateRoute (at App.tsx:65)
    in Switch (at App.tsx:57)
    in Router (created by BrowserRouter)
    in BrowserRouter (at App.tsx:48)
    in App (at src/index.tsx:12)

I am also seeing "Warning: Unknown event handler property onRowDataChange. It will be ignored." after upgrading to 1.39.0

This problem remains though upgrading to version 1.39.0

What progress on this issue?
I think, somewhere should be defined prop type on this, but I鈥檓 not sure where. Very annoying warning...

I will start to working on MT at tomorrow (1 hour daily). So this would be resolved in 1 week.

Before I read that there will be a fix in a week I wrote a small hack to get rid of the error when there are no editComponent defined for a column. So far, only for string type but more can be added. Hopefully, this code can help others to get rid of the error until a real fix is in place.

The code is written in TypeScript.

  import React, { ChangeEvent } from "react";
  import { EditComponentProps } from "material-table";

  interface RealEditComponentProps extends EditComponentProps {
    onRowDataChange?: (data: []) => void;
  }
  const cleanColumns = columns.map(column => {
    if (!column.editComponent) {
      /**
       * Without defining a custom component will lead to:
       * 1. the material-table default editComponents will send the onRowDataChange as an
       * attribute to the DOM element and that results in annoying errors in the developer
       * console.
       */
      column.editComponent = ({
        value,
        columnDef,
        rowData,
        onRowDataChange
      }: RealEditComponentProps) => {
        const props = {
          value: value || "",
          onChange: (event: ChangeEvent<HTMLInputElement>) => {
            const newRowData = Object.assign(rowData, {
              [columnDef.field]: event.target.value || "",
            });
            onRowDataChange && onRowDataChange(newRowData);
          }
        };

        return <input {...props} />;
      };
    }

    return column;
  });

Any update on this issue @mbrn ?

Hi, this problem still persist on ^1.40.0

小onfirm this error on version 1.40
How to fix it?

Any news about that issue? 馃

It's been a month since the last merge on this repo -- I think the mainter(s) are on vacation

Hi everyone,we will fix asap
Thanks

is there any update of this issue?

is there any update of this issue?

The onRowDataChange function is working well in version 1.51.0

I can confirm, too, that this is working on 1.54.1.

For those who are still having problems, I found that in some components the error is in the "value" attribute. Instead of using value={props.value}, use value={props.value || ""}.

It worked for me!

columns: [
    {
        title: 'Amount',
        field: 'amount',
        type: 'numeric',
        editComponent: (props) => (
            <MuiTextField
                type="number"
                value={props.value || ''}
                placeholder={props.columnDef.title}
                onChange={(e) => props.onChange(e.target.value)}
                inputProps={{ min: 1, style: { fontSize: '13px' } }}
            />
        )
    }
];

Hi All,

I have 2 columns Name and Description. Description should be set from the value returned from an API by passing the name entered.

const [columns, setColumns] = useState([
{ title: 'Name', field: 'name', editComponent: props => {
return (
value={props.value}
onChange={(e) =>
props.onRowDataChange({
...props.rowData,
name: e.target.value,
description: functionCall(e.target.value),
})
}
/>
)
} },
{ title: 'Description', field: 'description' },
]);

Using axios.get(url) to make the API call, but the description is set to promise object like [object Promise].

Can someone please help on how to set the actual return value from the function to description.

Was this page helpful?
0 / 5 - 0 ratings