user6761897
user6761897

Reputation:

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.

Upvotes: 1

Views: 285

Answers (1)

phoa
phoa

Reputation: 261

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>

);
}

Upvotes: 1

Related Questions