When you say, "I need to be able to filter by AND and OR", what I understand you to mean is this:
- If some Names and some Types are selected: show the articles whose Name and Type are both selected.
- If some Names are selected, but no Types: show the articles whose Name is selected, regardless of Type.
- If some Types are selected, but no Names: show the articles whose Type is selected, regardless of Name.
If this understanding is correct, I think it will be very difficult to accomplish is tracking the selected filters in a single array. This is because we need to check separately if any names are selected as well as any types. My recommendation would be to store these selected filters separately. For example:
const selectedFilters = {
names: [],
types: []
};
We would then need to update the logic that updates the selectedFilters:
const changedFilters = {
names: $this.data('category-name'),
types: $this.data('category-type')
};
['names', 'types'].forEach(key => {
if (!changedFilters[key]) { return; }
const value = changedFilters[key];
const index = selectedFilters[key].indexOf(value);
if (index > -1) {
selectedFilters[key] = selectedFilters[key].slice(0, index).concat(selectedFilters[key].slice(index + 1));
} else {
selectedFilters[key].push(value);
}
});
Finally, we loop through each .article-child and determine whether to show or hide it (using jQuery's .toggle method). The logic will filter by Name only if there are selected Names and will filter by Type only if there are selected Types:
$('.article-child').each(function () {
const $this = $(this);
const categoryName = $this.data('category-name');
const categoryType = $this.data('category-type');
let isVisible = true;
if (selectedFilters.names.length) {
isVisible = isVisible && selectedFilters.names.includes(categoryName);
}
if (selectedFilters.types.length) {
isVisible = isVisible && selectedFilters.types.includes(categoryType);
}
$this.toggle(isVisible);
});
Here is an example fiddle.
return filterArray.includes($(this).data('category-type')) && filterArray.includes($(this).data('category-name'));says you have to have both type and name selected - if either filter is unselected, you get nothing.pushto thefilterArrayto theelseblock.