How to properly use MUI FormControl component? - reactjs

I'm coding a contact form using React and MaterialUI.
I have some TextField components and one RadioGroup with two options.
MUI's documentation only shows FormControl wrapping a FormLabel for its RadioGroup.
Should my TextField components also be inside the same FormControl?
My code (simplified) is like this:
<form onSubmit={handleSubmit(onSubmit)}>
<TextField label="firstName" />
<TextField label="lastName" />
<TextField label="email" />
<TextField label="phone" />
<TextField label="message" />
<FormControl>
<FormLabel id="contact-options-label">Contact Options</FormLabel>
<RadioGroup aria-labelledby="contact-options-label">
<FormControlLabel
value="option1"
label="Option 1"
control={<Radio color="secondary" />}
/>
<FormControlLabel
value="option2"
label="Option 2"
control={<Radio color="secondary" />}
/>
</RadioGroup>
</FormControl>
<Button type="submit">Submit</Button>
</form>
Am I using FormControl properly in this case?

Related

Radio Button passing null value on selecting female using react-hook-form

I want to get value on submit, but getting value which is first, its passing null value on selecting female , onChange its working fine
<form onSubmit={handleSubmit(onSubmit)}>
<FormControl>
<FormLabel id="demo-radio-buttons-group-label">Gender</FormLabel>
<RadioGroup
// onChange={(e)=> console.log(e.target.value)}
{...register("myrad")}
>
<FormControlLabel value="Male" control={<Radio />}label="Male" />
<FormControlLabel value="Female" control={<Radio />}label="Female" />
</RadioGroup>
</FormControl>
<button type="submit">submit</button>
</form>
Replace your form tag with this
<RadioGroup
// onChange={(e)=> console.log(e.target.value)}
name="use-radio-group"
defaultValue="Female"
>
<FormControlLabel
{...register("myrad")}
value="Male"
control={<Radio />}
label="Male"
/>
<FormControlLabel
{...register("myrad")}
value="Female"
control={<Radio />}
label="Female"
/>
</RadioGroup>

How to write a checkbox inside form control or form control label without label

Here is the sample code, what I've done so far,
<FormGroup>
<FormControlLabel
control={
<Checkbox
checked={isItemSelected}
onChange={(event) => handleClick(event, id)}
/>}
label
data-testid={`checkboxId-${index}`}
/>
</FormGroup>
But I was unable to create a checkbox inside a form-control or form-control label without label.
use this :
<Checkbox
checked={isItemSelected}
onChange={event => handleClick(event, id)}
/>
then there isn't any label to handle

react-hook-form material-ui (FormControlLabel + Checkbox) using Controller

to use Material-ui in react-hook-form you should use <Controller and the method render instead of "as = {xy-control}" Also should not mix controller and inputRef = {register}.
A single control is also no problem.
But there is a compound control in Material-ui. "FormControlLabel + CheckBox" how do you integrate this control in the controller. All my attempts have failed.
This is how it works but I would like the FormControlLaben to be enclosed by the controller.
Does somebody has any idea?
<Controller
name="password"
control={control}
defaultValue={""}
render={(props) => <TextField {...props}
variant="outlined"
margin="normal"
required
fullWidth
label="Password"
type="password"
id="password"
autoComplete="current-password"
/>}
/>
<FormControlLabel
control={
<Checkbox
inputRef={register}
name="remember"
/>
}
label="remember"
/>
{/*That works, but it requires an OnChange. Why can't the controller bind it?*/}
<FormControlLabel
control={
<Controller
name={"remember2"}
control={control}
render={(props) => (
<Checkbox
{...props}
onChange={(e) => props.onChange(e.target.checked)}
/>
)}
/>
}
label="remember"
/>
Here's how I did it
<FormControlLabel
control={
<Controller
control={control}
inputRef={register}
name='controlName'
render={({onChange, value}) => (
<Checkbox
onChange={e => onChange(e.target.checked)}
checked={value}
/>
)}
/>
}
label="This is a label"
/>
From v7, I used this :
<Controller
name='contactAutre'
control={control}
defaultValue={false}
render={({ field }) => (
<FormControlLabel
control={<Checkbox {...field} />}
label='Autre'
/>
)}
/>
this was enough for me w/ Mui 5 & RHF 7
const { watch, register } = useForm<{saveEmail: boolean}>({
defaultValues: { saveEmail: true },
});
...
<FormControlLabel
control={
<Checkbox {...register('saveEmail')} checked={watch('saveEmail')} />
}
label="save email"
/>
Credit to Leo Roese for his example for Textfield. However you can apply the same logic for Checkboxes but slightly tweak.
const { control, formState: { errors } } = useForm()
<Controller
name="privacyAccept"
control={control}
render={({ field }) => (
<>
<FormControlLabel
control={<Checkbox {...field} />}
label="I agree to the privacy policy"
/>
{errors.privacyAccept && (
<FormHelperText error>{errors.privacyAccept.message}</FormHelperText>
)}
</>
)}
/>
Another way to make things more controlled:
<FormControlLabel
label="label here"
control={
<Controller
name="isSeparatedDelivery"
control={control}
render={({ field: { onChange, value } }) => (
<Checkbox
checked={value}
onChange={(e) => onChange(e.target.checked)}
/>
)}
/>
}
/>
or
<Controller
control={control}
name="selected"
render={({ field: { onChange, value } }) => (
<FormControlLabel
control={
<Checkbox
label="Sélectionner la question"
checked={value}
onChange={onChange}
/>
}
label="Sélectionner la question"
/>
)}
/>

How is Material UI's React rating component used in a form?

I am trying to use Material UI's React rating component within a react-hook-form.
...
<form onSubmit={handleSubmit(onSubmit)}>
<FormControlLabel
control={
<Checkbox
inputRef={register}
name="remember"
defaultValue={false}
/>
}
label="remember"
/>
<br />
<FormControlLabel
control={
<Rating
inputRef={register}
name="rating"
defaultValue={2}
precision={1}
icon={<RadioButtonUncheckedIcon fontSize="inherit" />}
/>
}
label="select rating"
/>
<Button type="submit">
Submit
</Button>
</form>
...
I can't understand why the value from the rating component is not being registered but the checkbox's value is. Please find the code at https://codesandbox.io/s/suspicious-drake-1d0kx?file=/src/form.js (on submit, the rating's value is not printed to the console while the checkbox's value is).
According to the doc, Rating have no input element to pass ref to like TextField or Checkbox, so a solution is to create an hidden input in replacement to store the rating value
<FormControlLabel
control={
<>
<input
name="rating"
type="number"
value={rating}
ref={register}
hidden
readOnly
/>
<Rating
name="rating"
value={rating}
precision={1}
onChange={(_, value) => {
setRating(value);
}}
icon={<RadioButtonUncheckedIcon fontSize="inherit" />}
/>
</>
}
label="select rating"
/>
Below is the forked codesandbox link for the modification

variant="filled" does not work on <Select multiple>

I don't know why the style is not applied.
Can anyone solve this problem?
<FormControl className={classes.formControl} variant="filled">
<InputLabel id="input-label">Multiple Select</InputLabel>
<Select
variant="filled"
fullWidth={true}
labelId="input-label"
multiple
value={value}
onChange={event => setValue(event.target.value)}
input={<Input />}
renderValue={() => value.join(", ")}
>
<MenuItem value="AAAAA">
<Checkbox checked={value.indexOf("AAAAA") !== -1} />
<ListItemText primary="AAAAA" />
</MenuItem>
<MenuItem value="BBBBB">
<Checkbox checked={value.indexOf("BBBBB") !== -1} />
<ListItemText primary="BBBBB" />
</MenuItem>
<MenuItem value="CCCCC">
<Checkbox checked={value.indexOf("CCCCC") !== -1} />
<ListItemText primary="CCCCC" />
</MenuItem>
</Select>
</FormControl>
Full Code:
https://codesandbox.io/s/select-multiple-tags-variant-filled-hc9y7
Who can help I thank!
Instead of adding the variant to the FormControl, use mui's <OutlinedInput /> component and not the <Input /> component for the input prop on Select
<Select
variant="filled"
fullWidth={true}
labelId="input-label"
multiple
value={value}
onChange={event => setValue(event.target.value)}
input={<OutlinedInput />}
renderValue={() => value.join(", ")}
>
I had the same issue and I got around using the AutoComplete component (albeit it is only in the lab section of Material UI): https://material-ui.com/components/autocomplete/
Hope that works out for you.

Resources