Hey All,

I am tryiung to create a function that lets me filter products on the page, by using html5 data-attributtes. Each prodct can have multiple values, as in: data-brand="acer", data-screen="17" data-processor="blah" etc etc.

I am trying to make it work with two filter options at the moment, and then I want to expand the function later.

This is how I get the values of the checked checkboxes:

function GetSelectedCBValues() 
{
    var selectedOptions = {};

    selectedOptions.Screen = $('input[name="screen_group[]"]:checked').map(function () 
    {
        return this.value;
    }).get();

    selectedOptions.Brand = $('input[name="brand_group[]"]:checked').map(function () 
    {
        return this.value;
    }).get();

    return selectedOptions;
}

And when I wantto either show/hide products on the page, I use this function:

function ShowHideProductDiv(div, show, hide) 
{
    if (show) $(div).show();
    if (hide) $(div).hide();
}

And this one to show ALL products, if nothing is checked

function ShowAllProducts() 
{
    $('.produkt_gruppe_div').show();
}

-------------------------------------------------------------------

Here is the tough one, where I try to run through all the products on the page, and check which of the products has a data-attributte value, that is also in one of the arrays, which are holding the checked values. If it is not, then I simply want to hide the product div, otherwise show it - It sounds all so simple, but not really - This is what i have:

function ShowAvailableProducts() 
{
    var selectedOptions = GetSelectedCBValues();
    console.log(selectedOptions);

    $('.produkt_gruppe_div').each(function (k, div) 
    {
        var divBrand    = $(div).data("brand_name");
        var divScreen   = $(div).data("screensize");

        // Hvis der er værdier i både brand og skærmstørrelse array
        if (selectedOptions.Screen.length >= 1 && selectedOptions.Brand.length >= 1) 
        {
            console.log("Der er valgt både brand og skærm");

            var mergedArray = $.merge( selectedOptions.Screen, selectedOptions.Brand ); // Merge arrays, så der er en der indeholder de valgte values
            console.log( mergedArray );

            // Tjek om den aktuelle div har en attribut der også findes i array
            if( $.inArray( divBrand, selectedOptions.Brand ) && $.inArray( divScreen, selectedOptions.Brand ) )
            {
                console.log( divBrand );
                console.log( divScreen );
                // Vis den div der har en af værdierne:
                ShowHideProductDiv(div, true, false);
            }
            else 
            {
                ShowHideProductDiv(div, false, true);
            }       
            /*
            if (selectedOptions.Screen == divScreen && selectedOptions.Brand == divBrand) 
            {
                console.log("Der er fundet et/flere match");
                ShowHideProductDiv(div, true, false);
            } 
            else 
            {
                ShowHideProductDiv(div, false, true);
            }
            */

        } 
        else if (selectedOptions.Screen.length >= 1) 
        {           
            if (selectedOptions.Screen == divScreen) 
            {
                ShowHideProductDiv(div, true, false);
            } 
            else 
            {
                ShowHideProductDiv(div, false, true);
            }
        } 
        else if (selectedOptions.Brand.length >= 1) 
        {
            if (selectedOptions.Brand == divBrand) 
            {
                ShowHideProductDiv(div, true, false);
            } 
            else 
            {
                ShowHideProductDiv(div, false, true);
            }
        } 
        else 
        {
            ShowAllProducts();
        }
    });
}

Anyone with experience on this?

Best regards, Klemme

Recommended Answers

All 12 Replies

Its a good example though, no doubt!

Your filter options go away, and as i need to filter products, that can have multiple filters, I need them to stay, and then traverse the product divs and only show the ones that has got one of the checked values.

So each product div, has got multiple data-attributtes: Like so:

<div class="produkt_gruppe_div" data-screensize="15.6" data-harddisk="500" data-grafikkort="intel hd graphics 4000" data-processor_producent="intel" data-processor_type="core i5" data-styresystem="microsoft windows 7 professional 64-bit edition" data-brand_name="fujitsu"><div class="kategori_product_heading_div"><h2 class="font_13 kategori_visning_product_heading">Fujitsu AH552/SL</h2>
</div>

So I need to be able to filter and show products that has got either 15" or 17" screen, or more... Say I have 8 screen sizes, I need to filter on all of them - are all checked, I display all and so on - I need the same thing going for brand names.

See examples above to see more clearly what I have so far :-)

I assume your data attributes (and checkboxes) are predetermined? Can you show how your brandname checkbox group looks?

Yes they are - Though I will work towards only display data-attributtes that are actually ON the page.

Here is an example of the brand group:

<input type="checkbox" name="brand_group[]" value="acer" id="acer" class="cb" />&nbsp;<span class="filter_paragraphs">Acer</span><br />
<input type="checkbox" name="brand_group[]" value="Amitech" id="Amitech" class="cb" />&nbsp;<span class="filter_paragraphs">Amitech"</span><br />
<input type="checkbox" name="brand_group[]" value="Apple" id="Apple" class="cb" />&nbsp;<span class="filter_paragraphs">Apple</span><br />
<input type="checkbox" name="brand_group[]" value="Dell" id="Dell" class="cb" />&nbsp;<span class="filter_paragraphs">Dell</span><br />
<input type="checkbox" name="brand_group[]" value="Fujitsu" id="Fujitsu" class="cb" />&nbsp;<span class="filter_paragraphs">Fujitsu</span><br />
<input type="checkbox" name="brand_group[]" value="Lenovo" id="Lenovo" class="cb" />&nbsp;<span class="filter_paragraphs">Lenovo</span><br />
<input type="checkbox" name="brand_group[]" value="Panasonic" id="Panasonic" class="cb" />&nbsp;<span class="filter_paragraphs">Panasonic</span><br />
<input type="checkbox" name="brand_group[]" value="Samsung" id="Samsung" class="cb" />&nbsp;<span class="filter_paragraphs">Samsung</span><br />
<input type="checkbox" name="brand_group[]" value="Sony" id="Sony" class="cb" />&nbsp;<span class="filter_paragraphs">Sony</span><br />
<input type="checkbox" name="brand_group[]" value="Toshiba" id="Toshiba" class="cb" />&nbsp;<span class="filter_paragraphs">Toshiba</span>

I get the values by the function shown in the first post.

More groups to come, but for now I only have data-screen_size and data-brand_name.

Klemme

It seemes to be an opportunity to use the filter method, and then compare chosen values from the tjeckboxes, something like this:

$('div[class=cb]').filter('div[data-screen=17][data-brand=lenovo][data-weight=2.3]').css('display','block');

So if i dynamically enter the [data-stuffhere] into the above string, and then base my show/hide upon that?

Reckon a one liner could really do that??

Maybe I could take $.each tjecked checkbox, and then push it into the string like so:

$('div[class=cb]').filter('div[data-screen=17][data-screen=16][data-screen=15][data-brand=lenovo][data-weight=2.3]').css('display','block');

...No your right, not unique data-names :-/

Would there be a way to tjeck if data-screen CONTAINS one of the selected values?

See this. It uses a single data attribute containing json. Should make it easier to query.

Could try using this inside the function in the first post (function ShowAvailableProducts() ):

$('#parentDiv').find('.produkt_gruppe_div[data-screen*="' + divScreen + '"]').show();

Any ideas are more than welcome..

/Klemme

Basically save all tjecked box values inside an array, and then loop the product divs -> Hide the ones with no matching data-atr value.

$.inArray(a,b); is my next try..

Just saw your post, ill give it a try with JSON values.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.