2

I have three sets of checkboxes which allow me to filter a number of divs based on data attributes. This works great but not as I need it to.

If you visit the jsfiddle below you will see a working test.

What I need it to do is:

  1. When more than one option is chosen within the same category e.g. 'small' and 'medium', it should increase the results i.e. show all 'small' and 'medium' results, (which is what it does at the moment).

  2. When more than one option is chosen within different categories e.g. 'medium' and 'north america' it should reduce the results i.e. show all 'medium' flowers in 'north america'

How would I go about fixing/amending my code to make this work please? (I hope this makes sense).

Below is the jquery I'm using:

            $('.flowers-wrap, .continents-wrap').delegate('input[type=checkbox]', 'change', function() {
                var $lis = $('.flowers > div'),
                    $checked = $('input:checked');  
                if ($checked.length) {                          
                    var selector = '';
                    $($checked).each(function(index, element){
                        if(selector === '') {
                            selector += "[data-category~='" + element.id + "']";                  
                        } else {
                            selector += ",[data-category~='" + element.id + "']";
                        }
                    });                        
                    $lis.hide(); 
                    console.log(selector);
                    $('.flowers > div').filter(selector).show();               
                } else {
                    $lis.show();
                }
            });

Please see the jsfiddle I have setup to demonstrate the issue I'm having - http://jsfiddle.net/n3EmN/

3
  • Try to set the namę property of the checkboxes, and when change occurs loop through group of checkboxes by their name property. Commented Apr 1, 2014 at 12:49
  • Thanks; would that give me the result I'm after? Commented Apr 1, 2014 at 13:59
  • Here is a JSFIDDLE, hope it helps. Commented Apr 2, 2014 at 9:41

2 Answers 2

1

Many thanks to Pho3nixHun for his help :)

Here is my own answer: (jsfiddle here).

$(document).ready(function() {

    var byProperty = [], byColor = [], byLocation = [];

    $("input[name=fl-colour]").on( "change", function() {
        if (this.checked) byProperty.push("[data-category~='" + $(this).attr("value") + "']");
        else removeA(byProperty, "[data-category~='" + $(this).attr("value") + "']");
    });

    $("input[name=fl-size]").on( "change", function() {
        if (this.checked) byColor.push("[data-category~='" + $(this).attr("value") + "']");
        else removeA(byColor, "[data-category~='" + $(this).attr("value") + "']");
    });

    $("input[name=fl-cont]").on( "change", function() {
        if (this.checked) byLocation.push("[data-category~='" + $(this).attr("value") + "']");
        else removeA(byLocation, "[data-category~='" + $(this).attr("value") + "']");
    });

    $("input").on( "change", function() {
        var str = "Include items \n";
        var selector = '', cselector = '', nselector = '';

        var $lis = $('.flowers > div'),
            $checked = $('input:checked');  

        if ($checked.length) {  

            if (byProperty.length) {        
                if (str == "Include items \n") {
                    str += "    " + "with (" +  byProperty.join(',') + ")\n";               
                    $($('input[name=fl-colour]:checked')).each(function(index, byProperty){
                        if(selector === '') {
                            selector += "[data-category~='" + byProperty.id + "']";                     
                        } else {
                            selector += ",[data-category~='" + byProperty.id + "']";    
                        }                
                    });                 
                } else {
                    str += "    AND " + "with (" +  byProperty.join(' OR ') + ")\n";                
                    $($('input[name=fl-size]:checked')).each(function(index, byProperty){
                        selector += "[data-category~='" + byProperty.id + "']";
                    });
                }                           
            }

            if (byColor.length) {                       
                if (str == "Include items \n") {
                    str += "    " + "with (" +  byColor.join(' OR ') + ")\n";                   
                    $($('input[name=fl-size]:checked')).each(function(index, byColor){
                        if(selector === '') {
                            selector += "[data-category~='" + byColor.id + "']";                    
                        } else {
                            selector += ",[data-category~='" + byColor.id + "']";   
                        }                
                    });                 
                } else {
                    str += "    AND " + "with (" +  byColor.join(' OR ') + ")\n";               
                    $($('input[name=fl-size]:checked')).each(function(index, byColor){
                        if(cselector === '') {
                            cselector += "[data-category~='" + byColor.id + "']";                   
                        } else {
                            cselector += ",[data-category~='" + byColor.id + "']";  
                        }                   
                    });
                }           
            }

            if (byLocation.length) {            
                if (str == "Include items \n") {
                    str += "    " + "with (" +  byLocation.join(' OR ') + ")\n";                
                    $($('input[name=fl-cont]:checked')).each(function(index, byLocation){
                        if(selector === '') {
                            selector += "[data-category~='" + byLocation.id + "']";                     
                        } else {
                            selector += ",[data-category~='" + byLocation.id + "']";    
                        }                
                    });             
                } else {
                    str += "    AND " + "with (" +  byLocation.join(' OR ') + ")\n";                
                    $($('input[name=fl-cont]:checked')).each(function(index, byLocation){
                        if(nselector === '') {
                            nselector += "[data-category~='" + byLocation.id + "']";                    
                        } else {
                            nselector += ",[data-category~='" + byLocation.id + "']";   
                        }   
                    });
                }            
            }

            $lis.hide(); 
            console.log(selector);
            console.log(cselector);
            console.log(nselector);

            if (cselector === '' && nselector === '') {         
                $('.flowers > div').filter(selector).show();
            } else if (cselector === '') {
                $('.flowers > div').filter(selector).filter(nselector).show();
            } else if (nselector === '') {
                $('.flowers > div').filter(selector).filter(cselector).show();
            } else {
                $('.flowers > div').filter(selector).filter(cselector).filter(nselector).show();
            }

        } else {
            $lis.show();
        }   

        $("#result").html(str); 

    });

    function removeA(arr) {
        var what, a = arguments, L = a.length, ax;
        while (L > 1 && arr.length) {
            what = a[--L];
            while ((ax= arr.indexOf(what)) !== -1) {
                arr.splice(ax, 1);
            }
        }
        return arr;
    }

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

Comments

0

You should hide the elements before you filter them and show them after, add a .hide() before the .filter(selector). Like so:

$('.flowers > div').hide().filter(selector).show(); 

This should hide all of the elements, then show the selected elements.

DEMO

1 Comment

Cheers; although it doesn't answer my question!? :0

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.