Pergunta

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/

Foi útil?

Solução

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;
    }

});

Outras dicas

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top