I intent to create a filter by showing and hiding divs with checkbox.
I have seen posts like this, but I have yet to achieve the result I´m expecting. This is a part of the code:
<div class="container">
<h3 style="font-size:14px; font-weight:normal;">Products by Room</h3>
<p style="font-size:12px;"><strong>Filter items by room:</strong></p>
<form>
<label style="font-size:12px;"><input type="checkbox" name="room" value="office" id="red" /> Office</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="bedroom" id="yellow" /> Bedroom</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="living-room" id="pink" /> Living Room</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="dining-room" id="purple" /> Dining Room</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="library" id="green" /> Library</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="hallway" id="other" /> Hallway</label>
</form>
<div class="products-by-room">
<div data-category="office library">Office, Library</div>
<div data-category="office">Office</div>
<div data-category="hallway library">Hallway, Library</div>
<div data-category="living-room dining-room">Living-room & Dining-room</div>
<div data-category="living-room">Living-room</div>
<div data-category="bedroom dining-room">Bedroom & Dining-room</div>
<div data-category="dining room">Dining room</div>
<div data-category="office">Office</div>
<div data-category="bedroom">Bedroom</div>
<div data-category="living-room">Living-room</div>
<div data-category="living-room dining-room office library">Living-room, Dining-room, Office & Library</div>
<div data-category="library">Library</div>
<div data-category="office">Office</div>
<div data-category="bedroom">Bedroom</div>
</div>
</div>
As you can see, in some divs there is only one data-category:
<div data-category="office">Office</div>
but I also have divs with multiple data-categories:
<div data-category="office library">Office & Library</div>
The result I am looking for is when I check the checkbox for "Office" I want it to show all the divs that contains office in the data-category attribute, wether it´s only office or office and other types of rooms.
So, if I selected the checkbox office, I would want to show only the following divs:
<div data-category="office library">Office, Library</div>
<div data-category="office">Office</div>
<div data-category="living-room dining-room office library">Living-room, Dining-room, Office & Library</div>
<div data-category="office">Office</div>
Any tips on how can I achieve this?
CodePudding user response:
Since you did not mention you are using vannila js or jquery, i assume you are using jquery as it is referred in your question.
I have also added comments for each line.
jQuery(function(){ // document ready to process
jQuery('form').find("input").on('change',function(){ // when the input changes
let selected = []; // init a selected array
jQuery('form').find("input").each(function(){ // on every input
if(jQuery(this).is(":checked")){ // check if the input is checked
selected.push(jQuery(this).val()); // push the selected value to selected array
}
})
if(!selected.length){ // if no items selected
jQuery("div.products-by-room div").show(); // show all
return; // stop code execution
}
jQuery("div.products-by-room div").hide(); // hide all divs
jQuery("div.products-by-room div").each(function(){ // take each div
const category = jQuery(this).attr('data-category'); // capture the attribute category
const categorySplitted = category.split(' '); // split each category by space
categorySplitted.forEach((cat)=>{ // foreach category array
if(selected.indexOf(cat) !== -1){ // cross check with selected categories; if selected
jQuery(this).show(); // show the div
}
});
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<h3 style="font-size:14px; font-weight:normal;">Products by Room</h3>
<p style="font-size:12px;"><strong>Filter items by room:</strong></p>
<form>
<label style="font-size:12px;"><input type="checkbox" name="room" value="office" id="red" /> Office</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="bedroom" id="yellow" /> Bedroom</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="living-room" id="pink" /> Living Room</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="dining-room" id="purple" /> Dining Room</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="library" id="green" /> Library</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="hallway" id="other" /> Hallway</label>
</form>
<div class="products-by-room">
<div data-category="office library">Office, Library</div>
<div data-category="office">Office</div>
<div data-category="hallway library">Hallway, Library</div>
<div data-category="living-room dining-room">Living-room & Dining-room</div>
<div data-category="living-room">Living-room</div>
<div data-category="bedroom dining-room">Bedroom & Dining-room</div>
<div data-category="dining room">Dining room</div>
<div data-category="office">Office</div>
<div data-category="bedroom">Bedroom</div>
<div data-category="living-room">Living-room</div>
<div data-category="living-room dining-room office library">Living-room, Dining-room, Office & Library</div>
<div data-category="library">Library</div>
<div data-category="office">Office</div>
<div data-category="bedroom">Bedroom</div>
</div>
</div>
CodePudding user response:
Consider the following.
$(function() {
$("form input[type='checkbox']").change(function() {
var selected = [];
$(this).closest("form").find(":checked").each(function(i, el) {
selected.push($(el).val());
});
if (selected.length == 0) {
$(".products-by-room > div").show();
return;
}
$(".products-by-room > div").each(function(i, el) {
var cat = $(el).data("category").split(" ");
$.each(cat, function(j, c) {
if (selected.indexOf(c) == -1) {
$(el).hide();
} else {
$(el).show();
}
});
});
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<h3 style="font-size:14px; font-weight:normal;">Products by Room</h3>
<p style="font-size:12px;"><strong>Filter items by room:</strong></p>
<form>
<label style="font-size:12px;"><input type="checkbox" name="room" value="office" id="red" /> Office</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="bedroom" id="yellow" /> Bedroom</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="living-room" id="pink" /> Living Room</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="dining-room" id="purple" /> Dining Room</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="library" id="green" /> Library</label><br>
<label style="font-size:12px;"><input type="checkbox" name="room" value="hallway" id="other" /> Hallway</label>
</form>
<div class="products-by-room">
<div data-category="office library">Office, Library</div>
<div data-category="office">Office</div>
<div data-category="hallway library">Hallway, Library</div>
<div data-category="living-room dining-room">Living-room & Dining-room</div>
<div data-category="living-room">Living-room</div>
<div data-category="bedroom dining-room">Bedroom & Dining-room</div>
<div data-category="dining room">Dining room</div>
<div data-category="office">Office</div>
<div data-category="bedroom">Bedroom</div>
<div data-category="living-room">Living-room</div>
<div data-category="living-room dining-room office library">Living-room, Dining-room, Office & Library</div>
<div data-category="library">Library</div>
<div data-category="office">Office</div>
<div data-category="bedroom">Bedroom</div>
</div>
</div>
Since you have multiple checkboxes multiple categories, you need to perform a few iterations.
You can use .filter()
in a similar fashion. Basically you would show all, then use .filter()
to reduce to the matched items and Hide those.