I made an ecommerce website and I’m trying to filter all the items by category, but I’m not able to make it work because I load my products with json/fetch (I tried the same code without using json/fetch and it works fine).
I have all my products in an array, and each product has a category (“snacks”, “candy” or “drink”), all the info for each product is in the json(category, name, id, etc). I have filter buttons for each category with it’s corresponding id.
I don’t get any error, it simply does not work. Here’s the relevant code:
//FILTER BUTTONS
<div class="filter-btns">
<button class="pb-3 filter-btn" id="all">All</button>
<button class="pb-3 filter-btn" id="drinks">Drinks</button>
<button class="pb-3 filter-btn" id="snacks">Snacks</button>
<button class="filter-btn" id="candy">Candy</button>
</div>
// LOAD PRODUCTS WITH FETCH
const URL = "products.json"
const products = []
const showProducts = (products) =>
{
let container = document.querySelector('#container');
for (const product of products)
{
let item = `<div class="filter-item all ${product.category}" id="${product.id}">
<div class="card h-100 shadow">
<img id="${product.id}" class="card-img-top" src="${product.img}" alt="..."/>
<div class="card-body p-4">
<div class="text-center">
<h5>"${product.name}"</h5>
<div class="d-flex justify-content-center small text-warning mb-2">
<div class="bi-star-fill"></div>
</div>
<span class="text-muted text-decoration-line-through"></span>
"${product.price}"
</div>
</div>
<div class="card-footer p-4 pt-0 border-top-0 bg-transparent">
<div class="text-center"><a class="cartButton btn btn-outline-dark mt-auto" id="${product.id}" href="#">Add to cart</a></div>
</div>
</div>
</div>`;
container.innerHTML += item
}
}
const getData = async () =>
{
try
{
const response = await fetch(URL);
const data = await response.json();
products.push(...data);
showProducts(data);
}
catch(e)
{
console.log(e);
}
}
getData();
// FILTER ITEMS
const allFilterItems = document.querySelectorAll('.filter-item');
const allFilterBtns = document.querySelectorAll('.filter-btn');
allFilterBtns.forEach((btn) => {
btn.addEventListener('click', () => {
showFilteredContent(btn);
});
});
function showFilteredContent(btn){
allFilterItems.forEach((item) => {
if(item.classList.contains(btn.id)){
item.style.display ="block";
}
else {
item.style.display = "none";
}
});
}
Any help would be amazing. Thanks!