0

I just want to make filter with checkbox array using jquery. It works fine when only one checkbox is selected but when I select two or more checkboxes it doesnot show all the divs. Could you please help me to find my mistake.

http://jsfiddle.net/EducateYourself/vr8noyyL/19/

<div id="filters">
    <div class="filterblock">
        <input id="check1" type="checkbox" name="check" value="cola" class="category">
        <label for="check1">Cola</label>
    </div>
    <div class="filterblock">
        <input id="check2" type="checkbox" name="check" value="fanta" class="category">
        <label for="check2">Fanta</label>
    </div>
    <div class="filterblock">
        <input id="check3" type="checkbox" name="check" value="sprite" class="category">
        <label for="check3">Sprite</label>
    </div>
</div>
4
  • Do you want to filter using and (divs that have all the selected tags) or using or (divs that have one of the selected tags)? Commented Nov 2, 2015 at 16:52
  • I want to filter using OR (divs that have at least one of the selected tags) Commented Nov 2, 2015 at 17:00
  • I have just updated jsfiddle link Commented Nov 2, 2015 at 17:01
  • It's great to post a JS fiddle link, but you should also include the code you are having problems with in the question itself. That way, the question can be read and understood even if the fiddle would not be available. Commented Nov 2, 2015 at 19:05

2 Answers 2

2

Use the jQuery filter() method and, use .data() instead of .attr():

$(document).ready(function () {
    $('.category').on('change', function () {
        //select all target elements, hide them, and filter ....
        $('.resultblock').hide().filter(function() {
            //initialize flag
            var found = -1;
            //save reference to current element for use in .each
            var that = $(this);
            //check if current element has any of the checked tags
            $(':checkbox[name=check]:checked').each(function() {
                if( that.data('tag').split(' ').indexOf( this.value ) > -1 ) {
                    //set flag
                    found = 1;
                    //exit .each, no more iterations needed
                    return false;
                }
            });
            //only elements where found is set to 1 would be returned
            return found > -1;
        //show elements in result set
        }).show();
    });
});

DEMO 1

And, if you want the pages to start off correctly - nothing showing as no tag checkbox is selected - just trigger the change event when the page loads.

        ....
        //show elements in result set
        }).show();
    }).change(); //<<<<----
});

DEMO 2

UPDATE

In order for selecting all and selecting none to both show everything, update DEMO 1 as follows:

            ....
            }).length > 0 || (found = 1); //<<<<<---
            return found > -1;
        }).show();
    });
});

DEMO 3

Sign up to request clarification or add additional context in comments.

4 Comments

thank you so much for your help! Demo 1 is ok for me. The only problem is when I uncheck all the checkboxes, it displays nothing but I want it to show all the divs.
Please take a look at DEMO 3.
it seems my code works as well after some editing (pls check the new jsfiddle) . I just hide all the divs before filtering them
Sounds good. Now you have options. If you like, you can delete the question or update it accordingly.
1

Your fiddle doesn't work because you don't have jQuery included. in the left dropdown box. But once you include jQuery it works somewhat. The question is how do you want to filter.

If 2 items are checked do you want to show those that have either item (inclusive)? Or do you want to show those items that have both (exclusive)?

Start by getting all the filters in an array:

 $('.resultblock').hide();
 var values = $("#filters input:checkbox:checked").map(function(){
                          return $(this).val();
                        }).get(); 

Inclusive filter is easy:

 $.each(values, function(idx, val){
     $('.resultblock[data-tag*="' + val + '"]').show();
 });

Exclusive filter is a little harder:

$.each($('.resultblock'), function(i, block){
    var $self = $(block);
    var show = true;
    var tag = $self.data('tag');
    $.each(values, function(idx, val){
        if(tag.indexOf(val) === -1){
            show = false;
            return;
        }
    });
    if(show){
        $self.show();
    }
});

here's a fiddle showing both: the inclusive is currently commented out: http://jsfiddle.net/vr8noyyL/16/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.