anon
anon

Reputation:

Toggle active CSS state with repeating divs React.JS

I've been stuck on for days now. I'm trying to keep each div (activity) selected when the user clicks on it and able to be de-selected (essentially having a toggle state). I have a list of JSON objects and rows of divs and that have a purple background when you hover over it.

enter image description here

<script type="text/babel">
      var items = [
     {
        "topicName": "Kanye West",
        "imageURL":"https://d235mwrq2dn9n5.cloudfront.net/wp-content/uploads/2016/07/Kanye-West-2-11-16-1-616x440-111.jpg"
     },
     {
        "topicName": "Kanye West",
        "imageURL":"https://d235mwrq2dn9n5.cloudfront.net/wp-content/uploads/2016/07/Kanye-West-2-11-16-1-616x440-111.jpg"
     },
     {
        "topicName": "Kanye West",
        "imageURL":"https://d235mwrq2dn9n5.cloudfront.net/wp-content/uploads/2016/07/Kanye-West-2-11-16-1-616x440-111.jpg"
     },
     {
        "topicName": "Kanye West",
        "imageURL":"https://d235mwrq2dn9n5.cloudfront.net/wp-content/uploads/2016/07/Kanye-West-2-11-16-1-616x440-111.jpg"
     },
     {
        "topicName": "Kanye West",
        "imageURL":"https://d235mwrq2dn9n5.cloudfront.net/wp-content/uploads/2016/07/Kanye-West-2-11-16-1-616x440-111.jpg"
     },
     {
        "topicName": "Kanye West",
        "imageURL":"https://d235mwrq2dn9n5.cloudfront.net/wp-content/uploads/2016/07/Kanye-West-2-11-16-1-616x440-111.jpg"
     },
     {
        "topicName": "Kanye West",
        "imageURL":"https://d235mwrq2dn9n5.cloudfront.net/wp-content/uploads/2016/07/Kanye-West-2-11-16-1-616x440-111.jpg"
     },
     {
        "topicName": "Kanye West",
        "imageURL":"https://d235mwrq2dn9n5.cloudfront.net/wp-content/uploads/2016/07/Kanye-West-2-11-16-1-616x440-111.jpg"
     },
     {
        "topicName": "Kanye West",
        "imageURL":"https://d235mwrq2dn9n5.cloudfront.net/wp-content/uploads/2016/07/Kanye-West-2-11-16-1-616x440-111.jpg"
     }
  ];

    var RepeatModule = React.createClass({
     getDefaultProps: function() {
      return { items: [] }
     },
     render: function() {

      var listItems = this.props.items.map(function(item) {
       return ( 

       <div className="column one-quarter"> 
        <div className="topicContainer">  
          <h3>{item.topicName}</h3>,
            <img src={item.imageURL}/>
        </div>
      </div>

       );
      });
      return (
        <div>
          {listItems}      
        </div>
      );
     }
    });
    ReactDOM.render(<RepeatModule items={items} />,     
     document.getElementById('topics'));
  </script>
  </head>
  <body>
  <div class="container">
    <div class="centerInterests row">
      <p class="select">Select 3 or more activities to personalize your feed</p>
      <input class="interestBox pad-75-left" type="text" placeholder="Search for activities">
      <p class="topicText">Popular Activities</p>
      <div class="row">
        <div id="topics"></div> 
      </div>
    </div>
  </div>

  <script src="/javascripts/start.js" type="text/javascript"></script> 
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script type="text/javascript">
    // $('.topicContainer').on('click', function (e) {
    //     $('.topicContainer').toggleClass("purpleOverlay");
    // });

    // $('div.topicContainer').click(function(){
    //    $('.topicContainer').toggleClass("purpleOverlay");
    //    console.log("here I go");
    // });
  </script>
  </body>

CSS Code:

.topicImage {
    padding-bottom: 75%;
    background-position: 50% 50%;
    background-repeat: no-repeat;
    background-size: cover;
    margin: 0 auto;
    position: relative !important;
    height:150px;
    background-color: rgba(0, 0, 0, 0.8) !important;

}

.text-inside-image {
  position: absolute;
  top: 20%;
  left: 35%;
  color: white;
  font-size: 24px;
  font-weight: 500;
  z-index: 1;
}

.topicContainer {
    position: relative;
    background-color: #171616;
    overflow: hidden;
    height: 150px;
}
.topicContainer h3 {
    text-align: center;
    z-index: 2;
    position: relative;
    color: #fff;
    padding: 50px;
} 
.topicContainer img {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: auto;
    z-index: 1;
    opacity: 0.6;
}

.topicContainer:hover {
  background-color: #5450DC;
}

.topicContainer.active {
  background-color: #5450DC;
}

.purpleOverlay {
  background-color: #5450DC;
}

I've tried everything from JQuery implementations to toggle active CSS states to implementing handleclick in React.js (i.e. https://jsfiddle.net/uwadhwnr/)

Why is this occurring? How can I solve this problem?

Upvotes: 1

Views: 1409

Answers (1)

Oleksandr T.
Oleksandr T.

Reputation: 77482

You need use states in order to handle active element,

var RepeatModule = React.createClass({
  getDefaultProps: function () {
    return { items: [] }
  },

  getInitialState: function () {
    return { items: [] }
  },

  componentDidMount: function () {
    const items = this.props.items.map((item) => {
      return Object.assign(item, { isActive: false });
    });

    this.setState({ items });
  },

  handleClick: function (e, index) {
    const items = this.state.items
      .map((item, i) => {
        if (index === i) {
          return Object.assign(item, { isActive: !item.isActive });
        } 

        return item;
      });

    this.setState({ items });
  },

  render: function() {
    const items = this.state.items.map((item, index) => {
      return <div className="column one-quarter" key={ index }>
        <div
          className={`topicContainer ${ item.isActive ? 'purpleOverlay' : '' }`}
          onClick={ (e) => this.handleClick(e, index) }
        >
          <h3>{ item.topicName }</h3>, <img src={ item.imageURL } />
        </div>
      </div>
    });

    return <div>{ items }</div>
  }
});

Example

Upvotes: 1

Related Questions