Home > Software design >  Filter products with checkbox and data-category
Filter products with checkbox and data-category

Time:09-30

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.

  • Related