I’m new to using this site, not sure if I need to edit my original question or if starting a new one is the appropiate way of doing things.
Anyway, I got some help yesterday with filtering using Javascript. Thanks again to those who helped me out. I tried to add another filter (price), along with modifying the javascript, but it’s not working. The Color and Size work like they’re suppose to, but I wanted to add another category, "price", to also aid in drilling-down the filtering.
-
What I’m trying to do it have the user select one or all the Colors and have those products displayed. If no Color is choosen then display all the products.
(That is already working) -
Then when/if they choose a Size or multiple Sizes, only show the products in the Colors from #1 AND the sizes chosen. If no Color is chosen then only show products with the choosen Size.
(That is already working) -
Now I’m trying to include another category called Price but I can’t get it working. So I’m trying to use #1 and #2 filtering to include a drill-down for price. As an example; if Color and Size is not chosen, then it will only show products with the checked Price. If Green and $20 is chosen, then it will not show any products. If no Color is selected, Medium and Large are selected, and $20 is selected, it will only show Product C.
I hope that clarifies what I’m trying to do. If anyone can help, that would be greatly appreciated!
const filterCheckboxes = document.querySelectorAll('.filter-checkbox');
const colorCheckboxes = document.querySelectorAll('.color-checkbox');
const sizeCheckboxes = document.querySelectorAll('.size-checkbox');
const priceCheckboxes = document.querySelectorAll('.price-checkbox');
const filterables = document.querySelectorAll('.filterable');
function updateFilter() {
const colorChecked = Array.from(colorCheckboxes)
.filter(checkbox => checkbox.checked)
.map(checkbox => checkbox.value);
const sizeChecked = Array.from(sizeCheckboxes)
.filter(checkbox => checkbox.checked)
.map(checkbox => checkbox.value);
const priceChecked = Array.from(priceCheckboxes)
.filter(checkbox => checkbox.checked)
.map(checkbox => checkbox.value);
if (!(colorChecked.length || sizeChecked.length || priceChecked.length)) {
filterables.forEach(filterable => {
filterable.style.display = 'block';
})
return;
}
filterables.forEach(filterable => {
const colors = filterable.dataset.colors.split(' ');
if (colorChecked.length >= 1 && sizeChecked.length >= 1 && priceChecked.length >= 2) {
if (colorChecked.includes(colors[0]) && sizeChecked.includes(colors[1]) && priceChecked.includes(colors[2])) {
filterable.style.display = 'block';
} else {
filterable.style.display = 'none';
}
} else {
if (colorChecked.includes(colors[0]) || sizeChecked.includes(colors[1]) || priceChecked.includes(colors[2])) {
filterable.style.display = 'block';
} else {
filterable.style.display = 'none';
}
}
});
}
filterCheckboxes.forEach(checkbox => {
checkbox.addEventListener('change', updateFilter);
});
updateFilter(); // initial filter based on default checkbox state
<div>
<h3>Color</h3>
<label><input type="checkbox" class="filter-checkbox color-checkbox" value="red">Red</label>
<label><input type="checkbox" class="filter-checkbox color-checkbox" value="green">Green</label>
<label><input type="checkbox" class="filter-checkbox color-checkbox" value="blue">Blue</label>
</div>
<div>
<h3>Size</h3>
<label><input type="checkbox" class="filter-checkbox size-checkbox" value="small">Small</label>
<label><input type="checkbox" class="filter-checkbox size-checkbox" value="medium">Medium</label><label>
<input type="checkbox" class="filter-checkbox size-checkbox" value="large">Large</label>
</div>
<div>
<h3>Price</h3>
<label><input type="checkbox" class="filter-checkbox price-checkbox" value="10">$10</label>
<label><input type="checkbox" class="filter-checkbox price-checkbox" value="20">$20</label><label>
<input type="checkbox" class="filter-checkbox price-checkbox" value="30">$30</label>
</div>
<div>
<br>
<hr>
<h1>Filtered Result</h1>
<div class="filterable" data-colors="blue large 30">Product A</div>
<div class="filterable" data-colors="green small 10">Product B</div>
<div class="filterable" data-colors="red medium 20">Product C</div>
<div class="filterable" data-colors="red large 30">Product D</div>
</div>
2
Answers
You missed it in the selector. It should be
document.querySelectorAll('.price-checkbox');
This can be shortened so much
Note I delegate from the nearest static container. Here I wrapped the filters in a div
Please note
every
only shows the elements that matches ALL filters.some
matches any element that contains a checked filter