Search code examples
javascriptjqueryhtmlfiltermasonry

Create multiple filter selector in javascript


I got these panels which have options to be filtered by Red, Green and Yellow class, and another Show All option. They are behaving ok, but what I would like to achieve is following: When clicked on Show All, and after that on for example on Yellow -> it should hide everything except yellow. Also, you should be able to select only Yellow + Green, Red + Yellow etc., so that only those buttons stay selected then. And when user clicks on all three buttons, it could automatically select "Show All"...

I'm little confused about logic how to set this up so any help would be welcome, thanks a lot!

Here's a pen with example: https://codepen.io/anon/pen/YOgqRX

$('.main__container').masonry({
    itemSelector: '.item',
    columnWidth: '.item'
});

$("#filter-show-all").on('click', function() {
    $(".item").each(function(item) {
        $(this).removeClass("panel-hide");
        $('.main__container').masonry();
    });
});

$("#filter-red").on('click', function() {
    $(".red").toggleClass("panel-hide");
    $('.main__container').masonry();
});

$("#filter-green").on('click', function() {
    $(".green").toggleClass("panel-hide");
    $('.main__container').masonry();
});

$("#filter-yellow").on('click', function() {
    $(".yellow").toggleClass("panel-hide");
    $('.main__container').masonry();
});

Solution

  • Open my code in codePen:

    CodePen

    Explainations are comments along with the coding.

    Head:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/masonry/4.2.2/masonry.pkgd.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.2/css/bootstrap.min.css">
    

    CSS:

    <style>
    .main__container {
        width: 100%;
    }
    .item {
        width: 100%;
        box-shadow: 1px 1px 1px rgba(0,0,0,.1);
        padding: 10px;
    }
    
    @media(min-width: 800px) {
        .item {
            width: 49%;
        }
    }
    
    .red {
      background: red;
    }
    
    .green {
      background: green;
    }
    
    .yellow {
      background: yellow;
    }
    /*added css*/
    .on{
        border: 3px solid blue;
    }
    .off{
        border: none;
    }
    </style>
    

    HTML:

    <div class="container">
      <div class="row">
            <div class="col-md-12">
                <div class="filters">
                    <button id="filter-show-all" class="on">Show all</button>
                    <button id="filter-red" class="on">Show red</button>
                    <button id="filter-green" class="on">Show green</button>
                    <button id="filter-yellow" class="on">Show yellow</button>
                </div>
            </div>
        </div>
    
        <div class="row">
            <div class="col-md-12">
                <div class="main__container">
                    <div class="item red">
                        <h4>Red</h4>
                    </div>
                    <div class="item green">
                        <h4>Green</h4>
                    </div>
                    <div class="item red">
                        <h4>Red</h4>
                    </div>
                    <div class="item yellow">
                        <h4>Yellow</h4>
                    </div>
                    <div class="item yellow">
                        <h4>Yellow</h4>
                    </div>
                    <div class="item green">
                        <h4>Green</h4>
                    </div>
                </div>
            </div>
        </div>
    </div>
    

    JQuery:

    $('.main__container').masonry({
        itemSelector: '.item',
        columnWidth: '.item'
    });
    /*
        Check if clicked button state is 'on' or 'off'
        if it is 'on', After click, let matched color block disappear,
        if it is 'off', After click, let matched color block show
    */ 
    
    /* turn showAll button off, hide all the items */
    function showAllOff_hideItems(){
        if($('#filter-show-all').attr('class')=='on'){
            $('#filter-show-all').click();          
        }       
    }
    
    $("#filter-show-all").on('click', function() {          
        if($(this).attr('class')=="on"){
            $(".item").each(function(item) {            
                $(this).hide();
            });
        }else{
            $(".item").each(function(item) {            
                $(this).show();     
    
            });
    
        }
        $('.main__container').masonry();
    });
    
    $("#filter-red").on('click', function() {
        showAllOff_hideItems();
        if($(this).attr('class')=="on"){
             $(".red").hide();
        }else{
            $('.red').show();
        }
    
        $('.main__container').masonry();
    });
    
    $("#filter-green").on('click', function() {
        showAllOff_hideItems();
        if($(this).attr('class')=="on"){
             $(".green").hide();
        }else{
            $('.green').show();
        }
    
        $('.main__container').masonry();
    });
    
    $("#filter-yellow").on('click', function() {
        showAllOff_hideItems();
        if($(this).attr('class')=="on"){
             $(".yellow").hide();
        }else{
            $('.yellow').show();
        }
    
        $('.main__container').masonry();
    });
    /* Esstential Coding here : */
    
    $('.filters button').on('click',function(){
    
        if($(this).attr('id')!="filter-show-all"){
            /*Toggle the clicked button*/
            if($(this).attr('class')=="on"){
                $(this).attr('class','off');
            }else{
                $(this).attr('class','on');
            }
    
        }else{
            /* if show all button is clicked */
            /* if it is on, turn all the buttons off */     
            if($(this).attr('class')=="on"){
                $('.filters button').each(function(){
                    $(this).attr('class','off');
                });
            /* if it is off, turn all the buttons on */ 
            }else{
                $('.filters button').each(function(){
                    $(this).attr('class','on');
                });
            }           
    
        }
    
    });