Nested collapse - javascript

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>

Related

how to add toggle function to sub children of <li> in jquery

when i am trying to add toggle function to the child nodes nothing is happening could you help me out.
$(document).ready(function() {
$('label.tree-toggler').click(function() {
$(this).parent().children('ul.tree').toggle(300);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav nav-list">
<li><label class="tree-toggler nav-header">WorkLoad</label>
<ul class="nav nav-list tree">
<li><label class="tree1">DME Report</label>
<ul class="tree1">
<li>
Report1
Report2
</li>
</ul>
</li>
<li>CAMB Report</li>
<li>LMAB Report</li>
<li>DMF Notification</li>
<li>LME Forecast Report</li>
</ul>
</li>
</ul>
You can make this work in a generic way by attaching the click event handler only to li elements which have child ul using the :has selector. Then you can toggle() those ul within the click handler.
Also note the handler will need to call stopPropagation() on the event to stop the parent li from closing their child ul elements too. Try this:
$(document).ready(function() {
$('ul > li:has(ul)').click(function(e) {
e.stopPropagation();
$(this).find('> ul').toggle(300);
});
});
ul > li > ul {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav nav-list">
<li>
<label class="nav-header">WorkLoad</label>
<ul class="nav nav-list tree">
<li>
<label class="tree1">DME Report</label>
<ul class="tree1">
<li>
Report1
Report2
</li>
</ul>
</li>
<li>CAMB Report</li>
<li>LMAB Report</li>
<li>DMF Notification</li>
<li>LME Forecast Report</li>
</ul>
</li>
</ul>
This would allow to simplify the above code to:
The code below mostly works as intended, ...
$(document).ready(function() {
$('label.tree-toggler, label.tree1').click(function() {
$(this).parent().children('ul.tree , ul.tree1').toggle(300);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav nav-list">
<li><label class="tree-toggler nav-header">WorkLoad</label>
<ul class="nav nav-list tree">
<li><label class="tree1">DME Report</label>
<ul class="tree1">
<li>
Report1
Report2
</li>
</ul>
</li>
<li>CAMB Report</li>
<li>LMAB Report</li>
<li>DMF Notification</li>
<li>LME Forecast Report</li>
</ul>
</li>
</ul>

how to hide child elements child elements in jQuery

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()
});
});

Dropdown menu on click

I have tried numerous JS queries and none seem to be working.
I want to only show my dropdown menus when the list item they relate to is clicked, they need to show until the user either clicks off the ul or clicks a link.
Here is my html:
<div class="sub-nav">
<div class="container">
<ul>
<li class="active">All</li>
<li>Videos</li>
<li>Images</li>
<li>Maps</li>
<li>News</li>
<a href="#">
<li id="has-sub">More
<ul>
<li>Shopping</li>
<li>Books</li>
<li>Flights</li>
<li>Apps</li>
</ul>
</li>
</a>
<a href="#">
<li id="search-tools">Search Tools
<ul>
<li id="has-sub">Any Country</li>
<li id="has-sub">Any Time</li>
<li id="has-sub">All Results</li>
</ul>
</li>
</a>
</ul>
</div>
</div>
Try this:
$("li:has(ul)").click(function(){
$("ul",this).toggle('slow');
});
Make sure you have the jQuery library.
In this solution dropdown menus collapse when a link is clicked as you asked.
$('a').click(function(){
$('.container ul:not(:first-child)').hide();
if($(this).next().is('ul')){
$(this).next().toggle('slow');
}
});
ul ul{
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sub-nav">
<div class="container">
<ul>
<li class="active">All</li>
<li>Videos</li>
<li>Images</li>
<li>Maps</li>
<li>News</li>
<a href="#"><li id="has-sub">More
<ul>
<li>Shopping</li>
<li>Books</li>
<li>Flights</li>
<li>Apps</li>
</ul>
</li></a>
<a href="#"><li id="search-tools">Search Tools
<ul>
<li id="has-sub">Any Country</li>
<li id="has-sub">Any Time</li>
<li id="has-sub">All Results</li>
</ul>
</li></a>
</ul>
</div>
</div>
<div class="sub-nav">
<div class="container">
<ul>
<li class="active">All</li>
<li>Videos</li>
<li>Images</li>
<li>Maps</li>
<li>News</li>
<li id="has-sub">More
<ul>
<li>Shopping</li>
<li>Books</li>
<li>Flights</li>
<li>Apps</li>
</ul>
</li>
<li id="search-tools">Search Tools
<ul>
<li id="has-sub">Any Country</li>
<li id="has-sub">Any Time</li>
<li id="has-sub">All Results</li>
</ul>
</li>
</ul>
</div>
</div>
this should work
Load jQuery library alternatively you can use like this.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Apply style to your menu html as below
<style>
li > ul{display:none;}
.show {display:block;}
</style>
Now this is what you are looking for.
<script>
jQuery("li:has(ul)").click(function(){
jQuery("ul",this).toggleClass('show');
});
</script>
$("li:has(ul)").click(function(){
$("ul",this).toggleClass('show');
});
li > ul{display:none;}
.show {display:block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sub-nav">
<div class="container">
<ul>
<li class="active">All</li>
<li>Videos</li>
<li>Images</li>
<li>Maps</li>
<li>News</li>
<a href="#"><li id="has-sub">More
<ul>
<li>Shopping</li>
<li>Books</li>
<li>Flights</li>
<li>Apps</li>
</ul>
</li></a>
<a href="#"><li id="search-tools">Search Tools
<ul>
<li id="has-sub">Any Country</li>
<li id="has-sub">Any Time</li>
<li id="has-sub">All Results</li>
</ul>
</li></a>
</ul>
</div>
</div>
Use jQuery instead of $, because some frameworks or cms tools have conflict with it. So jQuery works always.

Javascript toggle menu with multiple levels

I'm working on a navigation with 3 levels and want use toggle to expand and close those levels. I got it to work with the second level but am struggling with the third level.
I want the third level(purpose1,purpose2) to open when the second level(Purpose) is clicked.
<ul>
<li class="dropdown">About Us
<ul>
<li>Services</li>
<li>History</li>
</ul>
</li>
<li class="dropdown">Products
<ul class="products">
<li>Series</li>
<li>Purpose</li>
</ul>
<ul>
<li>purpose1</li>
<li>purpose2/li>
</ul>
</li>
</ul>
Javascript:
$('li.dropdown').click(function(){
$('li.dropdown').not(this).find('ul').hide();
$(this).find('ul').toggle();
});
$('ul.products').click(function() {
$('ul.products').not(this).find('ul').hide();
$(this).find('ul').toggle();
});
I've created a fiddle to illustrate the issue. The actual navigation is much more complex but this should do the job. Any suggestiones are really appreciated!
Your html is wrong. If the third lvl is to be displayed by clicking "purpose" it shoudl look like this:
<li class="dropdown">Products
<ul class="products">
<li>Series</li>
<li >Purpose
<ul >
<li>Series123</li>
<li>Series456</li>
</ul>
</li>
</ul>
</li>
Then just add a class to this thrid lvl list parent and add the jquery fucntion.
clicking in the product li is propagating up to the top level, which is causing the close.
$('ul.products').click(function(e) {
$('ul.products').not(this).find('ul').hide();
$(this).find('ul').toggle();
e.stopPropagation();
});
.
<ul>
<li class="dropdown">About Us
<ul>
<li>Services</li>
<li>History</li>
</ul>
</li>
<li class="dropdown">Products
<ul class="products">
<li>Series
<ul>
<li>Series123</li>
<li>Series456</li>
</ul>
</li>
<li>Purpose
<ul>
<li>purpose1</li>
<li>purpose2</li>
</ul>
</li>
</ul>
</li>
</ul>
here is the simplified working version, first move you 3rd level ul inside the li
<ul>
<li class="dropdown">About Us
<ul>
<li>Services</li>
<li>History</li>
</ul>
</li>
<li class="dropdown">Products
<ul class="products">
<li>Series
<ul>
<li>Series123</li>
<li>Series456</li>
</ul>
</li>
<li>Purpose</li>
</ul>
</li>
</ul>
and here goes the jQuery snippet -
$('li.dropdown a').click(function(){
$('li.dropdown').not(this).find('ul').hide();
$(this).parent('li').find('ul').toggle();
});
$('li.dropdown ul li').click(function() {
$(this).find('ul').toggle();
});
Check the working fiddle

Foundation top bar issue: The menu items floats down when added more menu items

In Zurb foundation, I've found top-bar to be working good. But whenever large no of menu Items are added, the menu items float down instead of collapsing.
Normal Image:
Issue Image:
Expected Image:
Code:
<div class="fixed">
<nav class="top-bar" data-topbar role="navigation">
<ul class="title-area">
<li class="name">
</li>
<li class="toggle-topbar menu-icon"><span>Menu</span></li>
</ul>
<section class="top-bar-section">
<ul class="left">
<li class="has-dropdown">WIKISAN
<ul class="dropdown">
<li>Choose Another Program</li>
<li>Home</li>
</ul>
</li>
<li class="has-dropdown">Organization
<ul class="dropdown">
<li>List Organization</li>
<li>Add Organization</li>
</ul>
</li>
<li class="has-dropdown">Group
<ul class="dropdown">
<li>List Group</li>
<li>Add Group</li>
</ul>
</li>
<li class="has-dropdown">Individual
<ul class="dropdown">
<li>List Individual</li>
<li>Add Individual</li>
<li>Add Individual To Program</li>
</ul>
</li>
<li class="has-dropdown">Program
<ul class="dropdown">
<li class="has-dropdown">Kisan
<ul class="dropdown">
<li>Kisan Training Form</li>
<li>Kisan Training List </li>
<li>Kisan Leverage Form</li>
<li>Kisan Leverage List</li>
<li>Kisan Asset </li>
<li>Kisan Seed </li>
</ul>
</li>
</ul>
</li><li class="has-dropdown">Settings
<ul class="dropdown">
<li>Land Unit Converter</li><li>Add Indicator</li><li>Add District</li><li class="has-dropdown">Individual Lookup
<ul class="dropdown">
<li>Individual Activity</li>
<li>Individual Education</li>
<li>Language</li>
<li>Latrine Type</li>
<li>Occupation List</li>
<li>Project List</li>
<li>Religion</li>
<li>Social Group</li>
</ul>
</li><li class="has-dropdown">Organization Lookup
<ul class="dropdown">
<li>Organization Category</li>
<li>Organization Component</li>
<li>OCAT Stage List</li>
<li>Organization Sector</li>
<li>Organization Type</li>
</ul>
</li><li class="has-dropdown">Group Lookup
<ul class="dropdown">
<li>Group Registration</li>
<li>Group Sector</li>
<li>Group Type</li>
</ul>
</li><li class="has-dropdown">Training Lookup
<ul class="dropdown">
<li>Training Sector</li>
<li>Beneficiary Type</li>
<li>Training Type</li>
</ul></li><li class="has-dropdown">Leverage Lookup
<ul class="dropdown">
<li>Leverage Scheme</li>
</ul></li></ul></li> <li class="has-dropdown">Report
<ul class="dropdown">
<li>Report Dashboard</li>
<li>Summary Query Report</li>
</ul>
</li>
</ul>
<ul class="right">
<li class="has-dropdown"> Logged in as Sujit Prasad Baniya
<ul class="dropdown">
<li>Change Password</li><li>User Location Settings</li><li class="has-dropdown">Admin
<ul class="dropdown"><li>Add users</li>
<li>List users</li>
<li>Set Program Targets</li>
<li>Set Default Location</li>
<li>Query Log Report</li><li>Debug Mode On</li><li>Add Program</li>
<li>List Program</li>
<li>Add Activity</li>
<li>Add Activity To Program</li></ul></li>
<li>Logout</li>
</ul>
</li>
</ul>
</section>
</nav>
</div>
Here is the code that generated following result

Categories