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

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>

Related

ReactJS Material UI Reset Radio Buttons

I have Material UI radio buttons in my ReactJS form :
<FormControl className={ styles.rowControl }>
<FormLabel>Direction</FormLabel>
<RadioGroup name="direction" onChange={ this.setOption } ref={ this.directionGroupRef }>
<FormControlLabel
className={ styles.rowFirstLabel }
control={<Radio />}
label="North"
ref={ this.northRef }
value="North"
/>
<FormControlLabel
className={ styles.rowFirstLabel }
control={<Radio />}
label="South"
value="South"
/>
<FormControlLabel
className={ styles.rowFirstLabel }
control={<Radio />}
label="Flip-Flop"
value="Flip-Flop"
/>
</RadioGroup>
</FormControl>
How can I remove any checked statuses among these radio buttons when the form is submitted?

How to properly use MUI FormControl component?

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?

react-hook-form and MUI FormControl

So I am trying to register some radio buttons for my form, however it will not register.
<FormControl component="fieldset" inputRef={register({ required: true })}>
<FormLabel component="legend">Promoting</FormLabel>
<RadioGroup aria-label="promoting" name="promoting" value={promoting} onChange={handleChange} inputRef={register({ required: true })}>
<FormControlLabel value="business" control={<Radio />} label="Business" />
<FormControlLabel value="nonprofit" control={<Radio />} label="Non-Profit" />
<FormControlLabel value="event" control={<Radio />} label="Event" />
</RadioGroup>
</FormControl>
I am wondering what I am doing wrong
Full code:
export default function BuildAd() {
const [promoting, setValue] = React.useState('female');
const handleChange = (event) => {
setValue(event.target.value);
};
const { register, handleSubmit, errors } = useForm();
const onSubmit = data => console.log(data);
console.log(errors);
return (
<div style={{ padding: 16, margin: 'auto', maxWidth: 600 }}>
<CssBaseline />
<Typography variant="h5" align="center" component="h2" gutterBottom>
Create your campaign
</Typography>
<Paper style={{ padding: 16 }}>
<form onSubmit={handleSubmit(onSubmit)}>
<input type="text" placeholder="First name" name="First name" ref={register({required: true, maxLength: 80})} />
<input type="text" placeholder="Last name" name="Last name" ref={register({required: true, maxLength: 100})} />
<input type="text" placeholder="Email" name="Email" ref={register({required: true, pattern: /^\S+#\S+$/i})} />
<input type="tel" placeholder="Mobile number" name="Mobile number" ref={register({required: true, minLength: 6, maxLength: 12})} />
<select name="Title" ref={register({ required: true })}>
<option value="Mr">Mr</option>
<option value="Mrs">Mrs</option>
<option value="Miss">Miss</option>
<option value="Dr">Dr</option>
</select>
<input name="Developer" type="radio" value="Yes" ref={register({ required: true })}/>
<input name="Developer" type="radio" value="No" ref={register({ required: true })}/>
<Typography variant="h5">What are you Advertising</Typography>
<Box m={2}/>
<FormControl component="fieldset" inputRef={register({ required: true })}>
<FormLabel component="legend">Promoting</FormLabel>
<RadioGroup aria-label="promoting" name="promoting" value={promoting} onChange={handleChange} inputRef={register({ required: true })}>
<FormControlLabel value="business" control={<Radio inputRef={register({ required: true })} />} label="Business" />
<FormControlLabel value="nonprofit" control={<Radio inputRef={register({ required: true })} />} label="Non-Profit" />
<FormControlLabel value="event" control={<Radio inputRef={register({ required: true })} />} label="Event" />
</RadioGroup>
</FormControl>
<input type="submit" />
</form>
</Paper>
</div>
);
}
You can fallback on controllable components by using Controller if it doesn't work.
In your case, I suspect it's because the name props passed to your RadioGroup is not the same as the name attribute when passed into native inputs like input or select.
react-hook-form V7
const { handleSubmit, control } = useForm({
defaultValues: {
promoting2: '',
},
});
<FormControl component="fieldset">
<FormLabel component="legend">Promoting</FormLabel>
<Controller
rules={{ required: true }}
control={control}
name="promoting2"
render={({ field }) => (
<RadioGroup {...field}>
<FormControlLabel
value="business"
control={<Radio />}
label="Business"
/>
<FormControlLabel
value="nonprofit"
control={<Radio />}
label="Non-Profit"
/>
<FormControlLabel
value="event"
control={<Radio />}
label="Event"
/>
</RadioGroup>
)}
/>
</FormControl>
react-hook-form V6
const { register, handleSubmit, errors, control } = useForm({
promoting: '',
});
const onSubmit = (data) => alert(JSON.stringify(data, null, 2));
<form onSubmit={handleSubmit(onSubmit)}>
<FormControl component="fieldset">
<FormLabel component="legend">Promoting</FormLabel>
<Controller
rules={{ required: true }}
control={control}
name="promoting"
as={
<RadioGroup>
<FormControlLabel
value="business"
control={<Radio />}
label="Business"
/>
<FormControlLabel
value="nonprofit"
control={<Radio />}
label="Non-Profit"
/>
<FormControlLabel
value="event"
control={<Radio />}
label="Event"
/>
</RadioGroup>
}
/>
</FormControl>
<input type="submit" />
</form>
If you want to read the value when onChange fires, you cannot do that when passing the element to the as props:
<Controller
{...}
as={
<MyComponent
onChange={handleChange} // handleChange will never be called
/>
}
/>
The reason is because Controller will copy the element that you pass in and pass its own onChange props that will override yours. See here and here.
To fix that problem, you need to use another way to pass the element down by using render props to gain more control on how you should render your components.
<Controller
rules={{ required: true }}
control={control}
name="promoting2"
render={({ name, onBlur, onChange, value }) => (
<RadioGroup
value={value}
onBlur={onBlur}
onChange={(e) => {
onChange(e);
console.log(e.target.value); // will be called this time
}}
>
<FormControlLabel
value="business"
control={<Radio />}
label="Business"
/>
{...}
</RadioGroup>
)}
/>

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

Can't .map for a material RadioGroup

I have:
const documentTypes = [
'General',
'Email',
'Fiction story',
'Blog post',
'Newsletter',
'Review',
'Website content'
]
and
<FormControl component="fieldset">
<FormLabel component="legend">Document Type</FormLabel>
<RadioGroup name="documentType" value={docType} onChange={handleChangeDoc}>
{documentTypes.map((documentType, idx) => {
<FormControlLabel value={documentType} control={<Radio />} label={documentType} key={idx} />
})}
<FormControlLabel value="other" control={<Radio />} label={<Input onFocus={() => setDocType('other')} />} />
</RadioGroup>
</FormControl>
but I don't see all of the options. Just the other. What am I doing wrong?
This is with material-ui for react.
I think you only need to return the FormControlLabel in the map.
Options 1) remove the {} around the FormControlLabel
<FormControl component="fieldset">
<FormLabel component="legend">Document Type</FormLabel>
<RadioGroup name="documentType" value={docType} onChange={handleChangeDoc}>
{documentTypes.map((documentType, idx) =>
<FormControlLabel value={documentType} control={<Radio />} label={documentType} key={idx} />
)}
<FormControlLabel value="other" control={<Radio />} label={<Input onFocus={() => setDocType('other')} />} />
</RadioGroup>
</FormControl>
Option 2) Just add return before FormControlLabel
<FormControl component="fieldset">
<FormLabel component="legend">Document Type</FormLabel>
<RadioGroup name="documentType" value={docType} onChange={handleChangeDoc}>
{documentTypes.map((documentType, idx) => {
return <FormControlLabel value={documentType} control={<Radio />} label={documentType} key={idx} />
})}
<FormControlLabel value="other" control={<Radio />} label={<Input onFocus={() => setDocType('other')} />} />
</RadioGroup>
</FormControl>

Resources