0

I have multiple selects set up as filters to filter (hide/show) DOM elements within a specific section of the page. The sections are set up like this (simplified):

<section id="people">
    <div data-filtervals="{"titleLevel":["2"],"titleFunction":["4","13"]}">John Doe</div>
    .
    .
    .
    <div data-filtervals="{"titleLevel":["1"],"titleFunction":["2","3","10"]}">Sally Smith</div>
</section>

My filters produce an array like this in console.log(filter):

titleFunction: Array[2]
    0: "1"
    1: "2"
    length: 2
titleLevel: Array[3]
    0: "1"
    1: "2"
    2: "3"
    length: 3

I am trying to write a function that will iterate over .each of the #people > div's and if the data-key(s) are not in the filter[key] value(s), hide the divs.

So in the example above, John Doe would be hidden because his data-titleLevel AND data-titleFunction are not included in the filter array. There are overlaps in data attribute values so combining them into a single array is not possible and legacy code prevents me from altering this for the moment.

My challenge is more about creating a Javascript (or jQuery) function that can dynamically compare one or more filters against data attributes with matching keys. I have been able to get the filter to work for either/or but not to dynamically filter against multiple filters, unless I hard code it.

I looked into .some() but keep hitting a wall with the logic and other SO "Array in Array" solutions like this and this but I have found they don't seem to quite solve this challenge.

EDIT: I have decided to combine the data attributes into a single data attribute with the value being JSON with keys matching the filter keys; perhaps this will make the comparison easier. Still looking for a solution while I work on it.

Community
  • 1
  • 1
Andrew
  • 42
  • 5
  • can you share a sample of array (2d) and the markup it should manipulate to hide and show based on values of this 2d array? – gurvinder372 Feb 12 '16 at 05:02

1 Answers1

0

Well here's my attempt at this. I don't know where your filters are coming from but if they're dynamic I hope they are in an one object. With that hypothesis I made a solution.I'm also guessing that you have found a way to organize the divs into one array of objects

So assumming that

var filters = {titleLevel:[1,2],titleFunction:[1,2,3]};
var divs = [{titleLevel:[2],titleFunction:[4,13]},{titleLevel:[1],titleFunction:[2,3,10]}];
var hasOverLap = function(arr1,arr2){   
    var flag = false;
    arr1.forEach((item)=>{
        if(arr2.indexOf(item) != -1){flag = true;}
    });
    return flag;
};

The following code should get you an object of filtered divs

divs.filter(div=>{
    for(var key in div){
        if(!hasOverLap(div[key],filters[key])){
            return false;
        }
    }
    return true;
});

It's not a complete solution but i hope it helps you get started.

D--
  • 86
  • 6
  • The filters are coming from 2 bootstrap-select fields, dedicated to the specific section they are to filter. I have edited the original code to put all of the filterable data into a single data attribute, as JSON, in the div. The keys in the data attribute will match the filter key. I'm thinking this will make it easier to compare the filter[key] value(s) against the data attribute[key] value(s). Perhaps this will make it easier for the filter method to search the data attribute for matching key=>value(s). – Andrew Feb 12 '16 at 20:05