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:
I tried to look for an event something like onCancelEdit but I didn't find anything, do you know how to solve this?
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" }
]}