0

See the following markup:

<div class="careersIntegration__listing" id="careers-listing">
  
  <div class="careersIntegration__accordion">
    <div class="careersIntegration__accordion-header">
      <span class="careersIntegration__accordion-dept">Sales</span>
    </div>
    <div class="careersIntegration__accordion-jobs" data-dept="sales"></div>
  </div>
  
  <div class="careersIntegration__accordion">
    <div class="careersIntegration__accordion-header">
      <span class="careersIntegration__accordion-dept">Customer Success</span>
    </div>
    <div class="careersIntegration__accordion-jobs" data-dept="customer-success">
      <figure class="careerCard" data-dept="customer-success">Job</figure>
    </div>
  </div>
  
</div>

I'm trying to hide .careersIntegration__accordion's which have .careersIntegration__accordion-jobs elements that have no children.

To simplify, if .careersIntegration__accordion-jobs has no children, hide the parent .careersIntegration__accordion element.

I've seen examples on existing SO posts (see this one), but cannot get the approach to work in my instance. See posts below which I have tried:

With my current approach below, the else statement is executed, unsure why?

$(".careersIntegration__accordion").each(function(){
  if( $(this).children(".careersIntegration__accordion-jobs").length == 0 ){
    $(this).parent().hide();
  } else{
    console.log('has children');
  }
});
Freddy
  • 683
  • 4
  • 35
  • 114

3 Answers3

1

Contrary to your assumption

$(this).children(".careersIntegration__accordion-jobs")

doesn't return the children of elements using the CSS class careersIntegration__accordion-jobs. In fact it only returns the actual elements using this CSS class. If you want to have it's children you need to append another call to .children().

For example:

$(".careersIntegration__accordion").each(function() {
  if ($(this).children(".careersIntegration__accordion-jobs").children().length == 0) {
    $(this).hide();
  } else {
    console.log('has children');
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="careersIntegration__listing">

  <!-- this should be hidden -->
  <div class="careersIntegration__accordion">
    <div class="careersIntegration__accordion-header">
      <span class="careersIntegration__accordion-dept">Sales</span>
    </div>
    <div class="careersIntegration__accordion-jobs"></div>
  </div>


  <!-- this should not be hidden -->
  <div class="careersIntegration__accordion">
    <div class="careersIntegration__accordion-header">
      <span class="careersIntegration__accordion-dept">Tech</span>
    </div>
    <div class="careersIntegration__accordion-jobs">
      <div>item</div>
    </div>
  </div>


</div>
obscure
  • 11,916
  • 2
  • 17
  • 36
  • Hi, using `.$(this).parent().hide();` hides the `. careersIntegration__listing` `div`. I've tried it with `.$(this).hide();`, so that it targets the `.careersIntegration__accordion` `div` instead. But, this didn't work for me either, it hid all of the `.careersIntegration__accordion` `div`'s – Freddy Jan 13 '22 at 14:21
  • Sorry my bad - I didn't test that part of your code as I assumed it's correct. I just corrected the snippet in my answer to use `$(this).hide();` instead and it seems to work as only the Sales div disappears. Still no luck? – obscure Jan 13 '22 at 14:32
  • Hmm, I have copied your `js` exactly, but in my instance, it hides all of the divs. See image here: https://i.imgur.com/lcK05RS.png. From the image you can see that one `.careersIntegration__accordion-jobs` has child elements, and one doesn't, but both of them are being targeted and hidden by the `js` – Freddy Jan 13 '22 at 14:44
  • The inline styles on `.careersIntegration__accordion` are set by the `hide()` function. I have no inline or other css set on `.careersIntegration__accordion` – Freddy Jan 13 '22 at 14:55
  • Can you post your exact code as a working snippet to your question? – obscure Jan 13 '22 at 14:56
  • No major changes from previous version, but done, updated question. – Freddy Jan 13 '22 at 15:03
  • What version of jquery are you using? What do you see if you put a `console.log($(this).children(".careersIntegration__accordion-jobs")[0],$(this).children(".careersIntegration__accordion-jobs")[0].children.length);` inside the `.each()` block? – obscure Jan 13 '22 at 16:28
  • I'm on jQuery version `3.6.0` and here is an image which shows the `console.log` requested: https://i.imgur.com/gUHsYli.png – Freddy Jan 14 '22 at 00:23
  • I'm running out of ideas Freddy. I tried replicating your scenario by using 10 `
    ` elements too and it correctly reports that there are 10 children. What is inside of each of those elements?
    – obscure Jan 14 '22 at 02:30
  • My apologies, I had a `fetch()` function running in which these `.careerCards` were being sorted into their categories. Your reply got me thinking that it may be returning `0` as it's running at the wrong time, so I moved your JS into my fetch and it started to work. Many thanks for your help – Freddy Jan 14 '22 at 20:18
  • Ah there lies the rub. I'm glad I could help and you got it sorted now! =) – obscure Jan 15 '22 at 16:02
0

You could use html() to get the information you need and then check if it's equal to an empty string:

$(this).children(".careersIntegration__accordion-jobs").html() === ''

That should do the trick!

0

Because $(this).children(".careersIntegration__accordion-jobs").length just counts the elements with the class careersIntegration__accordion-jobs - but you want to inspect the children of these elements.

The following code works:

$(document).ready(function(){
  $(".careersIntegration__accordion .careersIntegration__accordion-jobs").each(function(){
  console.log("children().length="+$(this).children().length);
    if( $(this).children().length == 0 ){
      $(this).hide();
      console.log('no children');
    } else{
      console.log('has children');
    }
  });
});
Check it out here: https://jsfiddle.net/czs0uya5/
Falco Preiseni
  • 387
  • 4
  • 12