javascriptjqueryhtmlcheckboxinput-filtering

How to show hide and hide divs using checkboxes with a certain set of conditions?


There seems to be quite few examples of div being hidden and shown via checkboxes but I have struggled to find one which tackles it in quite the same way as I am trying to do it.

What I am striving to do is create a 'simple' way of showing specific divs based on if a set of classes have been applied to different divs and then for those same divs to be hidden or shown depending on whether certain checkboxes are triggered

This is the snippet of the code:

$(document).ready(function () {

$("input[type=checkbox]").change(function () {
    var divId = $(this).attr("id");
    if ($("#expensive").is(":checked") && $(this).is(":checked") || $("#cheap").is(":checked") && $(this).is(":checked")) {
        $("." + divId).show();
    } else {
        $("." + divId).hide();
    };

In the example I added to in JSFiddle, I have split the check boxes into two main categories which are colour (which is made up of: red, green, blue and purple) and prices (which is made up of: "expensive and cheap)

The idea is I may wish to view all items with the class of "red" and both cheap or expensive. Alternatively I may wish to view some or all the colours but only the ones which are cheap.

I have tried to cut down the code to fairly small amount but there is one sequence which seems to be tripping the logic up and for the life of me I can't think how to get it to work in this one scenario or what I may have missed.

The example is located on JSFiddle here for people to test:

works except unless you do this:

If repeat this sequence:
1. turn off either cheap or expensive
2. turn off one of the colours
3. now turn on that same colour

The result is the colour you clicked back on again shows both cheap and expensive even though one of those checkboxes is off.

Every other combination seems to work and I was hoping what was written would be the most simple method but obviously something is missing and I can't see why it is not giving me the results I wanted. So if anyone has any thoughts on what I have missed out then I sure would appreciate the help.


Whilst I was waiting I had another go at it and expanded the show hide into simple straight forward chunks... what I did was to start off with showing everything and then hide each div if it was effected by the associated checkboxs.

$(document).ready(function() {

 $("input[type=checkbox]").change(function() {
    var divId = $(this).attr("id");
    $("." + divId).show();

    if (!$("#expensive").is(":checked")){
        $(".expensive").hide();
    };

    if (!$("#cheap").is(":checked")){
    $(".cheap").hide();     
    };

    if (!$("#cheap").is(":checked")){
    $(".cheap").hide();     
    };

    if (!$("#red").is(":checked")){
    $(".red").hide();       
    };

    if (!$("#blue").is(":checked")){
    $(".blue").hide();      
    };

    if (!$("#purple").is(":checked")){
    $(".purple").hide();        
    };

    if (!$("#green").is(":checked")){
    $(".green").hide();     
    };

 });

});

It's a bit of a long winded way to do it, but it seems to works.. although the answers which have been posted all look considerably better. So a big thanks to everyone who responded by posting snippets and advice

Kind regards


Solution

  • Simplest approach - separate the two categories, and only check when necessary...

        $(document).ready(function () {
        $("input[type=checkbox]").change(function () {
    
            var divId = $(this).attr("id"),
                    color = ['red', 'green', 'blue', 'purple'],
                    price = ['cheap', 'expensive'],
                    cat = $.inArray(divId, price) == -1 ? price : color;
    
    
            if (!$(this).is(":checked")) {
                $('div.' + divId).hide()
            } else {
                $.each(cat, function (i, ele) {
                    if ($('#' + ele).is(':checked')) {
                        $('div.' + divId + '.' + ele).show()
                    } else {
                        $('div.' + divId + '.' + ele).hide()
    
                    }
                })
            }
        });
    });