LaVOZs

The World’s Largest Online Community for Developers

'; reactjs - React MaterialTable editable row validation - how to show and hide error? - LavOzs.Com

I have a material-table and I want to run field validations on row editing only when the user clicks in save button.

I have this function to set the error:

const [nameError, setNameError] = useState({
        error: false,
        label: '',
        helperText: '',
    });

And the onRowUpdate:

onRowUpdate: (newData, oldData) =>
                    new Promise((resolve, reject) => {
                        setTimeout(() => {

                            if (newData.name === '') {
                                setNameError({
                                    error: true,
                                    label: 'required',
                                    helperText: 'Required helper text'
                                });
                                reject();
                                return;
                            }

                            resolve();
                            if (oldData) {
                                setState(prevState => {
                                    const data = [...prevState.data];
                                    data[data.indexOf(oldData)] = newData;
                                    return { ...prevState, data };
                                });
                            }
                        }, 600);
                    })

I can set the error, the problem is if I click on cancel button, next time I click on edit the error continues visible.

Here is a gif:

enter image description here

I tried to look for an event something like onCancelEdit but I didn't find anything, do you know how to solve this?

You can try this in Edit MaterialTableDemo - validation error

Complete React component code:

const tableIcons = {
    Add: forwardRef((props, ref) => <AddBox {...props} ref={ref} />),
    Check: forwardRef((props, ref) => <Check {...props} ref={ref} />),
    Clear: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
    Delete: forwardRef((props, ref) => <DeleteOutline {...props} ref={ref} />),
    DetailPanel: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
    Edit: forwardRef((props, ref) => <Edit {...props} ref={ref} />),
    Export: forwardRef((props, ref) => <SaveAlt {...props} ref={ref} />),
    Filter: forwardRef((props, ref) => <FilterList {...props} ref={ref} />),
    FirstPage: forwardRef((props, ref) => <FirstPage {...props} ref={ref} />),
    LastPage: forwardRef((props, ref) => <LastPage {...props} ref={ref} />),
    NextPage: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
    PreviousPage: forwardRef((props, ref) => <ChevronLeft {...props} ref={ref} />),
    ResetSearch: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
    Search: forwardRef((props, ref) => <Search {...props} ref={ref} />),
    SortArrow: forwardRef((props, ref) => <ArrowDownward {...props} ref={ref} />),
    ThirdStateCheck: forwardRef((props, ref) => <Remove {...props} ref={ref} />),
    ViewColumn: forwardRef((props, ref) => <ViewColumn {...props} ref={ref} />)
};



export default function MaterialTableDemo() {

    const [nameError, setNameError] = useState({
        error: false,
        label: '',
        helperText: '',
    });



    const [state, setState] = React.useState({
        data: [
            {
                name: 'Mehmet',
                surname: 'Baran'
            },
            {
                name: 'Zerya Betül',
                surname: 'Baran'
            },
        ],
    });

    return (
        <MaterialTable
            title="Editable Example"
            columns={
                [
                    {
                        title: 'Name', field: 'name',
                        editComponent: (props) => (
                            <TextField
                                type="text"
                                error={nameError.error}
                                helperText={nameError.helperText}
                                value={props.value ? props.value : ''}
                                onChange={e => props.onChange(e.target.value)}
                            />
                        )
                    },
                    { title: 'Surname', field: 'surname' }
                ]}
            data={state.data}
            icons={tableIcons}
            editable={{
                onRowUpdate: (newData, oldData) =>
                    new Promise((resolve, reject) => {
                        setTimeout(() => {

                            if (newData.name === '') {
                                setNameError({
                                    error: true,
                                    label: 'required',
                                    helperText: 'Required helper text'
                                });
                                reject();
                                return;
                            }

                            resolve();
                            if (oldData) {
                                setState(prevState => {
                                    const data = [...prevState.data];
                                    data[data.indexOf(oldData)] = newData;
                                    return { ...prevState, data };
                                });
                            }
                        }, 600);
                    })
            }}
        />
    );
}

Check if the value exists in editComponent.

const [nameError, setNameError] = useState({
    error: false,
    label: "",
    helperText: "",
    validateInput: false
});

columns={[
  {
    title: "Name",
    field: "name",
    editComponent: props => (
    <TextField
        type="text"
        error={
        !props.value && nameError.validateInput
            ? nameError.error
            : false
        }
        helperText={
        !props.value && nameError.validateInput
            ? nameError.helperText
            : ""
        }
        value={props.value ? props.value : ""}
        onChange={e => {
        if (nameError.validateInput) {
            setNameError({
            ...nameError,
            validateInput: false
            });
        }

        props.onChange(e.target.value);
        }}
    />
    )
  },
  { title: "Surname", field: "surname" }
]}

codesandbox

Related
Show or hide element in React
Hide keyboard in react-native
How do I conditionally add attributes to React components?
Invariant Violation: Objects are not valid as a React child
How to update parent's state in React?
React prop validation for date objects
Error Running React Native App From Terminal (iOS)
How to call loading function with React useEffect only once
How to compare oldValues and newValues on React Hooks useEffect?
React Material table editing using hooks