0

OK, it's friday and I'm really tired:

OK, it's nearly friday again (yes, one week later!) and I'm getting even more tired:

How do I find all elements with on of the entries from an array.

How do I make a freakin complicated jQuery selector that keep sending me in the fence over and over again?

My array (of selectors):

["one", "two", "three", "four", "five"]

My elements:

<div data-filters="one two three four five"></div>
<div data-filters="one three four five"></div>
<div data-filters="one two four five"></div>
<div data-filters="two three five"></div>
<div data-filters="one four five"></div>
<div data-filters="two three four five"></div>
<div data-filters="four five"></div>

What is the most optimized way of getting ALL elements that contain ONE of the strings in the array?

I'm already filtering using:

$(this).next().find('tr.normal').? ... how to extend selector using array

I have a range of divs which contain table of rows with data-filtertypes in the form of space separated strings:

<div class="category">
    <table>
        <tr data-filtertypes="one three five"><td></td></tr>
    </table>
</div>
<div class="category">
    <table>
        <tr data-filtertypes="one two four"><td></td></tr>
    </table>
</div>
<div class="category">
    <table>
        <tr data-filtertypes="three five"><td></td></tr>
    </table>
</div>

I initially hide all categories:

$('.category').hide()

I then want to show categories (and rows) based on the user typing into a field (search text on multiple other attributes not shown here for brevity), but first I want to reduce the collection by filtering using buttons with matching names - if any are selected.

var any_filters = ["two", "four"];

$('.category').hide().filter(
    if ( any_filters.length > 0 ) {
        // Here I (think) I need $.each() to iterate element using the any_filters array ... I want to 'return' a reduced selection set I can then pass on to another piped filter()
        // Problem with return here!?
        $.each( any_filters, function ( index, value ) {
            return $( '[data-filtertypes*="' + value + '"]' );
        });
    }
).filter(
    // What is passed into this filter?
    console.log( "?", this );
)

Is this approach totally screwed, or am I on the right track? And what pieces am I missing in making this 'tactic' work?

3
  • 2
    I am also tired, but can work for you if you pay for it. Commented May 22, 2015 at 12:51
  • 1
    None of these divs contain only one of the strings in the array. Do you want to get all the divs that have at least one of the strings of the array ? Commented May 22, 2015 at 12:52
  • Do you mean the elements containing "one"(string) or atleast one element from array. Aah. I'm confused. On a friday... Commented May 22, 2015 at 12:53

4 Answers 4

1

Selects all the divs that have 'value'

$("[data-filters*='value']")

DEMO

var selectors = ["one", "two", "three", "four", "five"];
$.each(selectors, function( index, value ) {
  console.log($("div[data-filters*='" + value + "']"));
});
Sign up to request clarification or add additional context in comments.

2 Comments

Throws me an error form jquery: TypeError: t.apply is not a function
@svendelle feel free to look at the attached jsFiddle, it is a working demo. It does use console.log and jsFiddle isn't extremely IE friendly
1

No need to have a loop, you can just play with a string. Use join and attribute contain selector.

Something like that :

var strSel = ["one", "two", "three", "four", "five"];

$('[data-filters*='+ strSel.join('], [data-filters*=') + ']');

Basicaly, it build a selector. This:

'[data-filters*='+ strSel.join('], [data-filters*=') + ']'

return a string like that :

[data-filters*=one], [data-filters*=two], [data-filters*=three], [data-filters*=four], [data-filters*=five]

Of course, if you have a string in you array equal to twenty and a data containing the value twenty-two, it will catch it.

Fiddle : http://jsfiddle.net/ackrqtvb/

Comments

0

By the way you can try,

var objs = $('[data-filters]');
var filterArray = ["one", "two", "three", "four", "five"];
$.each(objs, function(index, item) {
  var filters = $(this).data('filters').split(/\s+/);
  var count=1;
  $(filters).each(function(key, value) {
    if ($.inArray(value, filterArray)) {
      count++;
    }
  });
  if(count == filterArray.length && count == filters.length){
      $(this).append(' This element has all classes');
  }
});

var objs = $('[data-filters]');
var filterArray = ["one", "two", "three", "four", "five"];
$.each(objs, function(index, item) {
  var filters = $(this).data('filters').split(/\s+/);
  var count=1;
  $(filters).each(function(key, value) {
    if ($.inArray(value, filterArray)) {
      count++;
    }
  });
  if(count == filterArray.length && count == filters.length){
      $(this).append(' This element has all classes');
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-filters="one two three four five">All Filters</div>
<div data-filters="one three four five">2</div>
<div data-filters="one two four five">3</div>
<div data-filters="two three five">4</div>
<div data-filters="one four five">5</div>
<div data-filters="two three four five">6</div>
<div data-filters="four five">7</div>

1 Comment

Just FYI. When working with array, you shouldn't loop by creating a jQuery object ($(filters).each(...)) but instead use the jQuery property $.each ($.each(filters, function(...){...})).
0

Optimized for tiredness:

var targets = ["one", "two", "three", "four", "five"];

var matches = $('div[data-filters]').filter(function() {
    var filters = $(this).data('filters').split(' ');
    return $.map(targets, function(x) { return $.inArray(x, filters) < 0 ? null : x;}).length > 0;
});

http://jsfiddle.net/p8060r0o/

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.