0
votes

I am no sure if I simply not using the features correctly or if I don't understand form handling and validation with material-ui react components? For example the following code seems to correctly show validation errors before the form is submitted but I am having a hardtime getting the errors displayed to "clear".

const useStyles = makeStyles((theme: Theme) =>
    createStyles({
        input: {
            "&:invalid": {
                border: "red solid 2px"
            }
        },
        root: {
            '& .MuiTextField-root': {
                margin: theme.spacing(1),
                width: '25ch',
            },
        },
    }),
);
. . .
            <form className={classes.root} autoComplete="off">
                <div style={{ width: '400px' }}>
                    <TextField
                        style={{ width: '100%' }}
                        error
                        helperText="Name is required"
                        required id="name-standard-required"
                        name="name-standard-required"
                        label="Name"
                        placeholder="Name" />
                    <br/>
                    <TextField
                        style={{ width: '100%' }}
                        error
                        helperText="Email is required"
                        required id="email-standard-required"
                        name="email-standard-required"
                        label="Email"
                        placeholder="Email" />
                    <br/>
                    <TextField
                        style={{ width: '30%' }}
                        id="phone-pattern"
                        error
                        inputProps={{ className: classes.input, pattern: "[0-9]{1,11}" }}
                        name="phone-pattern"
                        label="Phone"
                        placeholder="eg.11234567890" />
                    <br/>
                    <TextField
                        style={{ width: '100%' }}
                        id="comments-multiline"
                        name="comments-multiline"
                        label="Comments"
                        rows={6}
                        multiline />
                </div>
                <Button
                    type="submit"
                    variant="contained"
                    color="primary"
                >
                    Submit
                </Button>
            </form>

I am having two problems with the above code. First, as I have mentioned the errors properly are displayed before the form is submitted. But these errors don't seem to clear. For example the first two fields properly show an error when the field is empty but once the input field is filled in I would expect the error indication to go away and it doesn't. Second, is more of a timing issue. The errors seem to show up before the user has a chance to enter any value. For this input validation no consideration seems to be given to the 'pristine' or 'dirty' states (in Angular world) of the input.

The other form validation method for this type of form is to assign input handlers to basic HTML events and do the validation 'manually' Like:

                        onInput={(e: React.FormEvent<EventTarget>) => {
                            let target = e.target as HTMLInputElement;
                            . . . . 
                        }}

I have tried this and it 'works'. But, it seems like there is a better way.

There is a library 'react-hook-form` that seems to handle the form validation before and after submission in a very concise and usable manner. But including this package seems to duplicate what already seems like an attempt (as far as I see it) at form validation in material-ui. So I guess what I would ideally like to see is the ease of form validation using the package 'react-hook-form' already baked into components of material-ui?

What are the options for form processing with material-ui components?

1

1 Answers

0
votes

To display error message dynamically you need to handle the error, you cannot pass error attribute directly to TextField if you do then it will show you error every time.
Instead what you can do it just set the error attribute conditionally.

 <TextField
      style={{ width: '100%' }}
      error={this.state.error? true : false}  //this will show err message only when there is error
      helperText="Name is required"
      required id="name-standard-required"
      name="name-standard-required"
      label="Name"
      placeholder="Name" />

But for this, you need to handle or keep track of errors in the state.
Note - If you are using function component then handle state accordingly instead of using this.state.