I have been trying to set up a filter on an array of items so that when the user clicks a checkbox, the list will display only items based on their selection. It needs to allow for multiple selections so that ANY (not ALL) of the multiple conditions are applied to the filter.
The code below is what I have, but it only applies the filter to the first checkbox, everytime I select a second, or third checkbox, the filter doesn't change.
let filterOptions = document.querySelectorAll(".filter_checkbox")
var filterList = [];
const handleFilterCheckbox = (e) => {
for(var i=0; filterOptions[i]; i++){
if(filterOptions[i].checked){
filterList.push(filterOptions[i].value);
}
}
console.log(filterList)
var getFilteredResults = hotelsList.filter(function (result) {
for(var i=0; i < filterList.length; i++){
return filterList.indexOf(result.locationName) >= 0;
}
});
if(filterList.length > 0){
setHotelsList(getFilteredResults)
}else{
setHotelsList(hotels)
}
}
UPDATE: Below is the full code
import { useState } from 'react'
import './cards.styles.css'
import Card from '../card/Card'
import hotels from '../../data/hotels_array'
export default function Cards(){
const [hotelsList, setHotelsList] = useState(hotels)
const handleSortChange = (e) => {
const sortValue = e.target.value
const copyHotelsList = [...hotelsList]
if(sortValue === "sort-default"){
setHotelsList(hotels)
}else{
copyHotelsList.sort((a, b) => {
if(sortValue === "sort-price-lh"){
return a.fromPrice - b.fromPrice
}else if (sortValue === "sort-price-hl"){
return b.fromPrice - a.fromPrice
}else if(sortValue === "sort-review-score"){
return b.guestRating - a.guestRating
}
})
setHotelsList(copyHotelsList)
}
}
const hotelCards = hotelsList.map(hotel =>{
return (
<Card
key={hotel.hotelId}
{...hotel}
/>
)
})
const hotelsListUniqueByLocation = [...new Map(hotels.map(item => [item.locationName, item])).values()];
let filterOptions = document.querySelectorAll(".filter_checkbox")
var filterList = [];
const handleFilterCheckbox = (e) => {
for(var i=0; filterOptions[i]; i++){
if(filterOptions[i].checked){
filterList.push(filterOptions[i].value);
}
}
console.log(filterList)
var getFilteredResults = hotelsList.filter(function (result) {
for(var i=0; i < filterList.length; i++){
return filterList.indexOf(result.locationName) >= 0;
}
});
if(filterList.length > 0){
setHotelsList(getFilteredResults)
}else{
setHotelsList(hotels)
}
}
const hotelLocations = hotelsListUniqueByLocation.map(location =>{
if(location.locationName != ""){
return (
<li key={location.locationName}>
<input type="checkbox" id={location.locationName} value={location.locationName} onChange={handleFilterCheckbox} className="filter_checkbox" />
<label htmlFor={location.locationName} className='fs12p'>{location.locationName}</label>
</li>
)
}
})
return(
<div className="results_container">
<aside>
<h3>Filter</h3>
Sorted by:
<select onChange={handleSortChange}>
<option value="sort-default">Recommended</option>
<option value="sort-price-lh">Price (low to high)</option>
<option value="sort-price-hl">Price (high to low)</option>
<option value="sort-review-score">Review score</option>
</select>
<div>
<input type="checkbox" value="wififree" id="wififree" className="filter_checkbox" />
<label htmlFor="wififree" className='fs12p'>Free Wi-Fi</label>
</div>
<div>
<ul className='hotel_locations'>
{hotelLocations}
</ul>
</div>
</aside>
<section className='cards_container container'>
{hotelCards}
</section>
</div>
)
}