问题
I have a large list of results which I want to filter out with a checkbox. so for example when you click on cat 3 you should see all items with the class cat3 and if you click cat2 as well you should see all the items with both cat2 and cat3. In the below code which is located in this fiddle, I have the onchange working so if you click on cat3 it only shows the cat3 items however I can't get the multiple ticks working here, how can this be achieved?
<form id="refine-cat">
<span><input type="checkbox" value="1" name="filtercol">cat 1</span>
<span><input type="checkbox" value="2" name="filtercol">cat 2</span>
<span><input type="checkbox" value="3" name="filtercol">cat 3</span>
</form>
<form id="refine-col">
<span><input type="checkbox" value="1" name="filtercat">col 1</span>
<span><input type="checkbox" value="2" name="filtercat">col 2</span>
<span><input type="checkbox" value="3" name="filtercat">col 3</span>
<span><input type="checkbox" value="4" name="filtercat">col 4</span>
</form>
<ul>
<li class="item cat-3 col-1">number 3</li>
<li class="item cat-3 col-1">number 3</li>
<li class="item cat-3 col-1">number 3</li>
<li class="item cat-1 col-1">number 1</li>
</ul>
(the list has more items in the fiddle)
JS
jQuery('#refine-cat input[type=checkbox]').bind('change', function (e) {
var jT = jQuery(this);
var val = jQuery(this).attr('value') || '';
if (jT.is(':checked')) {
jQuery('.item').hide();
jQuery('.cat-' + val).show();
} else {
jQuery('.item').show();
jQuery('.cat-' + val).hide();
}
});
jQuery('#refine-col input[type=checkbox]').bind('change', function (e) {
var jT = jQuery(this);
var val = jQuery(this).attr('value') || '';
if (jT.is(':checked')) {
jQuery('.item').hide();
jQuery('.col-' + val).show();
} else {
jQuery('.item').show();
jQuery('.col-' + val).hide();
}
});
回答1:
Try
var $items = jQuery('.item');
var $cats = jQuery('#refine-cat input[type=checkbox]');
var $cols = jQuery('#refine-col input[type=checkbox]');
$cols.add($cats).on('change', function (e) {
var cats = $cats.filter(':checked').map(function(){
return 'cat-' + (this.value || '')
}).get();
var cols = $cols.filter(':checked').map(function(){
return 'col-' + (this.value || '')
}).get();
if(cats.length || cols.length){
var $fitems = $items;
if(cats.length){
$fitems = $fitems.filter('.' + cats.join(', .'));
}
if(cols.length){
$fitems = $fitems.filter('.' + cols.join(', .'));
}
$fitems.show();
$items.not($fitems).hide();
} else {
$items.show();
}
});
Demo: Fiddle
回答2:
It looks like you need to loop through each checkbox and ensure that no other checkboxes are marked as check before you do jQuery('.item').hide();.
if (jT.is(':checked')) {
jQuery('.item').hide(); //--- Here, you are not taking into consideration that some .item(s) may need to remain shown if their respective checkbox is checked.
jQuery('.col-' + val).show();
来源:https://stackoverflow.com/questions/18765192/jquery-filter-unordered-list-by-class-name-onchange