StochasticNerd StochasticNerd - 21 days ago 6
CSS Question

Toggling CSS as a state for li items in React

I've a list of photos being displayed as a React Component.
The individual list items are initially displayed with a

+
sign. The behavior I'm trying to acheive is on clicking a particular list item, the sign changes to
-
, and once a different list item is clicked, the first one reverts to
+
and the current one goes to
-
.
This is my render code,

render() {
let classes = "glyphicon add-icon " + (this.state.glyphClass ? "glyphicon-plus" : "glyphicon-minus");
return (
<div className="row">

<ul className="list-inline">
{this.props.images.map(function (image) {

return (<li key={image.id}>
<a href="#" onClick={this.getMediaId} data-id={image.id} data-class={image.src} data-owner={image.owner}>
<div className="img-wrapper">
<div className="img" style={{backgroundImage: `url(${image.src})`}}></div>
<div className="img-selector">
<span className={classes} id="plus-icon" aria-hidden="true"></span>
</div>
</div>
</a>
</li>);
}, this)}

</ul>
</div>

);
}


This is the constructor,

constructor(props){
super(props);
this.getMediaId = this.getMediaId.bind(this);
this.state = { glyphClass : true };
}


And this is the method that does the toggle,

getMediaId(event){
event.preventDefault();
this.setState({
glyphClass: !this.state.glyphClass

});
console.log(this.state.glyphClass);
....
}


The behavior that I'm getting now is that onClick on any list item all the list items are toggling to
-
and then on a subsequent click all are toggling to
+
. I'd really appreciate some help in fixing this.

Answer

You can have a selectedItem in the state instead.

constructor(props){
    super(props);
    this.getMediaId = this.getMediaId.bind(this);
    this.state = { selectedItem : null };
}

Then in the get media set the id of selectedItem when clicked.

getMediaId(id){
    this.setState({
      selectedItem: id
    });
}

Then you can check the id when rendering the list. if the selectedItem has the same id of the list, render the - else render +.

render() {
return (
  <div className="row">

      <ul className="list-inline">
        {this.props.images.map(function (image) {

          const classes = this.state.selectedItem === image.id ? 'glyphicon add-icon glyphicon-minus' : 'glyphicon add-icon glyphicon-plus';

          return (<li key={image.id}>
                      <a href="#" onClick={(event) => {event.preventDefault(); this.getMediaId(image.id); }} data-id={image.id} data-class={image.src} data-owner={image.owner}>
                        <div className="img-wrapper">
                          <div className="img" style={{backgroundImage: `url(${image.src})`}}></div>
                            <div className="img-selector">
                                <span className={classes} id="plus-icon" aria-hidden="true"></span>
                            </div>
                        </div>
                      </a>
                  </li>);
        }, this)}

      </ul>
    </div>

);
}