Need to add an active class to both parent and child element if a user clicks on the child element in a list. My html is as follows:-
<ul class="tabs">
<li class="accordion">Bar
<ul class="sub">
<li>lorem/li>
<li>ipsum</li>
<li>Lorem Ipsum</li>
<li>Dolor Sit Amet</li>
</ul>
</li>
and I'm using the jquery code below to add an active class to both the parent and child element yet I'm having errors:-
$("ul.tabs li").click(function() {
$("ul.tabs li").removeClass("active").find(".sub li").removeClass("active");
$(this).addClass("active").find(".sub li").addClass("active");
});
Then styled my active class in CSS. say example
.active {background:#EFEFEF;}
only the clicked (this) child element should have the active class applied to it and not the whole li child elements. Now together with the child li (say lorem) the parent li (bar) should also be highlighted. Think of it like a tree accordion menu where both the selected child element and it's parent li have the active class with different css styling.
I'm just going to make an assumption here that you only want to add the active class to the list items like so: http://jsfiddle.net/gfkM4/
I hope that's what you were looking for. Cheers.
try this:
$("ul.tabs li").click(function() {
$("ul.tabs li, .sub li").removeClass("active");
$(this).find(".sub li").andSelf().addClass("active");
})
Updated: http://jsfiddle.net/4G7TJ/3/ (per your new requirement that only one child is selected)
$("ul.tabs li").click(function() {
// remove .active from all li descendants
$("ul.tabs li").not(this).removeClass("active");
$(this)
.addClass("active")
.not('.accordion')
.parents("li:first").addClass("active");
return false;
});
The idea behind returning false is to prevent the 'click' event from being propagated to the parent li when a child li is clicked, since that would undo the styling change on the child.
Update: Working demo - http://jsfiddle.net/4G7TJ/1/
// only trigger the click on direct descendants
// (otherwise the kids get the event first and this won't work)
$("ul.tabs > li").click(function() {
// remove .active from all li descendants
$("ul.tabs li").not(this).removeClass("active");
$(this).addClass("active").find(".sub li").addClass("active");
});
Also - <li>lorem/li> isn't closed, meaning that all of your tags are likely mismatched and you can't be sure what the 'current' list-item is (and in which list) when you click.
Here is demo for applying active class on accordion menu option using jQuery.
HTML:
<ul class="tabs">
<li class="accordion">
<a href="#tab1">
Bar
</a>
<ul class="sub">
<li>
lorem
</li>
<li>
ipsum
</li>
<li>
Lorem Ipsum
</li>
<li>
Dolor Sit Amet
</li>
</ul>
</li>
<li class="accordion">
<a href="#tab2">
Foo
</a>
<ul class="sub">
<li>
lorem
</li>
<li>
ipsum
</li>
<li>
Lorem Ipsum
</li>
<li>
Dolor Sit Amet
</li>
</ul>
</li>
</ul>
CSS:
.tabs li{
list-style:none;
}
.tabs li:hover{
background:#88ccf9;
}
.tabs li a{
color:#334499;
}
.tabs{
border:1px solid #3344ff;
background:#dcfcff;
padding:10px;
}
.tabs .accordion .sub{
padding:3px 3px 3px 18px;
display:none;
}
.tabs .active .sub{
display:block;
}
.tabs li.active{
background:#77d9c9;
}
JQuery:
$(function() {
$("ul.tabs li").click(function() {
// remove .active from all li descendants
$("ul.tabs li").not(this).removeClass("active");
//hide all sub menu except current active
$("ul.tabs li").not(this).find(".sub").hide(400);
//apply active class on current selected menu
$(this).addClass("active");
//check if sub menu exists
if($(this).find(".sub").length>0){
//show the selected sub menu
$(this).find(".sub").show(500);
//apply active class on all sub menu options
$(this).find(".sub li").andSelf().addClass("active");
}
});
});
I have done complete bin on http://codebins.com/bin/4ldqpa5
Related
I'm trying to get my nav link's sub items to pop up from the right side of the link, instead of sliding from under it using foundation's jQuery.
<ul class="side-nav">
<li>Collections
<ul>
<li>Autos</li>
<li>Models</li>
<li>Nature</li>
<li>Extreme Sports</li>
</ul>
</li>
</ul>
jQ file:
$('.side-nav li:has("ul")').children('ul').hide(); //hide submenu
$('.side-nav li:has("ul")').addClass('hasChildren'); // add class to li ul child
$('.side-nav li:has("ul")').click(function(){
$(this).toggleClass( "active" ) // add active class to clicked menu item
$(this).children('ul').slideToggle(); //toggle submenu
});
You can try doing this.
add .collections to the li and then apply position: absolute; style on its children.
$('.side-nav li:has("ul")').children('ul').hide(); //hide submenu
$('.side-nav li:has("ul")').addClass('hasChildren'); // add class to li ul child
$('.side-nav li:has("ul")').click(function(){
$(this).toggleClass( "active" ) // add active class to clicked menu item
$(this).children('ul').slideToggle(); //toggle submenu
});
.collections{
position:relative;
}
.collections ul{
position:absolute;
top:0;
margin-left: 7rem;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.0/css/foundation.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/js/foundation.min.js"></script>
<ul class="side-nav">
<li class="collections">Collections
<ul>
<li>Autos</li>
<li>Models</li>
<li>Nature</li>
<li>Extreme Sports</li>
</ul>
</li>
</ul>
Hope this helps.
I have a accordian-style nav here. So every time an H3 is clicked, the list items drop down.
1.I want to color the H3 green if it's clicked, so users know what's currently clicked.
2.I also want to color whatever item/dog is clicked ( the < a > elements).
So the currently clicked Heading and subheading should both be highlighted.
<div id="accordian">
<ul class="sidebar-nav" id=menu>
<li class="active">
<h3>ITEMS</h3>
<ul>
<li> item1</li>
<li> item2</li>
<li> item3</li>
</ul>
</li>
<li>
<h3>dogs</h3>
<ul>
<li> dog1</li>
<li> dog2</li>
<li> dog3</li>
</ul>
</li>
</ul>
</div>
THis is what I tried so far for 1, it doesn't work. Also, not sure how to do 2.
.sidebar-nav li.active{
color:green;
}
$('ul.sidebar-nav li h3').on('click', function(){
$('ul.sidebar-nav li').removeClass('active');
$(this).addClass('active');
});
You can do something like this:
$('ul.sidebar-nav li h3').on('click', function(){
$("ul.sidebar-nav li ul li, ul.sidebar-nav li h3").removeClass("active");
$(this).addClass("active");
});
$('ul.sidebar-nav li ul li').on('click', function(){
if($(this).parents("li").find("h3").hasClass("active")){
$(this).addClass("active");
}
});
.active{
color:green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="accordian">
<ul class="sidebar-nav" id=menu>
<li>
<h3>ITEMS</h3>
<ul>
<li> item1</li>
<li> item2</li>
<li> item3</li>
</ul>
</li>
<li>
<h3>dogs</h3>
<ul>
<li> dog1</li>
<li> dog2</li>
<li> dog3</li>
</ul>
</li>
</ul>
</div>
The idea is to use the clicked element to find the h3 and li that need to be highlighted. Also, in CSS, make the selector more generic so it will apply to both the h3 and li elements.
You are not targeting the H3 tag with your active class. In your code, $(this) is referring the the li. You will need to target the parent H3 of clicked li that has the listener.
EDIT
In the code example see my comments to the lines I added. I target all h3 tags and remove the active class to clear everything out, then I target just the parent h3 tag of the clicked li.
Also update your style to have a less specific class for any element with class active:
.active {
color:green;
}
$('ul.sidebar-nav li').on('click', function(){
$('ul.sidebar-nav li').removeClass('active');
// removes all active classes on h3 tags
$('#accordian').find('h3').removeClass('active');
$(this).addClass('active');
// add active to parent h3 as well
$(this).parents('h3').addClass('active');
});
// If you want them to to highlight independently you need 2 listeners
$('#accordion').find('.sidebar-nav h3').on('click', function() {
// removes all active classes on h3 tags
$('#accordian').find('h3').removeClass('active');
// add active to parent h3 as well
$(this).addClass('active');
});
$('#accordion').find('.sidebar-nav a').on('click', function() {
$('#accordion').find('.sidebar-nav a').removeClass('active');
$(this).addClass('active');
});
I have this code and when i press the link with a element i want to hide the ul with class name tab and show the ul with class tab-1 without hidding the both of ul elements.I have tried with jquery but with no success. The jQuery code is the following.
$("a").click(function() {
$(".tab").hide("slide", {direction: "left"}, "slow");
$(".tab-1").show("slide", {direction: "left"}, "slow");
});
How can i do it?
<ul class="tab">
<li>
Link 1
<ul class="tab-1">
<li>List 1</li>
<li>List 2</li>
</ul>
</li>
</ul>
You can't show a child of an element that is set to display:none. If parent is not displayed...anything inside parent can't be either
However you can set visibility:hidden on parent and visibility:visible on descendants
.tab {visibility:hidden}
.tab-1 {visibility:visible}
Note that this is very uncommon practice. It would help to have a better description of what you want to acheive
DEMO
Just hide all elements that match .tab > li > a.
Demo :
.tab, .tab ul {
list-style-type: none;
}
.tab > li > a {
display : none;
}
<ul class="tab">
<li>
Link 1
<ul class="tab-1">
<li>List 1</li>
<li>List 2</li>
</ul>
</li>
</ul>
I am trying to remove the parent container when the children li are removed. Each li has a dismissal anchor that once it is clicked, the li is removed.
What I would like is for that when all the li are removed, the div container will also be removed.
I am currently using backbone.js
<div class="container>
<ul>
<li><a class="dismiss"></a></li>
<li><a class="dismiss"></a></li>
<li><a class="dismiss"></a></li>
</ul>
</div>
Thanks for your help!
$(document).on("click",".dismiss",function(e){
e.preventDefault();
$(this).parent("li").remove();
if(!$(".container ul li").length){
$(".container").remove();
}
});
Working DEMO
I have the follow list that I need to be able to hide all accept for what is actually in focus with class active.
<Ul>
<Li>something</li>
<ul>
<li>Something</>
<li>Something</>
</ul>
<Li>something</li>
<Li>something</li>
<Li>
<Ul>
<Li class="active">something</li>
<Li>omething</li>
</Ul>
</li>
<Li>something</li>
</Ul>
I need to be able to use .hide() on all li that are not related to the bottom level one with the active class
The result would be
<Ul>
<Li>something</li>
<Li>something</li>
<Li>something</li>
<Li>
<Ul>
<Li class="active">something</li>
<Li>omething</li>
</Ul>
</li>
<Li>something</li>
</Ul>
You can traverse up the DOM yo find the first level li element and its siblings. If you have only two levels, this should work:
$('li.active').parent().closest('li').siblings().children('ul').hide();
If you have more than two levels, I suggest to give the root ul a class or ID:
$('li.active').closest('#root > li').siblings().children('ul').hide();
$( 'li:not(.active,.active ~ li,.active li,:has(.active))' ).hide();
This selects all li elements, but excludes (by using :not()):
.active — the active li element itself
.active ~ li — sibling li elements of the active li element
.active li — descendant li elements of the active li element
has(.active) — li elements that have the active li element as its descendant
jsfiddle demo
If you want to keep showing descendants of the active li element's siblings as well, add .active ~ li li to the :not() selectors:
$( 'li:not(.active,.active ~ li,.active li,.active ~ li li,:has(.active))' ).hide();
jsfiddle demo
Following up on OP's first comment to this answer:
Just add an li before the initial selector:
$( 'li li:not(.active,.active ~ li,.active li,.active ~ li li,:has(.active))' ).hide();
jsfiddle demo