I want to filter some content using checkboxes.
I've managed to do that thanks to an earlier post which I've simplified a bit here DEMO.
My problem is that each content item can have more than one category attached.When I select category A and category B and then deselect category B, the content item that have both categories attached are removed.
The project I'm working on is going to contain more than two categories. A content item can have many categories attached
HTML:
<ul id="filters">
<li>
<input type="checkbox" value="categorya" id="filter-categorya" />
<label for="filter-categorya">Category A</label>
</li>
<li>
<input type="checkbox" value="categoryb" id="filter-categoryb" />
<label for="filter-categoryb">Category B</label>
</li>
</ul>
<div class="categorya categoryb">A, B</div>
<div class="categorya">A</div>
<div class="categorya">A</div>
<div class="categorya">A</div>
<div class="categoryb">B</div>
<div class="categoryb">B</div>
<div class="categoryb">B</div>
Javascript:
$('input').click(function() {
var category = $(this).val();
if (!$(this).attr('checked')) $('.' + category).hide();
else $('.' + category).show();
});
$('input[type=checkbox]:checked') In this, we are first selecting all input elements where type is a checkbox and then adding: checked to filter only those which are checked.
I think the two most straightforward approaches would be on click of any of the filter checkboxes either:
Hide all <div>
elements, then loop through the checkboxes and for each checked one .show()
the <div>
elements with the associated category.
Loop through all checkboxes to make a list of the classes to be shown, then loop through the <div>
elements, checking each one to see if it has one of those classes and .hide()
or .show()
as appropriate.
Is there some general selector you can use to get all the <div>
elements? Do they have a particular container element, like how all the checkboxes are descendents of "#filters"?
// Solution 1
$("#filters :checkbox").click(function() {
$("div").hide();
$("#filters :checkbox:checked").each(function() {
$("." + $(this).val()).show();
});
});
Demo: http://jsfiddle.net/6wYzw/41/
// Solution 2
$("#filters :checkbox").click(function() {
var re = new RegExp($("#filters :checkbox:checked").map(function() {
return this.value;
}).get().join("|") );
$("div").each(function() {
var $this = $(this);
$this[re.source!="" && re.test($this.attr("class")) ? "show" : "hide"]();
});
});
Demo: http://jsfiddle.net/6wYzw/42/
I guess the first way is shorter, and easier to maintain...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With