简体   繁体   中英

Filter based on multiple select values

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

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
        }
    });
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM