2

Currently I have a simple material-table like this:

<MaterialTable
    options={myOptions}
    title="MyTitle"
    columns={state.columns}
    data={state.data}
    tableRef={tableRef} // Not working
    editable={{
      onRowAdd: ...,
      onRowDelete: ...,
      onRowUpdate: ...
    }}
  />;

where I'm trying to a create new add button (not edit the current one): each Row in the Bar Column should have a custom add button. I've looked through the MaterialTable source code but I couldn't reproduce the code that is used for the default add button which is:

        calculatedProps.actions.push({
          icon: calculatedProps.icons.Add,
          tooltip: localization.addTooltip,
          position: "toolbar",
          disabled: !!this.dataManager.lastEditingRow,
          onClick: () => {
            this.dataManager.changeRowEditing();
            this.setState({
              ...this.dataManager.getRenderState(),
              showAddRow: !this.state.showAddRow,
            });
          },
        });

in particular I can't get to access the dataManager variable.

current table

That is how the current table looks like, and I need to add the add button where there is the red sign.

1 Answer 1

8

I think this is what you are looking for:

enter image description here

The Actions column represents the default actions set. I added an specific button using custom column rendering (docs):

//..previous columns definition
{
  title: "Custom Add",
  field: "internal_action",
  editable: false,
  render: (rowData) =>
    rowData && (
      <IconButton
        color="secondary"
        onClick={() => addActionRef.current.click()}
      >
        <AddIcon />
      </IconButton>
    )
}

*Using rowData as conditional, prevents from rendering while filling the addition row.

Then I triggered the add action as shown here:

const MyComponent() {

const addActionRef = React.useRef();

return (
    <>
        <button onClick={() => addActionRef.current.click()}>
            Add new item
        </button>

        <MaterialTable
            //...
            components={{
                Action: props => {
                    //If isn't the add action
                    if (typeof props.action === typeof Function || props.action.tooltip !== 'Add') {
                            return <MTableAction {...props} />
                    } else {
                            return <div ref={addActionRef} onClick={props.action.onClick}/>;
                    }}
                }}
            editable={{
                onRowAdd: (newData, oldData) => Promise.resolve(); //your callback here
            }}
        />
    </>
);
}

I extended the original snippet in order to complete the addition cycle. If you need to handle different types of actions, I think Editable section from the oficial docs would be handy.

Hope this works for you! Full code and sandbox here:

import React, { Fragment, useState } from "react";
import MaterialTable, { MTableAction } from "material-table";
import AddIcon from "@material-ui/icons/AddAlarm";
import IconButton from "@material-ui/core/IconButton";

export default function CustomEditComponent(props) {
const tableRef = React.createRef();
const addActionRef = React.useRef();

const tableColumns = [
    { title: "Client", field: "client" },
    { title: "Name", field: "name" },
    { title: "Year", field: "year" },
    {
    title: "Custom Add",
    field: "internal_action",
    editable: false,
    render: (rowData) =>
        rowData && (
        <IconButton
            color="secondary"
            onClick={() => addActionRef.current.click()}
        >
            <AddIcon />
        </IconButton>
        )
    }
];

const [tableData, setTableData] = useState([
    {
    client: "client1",
    name: "Mary",
    year: "2019"
    },
    {
    client: "client2",
    name: "Yang",
    year: "2018"
    },
    {
    client: "client3",
    name: "Kal",
    year: "2019"
    }
]);

return (
    <Fragment>
    <MaterialTable
        tableRef={tableRef}
        columns={tableColumns}
        data={tableData}
        title="Custom Add Mode"
        options={{
        search: false
        }}
        components={{
        Action: (props) => {
            //If isn't the add action
            if (
            typeof props.action === typeof Function ||
            props.action.tooltip !== "Add"
            ) {
            return <MTableAction {...props} />;
            } else {
            return <div ref={addActionRef} onClick={props.action.onClick} />;
            }
        }
        }}
        actions={[
        {
            icon: "save",
            tooltip: "Save User",
            onClick: (event, rowData) => alert("You saved " + rowData.name)
        }
        ]}
        editable={{
        onRowAdd: (newData) =>
            Promise.resolve(setTableData([...tableData, newData]))
        }}
    />
    </Fragment>
);
Sign up to request clarification or add additional context in comments.

2 Comments

i added the code from that github thread. mine doesnt add a new row @NicoE
it adds a row from the component overriding part, right?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.