I have a checkbox filter for a product page I'm working on, and it works, but I'm getting duplicate results if an item matches multiple criteria. For example, if I check both 'Size 1' and 'Nike', the resulting product card displays twice. I would like it to only display once. Here's what I have:
let show_sizes_array = []; //Where the filtered sizes get stored
$(document).ready(function() {
showAllItems(); //Display all items with no filter applied
$(".size-filter-check").click(function() {
//When a checkbox is clicked
let size_clicked = $(this).attr("data-size"); //The certain size checkbox clicked
if ($(this).is(":checked")) {
show_sizes_array.push(size_clicked); //Was not checked so add to filter array
showItemsFiltered(); //Show items grid with filters
} else {
//Unchecked so remove from the array
show_sizes_array = show_sizes_array.filter(function(elem) {
return elem !== size_clicked;
});
showItemsFiltered(); //Show items grid with new filters
}
if (!$("input[type=checkbox]").is(":checked")) {
//No checkboxes are checked
show_sizes_array = []; //Clear size filter array
showAllItems(); //Show all items with NO filters applied
}
});
});
//Mock API data:
let category_items = [{
id: 1,
category_id: 8,
price: 39.42,
title: "Shoes with id #1",
thumbnail: "https://www.transparentpng.com/download/adidas-shoes/a4xO3G-adidas-shoes-adidas-shoe-kids-superstar-daddy-grade.png",
sizes: ["Size1"],
brand: ["Nike"]
},
{
id: 2,
category_id: 8,
price: 31.93,
title: "Shoes with id #2",
thumbnail: "https://www.transparentpng.com/download/adidas-shoes/a4xO3G-adidas-shoes-adidas-shoe-kids-superstar-daddy-grade.png",
sizes: ["Size2"],
brand: ["Adidas"]
},
{
id: 3,
category_id: 8,
price: 49.44,
title: "Shoes with id #3",
thumbnail: "https://www.transparentpng.com/download/adidas-shoes/a4xO3G-adidas-shoes-adidas-shoe-kids-superstar-daddy-grade.png",
sizes: ["Size3"],
brand: ["Nike"]
},
{
id: 4,
category_id: 8,
price: 65.38,
title: "Shoes with id #4",
thumbnail: "https://www.transparentpng.com/download/adidas-shoes/a4xO3G-adidas-shoes-adidas-shoe-kids-superstar-daddy-grade.png",
sizes: ["Size4"],
brand: ["Other"]
},
];
function showAllItems() {
//Default grid to show all items on page load in
$("#display-items-div").empty();
for (let i = 0; i < category_items.length; i++) {
let item_content =
'<div class="product-card" data-available-sizes="' +
category_items[i]["sizes"] +
'"><b>' +
category_items[i]["title"] +
'</b><br><img src="' +
category_items[i]["thumbnail"] +
'" height="64" width="64" alt="shoe thumbnail"><p>$' +
category_items[i]["price"] +
"</p></div>";
$("#display-items-div").append(item_content);
}
}
function showItemsFiltered() {
//Default grid to show all items on page load in
$("#display-items-div").empty();
for (let i = 0; i < category_items.length; i++) {
//Go through the items but only show items that have size from show_sizes_array
if (show_sizes_array.some((v) => category_items[i]["sizes"].includes(v))) {
let item_content =
'<div class="product-card" data-available-sizes="' +
category_items[i]["sizes"] +
'"><b>' +
category_items[i]["title"] +
'</b><br><img src="' +
category_items[i]["thumbnail"] +
'" height="64" width="64" alt="shoe thumbnail"><p>$' +
category_items[i]["price"] +
"</p></div>";
$("#display-items-div").append(item_content); //Display in grid
}
//Test filter for speeds//
if (show_sizes_array.some((v) => category_items[i]["brand"].includes(v))) {
let item_content =
'<div class="product-card" data-available-speed="' +
category_items[i]["sizes"] +
'"><b>' +
category_items[i]["title"] +
'</b><br><img src="' +
category_items[i]["thumbnail"] +
'" height="64" width="64" alt="shoe thumbnail"><p>$' +
category_items[i]["price"] +
"</p></div>";
$("#display-items-div").append(item_content); //Display in grid
}
//end test filter//
}
}
.product-page-wrapper {
display: flex;
padding: 20px;
}
.filter-wrapper {
border: 1px solid #eee;
width: 20%;
}
.items-wrapper {
width: 80%
}
.items {
padding: 20px;
}
.product-card {
width: 23%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="product-page-wrapper">
<!--Product Filter-->
<div class="filter-wrapper">
<h2>Filter by</h2>
<hr>
<h3>Size:</h3>
<form id="size-form">
<div class="form-check">
<input class="form-check-input size-filter-check" type="checkbox" value="" id="size-check" data-size="Size1">
<label class="form-check-label" for="size-check">Size 1</label>
</div>
<div class="form-check">
<input class="form-check-input size-filter-check" type="checkbox" value="" id="size-check" data-size="Size2">
<label class="form-check-label" for="size-check">Size 2</label>
</div>
<div class="form-check">
<input class="form-check-input size-filter-check" type="checkbox" value="" id="size-check" data-size="Size3r">
<label class="form-check-label" for="size-check">Size 3</label>
</div>
<div class="form-check">
<input class="form-check-input size-filter-check" type="checkbox" value="" id="size-check" data-size="Size4">
<label class="form-check-label" for="size-check">Size 4</label>
</div>
</form>
<h3>Brand:</h3>
<form id="brand-form">
<div class="form-check">
<input class="form-check-input size-filter-check" type="checkbox" value="" id="brand-check" data-size="Other">
<label class="form-check-label" for="size-check">Other</label>
</div>
<div class="form-check">
<input class="form-check-input size-filter-check" type="checkbox" value="" id="brand-check" data-size="Nike">
<label class="form-check-label" for="size-check">Nike</label>
</div>
<div class="form-check">
<input class="form-check-input size-filter-check" type="checkbox" value="" id="brand-check" data-size="Adidas">
<label class="form-check-label" for="size-check">Adidas</label>
</div>
<div class="form-check">
<input class="form-check-input size-filter-check" type="checkbox" value="" id="brand-check" data-size="Sketchers">
<label class="form-check-label" for="size-check">Sketchers</label>
</div>
</form>
</div>
<!--Display Items-->
<div class="items-wrapper">
<div class="items" id="display-items-div"></div>
</div>
</div>
I'm still rather new to JS, so I'm pleased that I've come as far as I have. Any help is appreciated, or if I'm using bad practices, please correct me now.
Aucun commentaire:
Enregistrer un commentaire