Reputation: 848
I think its a very silly doubt but I am stuck in this.. I have multiple radio buttons and I want to uncheck all the radio buttons as soon as I click the other radio button. How can I achieve it in react?
var options = [{id:1,nm:"Appointment fixed"},{id:2,nm:"Call later"},{id:3,nm:"Wrong number"},{id:4,nm:"Don't call again"},{id:5,nm:"Call later"}];
{options.map((item,i) => {
return (
<div onChange={(i)=>this.callOptions(i)}>
<label className="radio-inline"><input type="radio" value={i} ref={'ref_' + i} value={item.id}/>{item.nm}</label>
</div>
)
})}
Upvotes: 18
Views: 50298
Reputation: 404
I was trying this on react with bootstrap and I faced the same issue. What you can do is check if the radio button was clicked by using e.target.checked and then check it again with the previous state of the checked value set in state.
For Example this is what's in the render method
<input checked={this.state.radioButton} onClick={this.onClickAvailability} className="form-check-input" type="radio" value="Click" />
<label>Click</label>
And in the event handler
onClickAvailability(e){
if(e.target.checked && !this.state.radioButton){
this.setState({
radioButton:true,
})
}else if(e.target.checked && this.state.radioButton){
this.setState({
radioButton:false,
})
}
Please remember to set the initial value to false at the componentDidMount or in the constructor
Upvotes: 1
Reputation: 3913
Also, for a stateless component, if you want to deselect a radio item, you can also use checked
property:
const renderRadioGroup = data.map((radio, i) => {
return (
<span key={i}>
<input
className={radio.class}
id={radio.id}
type="radio"
name={radio.value}
value={radio.value}
onChange={e => {
onChange(e, itemKey);
}}
checked={defaultChecked === radio.value}
/>
<label htmlFor={radio.id}>{radio.label}</label>
</span>
);
}
in this case, defaultChecked
is passed as a prop and used as a variable within the Class.
Upvotes: 1
Reputation: 59491
You can either use a controlled input or an uncontrolled input. Below an example for each of the solutions.
Before I post that though, allow me to add some useful tips & links for you:
I've changed the way you use refs
because your approach is now deprecated and discouraged. Please see this post. Also, you almost certainly don't need any refs
here whatsoever; do consider removing them.
You're not using the key
prop for the items you're mapping. I've added that too. Please see this post
You might also want to read about controlled vs uncontrolled inputs. Here's another relevant post I made a while ago.
You have accidentally added two value
props for your checkbox.
Controlled
Add a state variable which is toggled each time you select a radio button. Something like:
constructor() {
super();
this.state = {checkedRadio: null};
}
changeRadio(e) {
this.setState(checkedRadio: e.target.value);
}
var options = [{id:1,nm:"Appointment fixed"},{id:2,nm:"Call later"},{id:3,nm:"Wrong number"},{id:4,nm:"Don't call again"},{id:5,nm:"Call later"}];
{options.map((item,i) => {
return (
<div key={item.id} onChange={(i)=>this.callOptions(i)}>
<label className="radio-inline"><input type="radio" checked={this.state.checkedRadio == i} ref={(el) => this["myRadioRef" + i] = el} value={item.id} onChange={this.changeRadio} />{item.nm}</label>
</div>
);
})}
Uncontrolled
The other option is to use an uncontrolled input. All you need to do to your existing code is to add a name
prop to your inputs. So like:
var options = [{id:1,nm:"Appointment fixed"},{id:2,nm:"Call later"},{id:3,nm:"Wrong number"},{id:4,nm:"Don't call again"},{id:5,nm:"Call later"}];
{options.map((item,i) => {
return (
<div key={item.id} onChange={(i)=>this.callOptions(i)}>
<label className="radio-inline"><input type="radio" name="myRadio" ref={(el) => this["myRadioRef" + i] = el} value={item.id} onChange={this.changeRadio} />{item.nm}</label>
</div>
);
})}
Upvotes: 11
Reputation: 4457
Give a common name attribute for you radio button. Change
<input type="radio" value={i} ref={'ref_' + i} value={item.id}/>
to
<input type="radio" value={i} name="abc" ref={'ref_' + i} value={item.id}/>
Upvotes: 13