2

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

2
  • what if without checking, should the filtering ignore this property? Commented Oct 25, 2019 at 12:08
  • If nothing is checked, just show every property in the array. No matter if they don't have a balcony or have one. Commented Oct 25, 2019 at 12:10

2 Answers 2

4

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

2 Comments

I was just wondering if the item has balcony true and the filter is not applied on balcony then the item will be filtered out even when the filter is on other fields which hold to be valid for item. What do you think?
@NikhilAggarwal, if you look at the conditions of op, like !filters.balcony && !filters.roofTerrace & filters.garden (beside the bitwise AND), you see, unwanted once have to be filtered out. thinkable would be to take a three step check box with a neutral value (which is not mentioned).
2

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

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.