user3209048 user3209048 - 1 month ago 18
React JSX Question

toggle background color of selected list item react.js

what i want to do it when i click on one of the list items i want the class selected to be applied and when i click again i want it to be removed, so basically a toggle function, but it happens to all 3 list items, so if i click on one, all get selected, but i want it so only one can be selected at a time

import React from 'react';



export default class Order extends React.Component {
constructor() {
super()
this.state = {
selected: false,
};
}

toggleChoice() {
const selected = !this.state.selected;
this.setState({selected});
}
render() {
const { selected } = this.state;
const selectedCircle = selected ? " selected":"";
return (
<div class="container" id="order-layout">
<div class="row">

<div class="card-panel white">
<div class="center">
<h5>Your Order</h5>
<p class="margin-top-30 bold">Choose Pizza size in cm</p>
<ul class="margin-top-30">
<li ><div onClick={this.toggleChoice.bind(this)} class={"circle-20 hovered-circle" + selectedCircle}>20</div></li>
<li ><div onClick={this.toggleChoice.bind(this)} class={"circle-30 hovered-circle" + selectedCircle}>30</div></li>
<li ><div onClick={this.toggleChoice.bind(this)} class={"circle-40 hovered-circle" + selectedCircle}>40</div></li>
</ul>

</div>
</div>

</div>
</div>
);
}
}

Answer

In your case selectedCircle has the same value for all list items. If you click on one of list items selectedCircle changes for the other ones too.

Thus, you need for every list item the different piece of state.

You can try something like this :

First change your state to :

this.state = {
  selectedCircle: {},
};

Your toggleChoice function needs to know on which list item you clicked. You can change it to something like this :

toggleChoice(name, event) {
   let selected = this.state.selectedCircle;
   selected = {};
   let selectedCircles = selected[name] == "selected" ? "" : "selected";
   selected[name] = selectedCircles;
   this.setState({selectedCircle: selected});
}

Then in your render you need to add to every list item the appropriate piece of state. Change your render function to something like :

render() {

return (
    <div className="container" id="order-layout">
        <div className="row">

                <div className="card-panel white">
                  <div className="center">
                    <h5>Your Order</h5>
                    <p className="margin-top-30 bold">Choose Pizza size in cm</p>
                    <ul className="margin-top-30">
                        <li ><div onClick={this.toggleChoice.bind(this, "first")} className={"circle-20 hovered-circle " + this.state.selectedCircle["first"]}>20</div></li>
                        <li ><div onClick={this.toggleChoice.bind(this, "second")} className={"circle-30 hovered-circle " + this.state.selectedCircle["second"]}>30</div></li>
                        <li ><div onClick={this.toggleChoice.bind(this, "third")} className={"circle-40 hovered-circle " + this.state.selectedCircle["third"]}>40</div></li>
                    </ul> 

                  </div>
                </div>

        </div>
    </div>
);

And voilà, that should work. Here is jsfiddle.

Hope this helps.

Comments