JackH
JackH

Reputation: 4735

Checking against several possible conditions in JavaScript easily?

I am building a page with some filter controls for search results. I have an array like this:

var vehicles = [
    {
        make: 'Audi',
        wheels: 4
    },
    {
        make: 'Chrysler',
        wheels: 3
    },
    {
        make: 'Toyota',
        wheels: 4
    },
    {
        make: 'Harley Davidson',
        wheels: 2
    }
];

var vehiclesToDisplay = [];

In my interface I have 3 checkboxes that allow the visitor to select vehicles based on the number of wheels like:

Now, the user can select any of these checkboxes. Let's say they only select 2 and 4 or more. In this case, I have to loop through the array, validate the two conditions and push the object to the variable vehiclesToDisplay. Similarly, the user could choose to only see 2 wheelers or 4 or more etc.

How would I go about validating for these multiple conditions? I have a few variables that hold the state of the checkboxes like this:

var wheels2 = true, // the value of the checkbox
    wheels3 = true,
    wheelsMore = true;

Any combination of these variables could be false / true. Doesn't seem right to anticipate all the combinations and write IF statements for each. How would I go about this?

Upvotes: 2

Views: 67

Answers (2)

A1rPun
A1rPun

Reputation: 16837

Just use multiple && & || statements to filter your array like this:

vehicles.filter(function(car){
    return wheels2 && car.wheels === 2
           || wheels3 && car.wheels === 3
           || wheelsMore && car.wheels > 3
});

If you happen to have filters (& vehicles) up to 30 wheels you don't want to write this down separately, to keep things DRY check @DavidThomas answer.

Upvotes: 3

David Thomas
David Thomas

Reputation: 253308

I'd suggest forming an array of the values of the checked check-boxes, and then checking if the wheels value of each object is held in that array, using filter():

// getting a NodeList of all the checked <input> elements with
// a type of 'checkbox':
var checkboxes = document.querySelectorAll('input[type=checkbox]:checked'),

    // Function.prototype.call() allows us to use the 
    // Array method, 'filter()', on the array-like NodeList:
    values = Array.prototype.filter.call(checkboxes, function (checkbox) {
        // within the anonymous function, the first argument
        // 'checkbox' is a reference to the array element of the
        // array over which we're iterating.

        // if the checkbox is checked (checkbox.checked
        // evaluates to a Boolean true) then we retain the
        // current array-element in the new Array returned
        // by Array.prototype.filter():
        return checkbox.checked;
    });

// iterating over the vehicles array:
vehiclesToShow = vehicles.filter(function (vehicle) {
    // as above the first (and only) argument of filter()
    // is a reference to the current array-element of the
    // array over which we're iterating.

    // if the value held in the vehicle.wheels property
    // is found within the values array (and so the index
    // returned by indexOf() is greater than -1, we retain
    // the current element in the newly-created array:
    return values.indexOf(vehicle.wheels) > -1;
});

This approach doesn't require you to know the various combinations or number of wheels in advance, or require you to manually write out each potential value in advance (which leads to the maintenance nightmare of, at some point, forgetting to update the conditions).

Upvotes: 3

Related Questions