#javascript #filter #shop
#javascript
Вопрос:
<div class="col-lg-3 col-md-6 shopItem Yellow XL Puma">
<div class="products-item ">
<div class="product-img">
<img class='img-fluid' src="img/kamizelka2.jpg" alt="kamizelka zółta">
<div class="overlay">
<a href="" class="btn mybtn1">Kup teraz</a>
</div>
</div>
<div class="product-content">
<div class="product-price">
<span class="new-price">11zł</span>
<span class="old-price">23zł</span>
</div>
<h5 class='product-name'>Kamizelka Dwa</h5>
</div>
</div>
</div>
У меня проблема, которую мне трудно объяснить.
Я попытался создать этот простой фильтр для товаров магазина.
В настоящее время эта функция принимает только один последний выбранный вариант (я имею в виду, что я не могу найти зеленый xl Adidas, но только один из этих вариантов, которые меняются при использовании назначенного элемента выбора.
Есть идеи, как это исправить?
function filterAction () {
const types = document.querySelectorAll('.form-control');
const storeProducts = document.querySelectorAll('.shopItem');
types.forEach((type)=>{
type.addEventListener('change',(e)=>{
storeProducts.forEach((product)=> {
product.style.display='none';
if(type.value =="All" ) {
product.style.display ="block"
} else {
if (product.classList.contains(type.value)) {
product.style.display = 'block'
} else {
product.style.display = "none"
}
}
})
})
})
}
filterAction();
<div class="search-item d-flex text-center">
<div class="form-group col-sm-4">
<label for="exampleFormControlSelect1">Color</label>
<select class="form-control" id="colorLabel">
<option data-filter="all">All</option>
<option data-filter="yellow">Yellow</option>
<option data-filter="green">Green</option>
<option data-filter="orange">Orange</option>
</select>
</div>
<div class="form-group col-sm-4">
<label for="exampleFormControlSelect1">Size</label>
<select class="form-control" id="exampleFormControlSelect1">
<option data-filter="all">All</option>
<option data-filter="s">S</option>
<option data-filter="m">M</option>
<option data-filter="l">L</option>
<option data-filter="xl">XL</option>
</select>
</div>
<div class="form-group col-sm-4">
<label for="exampleFormControlSelect1">Brand</label>
<select class="form-control" id="exampleFormControlSelect1">
<option data-filter="all">All</option>
<option class='options' data-filter="adidas">Adidas</option>
<option class='options' data-filter="puma">Puma</option>
<option class='options' data-filter="gucci">Gucci</option>
</select>
</div>
</div>
<!-- begin snippet: js hide: false console: true babel: false -->
Комментарии:
1. Пожалуйста, не могли бы вы поделиться кодом с
.shopItem
товарами?2. просто поделился 🙂 @Lucius
Ответ №1:
В вашем коде есть некоторые недостатки, если вы выберете какой-либо фильтр, вернетесь к предыдущему и выберите «Все», будет отображен весь магазин, даже если фильтры говорят «нет». Конечно, есть много способов создать фильтр с помощью ванильного JavaScript (и некоторые с помощью jQuery тоже), я сделал один, пытаясь не изменять большую часть вашего кода.
Во-первых, измените HTML-код вашего продукта и добавьте атрибут данных к каждому фильтру, потому что использование class к нему может быть немного запутанным:
<div class="shopItem" data-color="green" data-size="xl" data-brand="adidas">
<div class="products-item ">
<div class="product-img">
<div class="overlay">
<a href="" class="btn mybtn1">Green XL Adidas</a>
</div>
</div>
<div class="product-content">
<h5 class='product-name'>Green XL Adidas</h5>
</div>
</div>
</div>
У нас будет диктант со всеми вашими текущими пожеланиями по фильтрации:
const appliedFilters = {};
Он будет заполняться каждый раз при изменении фильтра, как:
{
size: "S",
color: "All",
brand: "Puma"
}
И, наконец, filterAction
функция:
function filterAction () {
const types = document.querySelectorAll('.form-control');
const storeProducts = document.querySelectorAll('.shopItem');
const appliedFilters = {};
types.forEach((type)=>{
type.addEventListener('change', function(e) {
appliedFilters[this.id] = this.value;
console.log(appliedFilters);
storeProducts.forEach(function(product) {
let canShow = true;
// Iterate all applied filters to determine if the product can be displayed or not
Object.keys(appliedFilters).forEach(function (key) {
// If it is 'All' option, we still can display the product
if (appliedFilters[key].toLowerCase() !== 'all' amp;amp; product.getAttribute('data-' key).toLowerCase() !== appliedFilters[key].toLowerCase()) {
canShow = false;
}
})
if (canShow) {
product.style.display = 'block';
}else{
product.style.display = 'none';
}
})
})
})
}
ДЕМОНСТРАЦИЯ:
function filterAction() {
const types = document.querySelectorAll('.form-control');
const storeProducts = document.querySelectorAll('.shopItem');
const appliedFilters = {};
types.forEach((type) => {
type.addEventListener('change', function(e) {
appliedFilters[this.id] = this.value;
console.log(appliedFilters);
storeProducts.forEach(function(product) {
let canShow = true;
// Iterate all applied filters to determine if the product can be displayed or not
Object.keys(appliedFilters).forEach(function(key) {
// If it is 'All' option, we still can display the product
if (appliedFilters[key].toLowerCase() !== 'all' amp;amp; product.getAttribute('data-' key).toLowerCase() !== appliedFilters[key].toLowerCase()) {
canShow = false;
}
})
if (canShow) {
product.style.display = 'block';
} else {
product.style.display = 'none';
}
})
})
})
}
filterAction();
.search-item {
margin-bottom: 10px;
}
<div class="search-item d-flex text-center">
<div class="form-group col-sm-4">
<label for="exampleFormControlSelect1">Color</label>
<select class="form-control" id="color">
<option data-filter="all">All</option>
<option data-filter="yellow">Yellow</option>
<option data-filter="green">Green</option>
<option data-filter="orange">Orange</option>
</select>
</div>
<div class="form-group col-sm-4">
<label for="exampleFormControlSelect1">Size</label>
<select class="form-control" id="size">
<option data-filter="all">All</option>
<option data-filter="s">S</option>
<option data-filter="m">M</option>
<option data-filter="l">L</option>
<option data-filter="xl">XL</option>
</select>
</div>
<div class="form-group col-sm-4">
<label for="exampleFormControlSelect1">Brand</label>
<select class="form-control" id="brand">
<option data-filter="all">All</option>
<option class='options' data-filter="adidas">Adidas</option>
<option class='options' data-filter="puma">Puma</option>
<option class='options' data-filter="gucci">Gucci</option>
</select>
</div>
</div>
<div class="shopItem" data-color="green" data-size="s" data-brand="puma">
<div class="products-item ">
<div class="product-img">
<div class="overlay">
<a href="" class="btn mybtn1">Green S Puma</a>
</div>
</div>
<div class="product-content">
<h5 class='product-name'>Green S Puma</h5>
</div>
</div>
</div>
<div class="shopItem" data-color="green" data-size="xl" data-brand="adidas">
<div class="products-item ">
<div class="product-img">
<div class="overlay">
<a href="" class="btn mybtn1">Green XL Adidas</a>
</div>
</div>
<div class="product-content">
<h5 class='product-name'>Green XL Adidas</h5>
</div>
</div>
</div>