简体   繁体   中英

How can i filter a list of divs when 2 checkboxes are checked using jquery or javascript?

I have a list of 4 divs and i use 2 checkboxes to filter the list by the existence of specific divs. The filtering works perfect until i check both 2 checkboxes.

As you can see in my code below if you try to check both "Card" & "Paypal" checkboxes the list is disappeared. Instead i need to display all of 4 divs. How can i make it work this way?

Here's the code:

 $("#by-card").change(function() { $('.store-block .store-payment-options').each(function() { if ($(this).find('.card-available').length === 0) { $(this).parent(".store-block").toggleClass('hide-me'); } }); }); $("#by-paypal").change(function() { $('.store-block .store-payment-options').each(function() { if ($(this).find('.paypal-available').length === 0) { $(this).parent(".store-block").toggleClass('hide-me'); } }); }); 
 .search-area { margin-bottom: 10px; } .storesList { margin-top: 20px; } #count { display: inline-block; } .store-block { width: 80%; margin-bottom: 10px; padding: 5px; background: #e5e5e5; position: relative; overflow: hidden; } .rating { position: absolute; right: 70px; top: 3px; } .minorder { position: absolute; right: 180px; top: 3px; } .paypal-available, .card-available { position: absolute; right: 10px; top: 5px; font-size: 11px; font-weight: bold; color: blue; } .right { float: right; } .left { float: left; } .hide-me { display: none; } .checkbox-lab { font-size: 12px; font-weight: bold; cursor: pointer; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <div class="checkboxes-area"> <div class=" inputRadioGroup"> <input type="checkbox" id="by-card"> <label for="by-card">Card</label> </div> <div class=" inputRadioGroup"> <input type="checkbox" id="by-paypal"> <label for="by-paypal">Paypal</label> </div> </div> <div class="storesList"> <div class="store-block"> <div class="store-name">Apple Store</div> <div class="rating">&bigstar; 4.5</div> <div class="minorder">100 €</div> <div class="store-payment-options"> <div class="card-available">CARD</div> </div> </div> <div class="store-block"> <div class="store-name">Nokia Store</div> <div class="rating">&bigstar; 3.8</div> <div class="minorder">250 €</div> <div class="store-payment-options"> <div class="paypal-available">PAYPAL</div> </div> </div> <div class="store-block"> <div class="store-name">Samsung Store</div> <div class="rating">&bigstar; 4.0</div> <div class="minorder">25 €</div> <div class="store-payment-options"> <div class="card-available">CARD</div> </div> </div> <div class="store-block"> <div class="store-name">Linux</div> <div class="rating">&bigstar; 4.9</div> <div class="minorder">50 €</div> <div class="store-payment-options"> <div class="paypal-available">PAYPAL</div> </div> </div> </div> 

To get that behaviour you need to change the code which you have:

  1. You need to have a single change function for the checkboxes of paypal and card
  2. Then whenever any of the checkbox is checked/unchecked, you can loop both the checkboxes to know if any of them is checked. If you get the checkbox checked then show the elements with class store-block where I have also added one more class same as the id value of the checkbox that is clicked.
  3. Using this class value it will be easy to determine the set of divs that belong to the particular checkbox.
  4. You also need to manage the scenario when all the checkbox are unchecked after they were checked so, for that I have used a variable oneChecked .

 $(".inputRadioGroup input[type='checkbox']").change(function() { var oneChecked = false; $(".inputRadioGroup input[type='checkbox']").each(function(){ var checked = this.checked; var checkedId = $(this).attr('id'); if(checked){ oneChecked = true; $('.'+checkedId).show(); } else { $('.'+checkedId).hide(); } }); if(!oneChecked){ $('.store-block').show(); } }); 
 .search-area { margin-bottom: 10px; } .storesList { margin-top: 20px; } #count { display: inline-block; } .store-block { width: 80%; margin-bottom: 10px; padding: 5px; background: #e5e5e5; position: relative; overflow: hidden; } .rating { position: absolute; right: 70px; top: 3px; } .minorder { position: absolute; right: 180px; top: 3px; } .paypal-available, .card-available { position: absolute; right: 10px; top: 5px; font-size: 11px; font-weight: bold; color: blue; } .right { float: right; } .left { float: left; } .hide-me { display: none; } .checkbox-lab { font-size: 12px; font-weight: bold; cursor: pointer; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="checkboxes-area"> <div class="inputRadioGroup"> <input type="checkbox" id="by-card"> <label for="by-card">Card</label> </div> <div class="inputRadioGroup"> <input type="checkbox" id="by-paypal"> <label for="by-paypal">Paypal</label> </div> </div> <div class="storesList"> <div class="store-block by-card"> <div class="store-name">Apple Store</div> <div class="rating">&bigstar; 4.5</div> <div class="minorder">100 €</div> <div class="store-payment-options"> <div class="card-available">CARD</div> </div> </div> <div class="store-block by-paypal"> <div class="store-name">Nokia Store</div> <div class="rating">&bigstar; 3.8</div> <div class="minorder">250 €</div> <div class="store-payment-options"> <div class="paypal-available">PAYPAL</div> </div> </div> <div class="store-block by-card"> <div class="store-name">Samsung Store</div> <div class="rating">&bigstar; 4.0</div> <div class="minorder">25 €</div> <div class="store-payment-options"> <div class="card-available">CARD</div> </div> </div> <div class="store-block by-paypal"> <div class="store-name">Linux</div> <div class="rating">&bigstar; 4.9</div> <div class="minorder">50 €</div> <div class="store-payment-options"> <div class="paypal-available">PAYPAL</div> </div> </div> </div> 

I'm not good at jQuery, but here's how I'd solve that using good old plain vanilla Javascript. The key change to your approach is to listen for the change event on a parent element of both checkboxes (instead of on each checkbox with a seperate handler), then check if either , or both , or no checkboxes are checked, and create the appropriate DOM state accordingly:

 var checkboxArea = document.querySelector('.checkboxes-area') var storeBlocks = Array.from(document.querySelectorAll('.store-block')) var byCard = document.getElementById('by-card') var byPaypal = document.getElementById('by-paypal') var cardBlocks = storeBlocks.filter(function(block) { return block.querySelector('.card-available') }) var payPalBlocks = storeBlocks.filter(function(block) { return block.querySelector('.paypal-available') }) checkboxArea.addEventListener('change', function(e) { switch (true) { case byCard.checked && byPaypal.checked: storeBlocks.forEach(function(block) { block.classList.remove('hide-me') }) break case byCard.checked: cardBlocks.forEach(function(block) { block.classList.remove('hide-me') }) payPalBlocks.forEach(function(block) { block.classList.add('hide-me') }) break case byPaypal.checked: cardBlocks.forEach(function(block) { block.classList.add('hide-me') }) payPalBlocks.forEach(function(block) { block.classList.remove('hide-me') }) break default: payPalBlocks.concat(cardBlocks).forEach(function(block) { block.classList.remove('hide-me') }) } }) 
 .search-area { margin-bottom: 10px; } .storesList { margin-top: 20px; } #count { display: inline-block; } .store-block { width: 80%; margin-bottom: 10px; padding: 5px; background: #e5e5e5; position: relative; overflow: hidden; } .rating { position: absolute; right: 70px; top: 3px; } .minorder { position: absolute; right: 180px; top: 3px; } .paypal-available, .card-available { position: absolute; right: 10px; top: 5px; font-size: 11px; font-weight: bold; color: blue; } .right { float: right; } .left { float: left; } .hide-me { display: none; } .checkbox-lab { font-size: 12px; font-weight: bold; cursor: pointer; } 
 <div class="checkboxes-area"> <div class="inputRadioGroup"> <input type="checkbox" id="by-card"> <label for="by-card">Card</label> </div> <div class="inputRadioGroup"> <input type="checkbox" id="by-paypal"> <label for="by-paypal">Paypal</label> </div> </div> <div class="storesList"> <div class="store-block"> <div class="store-name">Apple Store</div> <div class="rating">&bigstar; 4.5</div> <div class="minorder">100 €</div> <div class="store-payment-options"> <div class="card-available">CARD</div> </div> </div> <div class="store-block"> <div class="store-name">Nokia Store</div> <div class="rating">&bigstar; 3.8</div> <div class="minorder">250 €</div> <div class="store-payment-options"> <div class="paypal-available">PAYPAL</div> </div> </div> <div class="store-block"> <div class="store-name">Samsung Store</div> <div class="rating">&bigstar; 4.0</div> <div class="minorder">25 €</div> <div class="store-payment-options"> <div class="card-available">CARD</div> </div> </div> <div class="store-block"> <div class="store-name">Linux</div> <div class="rating">&bigstar; 4.9</div> <div class="minorder">50 €</div> <div class="store-payment-options"> <div class="paypal-available">PAYPAL</div> </div> </div> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM