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');
});
Related
I have nested lists draw in run time dynamic from database in away like this :
<div class="list"><ul>
<li>
listA
<ul>
<li>Alist1</li>
<li>Alist2</li>
<li>Alist3</li>
</ul>
</li>
<li>
listB
<ul>
<li>BList1</li>
<li>BList2</li>
<li>BList3</li>
</ul>
</li>
i want to change the back ground of list item when clicked but it change style of the all nested list by the following method :
var $li = $('#list li').click(function () {
$li.removeClass('selected');
$(this).addClass('selected');
});
using this style :
li.selected {
background-color: aqua;}
I know that i should use the direct descendant operator (>) to force change to parent only but my problem that list is drawn dynamically and I can't limit its levels and nested list.
is there away to always force only clicked item to be changed only ?
1- You can't use #list while your list have a class list not id list with classes you need to use dot not #
2- You need to use > like $('.list > ul > li')
$(document).ready(function(){
$('ul > li').on('click' , function(e){
e.stopPropagation();
//$('li > ul').hide();
$(this).find(' > ul').slideDown();
$(this).parent('ul').find('li').removeClass('selected');
$(this).addClass('selected');
});
});
ul{
background : #fff;
}
li > ul{
display : none;
}
li.selected{
background : red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="list">
<ul>
<li>
listA
<ul>
<li>Alist1
<ul>
<li>Alist1-1</li>
<li>Alist1-2</li>
<li>Alist1-3</li>
</ul>
</li>
<li>Alist2</li>
<li>Alist3</li>
</ul>
</li>
<li>
listB
<ul>
<li>BList1</li>
<li>BList2</li>
<li>BList3</li>
</ul>
</li>
</ul>
</div>
-- It'll be better to work with <a> see the next example
$(document).ready(function(){
$('a').on('click' , function(e){
e.preventDefault();
var GetLi = $(this).closest('li');
var GetBigUL = $(this).closest('ul');
var GetNextUL = $(this).next('ul');
GetBigUL.find('a').next('ul').not(GetNextUL).slideUp();
GetNextUL.slideDown();
GetBigUL.find('li').removeClass('selected');
GetLi.addClass('selected');
});
});
ul{
background : #fff;
}
li > ul{
display : none;
}
li.selected{
background : red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="list">
<ul>
<li>
<a>listA</a>
<ul>
<li>
<a>Alist1</a>
<ul>
<li><a>Alist1-1</a></li>
<li><a>Alist1-2</a></li>
<li><a>Alist1-3</a></li>
</ul>
</li>
<li><a>Alist2</a></li>
<li><a>Alist3</a></li>
</ul>
</li>
<li>
<a>listB</a>
<ul>
<li><a>BList1</a></li>
<li><a>BList2</a></li>
<li><a>BList3</a></li>
</ul>
</li>
</ul>
</div>
hi i have a unordered list menu, trying to make the sub-items slide down and up on clicking at the main items, i wrote a jQuery code that works but when click at open menu it close it and open again, but i was hoping it will just close it.
html
<div class="menuNav">
<ul>
<li><span>item_1</span>
<ul>
<li>sub-item_1-1</li>
<li>sub-item_1-2</li>
<li>sub-item_1-3</li>
<li>sub-item_1-4</li>
</ul>
</li>
<li><span>item_2</span>
<ul>
<li>sub-item_2-1</li>
<li>sub-item_2-2</li>
<li>sub-item_2-3</li>
<li>sub-item_2-4</li>
</ul>
</li>
<li><span>item_3</span>
<ul>
<li>sub-item_3-1</li>
<li>sub-item_3-2</li>
<li>sub-item_3-3</li>
<li>sub-item_3-4</li>
</ul>
</li>
</ul>
</div>
jQuery
$(document).ready(function() {
$('.menuNav ul li').click(function(){
$(this).parent().find('ul').slideUp("fast");
$(this).parent().find("li").removeClass('menuactive');
$(this).find('ul').slideDown("slow");
$(this).addClass('menuactive');
});
$('.menuNav ul .menuactive').click(function(){
$(this).parent().find('ul').slideUp("fast");
});
});
If the li has a class menuactive, call the slideUp() function and remove the class menuactive else call the slideUp() function on all uls, remove the class menuactive from all lis, call slideDown() on the one that was clicked and add the class menuactive to the one that was clicked.
$(document).ready(function() {
$('ul > li > ul').hide();
$('.menuNav > ul > li').click(function() {
if ($(this).hasClass('menuactive')) {
$(this).find('ul').slideUp('fast');
$(this).removeClass('menuactive');
} else {
$(this).siblings().find('ul').slideUp('fast');
$(this).siblings().removeClass('menuactive');
$(this).find('ul').slideDown('fast');
$(this).addClass('menuactive');
}
});
});
.menuactive {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="menuNav">
<ul>
<li><span>item_1</span>
<ul>
<li>sub-item_1-1</li>
<li>sub-item_1-2</li>
<li>sub-item_1-3</li>
<li>sub-item_1-4</li>
</ul>
</li>
<li><span>item_2</span>
<ul>
<li>sub-item_2-1</li>
<li>sub-item_2-2</li>
<li>sub-item_2-3</li>
<li>sub-item_2-4</li>
</ul>
</li>
<li><span>item_3</span>
<ul>
<li>sub-item_3-1</li>
<li>sub-item_3-2</li>
<li>sub-item_3-3</li>
<li>sub-item_3-4</li>
</ul>
</li>
</ul>
</div>
<ul id="nav">
<li>
Home
</li>
<li>
About
<ul>
<li>The product
<ul> // level 2
<li>x3</li>
<li>x4</li>
</ul>
</li>
<li>Meet the team
<ul> // level 2
<li>x1</li>
<li>x2</li>
</ul></li>
</ul>
</li>
</ul>
using jquery i wanted to select ul of level 2
like if i hover on 'The product' then i want to select only ul[level 2] that is next to it not all level 2 ul.
I use jQuery code to select like this
$('#nav li ul li').mouseover(function(){
$(this).children('ul').css('opacity','.5');
});
but this code effect on both level 2 ul i want to select the ul that is inside that <li> which is hover...
Try this using Child combinator selector:
$('#nav > li > ul > li').mouseover(function(){
$(this).children('ul').css('opacity','.5');
});
This means it will only select list items that are direct children of an unordered list. In other words, it only looks one level down the markup structure, no deeper.
Can do with CSS:
jsfiddle demo
#nav > li > ul > li:hover > ul {opacity:.5;}
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
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