Reputation: 143
I have this code in HTML, and need to add styles to some ancestor siblings with CSS (may not be able). Therefore I use Javascript to add classes to the ancestors.
I read that you can not create a parent selector with CSS.
FROM THIS:
<ul class="monitor"> <li><span>Servidor 1</span> <ul> <li><span>Hardware</span> <ul> <li>CPU</li> <li>Memoria</li> <li>Disco</li> </ul> </li> <li><span>Airviro</span> <ul> <li class="warning">AVDBM</li> <li>COLDB</li> </ul> </li> </ul> </li> <li><span>Servidor 2</span> <ul> <li><span>Hardware</span> <ul> <li class="error">CPU</li> <li class="warning">Memoria</li> <li>Disco</li> </ul> </li> <li><span>Airviro</span> <ul> <li>AVDBM</li> <li>COLDB</li> </ul> </li> </ul> </li> </ul>
TO THIS:
<ul class="monitor"> <li><span class="warning">Servidor 1</span> <ul> <li><span>Hardware</span> <ul> <li>CPU</li> <li>Memoria</li> <li>Disco</li> </ul> </li> <li><span class="warning">Airviro</span> <ul> <li class="warning">AVDBM</li> <li>COLDB</li> </ul> </li> </ul> </li> <li><span class="error">Servidor 2</span> <ul> <li><span class="error">Hardware</span> <ul> <li class="error">CPU</li> <li class="warning">Memoria</li> <li>Disco</li> </ul> </li> <li><span>Airviro</span> <ul> <li>AVDBM</li> <li>COLDB</li> </ul> </li> </ul> </li> </ul>
Any elegant solution?
Upvotes: 1
Views: 431
Reputation: 2250
First of all some consideration :
add classes to some ancestor siblings with CSS
this doesn't mean anything, you don't add classes with CSS, you style them.
I understand you wish to make a tree where, if a child element has the class .waring or .error then you want its parents to get the same class as well. This probably so you can make the text yellow/red for each tree step. So your problem is not just how to address al the parents and add them a class, but also how to style them properly
YOUR ORIGINAL HTML
<ul class="monitor">
<li><span>Servidor 1</span>
<ul>
<li><span>Hardware</span>
<ul>
<li>CPU</li>
<li>Memoria</li>
<li>Disco</li>
</ul>
</li>
<li><span>Airviro</span>
<ul>
<li class="warning">AVDBM</li>
<li>COLDB</li>
</ul>
</li>
</ul>
</li>
<li><span>Servidor 2</span>
<ul>
<li><span>Hardware</span>
<ul>
<li class="error">CPU</li>
<li class="warning">Memoria</li>
<li>Disco</li>
</ul>
</li>
<li><span>Airviro</span>
<ul>
<li>AVDBM</li>
<li>COLDB</li>
</ul>
</li>
</ul>
</li>
</ul>
HERE SOME EXTRA CSS
.monitor{
color:#00aa00;
}
.warning{
color:#ffaa00;
}
.error{
color:#ff0000;
}
// Notice the rule under here makes everything not warning or error green.
// Try the fiddle without this and you'll see why it's needed
li:not(.warning):not(.error){
color:#00aa00;
}
FINALLY SOME JQUERY
// Select all items with warning class
$('.warning').each(function(){
// for each item select all its parents which are li|ul
$(this).parents('li, ul').each(function(){
// for each parent clear all its classes
$(this).removeClass()
// then add the warning class
$(this).addClass('warning')
})
})
// same for erro AFTER WARNING as it is more relevant
// and should override the warning color
$('.error').each(function(){
$(this).parents('li, ul').each(function(){
$(this).removeClass()
$(this).addClass('error')
})
})
Hope this helps. HERE IS A WORKING FIDDLE
Fallowing @Jeremy's comment the jQuery could become
// Select all items with warning class
$('.warning').each(function(){
// for each item select all its parents which are li|ul
$(this).parentsUntil('.monitor', 'li, ul').each(function(){
// for each parent clear all its classes
$(this).removeClass()
// then add the warning class
$(this).addClass('warning')
})
})
// same for erro AFTER WARNING as it is more relevant
// and should override the warning color
$('.error').each(function(){
$(this).parentsUntil('.monitor', 'li, ul').each(function(){
$(this).removeClass()
$(this).addClass('error')
})
})
Notes :
Upvotes: 2
Reputation: 18942
Something like this might work for you:
$(this).parentsUntil('span', '.monitor').addClass('warning');
This would find all the ancestors of type "span" up until the nearest element with the "monitor" class, and add the "warning" class to each.
It's hard to be certain that this will work for you without a little more information about the problem you're trying to solve though.
Upvotes: 1