I need ul.list-group-subshould display none on first glance and when I click on "Click" (.dd), only one "list-group-sub" should display block from current li while "list-group-sub" should display none from other li and vice versa, only one is one "list-group-sub" open at a time
Fiddle Demo :
https://fiddle.jshell.net/alpeshlahad/zv3vpzew/3/
$(".list-group-item .dd").click(function() {
$("ul.list-group-sub").slideToggle();
});
ul.list-group-sub {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list-group member-list trainers-data ot-box">
<li class="list-group-item">
List 1
<span class="label">
Click
</span>
<ul class="list-group-sub">
<li class="list-group-item checked">Sublist 1</li>
<li class="list-group-item checked">Sublist 2</li>
<li class="list-group-item checked">Sublist 3</li>
</ul>
</li>
<li class="list-group-item">
List 2
<span class="label">
Click
</span>
<ul class="list-group-sub">
<li class="list-group-item checked">Sublist 1</li>
<li class="list-group-item checked">Sublist 2</li>
<li class="list-group-item checked">Sublist 3</li>
</ul>
</li>
</ul>
The issue is because your ul.list-group-sub selector is calling slideToggle() on all elements. You instead need to traverse the DOM to find the one related to the clicked .dd element. To do that you can use closest() to get the parent li, then find() to get the element you need.
To only display one menu at at time you also need to call slideUp() on them whilst toggling the target one. Try this:
$(".list-group-item .dd").click(function(e) {
e.preventDefault();
var $target = $(this).closest('li').find("ul.list-group-sub").slideToggle();
$('ul.list-group-sub').not($target).slideUp();
});
ul.list-group-sub { display: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list-group member-list trainers-data ot-box">
<li class="list-group-item">
List 1
<span class="label">
Click
</span>
<ul class="list-group-sub">
<li class="list-group-item checked">Sublist 1</li>
<li class="list-group-item checked">Sublist 2</li>
<li class="list-group-item checked">Sublist 3</li>
</ul>
</li>
<li class="list-group-item">
List 2
<span class="label">
Click
</span>
<ul class="list-group-sub">
<li class="list-group-item checked">Sublist 1</li>
<li class="list-group-item checked">Sublist 2</li>
<li class="list-group-item checked">Sublist 3</li>
</ul>
</li>
</ul>
Also note that I removed the use of javascript; in the href attribute of your a elements. You can instead call preventDefault() on the event to stop the default behaviour. This method has the benefit of de-coupling the JS logic from the HTML.
$("ul.list-group-sub").slideToggle() targets all sub-items. Use this:
$(this).closest('.list-group-item').find('.list-group-sub').slideToggle();
to target the corresponding list sub-items.
See demo below and updated fiddle here:
$(".list-group-item .dd").click(function() {
$(this).closest('.list-group-item').find('.list-group-sub').slideToggle();
});
ul.list-group-sub {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list-group member-list trainers-data ot-box">
<li class="list-group-item">
List 1
<span class="label">
Click
</span>
<ul class="list-group-sub">
<li class="list-group-item checked">Sublist 1</li>
<li class="list-group-item checked">Sublist 2</li>
<li class="list-group-item checked">Sublist 3</li>
</ul>
</li>
<li class="list-group-item">
List 2
<span class="label">
Click
</span>
<ul class="list-group-sub">
<li class="list-group-item checked">Sublist 1</li>
<li class="list-group-item checked">Sublist 2</li>
<li class="list-group-item checked">Sublist 3</li>
</ul>
</li>
</ul>
Related
I need one particular element of an unordered list to appear at the top of the list on page load, but not at the top of the page.
My code below works on Firefox and Safari, but not on Chrome or Opera. I use Javascript only.
Note that if I remove location.replace('#'); , the element will jump to the top of the page on page load, which is unwanted.
location.replace('#e');
location.replace('#');
#e {
color:#fff;
background:red;
}
#list {
overflow:auto;
height:100vh;
border:1px solid #000;
}
<div>LOGO</div>
<ul id="list">
<li id="a">Link a</li>
<li id="b">Link b</li>
<li id="c">Link c</li>
<li id="d">Link d</li>
<li id="e">Link e</li>
<li id="f">Link f</li>
<li id="g">Link g</li>
<li id="h">Link h</li>
<li id="i">Link i</li>
<li id="j">Link j</li>
<li id="k">Link k</li>
<li id="l">Link l</li>
<li id="m">Link m</li>
<li id="n">Link n</li>
<li id="o">Link o</li>
<li id="p">Link p</li>
<li id="q">Link q</li>
<li id="r">Link r</li>
<li id="s">Link s</li>
<li id="t">Link t</li>
<li id="u">Link u</li>
<li id="v">Link v</li>
<li id="w">Link w</li>
<li id="x">Link x</li>
<li id="y">Link y</li>
<li id="z">Link z</li>
<li id="aa">Link aa</li>
<li id="ab">Link ab</li>
<li id="ac">Link ac</li>
<li id="ad">Link ad</li>
<li id="ae">Link ae</li>
<li id="af">Link af</li>
<li id="ag">Link ag</li>
<li id="ah">Link ah</li>
<li id="ai">Link ai</li>
<li id="aj">Link aj</li>
<li id="ak">Link ak</li>
<li id="al">Link al</li>
<li id="am">Link am</li>
<li id="an">Link an</li>
<li id="ao">Link ao</li>
<li id="ap">Link ap</li>
<li id="aq">Link aq</li>
<li id="ar">Link ar</li>
<li id="as">Link as</li>
<li id="at">Link at</li>
<li id="au">Link au</li>
<li id="av">Link av</li>
<li id="aw">Link aw</li>
<li id="ax">Link ax</li>
<li id="ay">Link ay</li>
<li id="az">Link az</li>
</ul>
Although there is probably a smoother way to do it, here is the javascript that solves my issue:
location.replace('#e');
setTimeout(function() {
location.replace('#');
}, 1);
I'm trying to collapse a nested menu with jQuery. I read this answer and, to me, it appears to be similar to my solution. The problem is that mine doesn't work.
What I think I'm saying with my JavaScript code is: "hey, when a user clicks on a li that is the parent of a ul.submenu, get its ul.submenu children and attach the slideToggle only to it". But, as you can see from the snippet, it closes also the parent ul.submenu and I can't understand why.
$(document).ready(function () {
$('.submenu').hide();
$('.submenu').parent('li').click(function () {
$(this).children('ul.submenu').slideToggle("slow");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<ul class="menu">
<li>Home</li>
<li>Blog
<ul class="submenu">
<li>
Author
<ul class="submenu">
<li>New</li>
<li>Handle</li>
</ul>
</li>
<li>
<span>Category</span>
<ul class="submenu">
<li>New</li>
<li>Handle</li>
</ul>
</li>
<li>
<span>Tag</span>
<ul class="submenu">
<li>New</li>
<li>Handle</li>
</ul>
</li>
<li>
<span>Post</span>
<ul class="submenu">
<li>New</li>
<li>Handle</li>
</ul>
</li>
</ul>
</li>
<li>Photo</li>
<li>Settings</li>
</ul>
</nav>
You want to stop the click event from bubbling up the DOM and triggering the click handler on the parent. Use .stopPropagation() for that:
$(document).ready(function() {
$('.submenu').hide();
$('.submenu').parent('li').click(function(e) {
e.stopPropagation()
$(this).children('ul.submenu').slideToggle("slow");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<ul class="menu">
<li>Home</li>
<li>Blog
<ul class="submenu">
<li>
Author
<ul class="submenu">
<li>New</li>
<li>Handle</li>
</ul>
</li>
<li>
<span>Category</span>
<ul class="submenu">
<li>New</li>
<li>Handle</li>
</ul>
</li>
<li>
<span>Tag</span>
<ul class="submenu">
<li>New</li>
<li>Handle</li>
</ul>
</li>
<li>
<span>Post</span>
<ul class="submenu">
<li>New</li>
<li>Handle</li>
</ul>
</li>
</ul>
</li>
<li>Photo</li>
<li>Settings</li>
</ul>
</nav>
I have a menu populating from MySQL table and PHP up to some nested sub levels.
my menu like this:
A
B
C
If click on A first time it is showing all the child elements and again I click child elements of A it displaying child elements also fine.
But the problem is when I click on the B after open all the levels items of A it shows B sub elements fine. But again if I click A it showing all the elements except child child elements also.
I used jQuery for this.
So I want to bring back to the original state? ( only expand the top child elements, not the sub child elements ),
how to do that?
//this is my jquery code for elements clickable in menu.
$(document).ready(function() {
$(".lichild").parent().hide();
$(".limain").click(function() {
$(this).children('ul').show();
$(this).siblings(".limain").children('ul').hide();
});
$(".lichild").click(function() {
$(this).children('ul').show();
$(this).siblings().children('ul').hide()
});
});
<!-- This is the html I am generating using a PHP function -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="limain">A
<ul>
<li class="lichild">A1
<ul>
<li class="lichild">a2</li>
<li class="lichild">a1
<ul>
<li class="lichild">aaaaaa</li>
<li class="lichild">abbbbbb</li>
</ul>
</li>
</ul>
</li>
<li class="lichild">A2</li>
<li class="lichild">A3</li>
<li class="lichild">A4</li>
<li class="lichild">A5</li>
</ul>
<li class="limain">B
<ul>
<li class="lichild">B1</li>
<li class="lichild">B2</li>
</ul>
</li>
<li class="limain">C
<ul>
<li class="lichild">C1</li>
<li class="lichild">C2</li>
<li class="lichild">C3</li>
<li class="lichild">A6
<ul>
<li class="lichild">A8
<ul>
<li class="lichild">A10
<ul>
<li class="lichild">A13
</li>
<li class="lichild">A14
</li>
</ul>
</li>
<li class="lichild">A11
</li>
</ul>
</li>
<li class="lichild">A9
</li>
</ul>
</li>
<li class="lichild">A7
</li>
</ul>
</li>
<li class="limain">D
<ul>
<li class="lichild">D1</li>
<li class="lichild">D2
</li>
</ul>
</li>
</ul>
Use find inside siblings and hide it.
$(".lichild").parent().hide();
$(".limain").click(function() {
$(this).children('ul').show();
$(this).siblings(".limain").find('ul').hide(); // Change in this line
});
$(".lichild").click(function() {
$(this).children('ul').show();
$(this).siblings().children('ul').hide()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<ul>
<li class="limain">
A
<ul>
<li class="lichild">
A1
<ul>
<li class="lichild">a2</li>
<li class="lichild">
a1
<ul>
<li class="lichild">aaaaaa</li <li class="lichild">abbbbbb</li>
</ul>
</li>
</ul>
</li>
<li class="lichild">A2</li>
<li class="lichild">A3</li>
<li class="lichild">A4</li>
<li class="lichild">A5</li>
</ul>
<li class="limain">
B
<ul>
<li class="lichild">B1</li>
<li class="lichild">B2</li>
</ul>
</li>
<li class="limain">
C
<ul>
<li class="lichild">C1</li>
<li class="lichild">C2</li>
<li class="lichild">C3</li>
<li class="lichild">
A6
<ul>
<li class="lichild">
A8
<ul>
<li class="lichild">
A10
<ul>
<li class="lichild">A13
</li>
<li class="lichild">A14
</li>
</ul>
</li>
<li class="lichild">A11
</li>
</ul>
</li>
<li class="lichild">A9
</li>
</ul>
</li>
<li class="lichild">A7
</li>
</ul>
</li>
<li class="limain">
D
<ul>
<li class="lichild">D1</li>
<li class="lichild">D2
</li>
</ul>
</li>
</ul>
$(document).ready(function () {
$(".lichild").parent().hide();
$(".limain").click(function () {
$(this).children('ul').show();
$(this).siblings().find('ul').hide();
});
$(".lichild").click(function () {
$(this).children('ul').show();
$(this).siblings('li').find('ul').hide()
});
});
Having a bit issue figuring out how to select only the first child in a li tag that has a link in it.
HTML:
<ul class="dropdown-menu" role="menu" aria-expanded="true">
<li role="presentation" class="dropdown-header">Label</li>
<li>Select Me </li>
</ul>
JavaScript:
dropdown.find('.dropdown-menu li:first-child a').focus();
In this particular case it doesn't get past the list item that is the "Label"
You can use eq method.
eq method reduce the set of matched elements to the one at the
specified index.
$('body').find('.dropdown-menu li a').eq(0).css('color','red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="dropdown-menu" role="menu" aria-expanded="true">
<li role="presentation" class="dropdown-header">Label 1</li>
<li role="presentation" class="dropdown-header">Label 2</li>
<li role="presentation" class="dropdown-header">Label 3</li>
<li>Select Me </li>
</ul>
Another method is to use :first pseudo-selector.
first method reduce the set of matched elements to the first in the
set.
$('body').find('.dropdown-menu li a:first').css('color','red');
$('body').find('.dropdown-menu li a:first').css('color','red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="dropdown-menu" role="menu" aria-expanded="true">
<li role="presentation" class="dropdown-header">Label</li>
<li>Select Me </li>
</ul>
Also, another solution that can help you is to use $.each method in order to search for the first li which has hyperlink element.
$('ul li').each(function(){
if($(this).find('a').length>0){
$(this).find('a').css('color','red');
return false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="dropdown-menu" role="menu" aria-expanded="true">
<li role="presentation" class="dropdown-header">Label 1</li>
<li role="presentation" class="dropdown-header">Label 2</li>
<li role="presentation" class="dropdown-header">Label 3</li>
<li>Select Me </li>
</ul>
What about $('.dropdown-menu > li > a').first()?
I have a menu structure like the below in Drupal 7. This is a part of the Nicemenu module in Drupal. I am applying a width to the second level ul - the sub menu ul, and this gets applied to all the second level ul. What I need is a variable width for the second level ul's. All these HTML sre dynamically generated by Drupal and I may not be able to hard code any classes or ID to these second level uls. I targeted these using pseudo-classes but didn't achieve what I want.
Here's the HTML
<ul class="menu">
<li class="first leaf"><a class="active" href="">Menu 1</a></li>
<li class="expanded"><a title="" href="">Menu 2</a>
<ul class="menu"> <!--This should have width of 200px-->
<li class="first leaf">Menu 2a</li>
<li class="last leaf">Menu 2b</li>
</ul>
</li>
<li class="expanded"><a title="" href="">Menu 3</a>
<ul class="menu"><!-- Width should be 350px-->
<li class="first leaf">Menu 3a</li>
<li class="leaf">Menu 3b</li>
<li class="leaf">Menu 3c</li>
<li class="leaf">Menu 3d</li>
<li class="leaf">Menu 3e</li>
<li class="leaf">Menu 3f</li>
<li class="leaf">Menu 3g</li>
<li class="last leaf">Menu 3h</li>
</ul>
</li>
<li class="expanded"><a title="" href="">Menu 4</a>
<ul class="menu"><!-- Width should be 200px-->
<li class="first expanded"><a title="" href="">Menu 4a</a><ul class="menu">
<li class="first last leaf">Menu 4a-1</li>
</ul>
</li>
<li class="last leaf">Menu 4b</li>
</ul>
</li>
<li class="leaf">Menu 5</li>
<li class="expanded"><a title="" href="">Menu 5a</a>
<ul class="menu"><!-- Width should be 150px-->
<li class="first last leaf">Menu 5b
</li>
</ul>
</li>
<li class="leaf">Menu 6</li>
<li class="leaf">Menu 7</li>
<li class="expanded"><a title="" href="">Menu 8</a>
<ul class="menu"><!-- Width should be 200px-->
<li class="first leaf">Menu 8</li>
<li class="last leaf">Menu 9</li>
</ul></li>
<li class="last leaf">Contact Us</li>
</ul>
You really need id attributes in your <ul> elements, so you can use CSS to set the widths for each id. This is the most convenient and robust way to style separate HTML elements.
Add html ID to content field shows a solution how to add these id attributes.