0

I currently have some code to filter an array based on price range using a slider. I need to be able to add checkboxes for various sizes and colors so that I can also filter using their values. This is the code I have so far but am unsure how to implement checkboxes so that I have have multiple ways of filtering the array.

//this is the main generated array
    var product = [{"price":"200","color":"red","size":"small"},
                   {"price":"250","color":"brown","size":"medium"},
                   {"price":"300","color":"red","size":"large"}];

// array to display filtered array
    var filteredProducts = [];  
    var key = 0;

//start of price range filter
    if(!minPrice && !maxPrice){
       filteredProducts = products;
    } else{
       $.each(products, function(i, object) {   
           var curentPrice = parseFloat(object.price); 
           var priceMinOk = true;
           var priceMaxOk = true;
       // filter results match the price range
           if(maxPrice || minPrice){
              if(maxPrice && maxPrice<curentPrice){
                 priceMaxOk = false;
              }
              if(minPrice && minPrice>curentPrice){
                 priceMinOk = false;
              }
           }  
       //  loop over list and get only related to new array
           if( priceMinOk && priceMaxOk ){  
              filteredProducts[key] = object;                  
              key++;
           }  
       });
    } 

Thanks in advance for any help"

Fiddle http://jsfiddle.net/ltbmedia/86pEn/

1 Answer 1

1

Use $.grep instead of $.each, and structure the code like this:

var products = [ /* ... */ ],
    predicates = [
        function predicate1(obj) { /* ... */ },
        function predicate2(obj) { /* ... */ },
        // ... ,
        function predicateN(obj) { /* ... */ }
    ],
    filteredProducts;

filteredProducts = $.grep(products, function (element, index)
{
    for (var i=0; i<predicates.length; i++)
    {
        if (!predicates[i](element)) return false;
    }

    return true;
});

Example: http://jsfiddle.net/mattball/Rsbcu/


More complex example: http://jsfiddle.net/mattball/vZzjM/

You might notice that you're still getting an empty array back, but this actually makes sense. Given the criteria you've specified (minPrice = 201, maxPrice = 301, color = red or green, size = small) there are no matching array elements.

Loosen up the price criteria just a tiny bit and you'll see that everything works as expected: http://jsfiddle.net/mattball/MQ8Mc/

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

8 Comments

Thanks Matt, I am assuming that each 'function predicate1(obj) { /* ... */ } is for each filter element (ie size), is that right?
That's right. Each predicate would test for a separate condition on each element. In the example code in your question, you'd use two predicates, one to test the min price condition, and one to test the max price condition. BTW, a predicate is a function which returns a boolean value.
Thanks again but not sure I quite know what you mean. How would a predictate function test for a specific element value, sorry, been banging my head against the wall all day on this one!
Hi Matt, thanks for that and I think it cleared things up a bit! Would it be possible for you to look at my edit and see where I am going wrong, getting an empty array now and can I use multiple checkboxes with this method? Thanks...
For starters, you're trying to parseFloat colors and sizes, which just won't work...
|

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.