Reputation: 1417
I have a set of nested ul's that look like this:
<ul id="educationList">
<li class="category"><p>Media production</p>
<ul>
<li class="education" style="display: block;">
<a href="#">Real time 3D animation</a>
</li>
<li class="education" style="display: block;">
<a href="#">Filming with Steadicam</a>
</li>
<li class="education" style="display: block;">
<a href="#">Sound Effects</a>
</li>
</ul>
</li>
</ul>
The top ul (educationList) holds a list of categories and each category has a sub list (ul) with the educations that sort under this category. A classic nested list structure. In the sample code above I have just one category - in the real code there are a lot of categories.
I have a jQuery filtering function that shows/hides li-elements that have the class "education" (sub list elements). Sometimes this filtering function hides all sub list elements, so the HTML looks like this:
<ul id="educationList">
<li class="category"><p>Media production</p>
<ul>
<li class="education" style="display: none;">
<a href="#">Real time 3D animation</a>
</li>
<li class="education" style="display: none;">
<a href="#">Filming with Steadicam</a>
</li>
<li class="education" style="display: none;">
<a href="#">Sound Effects</a>
</li>
</ul>
</li>
</ul>
The difference is that all sub list elements now all have the inline style display: none. All of a sudden I have no real use for the parent li with the class "category" since there are no educations under this category.
Now I'm looking for a smart way to find all category list items that have no visible child education list items and simply hide the category list item. I will have to run this function every time that I do any filtering because the filtering will affect the child education list items - some that where visible will be hidden and some that where hidden will become visible again.
Also - I will have a lot of elements so it's an advantage if the code is not too resource hungry. Still, this is not the time to be picky. Any solution will do and I'll have to work on optimizing later.
Thanks in advance! /Thomas Kahn
Upvotes: 1
Views: 4557
Reputation: 462
$("li.category").each(function(){
if($(this).find("li.education").css("display")=="none")
{
$(this).hide();
}
});
Upvotes: 0
Reputation: 26183
This is the simple and convenient jQuery solution that doesn't completely ignore resource usage:
$('li.category').each(function() {
var $li = $(this);
if(!$li.find('li:visible').length) {
$li.hide();
}
});
If you need performance optimization, you could do this instead, which doesn't have the overhead of the .each
:
var categories = $('li.category');
for(var i=0,category;category = categories.eq(i);i++) {
if(!category.find('li:visible').length) {
category.hide();
}
}
EDIT: fixed bug in optimized version
Upvotes: 4
Reputation: 136104
This should be as simple as:
$('li.category:not(:has(li:visible))').hide();
Live example: http://jsfiddle.net/wTKEQ/
If you run it as-is, then the category will be hidden. If you change one or more of the sub-items to display:block
, nothing happens.
Upvotes: 5
Reputation: 380
$("li.category").each(function(){
if($(this).find("li:visible").size() == 0)$(this).hide();
});
Upvotes: 2