Search code examples
reactjsmaterial-table

How can you customize a field when adding a row from the library material-table?


When adding a row to an editable table using the library material-table, how can you customize a field? I'd like to either make the field read-only or something else where the user cannot change the field. I've tried the read-only option for columns, but that only makes it read-only for updating fields.

import React from "react";
import MaterialTable from "material-table";
import Edit from "@material-ui/icons/Edit"
import Add from "@material-ui/icons/Add"
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  return (
    <MaterialTable
      title="Editable Preview"
      columns={[
        { title: "Name", field: "name", readonly: true  }, // only works on update
        { title: "Surname", field: "surname" },
        { title: "Birth Year", field: "birthYear", type: "numeric" }
      ]}
      data={[
        { name: "Mehmet", surname: "Baran", birthYear: 1987, birthCity: 63 },
        {
          name: "Zerya Betül",
          surname: "Baran",
          birthYear: 2017,
          birthCity: 34
        }
      ]}
      title="Basic"
      options={{
        paging: false
      }}
      icons={{
        Add: () => <Add />,
        Edit: () => <Edit />
      }}
      editable={{
        onRowAdd: newData =>
          new Promise((resolve, reject) => {
            setTimeout(() => {
              {
                /* const data = this.state.data;
                        data.push(newData);
                        this.setState({ data }, () => resolve()); */
              }
              resolve();
            }, 1000);
          }),
          onRowUpdate: (newData, oldData) =>
            new Promise((resolve, reject) => {
              setTimeout(() => {
                {
                  // const data = this.state.data;
                  // const index = data.indexOf(oldData);
                  // data[index] = newData;
                  // this.setState({ data }, () => resolve());
                }
                resolve()
              }, 1000)
            })
      }}
    />
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Solution

  • According to the docs you can override the component and just use a custom function to render the field.

    ...
    
        <MaterialTable
          title="Editable Preview"
          component={{
            // add the custom component here
          }}
          columns={[
            { title: "Name", field: "name", readonly: true  }, // only works on update
            { title: "Surname", field: "surname" },
            { title: "Birth Year", field: "birthYear", type: "numeric" }
          ]}
          data={[
            { name: "Mehmet", surname: "Baran", birthYear: 1987, birthCity: 63 },
            {
              name: "Zerya Betül",
              surname: "Baran",
              birthYear: 2017,
              birthCity: 34
            }
          ]}
          title="Basic"
          options={{
            paging: false
          }}
          icons={{
            Add: () => <Add />,
            Edit: () => <Edit />
          }}
          editable={{
            onRowAdd: newData =>
              new Promise((resolve, reject) => {
                setTimeout(() => {
                  {
                    /* const data = this.state.data;
                            data.push(newData);
                            this.setState({ data }, () => resolve()); */
                  }
                  resolve();
                }, 1000);
              }),
              onRowUpdate: (newData, oldData) =>
                new Promise((resolve, reject) => {
                  setTimeout(() => {
                    {
                      // const data = this.state.data;
                      // const index = data.indexOf(oldData);
                      // data[index] = newData;
                      // this.setState({ data }, () => resolve());
                    }
                    resolve()
                  }, 1000)
                })
          }}
        />
      );
    }
    
    ...