I'm using dropdowns from PrimeReact
. I have to implement them so that the values from the first upper main dropdown change the values of all the lower ones, which I already did, but then I need than each dynamically dropdown from the lower block have to change change only its unique value:
I cannot understand how to implement it.
This is my code :
class LeagueCard extends Component {
state = {
selectedItemDefaultDropDown: this.props.cardContent.insuranceVariants[0],
selectedItemPersonallyDropDown: null
};
createOptions = (arr) => {
return arr.map(item => ({label: item, value:item}))
};
render() {
const {
cardIndex, cardContent: {
insuranceVariants,
price,
},
} = this.props;
const insuranceOptions = this.createOptions(insuranceVariants);
return (
<>
<div className={styles.header}>
<h4>League {cardIndex + 1}</h4>
<h4>Total {price.reduce((a, b) => a + b)} PLN</h4>
</div>
<div className={styles.defaultDropDownWrapper}>
<p>Default variant of the insurance program</p>
<Dropdown //MAIN DROPDOWN WORKS PERFECTLY
value={this.state.selectedItemDefaultDropDown}
options={insuranceOptions}
onChange={e => {
this.setState({ selectedItemDefaultDropDown:e.value });
}}
/>
</div>
<table>
<thead>
<tr>
<th className={styles.columnName}>#</th>
<th className={styles.columnName}>FIRST AND LAST NAME</th>
<th className={styles.columnName}>AGE</th>
<th className={styles.columnName}>VARIANT OF THE INSURANCE PROGRAM</th>
</tr>
</thead>
<tbody>
{insuranceVariants.map((item, index) =>
<tr key={index} className={(index + 1) % 2 === 0 ? styles.evenTabStyle : styles.baseTabStyle}>
<td>{index + 1}</td>
<td>Jan Nowak</td>
<td>20</td>
<td>
<Dropdown //SECONDARY DYNAMICALLY DROPDOWNS WITH TROUBLES
value={this.state.selectedItemDefaultDropDown}
options={insuranceOptions}
onChange={e => {
this.setState({ selectedItemDefaultDropDown: e.value});
}}
/>
</td>
</tr>)}
</tbody>
</table>
</>
);
}
}
There is various way to achieve this but the most simple way I can think of right now is following
Because you have 3 dropdown ( in this case ) so you need to keep 3 entry in state for each dropdown
keep your state something like this
{
primaryDropdown: 'selected option',
secondaryDropdowns: ['selected value for first', 'selected value for second']
}
I am keeping array because you can change the number of secondary dropdown dynamically
now the onChangeHandler
for primary dropdown will look like this
primaryOnChangeHander(selected) {
this.setState(prevState => {
const newState = {
...prevState,
primaryDropdown: selected,
secondaryDropdowns: prevState.secondaryDropdowns.map(item => selected )
};
return newState;
})
}
when primary dropdown changes you are going to update the primary dropdown and secondary dropdowns as well
and onChangeHander
for secondary dropdown looks like
secondaryOnChangeHander (selected, indexOfDropdown) {
this.setState(prevState => ({
...prevState,
secondaryDropdowns: prevState.secondaryDropdowns.map((item, index) => {
if (index === indexOfDropdown) {
return selected;
} else {
return item;
}
})
}))
}
When secondary dropdown value changes you only update that perticular dropdowns value
your code will now look like this
/* important note here: assuming that insuranceVariants is a fixed length array */
class LeagueCard extends Component {
state = {
/* better would be to create a variable for `this.props.cardContent.insuranceVariants[0]` and use that */
primaryDropdown: this.props.cardContent.insuranceVariants[0],
secondaryDropdowns: [this.props.cardContent.insuranceVariants.map(item => this.props.cardContent.insuranceVariants[0]]
};
createOptions = (arr) => {
return arr.map(item => ({label: item, value:item}))
};
primaryOnChangeHander(selectedValue) {
this.setState(prevState => {
const newState = {
...prevState,
primaryDropdown: selectedValue,
secondaryDropdowns: prevState.secondaryDropdowns.map(item => selectedValue)
};
return newState;
})
}
secondaryOnChangeHander (selectedValue, indexOfChangedDropdown) {
this.setState(prevState => ({
...prevState,
secondaryDropdowns: prevState.secondaryDropdowns.map((item, index) => {
if (index === indexOfChangedDropdown) {
return selectedValue;
} else {
return item;
}
})
}));
}
render() {
const {
cardIndex, cardContent: {
insuranceVariants,
price,
},
} = this.props;
const insuranceOptions = this.createOptions(insuranceVariants);
return (
<>
<div className={styles.header}>
<h4>League {cardIndex + 1}</h4>
<h4>Total {price.reduce((a, b) => a + b)} PLN</h4>
</div>
<div className={styles.defaultDropDownWrapper}>
<p>Default variant of the insurance program</p>
<Dropdown //MAIN DROPDOWN WORKS PERFECTLY
value={this.state.primaryDropdown}
options={insuranceOptions}
onChange={e => {
this.primaryOnChangeHander(e.value);
}}
/>
</div>
<table>
<thead>
<tr>
<th className={styles.columnName}>#</th>
<th className={styles.columnName}>FIRST AND LAST NAME</th>
<th className={styles.columnName}>AGE</th>
<th className={styles.columnName}>VARIANT OF THE INSURANCE PROGRAM</th>
</tr>
</thead>
<tbody>
{insuranceVariants.map((item, index) =>
<tr key={index} className={(index + 1) % 2 === 0 ? styles.evenTabStyle : styles.baseTabStyle}>
<td>{index + 1}</td>
<td>Jan Nowak</td>
<td>20</td>
<td>
<Dropdown //SECONDARY DYNAMICALLY DROPDOWNS WITH TROUBLES
value={this.state.secondaryDropdowns[index]}
options={insuranceOptions}
onChange={e => {
this.secondaryOnChangeHander(e.value, index);
}}
/>
</td>
</tr>)}
</tbody>
</table>
</>
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With