Material-table: Prevent row fields from resetting on custom validation.

Created on 6 Jun 2019  路  2Comments  路  Source: mbrn/material-table

I'm making my own validation when adding a new row, so it avoids creating a new one with any missing fields. The thing is I'm trying to prevent the creation but I want the row not to close, instead keeping it in it's editable state, with the data the user wrote, so it's not lost.
I kinda resolved keeping the row editable, but when it validated the fields, all the data the user entered resets.
This is my code:


import React, { Component } from "react";
import { checkObjectLength, checkObjectKey } from "./../helpers";
import MaterialTable from "material-table";
import SnackbarNotification from "./SnackbarNotification";

class CustomTable extends Component {
  state = {
    open: false,
    message: "",
    alertStyle: "",
    temporaryData: {},
    columns: [
      {
        title: "Column1",
        field: "column1",
        lookup: {
          1: "option1",
          2: "option2",
          3: "option3"
        }
      },
      {
        title: "Column2",
        field: "column2",
        lookup: {
          10: "option1",
          11: "option2",
          12: "option3",
          13: "option4"
        }
      },
      {
        title: "column3",
        field: "column3",
        lookup: {
          20: "option1"
        }
      },
      { title: "column4", field: "column4" }
    ],
    data: [
      {
        column1: "somedata",
        column2: "somedata",
        column3: "somedata",
        column4: "somedata"
      }
    ]
  };

  handleClose = () => {
    this.setState({
      open: false
    });
  };

  render() {
    return (
      <div>
        <style global="true" jsx="true">
          {`
            .MuiFormControl-root.MuiTextField-root {
              width: 100%;
            }
          `}
        </style>

        <CustomTable
          options={{
            search: false,
            actionsColumnIndex: 4,
            filtering: true
          }}
          components={{
            Container: props => props.children
          }}
          title="Search by"
          columns={this.state.columns}
          data={this.state.data}
          editable={{
            onRowAdd: newData => {
              return new Promise(resolve => {
                setTimeout(() => {
                  const data = [...this.state.data];
                  if (checkObjectLength(newData)) {
                    return this.setState({
                      open: true,
                      message: "Some fields are missing!",
                      alertStyle: "error",
                      temporaryData: newData
                    });
                  }
                  resolve();
                  data.push(newData);
                  this.setState({
                    ...this.state,
                    data,
                    open: true,
                    message: "Successfully saved!",
                    alertStyle: "success"
                  });
                }, 300);
              });
            },
            onRowUpdate: (newData, oldData) => {
              return new Promise(resolve => {
                setTimeout(() => {
                  resolve();
                  const data = [...this.state.data];
                  //Only checking this field since it's the only one that can be empty on edit
                  if (checkObjectKey(newData.value)) {
                    return this.setState({
                      open: true,
                      message: "Some fields are missing!",
                      alertStyle: "error"
                    });
                  }
                  data[data.indexOf(oldData)] = newData;
                  this.setState({
                    ...this.state,
                    data,
                    open: true,
                    message: "Successfully updated!",
                    alertStyle: "success"
                  });
                }, 300);
              });
            },
            onRowDelete: oldData => {
              return new Promise(resolve => {
                setTimeout(() => {
                  resolve();
                  const data = [...this.state.data];
                  data.splice(data.indexOf(oldData), 1);
                  this.setState({
                    ...this.state,
                    data,
                    open: true,
                    message: "Successfully deleted!",
                    alertStyle: "success"
                  });
                }, 300);
              });
            }
          }}
        />
        <SnackbarNotification
          open={this.state.open}
          handleClose={this.handleClose}
          message={this.state.message}
          alertStyle={this.state.alertStyle}
        />
      </div>
    );
  }
}

export default CustomTable;

help wanted

All 2 comments

You can call reject of promise to cancel process.

I'm able to make it work by calling reject in adding case, but in updating, my form is reset, any idea ?

function handleOnUpdate(newData, oldData) {
    return new Promise((resolve, reject) => {
      console.log('oldData', oldData);
      console.log('newData', newData);
      if (!validateForm(newData)) {
        reject();
      } else {
        resolve();
        saveData(newData);
      }
    });
  }
Was this page helpful?
0 / 5 - 0 ratings