Handle Availability(disable) For Multiple Input Fields In React
I want to manage the 'disable' attribute for multiple input fields. I have created a large form (over 30 inputs), and several of them will only be available if the previous checkbox is checked.
My current setup is something like the example below. In this example you can only select 'special_offers' if 'newsletter' is selected.
class Form extends React.Component {
state={
newsletter: false,
specialOffers: false,
disabled:true,
}
handleChangeCheck = name => e => {
this.setState({
[name]: e.target.checked
});
if (name === 'newsletter') {
this.checkNewsletterValue()
}
};
checkNewsletterValue() {
if(this.state.newsletter === true){
this.setState( {disabled: !this.state.disabled} )
}
}
render() {
return(
<div>
<Checkbox name="newsletter" value={this.state.newsletter}
onChange={handleChangeCheck('newsletter')}>Sign up for news letter
</Checkbox>
<Checkbox name="special_offers" value={this.state.specialOffers}
onChange={handleChangeCheck('specialOffers')} disabled =
{this.state.disabled}>
Sign up special offers
</Checkbox>
</div>
);
}
};
My problem is that I would end up with an even larger state if I need to create a new state to change the 'disable' attribute for every single input field that is dependant on a previous selection.
Is there a way to create a generalised solution to handle all 'disable' values for my input fields?
Answer
Let's say that we have a key for each input
, a key for each checkbox
.
in this case we have newsletter
and special_offers
the scenario I'm proposing is to have an array in state:
- checkedBoxes
- to store the values of the names of the boxes that control whether the other boxes are allowed or not.
and in your default handleChangeCheck
, each time a box that is checked, we push it's name to the array.
handleChangeCheck = name => e => {
let newCheckedBoxes = [...this.state.checkedBoxes]//don't forget to add a default value for that in the state as an array.
//conditionally add or remove the items.
if(newCheckedBoxes.indexOf(name)){
newCheckedBoxes = newCheckedBoxes.filter(_name => _name !== name);
} else {
newCheckedBoxes.push(name);
}
e.target.checked && newCheckedBoxes.push(name)
this.setState({
[name]: e.target.checked,
checkedBoxes: newCheckedBoxes,
});
};
and in your conditionally disabled boxes.
<Checkbox
name="special_offers"
value={this.state.specialOffers}
onChange={handleChangeCheck('specialOffers')}
disabled={!this.state.checkedBoxes.includes('newsletter')}>
Sign up special offers
</Checkbox>
Related Questions
- → Import statement and Babel
- → should I choose reactjs+f7 or f7+vue.js?
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → .tsx webpack compile fails: Unexpected token <
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → React Native with visual studio 2015 IDE
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM
- → How do I determine if a new ReactJS session and/or Browser session has started?
- → Alt @decorators in React-Native
- → How to dynamically add class to parent div of focused input field?