how to find all class name in ul > li - javascript

I have to change my html code by javascript.
I want to add span tag for a tag if it contains has-children in class for li tag
<span> <a></a> <span class="sub-menu-toggle"></span></span>
it is my code that I can change first step li.has-children
how can I change all ? class=has-children
$('.has-children').each(function(i, e) {
var aTag = $(this).find('a')[0].outerHTML;
var ulTag = $(this).find('ul')[0].outerHTML;
$(this).html('<span>' + aTag + '<span class="sub-menu-toggle"></span></span>' + ulTag);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="site-menu">
<ul style="display: none">
<li class="has-children">
Menu
<ul class="sub-menu">
<li class="has-children">
First Sub Menu
<ul class="sub-menu">
<li class="">
Second Sub Menu
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>

How about this?
Use a better selector
wrap
after
$('.has-children>a').each(function() {
$(this).wrap('<span/>')
.after('<span class="sub-menu-toggle"/>');
});
a { text-decoration: none }
span a { text-decoration: underline }
.sub-menu-toggle::after { content: " ʘ" }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="site-menu">
<ul style="display">
<li class="has-children">
Menu
<ul class="sub-menu">
<li class="has-children">
First Sub Menu
<ul class="sub-menu">
<li class="">
Second Sub Menu
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>

Related

How to change a class when one of the elements classname change?

I have this menu of elements, what is the best approach to change the last div element from hidden to visible when one of the elements with class closed changes to open using Jquery, What i want is when i click on one of the li and change it from closed to , i want to change the dynamic ul to display none or block, do i need to loop over all the elements and check their class?
<ul class="groupmenu">
<li class="closed"></li>
<ul class="level1"></ul>
<li class="closed"></li>
<ul class="level1"></ul>
<li class="closed"></li>
<ul class="level1"></ul>
<li class="closed"></li>
<ul class="level1"></ul>
<li class="closed"></li>
<ul class="level1"></ul>
<li class="closed"></li>
<ul class="level1"></ul>
<li class="closed"></li>
<ul class="level1"></ul>
<li class="closed"></li>
<ul class="level1"></ul>
<li class="closed"></li>
<ul class="level1"></ul>
<li class="closed"></li>
</ul>
<div class="dynamic hidden"></div>
First of all, your ul.level1 elements should be wrapped in li elements.
Then, on click of a li.closed element, you could :
toggle the visibility of its ul.level1 child element.
toggle the visibility of your div.dynamic element using !$("ul.level1:not(.hidden)").length. It will return a boolean whose value will be false if there is at least 1 ul.level1 element that does not have the .hidden class. Otherwise it will return true.
$("li.closed").click(function() {
$(this).find("ul.level1").toggleClass("hidden");
$("div.dynamic").toggleClass("hidden",!$("ul.level1:not(.hidden)").length);
});
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="groupmenu">
<li class="closed">
ul closed
<ul class="level1 hidden">
<li>visible</li>
</ul>
</li>
<li class="closed">
ul closed
<ul class="level1 hidden">
<li>visible</li>
</ul>
</li>
<li class="closed">
ul closed
<ul class="level1 hidden">
<li>visible</li>
</ul>
</li>
<li class="closed">
ul closed
<ul class="level1 hidden">
<li>visible</li>
</ul>
</li>
</ul>
<div class="dynamic hidden">
dynamic
</div>

My sub menu is still not working properly (jQuery)

I'm creating a sub menu using jquery. I have made the code as below. But there is still something that is not working properly. What I want is, when the start, the menu is closed. Currently, all menus are open. How do I do it, can anyone help me?
$('.list-menu > li').click(function () {
var child = $(this).children('ul');
if(child.length===0){
$(this).children().addClass("active");
return;
}
$('.list-menu ul').not(child).slideUp('normal');
child.slideDown('normal');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="list-menu">
<li class="menu-1">
Getting Started
<ul class="submenu">
<li id="sub-1">Child 1
</li>
<li id="sub-2">Child 2
</li>
</ul>
</li>
<li class="menu-2">
Controlling How Data is Indexed
<ul class="submenu">
<li id="sub-3">Child 1
</li>
<li id="sub-4">Child 2
</li>
</ul>
</li>
<li class="menu-3">
Uploading and Indexing Data
<ul class="submenu">
<li id="sub-5">Child 1
</li>
<li id="sub-6">Child 2
</li>
</ul>
</li>
<li>
<a href="#">
Querying For More Information
</a>
</li>
</ul>
You can set the child ul elements to display: none on page load using CSS:
ul > li > ul { display: none; }
$('.list-menu > li').click(function() {
var child = $(this).children('ul');
$(this).children().addClass("active");
$('.list-menu ul').not(child).slideUp('normal');
child.slideToggle('normal');
});
ul > li > ul { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="list-menu">
<li class="menu-1">
Getting Started
<ul class="submenu">
<li id="sub-1">Child 1
</li>
<li id="sub-2">Child 2
</li>
</ul>
</li>
<li class="menu-2">
Controlling How Data is Indexed
<ul class="submenu">
<li id="sub-3">Child 1
</li>
<li id="sub-4">Child 2
</li>
</ul>
</li>
<li class="menu-3">
Uploading and Indexing Data
<ul class="submenu">
<li id="sub-5">Child 1
</li>
<li id="sub-6">Child 2
</li>
</ul>
</li>
<li>
Querying For More Information
</li>
</ul>

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>

Make sub menus expandable using JavaScript

I am working on a navigation menu with nested sub menus. I was wondering if there is a way I can achieve the menus to be expandable when I click the parent menu item
This is my HTML code, as you guys can see I have 2 ng-repeat inside the parent menu item and another one if the sub menu item has one or more sub menus
<div id="sidebar-wrapper" ng-controller="navigationController" style="overflow-y: auto; margin-top:-20px;" class="hidden-print" ng-hide="hideSidebar()">
<nav role="navigation" class="navbar navbar-default navbar-bigfont" style="border-width: 0">
<ul class="nav nav-pills nav-stacked">
<li class="portal-text-19b" ng-repeat="item in newMenu" ng-class="{active: hightlight === item.title && item.path !== '#'}" ng-show="showItem(item.path, item.allowAll)">
<a style="text-transform: uppercase" href="{{item.path}}" ng-click="item.fn()">
<span class="{{item.icon}}"></span> {{item.title}}
<span style="font-size: 7px;" ng-if="item.childs" class="glyphicon glyphicon-play"></span>
</a>
<ul class="nav nav-pills nav-stacked">
<li style="list-style-type: none;" ng-repeat="child in item.childs" ng-class="{active: hightlight === child.title && child.path !== '#'}" ng-show="showItem(child.path, child.allowAll)">
<a href="{{child.path}}" ng-click="child.fn()">
<span class="{{child.icon}}"></span> {{child.title}}
</a>
<ul class="nav nav-pills nav-stacked">
<li style="list-style-type: none;" ng-repeat="child2 in child.childs" ng-class="{active: hightlight === child2.title && child2.path !== '#'}" ng-show="showItem(child2.path, child2.allowAll)">
<a href="{{child2.path}}" ng-click="child2.fn()">
<span class="{{child2.icon}}"></span> {{child2.title}}
</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
You can simply set the inner ul elements as hidden, and then use the following code to show/hide them:
$("ul li").has("ul").click(function() {
$(this).find("ul").toggle();
});
This will toggle hiding and showing the sub ul elements on their parent li click.
Explanation:
It uses .has() method to attach the click event handler to only li having ul children, and .toggle() method to show/hide the child list of the clicked li element.
Demo:
This is a working Demo Snippet:
$("ul li").has("ul").click(function() {
$(this).find("ul").toggle();
});
ul li {
cursor: pointer;
}
ul li ul {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>list item 1</li>
<li>list item 2
<ul>
<li>list item 2-a</li>
<li>list item 2-b</li>
</ul>
</li>
<li>list item 3</li>
<li>list item 4</li>
</ul>

Can't select a child

I got this HTML:
<ul>
<li>Test</li>
<li>Test2</li>
<a href="#" class="with-sub"><li>Test3</li>
<ul class="sub">
<li>Sub1</li>
<li>Sub2</li>
<li>Sub3</li>
</ul>
</a>
</ul>
And jQuery:
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
$( document ).ready(function() {
$(".sub").hide();
});
$(".with-sub").click(function() {
$(this).find(".sub").slideDown( "slow", function() {
});
});
</script>
When I click on the link with "with-sub" class nothing happens.
You can change your html and jquery to following:
$(".with-sub").click(function() {
$(this).next("ul").slideDown();
});
.sub {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<a href="#">
<li>Test</li>
</a>
<a href="#">
<li>Test2</li>
</a>
<a href="#" class="with-sub">
<li>Test3
<ul class="sub">
<li>Sub1
</li>
<li>Sub2
</li>
<li>Sub3
</li>
</ul>
</li>
</a>
</ul>
As mention in comments your html is not correct. ul elements can contain zero or more li elements, eventually mixed with ol and ul elements.
$(".with-sub").click(function() {
$(this).find("ul").toggle();
});
.sub {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
Test
</li>
<li>
Test2
</li>
<li class="with-sub">Test3
<ul class="sub">
<li>
Sub1
</li>
<li>
Sub2
</li>
<li>
Sub3
</li>
</ul>
</li>
</ul>
Your current code does not work because you are attempting to bind an event to elements that do not exist in the DOM yet - you need to put the click() handler inside the DOMReady handler.
Also note that your HTML is invalid - only li elements can be direct descendants of the ul element. Try this:
<ul>
<li>
Test
</li>
<li>
Test2
</li>
<li>
Test3
<ul class="sub">
<li>
Sub1
</li>
<li>
Sub2
</li>
<li>
Sub3
</li>
</ul>
</li>
</ul>
Once you've fixed your HTML, the following jQuery will work:
$(document).ready(function() {
$(".sub").hide();
$(".with-sub").click(function() {
$(this).siblings(".sub").slideDown("slow");
});
});
Working example

Categories