Filter by data-attributes

Filters by several attributes simultaneously

by chayacooper

HTML

<form>
<div id="container">    
    <div id="attributes-Colors" class="filterOptions" data-type="color">  
         <ul > 
            <li><input type=checkbox name="color[]" data-color="All" class="all">All Colors</li>
            <li><input type=checkbox name="color[]" data-color="Blue">Blue</li>
            <li><input type=checkbox name="color[]" data-color="Red">Red</li>
            <li><input type=checkbox name="color[]" data-color="Black">Black</li>
            <li><input type=checkbox name="color[]" data-color="Gray">Gray</li> 
       </ul> 
    </div>    
    <div id="attributes-Silhouettes" class="filterOptions" data-type="style"> 
        <ul >               
            <li><input type=checkbox name="style[]" data-style="All" class="all">All Styles</li>
            <li><input type=checkbox name="style[]" value="V-Neck" data-style="V-Neck">V-Neck</li>
            <li><input type=checkbox name="style[]" value="Crew_Neck" data-style="Crew_Neck">Crew Neck</li>
            <li><input type=checkbox name="style[]" value="Sleeveless" data-style="Sleeveless">Sleeveless</li>        
            <li><input type=checkbox name="style[]" value="Short_Sleeves" data-style="Short_Sleeves">Short Sleeves</li>
            <li><input type=checkbox name="style[]" value="Long_Sleeves" data-style="Long_Sleeves">Long Sleeves</li>        
        </ul>
    </div>
    <div>  
        <ul id="content">
            <li data-style="Short_Sleeves, V-Neck" data-color="Black">Short Sleeves, V-Neck, Black</li>
            <li data-style="Crew_Neck, Short_Sleeves, V-Neck" data-color="Blue, Red, Black">Crew Neck, Short Sleeves, V-Neck, Blue, Red, Black</li>     
            <li data-style="Sleeveless, V-Neck" data-color="Black & White">Sleeveless, V-Neck, Black & White</li>      
            <li data-style="Crew_Neck, V-Neck" data-color="Black">Crew Neck, V-Neck, Black</li>       
            <li data-style="V-Neck" data-color="Black">V-Neck, Black</li>       
            <li...

CSS

ol, ul {
    list-style: none;
}
.filterOptions ul {
    margin: 10px 0;
    overflow: hidden;
}
.filterOptions ul li {
    margin-right: 2px;
    float: left;
}
.filterOptions ul li a {
    padding: 0 10px;
    border: 1px solid #999;
    background: #cfcfcf;
    color: #fff;
    font-weight: bold;
    line-height: 50px;
    text-decoration: none;
    display: block;
}
.filterOptions ul li a:hover {
    background: #c9c9c9;
}
.filterOptions ul li.active a {
    background: #999;
}

JavaScript

$(document).ready(function () {
        // use 2 arrays so the combined handler uses correct group 
        var selected = { color: [], style: [] };
        
        // code was similar enough to combine to 1 handler for both groups
        $('.filterOptions').on("change", ":checkbox", function (e) {
            // figure out which group...
            var type = $(e.delegateTarget).data("type");
            var $this = $(this);
            // ...and the value of the checkbox checked
            var attrValue = $this.data(type);
            
            // same as before but using 'type' to access the correct array
            if ($this.parent().hasClass("active")) {
                $this.parent().removeClass("active");
                selected[type].splice(selected[type].indexOf(attrValue),1);
            }
            else {
                $this.parent().addClass("active");
                selected[type].push(attrValue);
            }
            
            // get a jQuery object with all the options the user selected
            var checked = $(":checked", ".filterOptions");
            
            // show all of the available options if...
            if (checked.length == 0 // ...no boxes are checked
                || // ...or...
                checked.filter(".all").length > 0) // ...the user checked an "All" box...
            {
                $('#content').find('*').show();
            } 
            else {
                // hide 'em all
                $("#content").find("*").hide();
                // go through both style and color arrays
                for (var key in selected) {
                    // and show any that have been checked
                    $.each(selected[key], function(index,item) {
                        $('#content').find('[data-' + key + ' *="' + item + '"]').show();
                    });
                }
            }
        }); 
    });