Reputation: 143
Problem: I want to hide multiple elements based on if the child elements of similarly named elements are showing or not.
Context: I have multiple list items contained within one div like so:
<div class="itemGrid">
<ul>
<li>
<button class="header" id="headerCommonItems">
"Common Items"
::after
</button>
<ul class="icons" id="iconsCommonItems">
<li class="itemTile">Apples</li>
<li class="itemTile">Oranges</li>
</ul>
</li>
<li>
<button class="header" id="headerUncommonItems">
"Uncommon Items"
::after
</button>
<ul class="icons" id="iconsUncommonItems">
<li class="itemTile">Pears</li>
<li class="itemTile">Bananas</li>
</ul>
</li>
<li>
<button class="header" id="headerRareItems">
"Rare Items"
::after
</button>
<ul class="icons" id="iconsRareItems">
<li class="itemTile">Pineapples</li>
<li class="itemTile">Guavas</li>
</ul>
</li>
</ul>
</div>
I have a search feature that show/hides icons based on the search criteria (e.g. if I searched the term "common", it would only show the icons for Apples and Oranges, but hide all other icons).
I want to hide the headers if there are no corresponding icons that are visible. So using the previous example, I only want the "Common Items" header to show if I'm searching for the term "Common" and hide "Uncommon Items" and "Rare Items" headers. At the moment, it still would show the other headers even though there are no icons underneath.
I've tried referencing multiple SO pages, but this is my first time working with JQuery and I can't seem to get it to work. Here's a variation of what I've tried so far.
$.each($("[id ^= 'icons']").filter(
function()
{
if ($(this).find('li:visible').length !== 0)
{
console.log("Visible children.");
return;
}
}))
.hide();
I've been able to hide the icons, but I don't know how to reference the corresponding headers and hide those if the child elements of the icons are hidden.
Here are the other SO pages I've been referencing:
Check if all children elements are hidden
How to hide parent if children are hidden?
Upvotes: 0
Views: 142
Reputation: 6532
If I understood you correctly: "I want to hide the headers if there are no corresponding icons that are visible";
Just change your if logic to find hidden, not visible === 0
, and then search for that elements siblings (.header
is not a children of ul class="icons"
):
$(this).siblings(".header").hide();
I also added to remove list icon:
$(this).parents("li").hide();
As you can see from example below, if both items in list "Uncommon Items"
have class: hidden
, it will remove all around it. If one is visible, it wont.
$.each($("[id ^= 'icons']").filter(
function() {
$(this).siblings(".header").show();
$(this).parents("li").show();
if ($(this).find('li:visible').length === 0) {
$(this).siblings(".header").hide();
$(this).parents("li").hide();
console.log("Hidden children.");
return;
}
}))
.hide();
.hidden {
display: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="itemGrid">
<ul>
<li>
<button class="header" id="headerCommonItems">
"Common Items"
::after
</button>
<ul class="icons" id="iconsCommonItems">
<li class="itemTile">Apples</li>
<li class="itemTile">Oranges</li>
</ul>
</li>
<li>
<button class="header" id="headerUncommonItems">
"Uncommon Items"
::after
</button>
<ul class="icons" id="iconsUncommonItems">
<li class="itemTile hidden">Pears</li>
<li class="itemTile hidden">Bananas</li>
</ul>
</li>
<li>
<button class="header" id="headerRareItems">
"Rare Items"
::after
</button>
<ul class="icons" id="iconsRareItems">
<li class="itemTile">Pineapples</li>
<li class="itemTile">Guavas</li>
</ul>
</li>
</ul>
</div>
Edit:
As requested add this out side of your if
statement, it will always first show/reset all and then make new filtering in if
statement.
$(this).siblings(".header").show();
$(this).parents("li").show();
Upvotes: 1