Reputation: 596
I want to build simple form using Material-UI which has:
And then, basing on which option is checked I want to push certain information to my formData
and send it to my backend on handleSubmit
My Form component looks like this:
const MyFormComponent= () => {
const [formData, setFormData] = useState({ reason: "", feedback: ""});
const [checkboxesState, setCheckboxesState] = useState({
one: false,
two: false,
three: false
})
const handleSubmit = (e) => {
/* ... */
};
const handleChange = (e) => {
/* ... */
}
return (
<>
<form onSubmit={handleSubmit}>
<Grid container>
<FormLabel component="legend"> Some asked question here? </FormLabel>
<FormGroup>
<FormControlLabel
control={<Checkbox checked={checkboxesState.one} color="primary" onChange={handleChange} name="one" />}
label="Label for my first checkbox"
/>
<FormControlLabel
control={<Checkbox checked={checkboxesState.two} color="primary" onChange={handleChange} name="two" />}
label="Label for my secound checkbox"
/>
<FormControlLabel
control={<Checkbox checked={checkboxesState.three} color="primary" onChange={handleChange} name="three" />}
label="Label for my third checkbox"
/>
</FormGroup>
</Grid>
<ButtonWrapper>
<Button variant="outlined" color="secondary" type="submit"> Delete </Button>
<Button variant="contained" color="primary"> Go back </Button>
</ButtonWrapper>
</form>
</>
);
}
So I came up with solution on my handleChange
like this, works perfectly fine, but I will have to create another if(/* */) else if(/* */) else if(/* */)
instruction on my handleSubmit
.
I believe there is much more elegant solution based on Material-UI components API which I don't know yet or don't know how to use it. Can someone suggest me something else in this situation?
const handleChange = (e) => {
if(e.target.name === "one") {
setCheckboxesState({
one: e.target.checked,
two: false,
three: false
});
} else if (e.target.name === "two") {
setCheckboxesState({
one: false,
two: e.target.checked,
three: false
});
} else if (e.target.name === "three") {
setCheckboxesState({
one: false,
two: false,
three: e.target.checked
});
}
}
Upvotes: 2
Views: 4275
Reputation: 654
If you want to achieve "Multiple options, only one selected", Radio Buttons is a better UX choice for that scenario.
Quoting from https://www.nngroup.com/articles/checkboxes-vs-radio-buttons/
Radio buttons are used when there is a list of two or more options that are mutually exclusive and the user must select exactly one choice. In other words, clicking a non-selected radio button will deselect whatever other button was previously selected in the list.
Checkboxes are used when there are lists of options and the user may select any number of choices, including zero, one, or several. In other words, each checkbox is independent of all other checkboxes in the list, so checking one box doesn't uncheck the others.
To achieve Radio group using Material UI, please refer to Material UI docs. They have excellent examples.
import React from 'react';
import Radio from '@material-ui/core/Radio';
import RadioGroup from '@material-ui/core/RadioGroup';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import FormControl from '@material-ui/core/FormControl';
import FormLabel from '@material-ui/core/FormLabel';
export default function RadioButtonsGroup() {
const [value, setValue] = React.useState('female');
const handleChange = (event) => {
setValue(event.target.value);
};
return (
<FormControl component="fieldset">
<FormLabel component="legend">Gender</FormLabel>
<RadioGroup aria-label="gender" name="gender1" value={value} onChange={handleChange}>
<FormControlLabel value="female" control={<Radio />} label="Female" />
<FormControlLabel value="male" control={<Radio />} label="Male" />
<FormControlLabel value="other" control={<Radio />} label="Other" />
<FormControlLabel value="disabled" disabled control={<Radio />} label="(Disabled option)" />
</RadioGroup>
</FormControl>
);
}
Upvotes: 3
Reputation: 8774
You could track the current select checkbox with one variable instead of multiple.
const MyFormComponent= () => {
const [formData, setFormData] = useState({ reason: "", feedback: ""});
const [checkboxesState, setCheckboxesState] = useState(-1)
const handleSubmit = (e) => {
/* ... */
};
const handleChange = (e) => {
setCheckboxesState(e.target.name);
}
return (
<>
<form onSubmit={handleSubmit}>
<Grid container>
<FormLabel component="legend"> Some asked question here? </FormLabel>
<FormGroup>
<FormControlLabel
control={<Checkbox checked={checkboxesState === 0} color="primary" onChange={handleChange} name={0} />}
label="Label for my first checkbox"
/>
<FormControlLabel
control={<Checkbox checked={checkboxesState === 1} color="primary" onChange={handleChange} name={1} />}
label="Label for my secound checkbox"
/>
<FormControlLabel
control={<Checkbox checked={checkboxesState === 2} color="primary" onChange={handleChange} name={2} />}
label="Label for my third checkbox"
/>
</FormGroup>
</Grid>
<ButtonWrapper>
<Button variant="outlined" color="secondary" type="submit"> Delete </Button>
<Button variant="contained" color="primary"> Go back </Button>
</ButtonWrapper>
</form>
</>
);
}
Upvotes: -1