4

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

});
2
  • filter() lets you pass a function in, instead of a selector. api.jquery.com/filter Commented Sep 7, 2011 at 16:53
  • right, well technically I am using it as a function but it's very basic at this point. Commented Sep 7, 2011 at 17:01

3 Answers 3

2

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;
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I wouldn't worry about compatibility - it's going to be run on Firefox 3+ so that shouldn't be an issue.
1

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/

Comments

1

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

});

Comments

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.