Reputation: 12923
Consider the following:
$('#num-locations input[type="checkbox"]').on('click', function(e) {
if (e.target.checked) {
var location = e.target.dataset.location;
$('.manage-wrapper').each(function() {
var city = $(this).data('city');
if (city !== location) {
$(this).toggleClass('hide-on-location');
}
});
} else {
$('.hide-on-location').toggleClass('hide-on-location');
}
});
So with in this selector: #num-locations input[type="checkbox"]
I check if the value is checked, if so I apply a class to any .manage-wrapper
that doesn't match the data-
attribute.
When you uncheck said checkbox, it removes the class. Great.
This works for one checkbox with in the #num-locations input[type="checkbox"]
How ever, I have multiple check boxes with in #num-locations
and I cannot target them individually because they are added dynamically.
Question:
How do I write this such that if you check 1 or more checkboxes that it will toggle the class and if you uncheck one or more it untoggles the class?
Example data, all elements that don't match a data-location of Sample
would be hidden, great. Uncheck, Sample
is now shown.
Now what about checking Sample
and Crab Apple
, any element that doesn't match Sample
or Crab Apple
needs to be hidden, when I uncheck Crab Apple
, all elements that match Crab Apple
should be shown but all elements that don't match Sample
Should still be hidden.
I cannot check for specific attributes, because this is dynamic.
Upvotes: 0
Views: 73
Reputation: 21672
It sounds like you're trying to create a generic set of filtering checkboxes. If so, the code below should help you out. I mocked up the HTML as you hadn't included it in your question, however I think it should be adequate.
Here are some of the methods used.
.map()
to change our collection of elements into a collection of their data-city
values
.get()
to return the data values as an Array
.filter()
to narrow down our manage-wrapper
selection to only those not checked
I've also included comments in the code itself to document each step in a bit more detail.
$("#num-locations input[type=checkbox]").on("click", refreshFilters);
function refreshFilters() {
var $checkedInputs = $("#num-locations input[type=checkbox]:checked");
var $manageWrappers = $(".manage-wrapper");
$manageWrappers.removeClass("hide-on-location"); //Start with all shown
if (!$checkedInputs.length) return; //If nothing is checked, exit early
//Get the checked cities as an array, e.g. ["New York", "Chicago"]
var cities = $checkedInputs.map(function() { return $(this).data("city") }).get();
//Find any .manage-wrapper whose data-location is NOT in that array, and hide it
$manageWrappers
.filter(function() { return !cities.includes($(this).data("location")); })
.addClass("hide-on-location");
}
.hide-on-location { display: none; }
#num-locations { margin-bottom: 10px; }
.manage-wrapper { border: 1px solid #ccc; padding: 10px; margin: 5px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="num-locations">
<input type="checkbox" id="cb1" data-city="New York"> <label for="cb1">New York</label>
<input type="checkbox" id="cb2" data-city="Seattle"> <label for="cb2">Seattle</label>
<input type="checkbox" id="cb3" data-city="Chicago"> <label for="cb3">Chicago</label>
</div>
<div class="manage-wrapper" data-location="New York">New York</div>
<div class="manage-wrapper" data-location="Seattle">Seattle</div>
<div class="manage-wrapper" data-location="New York">New York</div>
<div class="manage-wrapper" data-location="Chicago">Chicago</div>
<div class="manage-wrapper" data-location="New York">New York</div>
<div class="manage-wrapper" data-location="Chicago">Chicago</div>
<div class="manage-wrapper" data-location="Seattle">Seattle</div>
Upvotes: 1