firedrawndagger
firedrawndagger

Reputation: 3733

Using jQuery's filter() function to extract an array with different criteria

I have a basic dataset stored in javascript that I want to filter based on user checked checkboxes. I know I can use jQuery's filter() function to filter the result set on multiple criteria, however the issue I'm running into is that the criteria would change depending on user input.

var myArray = [["Adelaide", 2, "yes", "female"],
           ["Ada", 2, "yes", "female"],
           ["Amanda", 1, "yes", "female"],
           ["Wolf", 3, "no", "male"],
           ["Rhonda", 1, "no", "female"]];

HTML:

<input id="rate-3" name="rating" type="checkbox" value="rate-3" />3 Stars<br />
<input id="rate-2" name="rating" type="checkbox" value="rate-2" />2 Stars<br />
<input id="rate-1" name="rating" type="checkbox" value="rate-1" />1 Star<br />
<a href="#" id="submitform">Submit Filters</a>

How would I pass multiple criteria to the .filter(function)? As an example, someone might select rate-1 and rate-3 checkboxes which is what I currently hard coded the function to look for, however I want it to be flexible depending on the user submitted input.

I guess I could just write a number of if/else statements but is there a more elegant way of doing this?

JQuery:

$("#submitform").click(function() {
    var userSelectedFilters = new Object();

    userSelectedFilters.rate3 = $("#rate-3").is(':checked');
    userSelectedFilters.rate2 = $("#rate-2").is(':checked');
    userSelectedFilters.rate1 = $("#rate-1").is(':checked');

    var filteredArray = myArray.filter(
    function(el) {
       // currently hardcoded
       return ((el[1] == 1) || (el[1] == 3));
     }
    );

});

Upvotes: 4

Views: 1126

Answers (3)

roselan
roselan

Reputation: 3775

you might to review your html and use name="rating[]" for each box, it will spare you a lot of headhache.

As it is, in your submit function:

$('input:checked').each( function () {
   userSelectedFilters[this.id] = this.id;
});

but again, the full stackofcode can be avoided, just do a little research on stackoverflow (or google). anyway: here is your code:

var myArray = [["Adelaide", 2, "yes", "female"],
           ["Ada", 2, "yes", "female"],
           ["Amanda", 1, "yes", "female"],
           ["Wolf", 3, "no", "male"],
           ["Rhonda", 1, "no", "female"]];

$("#submitform").click(function() {

    var choices = [];

    $('input:checked').each( function () {
       choices.push(this.id.charAt(this.id.length-1)); 

    });


    var filteredArray = myArray.filter(
    function(el) {

       for (i in choices) {
            if ( choices[i] == el[1] ) {
                return true;
            }
       }
       return false
     }
    );

    console.log (filteredArray );

});

Upvotes: 1

Nicola Peluchetti
Nicola Peluchetti

Reputation: 76880

You could do:

var myArray = [["Adelaide", 2, "yes", "female"],
           ["Ada", 2, "yes", "female"],
           ["Amanda", 1, "yes", "female"],
           ["Wolf", 3, "no", "male"],
           ["Rhonda", 1, "no", "female"]];

$("#submitform").click(function() {

    var userSelectedFilters = [];
    $("input:checkbox:checked").each(function(){
         userSelectedFilters.push(this.value)
    });



    var filteredArray = myArray.filter(
    function(el) {
       // currently hardcoded
        for (i =0, lungh = userSelectedFilters.length ; i< lungh; i++){
            console.log(userSelectedFilters[i]);
            if (el[1] == userSelectedFilters[i]){
               return true;
            }

        }
        return false;
     }
    );


});

fiddle here: http://jsfiddle.net/pWJwt/

Upvotes: 1

Joe
Joe

Reputation: 82594

Build an array and check if that number is contained in the array: DEMO

$("#submitform").click(function() {
    var userSelectedFilters = [];

    $("#rate-3").is(':checked') && userSelectedFilters.push(3);
    $("#rate-2").is(':checked') && userSelectedFilters.push(2);
    $("#rate-1").is(':checked') && userSelectedFilters.push(1);

    var filteredArray = myArray.filter(
    function(el) {
       // currently hardcoded
        return userSelectedFilters.indexOf(el[1]) !== -1;
     }
    );
});

indexOf isn't universal though, but there is a shim:

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
        "use strict";
        if (this === void 0 || this === null) {
            throw new TypeError();
        }
        var t = Object(this);
        var len = t.length >>> 0;
        if (len === 0) {
            return -1;
        }
        var n = 0;
        if (arguments.length > 0) {
            n = Number(arguments[1]);
            if (n !== n) { // shortcut for verifying if it's NaN
                n = 0;
            } else if (n !== 0 && n !== window.Infinity && n !== -window.Infinity) {
                n = (n > 0 || -1) * Math.floor(Math.abs(n));
            }
        }
        if (n >= len) {
            return -1;
        }
        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
        for (; k < len; k++) {
            if (k in t && t[k] === searchElement) {
                return k;
            }
        }
        return -1;
    }
}

Upvotes: 2

Related Questions