Reputation: 213
I have list of items that I am showing in Checkboxlist. Items are coming from get webapi and it returns xml. On Page load, in case of is-assigned="FALSE" checkboxes are disabled, and in case of is-assigned="TRUE", checkboxes are enabled. User can only select checkboxes that are enabled.
<?xml version="1.0"?>
<Product>
<states is-assigned="FALSE" product-state-id="11">Alabama</states> disable
<states is-assigned="FALSE" product-state-id="12">Alaska</states>disable
<states is-assigned="FALSE" product-state-id="21">Arizona</states>
<states is-assigned="TRUE" product-state-id="22">Colorado</states> enable on page load
<states is-assigned="TRUE" product-state-id="33">Connect</states> enable on page load
</Product>
</xml>
export class AssignStates extends React.Component {
constructor(props) {
super(props);
this.state = {
Template_ID: "",
templatestates: [],
checkedItems: [],
}
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
const id = Number(event.target.id);
const index = this.state.checkedItems.indexOf(id);
const updatedArray = [...this.state.checkedItems];
if (index !== -1) {
updatedArray.splice(index, 1);
} else {
updatedArray.push(id);
}
this.setState((prevState) => ({
checkedItems: updatedArray
}));
}
componentDidUpdate(prevProps) {
const Template_ID = this.props.key_id;
if (prevProps.key_id !== this.props.key_id) {
console.log(`key_id: ${this.props.key_id}`);
this.getListOfStates(Template_ID);
}
}
getListOfStates(Template_ID) {
axios
.get(REQUEST_URL, { "Content-Type": "application/xml; charset=utf-8" })
.then((response) => {
const jsonDataFromXml = new XMLParser().parseFromString(response.data);
const states = jsonDataFromXml.getElementsByTagName("states");
console.log(states);
this.setState({
templatestates: states,
checkedItems: states
.filter(({ attributes }) => attributes["is-assigned"] === "TRUE")
.map(({ attributes }) => Number(attributes["product-state-id"]))
});
});
}
render() {
return (
<div>
<form>
<div>
<ul> {this.state.templatestates.map((item, index) => { return ( <li key={item.attributes["product-state-id"]}> <label> <input type="checkbox" id={item.attributes["product-state-id"]} checked={this.state.checkedItems.includes( Number(item.attributes["product-state-id"]) )} value={item.value} onChange={this.handleChange} />
{item.value} </label> </li> ); })} </ul>
</div>
<button type="submit">Submit</button>
</form>
</div>
);
}
}
export default AssignStates;
Thanks
Upvotes: 0
Views: 99
Reputation: 203062
When computing the states
value that is returned for the this.state.templatestates
state value map the states
array and inject a disabled
property into each item. When mapping this.state.templatestates
to the checkbox inputs set the disabled
prop accordingly.
Example:
getListOfStates(Template_ID) {
axios
.get(REQUEST_URL, { "Content-Type": "application/xml; charset=utf-8" })
.then((response) => {
const jsonDataFromXml = new XMLParser().parseFromString(response.data);
console.log(jsonDataFromXml.getElementsByTagName('states'));
const states = jsonDataFromXml.getElementsByTagName("states");
this.setState({
templatestates: states.map((el) => ({
...el,
disabled: el.attributes["is-assigned"] === "FALSE" // <-- inject disabled property
})),
checkedItems: states
.filter(({ attributes }) => attributes["is-assigned"] === "TRUE")
.map(({ attributes }) => Number(attributes["product-state-id"]))
});
});
}
...
{this.state.templatestates.map((item, index) => {
return (
<li key={item.attributes["product-state-id"]}>
<label>
<input
type="checkbox"
id={item.attributes["product-state-id"]}
checked={this.state.checkedItems.includes(
Number(item.attributes["product-state-id"])
)}
value={item.value}
onChange={this.handleChange}
disabled={item.disabled} // <-- set disabled prop on input
/>
{item.value}
</label>
</li>
);
})}
To "toggle all" only the assigned items then filter the templatestates
array prior to mapping the id values.
toggleAll = (checked) => () =>
this.setState((prevState) => ({
checkedItems: checked
? prevState.templatestates
.filter(({ attributes }) => attributes["is-assigned"] === "TRUE")
.map(({ attributes }) => Number(attributes["product-state-id"]))
: []
}));
Upvotes: 1