Thomas
Thomas

Reputation: 7118

CSS/jQuery selector to find elements which don't have a certain parent

I found solutions to check if the parent does not have a certain class using :parent, but I want to have a node type excluded. In my case I only wants forms which are not placed withing an article.

I found a solution with filter, but I was wondering if there is a selector only way to achieve the same:

$('form.frm').filter(function() {
    return $(this).parent().is(":not(article)");
});

EDIT: This solution isn't perfect as it only works if the form.frm is an immediate child of article. Sometimes I have a div in between. Here a simplified DOM structure:

<div id="pageContent">
    <articel>
        <div class="box">
            <form class="frm"></form>
        </div>
    </article>
    <articel>
        <form class="frm"></form>
    </article>
</div>

Upvotes: 2

Views: 1675

Answers (2)

Mohammad
Mohammad

Reputation: 21499

Use .closest() to find any article parent of element and check if length of selector is 0.

$('form.frm').filter(function() {
  return $(this).closest('article').length == 0;
}).css('color', 'red');

$('form.frm').filter(function() {
  return $(this).closest('article').length == 0;
}).css('color', 'red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="pageContent">
  <article>
    <div class="box">
      <form class="frm">article > div</form>
    </div>
  </article>
  <article>
    <form class="frm">article</form>
  </article>
  <div class="box">
    <form class="frm">div</form>
  </div>
</div>

Also you can select all .frm and use .not() to exclude all element has article parent.

$('.frm').not($('article').find('.frm')).css('color', 'red');

Upvotes: 3

Richard Parnaby-King
Richard Parnaby-King

Reputation: 14891

Answer is a modification of Mohammad's. The difference is that this code is not using filter, it is using not:

$('form.frm').not('article form.frm')

This is more or less the same thing. You specify a global selector, then exclude the forms you do not want (in this case, any form that is a descendent of article).

$('form.frm').not('article form.frm').css('color', 'red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="pageContent">
  <article>
    <div class="box">
      <form class="frm">article > div</form>
    </div>
  </article>
  <article>
    <form class="frm">article</form>
  </article>
  <div class="box">
    <form class="frm">div</form>
  </div>
</div>

Upvotes: 2

Related Questions