DaFois
DaFois

Reputation: 2223

How to hide/show parent elements with jQuery

I have a jquery filter that filters elements containing the string in the input#box hiding them. I've added the initial letters to the HTML and I want to hide them when all contained element are hidden. I've tried several combination of jQuery parentsand closest without any success...

$('#box').keyup(function() {
  var valThis = $(this).val().toLowerCase();
  if (valThis == "") {
    $('.indicazione').show();
  } else {
    $('.indicazione').each(function() {
      var text = $(this).text().toLowerCase();
      if (text.indexOf(valThis) >= 0) {
        $(this).show();
      } else {
        $(this).hide();
        $(this).parents('.indicazione_wrapper').hide(); /*This Line doesn't work*/
      }
    });
  };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
  <div class="col-sm-12 mt-5 mb-3">
    <input id="box" type="text" />
  </div>
</div>
<div class="row">
  <div class="col-sm-12 mt-3" id="lettera"><strong>A</strong></div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">AAA</a>
    </div>
  </div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">ABC</a>
    </div>
  </div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">CDE</a>
    </div>
  </div>
  <div class="col-sm-12 mt-3" id="lettera"><strong>B</strong></div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">BBB</a>
    </div>
  </div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">ABC</a>
    </div>
  </div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">CDE</a>
    </div>
  </div>
</div>

Upvotes: 0

Views: 194

Answers (4)

daremachine
daremachine

Reputation: 2788

Remove unnecessary $(this).parents('.indicazione_wrapper').hide(); from if and add this code

if($(this).closest('.indicazione_wrapper').find('.indicazione:hidden').length ==                            
    $(this).closest('.indicazione_wrapper').find('.indicazione').length) {
        $(this).closest('.indicazione_wrapper').first().hide();
}

And you need wrap your items into

<div class="indicazione_wrapper"> ... </div>

$('#box').keyup(function() {
  var valThis = $(this).val().toLowerCase();
  if (valThis == "") {
    $('.indicazione').show();
  } else {
    $('.indicazione').each(function() {
    
     $(this).closest('.indicazione_wrapper').first().show(); // <-- show latters after input change
    
      var text = $(this).text().toLowerCase();
      if (text.indexOf(valThis) >= 0) {
        $(this).show();
      } else {
        $(this).hide();
      }
      
      // hide latter if all items are hidden
      if($(this).closest('.indicazione_wrapper').find('.indicazione:hidden').length == 			    		    $(this).closest('.indicazione_wrapper').find('.indicazione').length) {
    	  $(this).closest('.indicazione_wrapper').first().hide();
      }
    
    });
  };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
  <div class="col-sm-12 mt-5 mb-3">
    <input id="box" type="text" />
  </div>
</div>
<div class="row">
  <div class="indicazione_wrapper">
    <div class="col-sm-12 mt-3" id="lettera"><strong>A</strong></div>
    <div class="col-sm-4 col-md-3 d-flex ">
      <div class="card card-body flex-fill my-3">
        <a class="indicazione" href="#">AAA</a>
      </div>
    </div>
    <div class="col-sm-4 col-md-3 d-flex">
      <div class="card card-body flex-fill my-3">
        <a class="indicazione" href="#">ABC</a>
      </div>
    </div>
    <div class="col-sm-4 col-md-3 d-flex">
      <div class="card card-body flex-fill my-3">
        <a class="indicazione" href="#">CDE</a>
      </div>
    </div>
  </div>
  <div class="indicazione_wrapper">
    <div class="col-sm-12 mt-3" id="lettera"><strong>B</strong></div>
    <div class="col-sm-4 col-md-3 d-flex">
      <div class="card card-body flex-fill my-3">
        <a class="indicazione" href="#">BBB</a>
      </div>
    </div>
    <div class="col-sm-4 col-md-3 d-flex">
      <div class="card card-body flex-fill my-3">
        <a class="indicazione" href="#">AX</a>
      </div>
    </div>
    <div class="col-sm-4 col-md-3 d-flex">
      <div class="card card-body flex-fill my-3">
        <a class="indicazione" href="#">CDE</a>
      </div>
    </div>
  </div>     
</div>

Upvotes: 0

Lapskaus
Lapskaus

Reputation: 1721

You can't hide the inital letters when all contained elements are hidden, because your your initial headers are not containing the elements you are hiding.

Wrap your child elements ("AAA", "ABC") in the div containting your initial letters "A". Then you can select them with the parent() selector.

<div class="col-sm-12 mt-3" id="lettera"><strong>A</strong> <!-- REMOVE here-->
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">AAA</a>
    </div>
  </div>
</div> <!-- ADD here-->

Then you can select them using parent()

$('.indicazione_wrapper').parent();

Upvotes: 0

Kunal Mukherjee
Kunal Mukherjee

Reputation: 5853

I dont think the $(this).hide() is necessary as you are already hiding the parent div.

Change your code to this:

$('#box').keyup(function() {
  var valThis = $(this).val().toLowerCase();
      
  if (valThis == "") {
    $('.indicazione_wrapper').show();
  } else {
    $('.indicazione').each(function() {
      var text = $(this).text().toLowerCase();
      if (text.indexOf(valThis) >= 0) {
        $(this).show();
      } else {
         $(this).parents('.indicazione_wrapper').hide();
      }
    });
  };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
  <div class="col-sm-12 mt-5 mb-3">
    <input id="box" type="text" />
  </div>
</div>
<div class="row">
  <div class="col-sm-12 mt-3" id="lettera"><strong>A</strong></div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">AAA</a>
    </div>
  </div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">ABC</a>
    </div>
  </div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">CDE</a>
    </div>
  </div>
  <div class="col-sm-12 mt-3" id="lettera"><strong>B</strong></div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">BBB</a>
    </div>
  </div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">ABC</a>
    </div>
  </div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">CDE</a>
    </div>
  </div>
</div>

Upvotes: 0

Chris Barr
Chris Barr

Reputation: 33970

Your code works just fine, except that you called $(this).parents('.indicazione_wrapper').hide() to hide that element, but then you never showed it again.

I've added the .indicazione_wrapper selector this part

if (valThis == "") {
    $('.indicazione, .indicazione_wrapper').show(); 
  } else { ...

and then I added some BG color to show that the correct elements are hiding and showing.

$('#box').keyup(function() {
  var valThis = $(this).val().toLowerCase();
  if (valThis == "") {
    $('.indicazione, .indicazione_wrapper').show(); 
  } else {
    $('.indicazione').each(function() {
      var text = $(this).text().toLowerCase();
      if (text.indexOf(valThis) >= 0) {
        $(this).show();
      } else {
        $(this).hide();
        $(this).parents('.indicazione_wrapper').hide(); /*This Line doesn't work*/
      }
    });
  };
});
.indicazione_wrapper {
  background: lightblue;
}

.indicazione {
  background: pink;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
  <div class="col-sm-12 mt-5 mb-3">
    <input id="box" type="text" />
  </div>
</div>
<div class="row">
  <div class="col-sm-12 mt-3" id="lettera"><strong>A</strong></div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">AAA</a>
    </div>
  </div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">ABC</a>
    </div>
  </div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">CDE</a>
    </div>
  </div>
  <div class="col-sm-12 mt-3" id="lettera"><strong>B</strong></div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">BBB</a>
    </div>
  </div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">ABC</a>
    </div>
  </div>
  <div class="col-sm-4 col-md-3 d-flex indicazione_wrapper">
    <div class="card card-body flex-fill my-3">
      <a class="indicazione" href="#">CDE</a>
    </div>
  </div>
</div>

Upvotes: 1

Related Questions