英文:
jquery filter is faulty and shows all results
问题
我有一些divs
,我试图根据一些下拉筛选器来筛选它们。我正在使用data-product_cost=true
属性来筛选它们,所以如果我在下拉菜单中选择product_cost
,那么所有具有product_cost=true
属性的产品divs
将显示在列表中,而不会显示其他任何内容。
从“Kontogebühren”下拉列表中,如果选择“Kostenlose Kontoführung”,目前会显示所有卡片。它应该只显示N26、Comdirect和DKB卡片,用于“Kostenlose Kontoführung”选项选择。
我无法找到filtering_vergleiche()
函数中的错误,因为我对jQuery有点陌生。
英文:
I have a couple of divs
that I'm trying to filter them according to some dropdown filters. I'm using a data-product_cost=true
attribute to list to filter them, so if I were to pick product_cost
in the dropdown, all product divs with the product_cost=true
attribute would show up the list and not any of the rest.
From the "Kontogebühren" dropdown list, if “Kostenlose Kontoführung” is selected, currently it shows all the cards. it should show only N26, Comdirect and DKB cards for the “Kostenlose Kontoführung” option selection.
// select tag
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
jQuery(document).ready(function($) {
jQuery("#products-filter").change(function() {
filtering_vergleiche();
});
filtering_vergleiche();
function filtering_vergleiche() {
var choosen_filter = [];
jQuery('.product-item').removeClass('filter_hidden');
jQuery('.filter_no_results').remove();
jQuery('.products-filter select option:selected').each(function(index) {
var current_filter_name = jQuery(this).attr('name');
var current_filter_value = jQuery(this).attr('value');
//Create object with all necessary info
choosen_filter.push({
"name": current_filter_name,
"value": current_filter_value
});
});
count_item = 0;
count_hidden = 0;
jQuery('.product-item').each(function(index) {
for (var i = 0; i < choosen_filter.length; ++i) {
choosen_filter_item = choosen_filter[i];
choosen_filter_name = choosen_filter_item.name;
choosen_filter_value = choosen_filter_item.value;
filter_value_on_product = jQuery(this).attr('data-' + choosen_filter_name);
if (choosen_filter_value != 'alle') {
if (filter_value_on_product.indexOf(',') > -1) {
let segments = filter_value_on_product.split(',').map(element => element.trim());;
if (!segments.includes(choosen_filter_value)) {
jQuery(this).addClass('filter_hidden');
}
} else if (filter_value_on_product != choosen_filter_value) {
jQuery(this).addClass('filter_hidden');
}
}
}
count_item++;
});
jQuery('.product-item.filter_hidden').each(function(index) {
count_hidden++;
});
//Nachricht anzeigen wenn keine Produkte gefunden wurden
if (count_hidden == count_item) {
jQuery("<p class='filter_no_results'>Zu dieser Auswahl wurden leider keine Ergebnisse gefunden.<br>Bitte andere Kriterien auswählen.<p>").appendTo('.product-item-listing');
}
}
});
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<select id="filter_checkboxes" class="vergleich_select" size="1" name="term">
<option id="filter_all" name="filter_alle" value="alle">
Alle
</option>
<option id="product_cost" name="product_cost" value="true">
Kostenlose Kontoführung
</option>
<option id="incentive" name="incentive" value="true">
Mit Startguthaben
</option>
</select>
<div class="product-item" data-incentive="false" data-partnercard="false" data-atm_euro_fee="false" data-atm_international_fee="false" data- incoming_pm_min="true" data-product_cost="true">
N26
</div>
<div class="product-item " data-incentive="false" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="true" data- incoming_pm_min="false" data-product_cost="true">
ComDirect
</div>
<div class="product-item" data-incentive="false" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="true" data- incoming_pm_min="false" data-product_cost="true">
DKB
</div>
<div class="product-item" data-incentive="true" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="false" data-incoming_pm_min="false" data-product_cost="true">
Revolut
</div>
</div>
</body>
</html>
<!-- end snippet -->
I can't seem to find what's faulty in the filtering_vergleiche()
function as I'm a bit of a newbie to jQuery.
答案1
得分: 1
问题出在你的选择器上。
.change()
处理程序应该在 jQuery("#filter_checkboxes")
上。
获取选项值的循环应该使用 jQuery("#filter_checkboxes option:selected")
。
你需要为 .filter_hidden
添加 CSS 来隐藏元素。
jQuery(document).ready(function($) {
jQuery("#filter_checkboxes").change(function() {
filtering_vergleiche();
});
filtering_vergleiche();
function filtering_vergleiche() {
var choosen_filter = [];
jQuery('.product-item').removeClass('filter_hidden');
jQuery('.filter_no_results').remove();
jQuery('#filter_checkboxes option:selected').each(function(index) {
var current_filter_name = jQuery(this).attr('name');
var current_filter_value = jQuery(this).attr('value');
//创建包含所有必要信息的对象
choosen_filter.push({
"name": current_filter_name,
"value": current_filter_value
});
});
count_item = 0;
count_hidden = 0;
jQuery('.product-item').each(function(index) {
for (var i = 0; i < choosen_filter.length; ++i) {
choosen_filter_item = choosen_filter[i];
choosen_filter_name = choosen_filter_item.name;
choosen_filter_value = choosen_filter_item.value;
filter_value_on_product = jQuery(this).attr('data-' + choosen_filter_name);
if (choosen_filter_value != 'alle') {
if (filter_value_on_product.indexOf(',') > -1) {
let segments = filter_value_on_product.split(',').map(element => element.trim());;
if (!segments includes(choosen_filter_value)) {
jQuery(this).addClass('filter_hidden');
}
} else if (filter_value_on_product != choosen_filter_value) {
jQuery(this).addClass('filter_hidden');
}
}
}
count_item++;
});
jQuery('.product-item.filter_hidden').each(function(index) {
count_hidden++;
});
//如果没有找到产品,则显示消息
if (count_hidden == count_item) {
jQuery("<p class='filter_no_results'>Zu dieser Auswahl wurden leider keine Ergebnisse gefunden.<br>Bitte andere Kriterien auswählen.<p>").appendTo('.product-item-listing');
}
}
});
.filter_hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<select id="filter_checkboxes" class="vergleich_select" size="1" name="term">
<option id="filter_all" name="filter_alle" value="alle">
Alle
</option>
<option id="product_cost" name="product_cost" value="true">
Kostenlose Kontoführung
</option>
<option id="incentive" name="incentive" value="true">
Mit Startguthaben
</option>
</select>
<div class="product-item" data-incentive="false" data-partnercard="false" data-atm_euro_fee="false" data-atm_international_fee="false" data-incoming_pm_min="true" data-product_cost="true">
N26
</div>
<div class="product-item " data-incentive="false" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="true" data-incoming_pm_min="false" data-product_cost="true">
ComDirect
</div>
<div class="product-item" data-incentive="false" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="true" data-incoming_pm_min="false" data-product_cost="true">
DKB
</div>
<div class="product-item" data-incentive="true" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="false" data-incoming_pm_min="false" data-product_cost="true">
Revolut
</div>
</div>
</body>
</html>
英文:
The problem is all in your selectors.
The .change()
handler should be on `jQuery("#filter_checkboxes").
The loop to get option values should use jQuery("#filter_checkboxes option:selected")
.
You need CSS for .filter_hidden
to hide the element.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
jQuery(document).ready(function($) {
jQuery("#filter_checkboxes").change(function() {
filtering_vergleiche();
});
filtering_vergleiche();
function filtering_vergleiche() {
var choosen_filter = [];
jQuery('.product-item').removeClass('filter_hidden');
jQuery('.filter_no_results').remove();
jQuery('#filter_checkboxes option:selected').each(function(index) {
var current_filter_name = jQuery(this).attr('name');
var current_filter_value = jQuery(this).attr('value');
//Create object with all necessary info
choosen_filter.push({
"name": current_filter_name,
"value": current_filter_value
});
});
count_item = 0;
count_hidden = 0;
jQuery('.product-item').each(function(index) {
for (var i = 0; i < choosen_filter.length; ++i) {
choosen_filter_item = choosen_filter[i];
choosen_filter_name = choosen_filter_item.name;
choosen_filter_value = choosen_filter_item.value;
filter_value_on_product = jQuery(this).attr('data-' + choosen_filter_name);
if (choosen_filter_value != 'alle') {
if (filter_value_on_product.indexOf(',') > -1) {
let segments = filter_value_on_product.split(',').map(element => element.trim());;
if (!segments.includes(choosen_filter_value)) {
jQuery(this).addClass('filter_hidden');
}
} else if (filter_value_on_product != choosen_filter_value) {
jQuery(this).addClass('filter_hidden');
}
}
}
count_item++;
});
jQuery('.product-item.filter_hidden').each(function(index) {
count_hidden++;
});
//Nachricht anzeigen wenn keine Produkte gefunden wurden
if (count_hidden == count_item) {
jQuery("<p class='filter_no_results'>Zu dieser Auswahl wurden leider keine Ergebnisse gefunden.<br>Bitte andere Kriterien auswählen.<p>").appendTo('.product-item-listing');
}
}
});
<!-- language: lang-css -->
.filter_hidden {
display: none;
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<select id="filter_checkboxes" class="vergleich_select" size="1" name="term">
<option id="filter_all" name="filter_alle" value="alle">
Alle
</option>
<option id="product_cost" name="product_cost" value="true">
Kostenlose Kontoführung
</option>
<option id="incentive" name="incentive" value="true">
Mit Startguthaben
</option>
</select>
<div class="product-item" data-incentive="false" data-partnercard="false" data-atm_euro_fee="false" data-atm_international_fee="false" data- incoming_pm_min="true" data-product_cost="true">
N26
</div>
<div class="product-item " data-incentive="false" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="true" data- incoming_pm_min="false" data-product_cost="true">
ComDirect
</div>
<div class="product-item" data-incentive="false" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="true" data- incoming_pm_min="false" data-product_cost="true">
DKB
</div>
<div class="product-item" data-incentive="true" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="false" data-incoming_pm_min="false" data-product_cost="true">
Revolut
</div>
</div>
</body>
</html>
<!-- end snippet -->
答案2
得分: 0
我觉得我明白你的意思了。我修复了不少语法问题 - 在HTML验证器中发布HTML以查看这些问题。
这里我添加了一些选项,以便在选择时更具说明性(我改成了multiple
,所以你可以选择多个)
我使用颜色和数据属性来显示已选择的内容。
jQuery(function($) {
$("#filter_select").on('change', filtering_vergleiche).first().trigger('change');
//triggered instead of calling: filtering_vergleiche();
function filtering_vergleiche(event) {
let choosen_filter = [];
$('.product-item').each(function() {
this.dataset.chosen = "false";
});
let $choices = $(this).find('option:selected');
$('.product-item').removeClass('filter_hidden');
$('.product-item-listing').find('.filter_no_results').remove();
// nothing picked so get out of here
if (!$choices.length) {
return;
}
$choices.each(function(index) {
choosen_filter.push({
"name": $(this).attr('name'),
"value": $(this).attr('value')
});
});
let $products = $('.product-item');
let count_item = $products.length; //0;
let count_hidden = 0;
$products.each(function(index) {
let isChoice = this.dataset.chosen == "true";
// we already chose it so go to next one
if (isChoice) return;
for (var i = 0; i < choosen_filter.length; ++i) {
let choosen_filter_item = choosen_filter[i];
let choosen_filter_name = choosen_filter_item.name;
let choosen_filter_value = choosen_filter_item.value;
let filter_value_on_product = $(this).data(choosen_filter_name);
filter_value_on_product = filter_value_on_product || $(this).data('choice') == choosen_filter_value;
this.dataset.chosen = this.dataset.chosen == "true" || choosen_filter_value == 'alle' || filter_value_on_product ? "true" : "false";
}
});
let hiddenOnes = $('.product-item').filter('.filter_hidden');
count_hidden = hiddenOnes.length;
if (count_hidden == count_item) {
$("<p class='filter_no_results'>Zu dieser Auswahl wurden leider keine Ergebnisse gefunden.<br>Bitte andere Kriterien auswählen.<p>").appendTo('.product-item-listing');
}
}
});
.filter_hidden {
border: solid green 1px;
}
.vergleich_select {
height: 6rem;
}
.product-item-listing {
margin-top: 1rem;
border: solid 1px red;
}
.product-item[data-chosen="true"] {
background-color: #ddffdd44;
}
.product-item[data-chosen="false"] {
background-color: #ddddff44;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="filter_select" class="vergleich_select" size="1" name="term" multiple>
<option name="filter_alle" value="alle" data-choice="all">
Alle (All)
</option>
<option name="product_cost" value="true" data-choice="product_cost">
Kostenlose Kontoführung (Free Account Management)
</option>
<option name="incentive" value="true" data-choice="incentive">
Mit Startguthaben (With starting credit)
</option>
<option name="incoming_pm_min" value="true" data-choice="incoming_pm_min">
incoming_pm_min = true
</option>
<option name="incentive" value="true" data-choice="partnercard">
partnercard = true
</option>
<option name="incentive" value="true" data-choice="atm_international_fee">
atm_international_fee = true
</option>
</select>
<div class="product-item" data-incentive="false" data-partnercard="false" data-atm_euro_fee="false" data-atm_international_fee="false" data-incoming_pm_min="true" data-product_cost="true">N26</div>
<div class="product-item " data-incentive="false" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="true" data-incoming_pm_min="false" data-product_cost="true">ComDirect</div>
<div class="product-item" data-incentive="false" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="true" data- incoming_pm_min="false" data-product_cost="true">DKB</div>
<div class="product-item" data-incentive="true" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="false" data-incoming_pm_min="false" data-product_cost="true">Revolut</div>
<div class="product-item-listing">empty</div>
英文:
I think I see where you are going with this. A good number of syntax issues I fixed - post the HTML in an HTML validator to see those.
Here I added a few options to make it more illustrative when you select (I changed to multiple
so you can pick more than one)
I used colors and a data attribute to do some to show what has been chosen.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
jQuery(function($) {
$("#filter_select").on('change', filtering_vergleiche).first().trigger('change');
//triggered instead of calling: filtering_vergleiche();
function filtering_vergleiche(event) {
let choosen_filter = [];
$('.product-item').each(function() {
this.dataset.chosen = "false";
});
let $choices = $(this).find('option:selected');
$('.product-item').removeClass('filter_hidden');
$('.product-item-listing').find('.filter_no_results').remove();
// nothing picked so get out of here
if (!$choices.length) {
return;
}
$choices.each(function(index) {
choosen_filter.push({
"name": $(this).attr('name'),
"value": $(this).attr('value')
});
});
let $products = $('.product-item');
let count_item = $products.length; //0;
let count_hidden = 0;
$products.each(function(index) {
let isChoice = this.dataset.chosen == "true";
// we already chose it so go to next one
if (isChoice) return;
for (var i = 0; i < choosen_filter.length; ++i) {
let choosen_filter_item = choosen_filter[i];
let choosen_filter_name = choosen_filter_item.name;
let choosen_filter_value = choosen_filter_item.value;
let filter_value_on_product = $(this).data(choosen_filter_name);
filter_value_on_product = filter_value_on_product || $(this).data('choice') == choosen_filter_value;
this.dataset.chosen = this.dataset.chosen == "true" || choosen_filter_value == 'alle' || filter_value_on_product ? "true" : "false";
}
});
let hiddenOnes = $('.product-item').filter('.filter_hidden');
count_hidden = hiddenOnes.length;
if (count_hidden == count_item) {
$("<p class='filter_no_results'>Zu dieser Auswahl wurden leider keine Ergebnisse gefunden.<br>Bitte andere Kriterien auswählen.<p>").appendTo('.product-item-listing');
}
}
});
<!-- language: lang-css -->
.filter_hidden {
border: solid green 1px;
}
.vergleich_select {
height: 6rem;
}
.product-item-listing {
margin-top: 1rem;
border: solid 1px red;
}
.product-item[data-chosen="true"] {
background-color: #ddffdd44;
}
.product-item[data-chosen="false"] {
background-color: #ddddff44;
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="filter_select" class="vergleich_select" size="1" name="term" multiple>
<option name="filter_alle" value="alle" data-choice="all">
Alle (All)
</option>
<option name="product_cost" value="true" data-choice="product_cost">
Kostenlose Kontoführung (Free Account Management)
</option>
<option name="incentive" value="true" data-choice="incentive">
Mit Startguthaben (With starting credit)
</option>
<option name="incoming_pm_min" value="true" data-choice="incoming_pm_min">
incoming_pm_min = true
</option>
<option name="incentive" value="true" data-choice="partnercard">
partnercard = true
</option>
<option name="incentive" value="true" data-choice="atm_international_fee">
atm_international_fee = true
</option>
</select>
<div class="product-item" data-incentive="false" data-partnercard="false" data-atm_euro_fee="false" data-atm_international_fee="false" data-incoming_pm_min="true" data-product_cost="true">N26</div>
<div class="product-item " data-incentive="false" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="true" data-incoming_pm_min="false" data-product_cost="true">ComDirect</div>
<div class="product-item" data-incentive="false" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="true" data- incoming_pm_min="false" data-product_cost="true">DKB</div>
<div class="product-item" data-incentive="true" data-partnercard="true" data-atm_euro_fee="true" data-atm_international_fee="false" data-incoming_pm_min="false" data-product_cost="true">Revolut</div>
<div class="product-item-listing">empty</div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论