Tone Škoda
Tone Škoda

Reputation: 1523

JQuery find() with option to ignore specific tags and their children

I need a jQuery function that will ignore (filter out) specific tags and all their (grand)children when searching, based on their properties. More specific: I want to find tag which has attribute data-type="a", but only if one of its (grand)parents doesn't have attribute data-type="b". I guess this doesn't exist and I should write my own javascript code to search. I am inclined to do that but I read that is error prone and not browser compatible?

Upvotes: 0

Views: 112

Answers (3)

Tone Škoda
Tone Škoda

Reputation: 1523

I ended up using $.filter() with $.parentsUntil(). Here is general function for someone to use it:

// returns found jquery tag(s), jquery object
function FindWithFilterOut($ctlMain, filterIn,

    // any controls that have these properties are filtered out of search and all their children
    // to define multiple filters combined with OR operator use selectors separated with comma, for excample: [data-type='a'],[data-type='c'] 
    filterOut

    ) {
    return $ctlMain.find(filterIn).filter(function (index) {
        var $parentToFilterOut = $(this).parentsUntil($ctlMain, filterOut);
        if ($parentToFilterOut.length > 0)
            return false;
        if ($(this).is(filterOut))
            return false;
        return true;
    });
}

https://jsfiddle.net/tskoda/80s9d61s/3/

Upvotes: 0

Rafael Kennedy
Rafael Kennedy

Reputation: 1004

jQuery provides a method for doing exactly this kind of thing called .grep() (see docs )

var aTypes = $('[data-type="a"]')

aTypes = $.grep(aTypes, function(el, i) {
  return $(el).parents('[data-type="b"]').length === 0
})

console.log(aTypes)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-type="a"></div>
<div data-type="a">
  <div data-type="b"></div>
</div>
<div data-type="b"></div>
<div data-type="b">
 <div data-type="a">Ignore Me</div>
</div>
<div data-type="a">
  <div data-type="a"></div>
</div>

Upvotes: 3

quirimmo
quirimmo

Reputation: 9988

var aTypes = $('[data-type="a"]');
var aTypesToKeep = [];
$.each(aTypes, function() {
    var hasBType = $(this).parents().every(function(el) {
        return $(this).attr('data-type') === 'b';
    });
    if (!hasBType) {
        aTypesToKeep.push($(this));
    } 
});
// aTypesToKeep array with jQuery elements of data-type a that don't have parent with data-type b

Upvotes: 1

Related Questions