Berin Aptula
Berin Aptula

Reputation: 224

Filtering an array depending on multiple checkbox conditions

I am building a real estate website where users can apply filters. One of the filters I want to have is whether the property has a balcony, roof terrace and a garden.

So when I have only one checkbox checked(balcony) I want to show all the properties with balconies. But when I have two checkboxes checked(e.g. garden and balcony) I want to render only the properties with these specific qualities, who have both garden and balcony.

I have a solution which is rather complex and difficult to maintain. Currently I have only 3 checkboxes, but what if I add 5more? The code would become very inefficient and everything has to be coded again.

Here is my "complex" solution:

var filters = {
 balcony: false,
 garden: false,
 roofTerrace: false
};

const checkboxFilter = plotAreaFilter.filter((item) => {
    // If only Balcony is checked
    if (filters.balcony && !filters.roofTerrace & !filters.garden) {
        if (item.balcony) {
            return true
        }
    }
    // If both Balcony and Roof Terrace is checked
    else if (filters.balcony && filters.roofTerrace & !filters.garden) {
        if (item.balcony && item.roofTerrace) {
            return true
        }
    }
    // If all three Balcony, Roof Terrace and Garden is checked
    else if (filters.balcony && filters.roofTerrace & filters.garden) {
        if (item.balcony && item.roofTerrace && item.garden) {
            return true
        }
    }
    // If only Roof Terrace is checked 
    else if (!filters.balcony && filters.roofTerrace & !filters.garden) {
        if (item.roofTerrace) {
            return true
        }
    }
    // If only Garden is checked
    else if (!filters.balcony && !filters.roofTerrace & filters.garden) {
        if (item.garden) {
            return true
        }
    }

    // If both Roof Terrace and Garden is checked
    else if (!filters.balcony && filters.roofTerrace & filters.garden) {
        if (item.roofTerrace && item.garden) {
            return true
        }
    }

    // If only Balcony and Garden is checked 
    else if (filters.balcony && !filters.roofTerrace & filters.garden) {
        if (item.balcony && item.garden) {
            return true
        }
    } else {
        return true
    }
})
return checkboxFilter;

I am really hoping that there is a better solution to that

Upvotes: 2

Views: 1180

Answers (2)

Nikhil Aggarwal
Nikhil Aggarwal

Reputation: 28455

You can try following

  • For each item in plotAreaFilter array do the following
  • Check it against every filter condition where for each filter will be true if
  • filter is not applied or if applied the corresponding value for item is true

var filters = {balcony: true,garden: true,roofTerrace: false};
var plotAreaFilter = [{"balcony": true, "garden": true}];

const checkboxFilter = plotAreaFilter.filter(item => Object.entries(filters).every(([key, value]) => !value || item[key])); 

console.log(checkboxFilter);

For reference, Array.every & Object.entries

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386560

You could take get the entries and check all against the given value.

var filters = { balcony: false, garden: true, roofTerrace: true },
    wanted = Object.entries(filters), // [['balcony', false], ['garden', true], ['roofTerrace', true]]
    checkboxFilter = plotAreaFilter.filter(item => wanted.every(([k, v]) => item[k] === v));

Upvotes: 4

Related Questions