Hassan Shahbaz
Hassan Shahbaz

Reputation: 606

Toggle Show/Hide `active` class on li's in react js

Hi i want to show/hide the class when click on li's in a ul. Following is the code of ul:

<ul className="period">
                            <li className="" onClick={this.onChangeForDays} value="Indefinitely">Indefinitely</li>
                            <li className="active" onClick={this.onChangeForDays} value="1">1 Day</li>
                            <li className="" onClick={this.onChangeForDays} value="7">1 Week</li>
                            <li className="" onClick={this.onChangeForDays} value="30">1 Month</li>
                            <li className="" onClick={this.onChangeForDays} value="90">3 Months</li>
                            <li className="" onClick={this.onChangeForDays} value="180">6 Months</li>
                        </ul>

So what i want to achieve is to write a common function when i click on any of the <li> it should show active class for that particular <li> and hide the active class for all other <li>. One more thing i want to show active class by default on one of the <li> as well so lets say i want first <li> to have active class by default, i tried to write the function but i got stuck.

   onChangeForDays(changeEvent) {
    this.setState({
        'fordays': changeEvent.target.value,
        'isActive': true
    });
}

how can i achieve this can someone help. Thanks

Upvotes: 1

Views: 1618

Answers (2)

Cat_Enthusiast
Cat_Enthusiast

Reputation: 15688

You can store the list of items in an array, and give each item object a clicked property like this.

let listItems = [
  { days: "Indefinitely", clicked: true, desc: "Indefinitely" },
  { days: 1, clicked: false, desc: "1 Day" },
  { days: 7, clicked: false, desc: "1 Week" },
  { days: 30, clicked: false, desc: "1 Month" },
  { days: 90, clicked: false, desc: "3 Months" },
  { days: 180, clicked: false, desc: "6 Months" }
];

This pattern will make your code more manageable. Also, it will make it easier to keep track of the "active" state of each item. Then create a list-iterating function to render the list-items with their corresponding days.

See working sandbox: https://codesandbox.io/s/pensive-ptolemy-oguo1

import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";

let listItems = [
  { days: 1, clicked: true, desc: "1 Day" },
  { days: 7, clicked: false, desc: "1 Week" },
  { days: 30, clicked: false, desc: "1 Month" },
  { days: 90, clicked: false, desc: "3 Months" },
  { days: 180, clicked: false, desc: "6 Months" }
];

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      listItems: listItems
    };
  }

  handleOnClick = e => {
    const { listItems } = this.state;

    const updatedItems = listItems.map(item => {
      if (item.days == e.target.value) {
        return {
          ...item,
          clicked: true
        };
      } else {
        return {
          ...item,
          clicked: false
        };
      }
    });

    this.setState({
      listItems: updatedItems
    });
  };

  createListItems = () => {
    const { listItems } = this.state;

    return listItems.map(item => {
      return (
        <li
          onClick={this.handleOnClick}
          className={item.clicked ? "active" : ""}
          value={item.days}
        >
          {item.desc}
        </li>
      );
    });
  };

  render() {
    return <ul>{this.createListItems()}</ul>;
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

The handleOnClick function will create an updated array of items. It will find the item selected and set clicked to true. All other items will have click set to false.

To determine what class each item will have, we use a ternary operator to check whether its own clicked property is true, which again can be changed by handleOnClick()

<li
  onClick={this.handleOnClick}
  className={item.clicked ? "active" : ""}
  value={item.days}
>

Upvotes: 1

Tien Duong
Tien Duong

Reputation: 2595

You can use this.state.fordays in render to check which element is active

<li className={this.state.fordays === 'Indefinitely' ? 'active' : ''} onClick={this.onChangeForDays} value="Indefinitely">Indefinitely</li>

Upvotes: 1

Related Questions