Filter array of objects through checkboxes
So I had to do a couple changes in your code in order to address for proper filtering:
- Added a
value
key on bothlistCheckboxesRating
andlistCheckboxesGenre
to use it for filtering.
export const listCheckboxesGenre = [ { id: 0, name: 'genre', label: 'Any Genre', value: '' }, ...}
- updated
onChangeHandler
to passvalue
back tohandleFilters
instead of theid
const onChangeHandler = (checkboxId) => { // ... handleFilters(newState.map((id) => list[id].value));};
- Created a couple filter functions to filter movies.
const handleFilters = (checkboxState, key) => { const newFilters = { ...selected }; newFilters[key] = checkboxState; const hasFilters = newFilters.rating.length > 0 || newFilters.genre.length > 0; const filterRating = (module) => newFilters.rating.includes(0) || newFilters.rating.includes(module.rating); const filterGenre = (module) => newFilters.genre.includes('') || newFilters.genre.includes(module.genre); const filteredMovies = data.filter( (m) => !hasFilters || filterRating(m) || filterGenre(m) ); setMovies(filteredMovies); setSelected(newFilters);};
WORKING DEMO:
I did some refactoring.
- Made data more generic.
export const listCheckboxesRating = { key: 'rating', data: [ { id: 1, name: 'rating1', label: 'Rating 1', value: 1 }, ... }
- Refactor Checkbox component and just pass data.
<Checkboxes list={listCheckboxesGenre} handleFilters={handleFilters} />
- Made filtration process work with value and key.
// Filtration process let filteredMovies = data.filter((movie) => { for (let key in newFilters) { if ( newFilters.hasOwnProperty(key) && Array.isArray(newFilters[key]) && newFilters[key].length > 0 ) { if ( newFilters[key].findIndex((value) => movie[key] === value) === -1 ) { return false; } } } return true; });
Working DEMO:https://codesandbox.io/s/react-filter-forked-gs2b2?file=/src/components/App.js