javascriptreactjssetstatereact-component

Filter The List Using Multiple CheckBoxes in React Js


Hello guys i am trying to filter the list of array of objects onClick of the checkbox based on a condition, but my else condition in handle method's is returning me a same array the state doesn't change,so i want default list that is remove filtered list when i try to uncheck the checkbox on all of it.

import React from "react";
import "./Search.css";

class Search extends React.Component {
  constructor() {
    super();
    this.state = {
      searchLists: [
        {
          id: 1,
          type: "All",
          name: "Akash",
          location: "bangalore",
          experience: 1
        },
        {
          id: 2,
          type: "FullTime",
          name: "feroz",
          location: "mumbai",
          experience: 3
        },
        {
          id: 3,
          type: "PartTime",
          name: "Farheen",
          location: "agra",
          experience: 5
        },
        {
          id: 4,
          type: "Freelancer",
          name: "Raju",
          location: "chennai",
          experience: 6
        },
        {
          id: 5,
          type: "All",
          name: "Asif",
          location: "vegas",
          experience: 7
        }
      ],
      checked: false
    };
  }

  handleAll = () => {
    console.log("i clicked");
    if (this.state.checked === false) {
      const filteredAll = this.state.searchLists.filter(
        item => item.type === "All"
      );

      console.log(filteredAll);
      this.setState({ searchLists: filteredAll, checked: true });
    } else {
      setTimeout(() => {
        this.setState({
          searchLists: this.state.searchLists,
          checked: false
        });
      }, 10000);
    }
  };

  handleFullTime = () => {
    if (this.state.checked === false) {
      const filteredFullTime = this.state.searchLists.filter(
        item => item.type === "FullTime"
      );
      console.log(filteredFullTime);
      this.setState({ searchLists: filteredFullTime, checked: true });
    } else {
      setTimeout(() => {
        this.setState({
          searchLists: this.state.searchLists,
          checked: false
        });
      }, 10000);
    }
  };

  handlePartTime = () => {
    if (this.state.checked === false) {
      const filteredPartTime = this.state.searchLists.filter(
        item => item.type === "PartTime"
      );
      console.log(filteredPartTime);
      this.setState({ searchLists: filteredPartTime, checked: true });
    } else {
      setTimeout(() => {
        this.setState({
          searchLists: this.state.searchLists,
          checked: false
        });
      }, 10000);
    }
  };

  handleFreelancer = () => {
    if (this.state.checked === false) {
      const filteredFreelancer = this.state.searchLists.filter(
        item => item.type === "Freelancer"
      );
      console.log(filteredFreelancer);
      this.setState({ searchLists: filteredFreelancer, checked: true });
    } else {
      setTimeout(() => {
        this.setState({
          searchLists: this.state.searchLists,
          checked: false
        });
      }, 10000);
    }
  };

  render() {
    console.log("rendered");
    const mapped = this.state.searchLists.map(item => {
      return (
        <div key={item.id}>
          <li>
            {item.name}
            {item.type}
          </li>
        </div>
      );
    });
    return (
      <div className="searchContainer">
        <form>
          <label htmlFor="myInput">All</label>
          <input
            id="myInput"
            type="checkbox"
            onClick={this.handleAll}
            checked={this.state.checked}
          />
          <label htmlFor="myInput">FullTime</label>
          <input id="myInput" type="checkbox" onClick={this.handleFullTime} />
          <label htmlFor="myInput">PartTime</label>
          <input id="myInput" type="checkbox" onClick={this.handlePartTime} />
          <label htmlFor="myInput">Freelancer</label>
          <input id="myInput" type="checkbox" onClick={this.handleFreelancer} />
        </form>
        <ul style={{ marginLeft: "70px" }}>{mapped}</ul>
      </div>
    );
  }
}

export default Search;


here is the link to my code https://codesandbox.io/s/eloquent-brattain-orv76?file=/src/Search.js


Solution

  • The checked state is not valid. We should store it as an array and push/pop the checked/unchecked items from it.

    https://codesandbox.io/s/upbeat-ramanujan-b2jui

    import React from "react";
    import "./Search.css";
    
    class Search extends React.Component {
      constructor() {
        super();
        this.state = {
          filterList: [
            {
              id: 11,
              name: "Part Time",
              value: "PART_TIME"
            },
            {
              id: 12,
              name: "Full Time",
              value: "FULL_TIME"
            },
            {
              id: 13,
              name: "Freelancer",
              value: "FREELANCER"
            }
          ],
          searchLists: [
            {
              id: 1,
              type: "PART_TIME",
              name: "Akash",
              location: "bangalore",
              experience: 1
            },
            {
              id: 2,
              type: "PART_TIME",
              name: "feroz",
              location: "mumbai",
              experience: 3
            },
            {
              id: 3,
              type: "FULL_TIME",
              name: "Farheen",
              location: "agra",
              experience: 5
            },
            {
              id: 4,
              type: "FREELANCER",
              name: "Raju",
              location: "chennai",
              experience: 6
            },
            {
              id: 5,
              type: "FULL_TIME",
              name: "Asif",
              location: "vegas",
              experience: 7
            }
          ],
          activeFilter: []
        };
      }
    
      onFilterChange(filter) {
        const { filterList, activeFilter } = this.state;
        if (filter === "ALL") {
          if (activeFilter.length === filterList.length) {
            this.setState({ activeFilter: [] });
          } else {
            this.setState({ activeFilter: filterList.map(filter => filter.value) });
          }
        } else {
          if (activeFilter.includes(filter)) {
            const filterIndex = activeFilter.indexOf(filter);
            const newFilter = [...activeFilter];
            newFilter.splice(filterIndex, 1);
            this.setState({ activeFilter: newFilter });
          } else {
            this.setState({ activeFilter: [...activeFilter, filter] });
          }
        }
      }
    
      render() {
        const { filterList, activeFilter } = this.state;
        let filteredList;
        if (
          activeFilter.length === 0 ||
          activeFilter.length === filterList.length
        ) {
          filteredList = this.state.searchLists;
        } else {
          filteredList = this.state.searchLists.filter(item =>
            this.state.activeFilter.includes(item.type)
          );
        }
        return (
          <div className="searchContainer">
            <form>
              <label htmlFor="myInput">All</label>
              <input
                id="myInput"
                type="checkbox"
                onClick={() => this.onFilterChange("ALL")}
                checked={activeFilter.length === filterList.length}
              />
              {this.state.filterList.map(filter => (
                <React.Fragment>
                  <label htmlFor={filter.id}>{filter.name}</label>
                  <input
                    id={filter.id}
                    type="checkbox"
                    checked={activeFilter.includes(filter.value)}
                    onClick={() => this.onFilterChange(filter.value)}
                  />
                </React.Fragment>
              ))}
            </form>
            <ul style={{ marginLeft: "70px" }}>
              {filteredList.map(item => (
                <div key={item.id}>
                  <li>
                    {item.name} -- {item.type}
                  </li>
                </div>
              ))}
            </ul>
          </div>
        );
      }
    }
    
    export default Search;