Home > Net >  Filter based on multiple select values
Filter based on multiple select values

Time:08-25

I have a data with the format like this

const data = [
  {
    dealId: 1,
    name: "deal 1",
    funding_type: "D",
    category: "Industrials",
    status: "Funding",
    topic: "Latest"
  },
  {
    dealId: 2,
    name: "deal 2",
    funding_type: "E",
    category: "Financials",
    status: "Launching",
    topic: "Most Funded"
  },
  ...
]

I have four filter dropdowns and I am trying to filter multiple values at once, but I can only seem to filter one at a time. How can I achieve this ?

Here is my approach

  const [filteredData, setFilteredData] = useState([]);

 function myFilter(selectedValue, type, toFilterData) {
    return toFilterData.filter((item) => {
      const filter = {
        category: true,
        type: true,
        status: true,
        topic: true
      };

      if (type === "category")
        filter.category = item.category === selectedValue;

      if (type === "type") filter.type = item.funding_type === selectedValue;

      if (type === "status") filter.status = item.status === selectedValue;

      if (type === "topic") filter.topic = item.topic === selectedValue;

      return filter.category && filter.type && filter.status && filter.topic;
    });
  }

  function handleChangeTest(e, type) {
    const arr = myFilter(e.target.value, type, data);

    setFilteredData(arr);
  }

   return (

       <select
          id="filter-sector"
          className="input-field cursor-pointer"
          onChange={(e) => handleChangeTest(e, "topic")}
          onSelect={(e) => handleChangeTest(e, "topic")}
        >
          {topicOptions.map((sector) => (
            <option value={sector.value} key={sector.value}>
              {sector.placeholder}
            </option>
          ))}
        </select>
    
    // ... other selects

    filteredData.length > 0
      ? filteredData.map((d) => <div>{d.name}</div>)
      : null
  );

You can see my full code here CodeSandbox

CodePudding user response:

Why are you checking in your filter if every props of your filter object is set to true ? Assuming your param type can have one value at a time something like the code below should work.

   function myFilter(selectedValue, type, toFilterData) {
    return toFilterData.filter((item) => {
        switch (type) {
            case "category":
                return item.category === selectedValue
            case "type":
                return item.funding_type === selectedValue
            case "status":
                return item.status === selectedValue
            case "topic":
                return item.topic === selectedValue
            default:
                return false
        }
    });
}

CodePudding user response:

Turned out I was always filtering my original data and not the filtered data from other selected categories, changing my render function and onChange function works

Got some reference from this answer

function renderList() {
    let filteredItems = testData.data;

    ["category", "funding_type", "status", "topic"].forEach(function (
      filterBy
    ) {
      const filterValue = testData[filterBy];
      if (filterValue) {
        filteredItems = filteredItems.filter(function (item) {
          return item[filterBy] === filterValue;
        });
      }
    });

    console.log(filteredItems);
    return (
      <div className="container">
        <div className="filter-form">
          <FilterItems data={filteredItems} />
        </div>
      </div>
    );
  }

Full code here

  • Related