How to toggle next ul class? - javascript

I am trying to open/close nested sub menus, I have three or four levels of nested uls which are all closed but the first one. When I start clicking on the elements, the next ul should open and toggle show/hide. The js below it's not fully accomplishing what I am looking for.
CSS
.closed {
display: none;
}
.opened {
display: block;
}
HTML
<ul>
<li><button type="button">TOGGLE</button>
<ul class="closed">
<li>Two
<ul class="closed">
<li>Three
<ul class="closed">
<li>Four</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
Trying js:
$("button").on("click", function(){
$(this).parent().next("ul").toggle(function() {
$(this).removeClass("closed").addClass("opened");
}, function() {
$(this).removeClass("opened").addClass("closed");
});
});

You should use $(this).next("ul") instead of $(this).parent().next("ul"), because ul is the immediate next element of the button. And you can use toggleClass method for toggling class like following.
$("button").on("click", function(){
$(this).next("ul").toggleClass("closed opened");
});

Related

jquery toggle between ul li many to many child

Check my html code bellow. There i want if Level1 clicked it will hide all of its child ul and li of level1 then if clicked it back it will show again i mean toggle between them. Like this way if i click Level2 it will only toggle its child ul and li as like Level1. But as per my current first step i am trying to toggle on Level1 but the issue it once i click Level1 its totally getting hidden and not come back again. Anyone can tell me how can i achieve this?
here is my fiddle link
Html:
<ul>
<li class="l1">
Level1
<ul>
<li>
Level2
<ul>
<li>Level2 child</li>
<li>Level2 child</li>
<li>Level2 child</li>
</ul>
</li>
<li>Level2</li>
<li>Level2</li>
</ul>
</li>
<li class="l1">
Level1
<ul>
<li>Level2</li>
<li>Level2</li>
<li>Level2</li>
</ul>
</li>
</ul>
Jquery:
$(document).ready(function () {
$('.l1').on('click',function(){
$(this).toggle();
//alert("clicked");
});
});
I think the issue you're facing is that you're selecting the whole element rather than just it's children. Check out the following JS and let me know if that's what you're looking for
$(document).ready(function () {
$('.l1').on('click',function() {
$(this).find("ul").toggle();
});
});

How to hide parent <li> if all the children are hidden in jquery

I am new in Jquery
My Webpage structure is like this
<div id="MenuSection">
<ul>
<li>Master // Main Menu
<ul>
<li>Master1</li>
<li>Master2</li>
<li>Master3</li>
</ul>
</li>
<li>Transaction // Main Menu
<ul>
<li>Transaction1</li>
<li>Transaction2</li>
<li>Transaction3</li>
</ul>
</li>
<li>Report // Main Menu
<ul>
<li>Report1</li>
<li>Report2</li>
<li>Report3</li>
</ul>
</li>
</ul>
</div>
I want that when all the children of any Parent(main menu) are hidden, Parent should also be hidden. Let's say if Report1, Report2, Report3 are hidden then Parent that is "Report" should also be hidden.
How can I achieve this through Jquery ?
One way is to iterate over each main menu li to see if its children are all :visible:
$("#MenuSection>ul>li").each(function() {
if ($(this).find(">ul>li:visible").length == 0) {
$(this).hide();
}
});
there are other ways to do this, such as using .filter or .map, but this should get you what you need.
Given the nested ul's the above uses > to ensure only the directly ul>li children are processed. If you have multiple levels, you might need to change accordingly, eg for the first: #MenuSection li would apply to all lis and the second .find(">ul>li:visible") only looks at direct li children.
$("#MenuSection>ul>li").each(function() {
if ($(this).find("li:visible").length == 0) {
$(this).hide();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="MenuSection">
<ul>
<li>Master
<ul>
<li>Master1</li>
<li>Master2</li>
<li>Master3</li>
</ul>
</li>
<li>Transaction
<ul>
<li>Transaction1</li>
<li>Transaction2</li>
<li>Transaction3</li>
</ul>
</li>
<li>Report
<ul>
<li style='display:none'>Report1</li>
<li style='display:none'>Report2</li>
<li style='display:none'>Report3</li>
</ul>
</li>
</ul>
</div>
JavaScript does it fairly easy. You would need expand on this to execute this check every on the relevant list every time you hide or show a list item.
function isHidden(array) {
for(var i = 0; i < array.length - 1; i++) {
if(array[i+1].style.display != "none") {
return false;
};
};
return true;
};
var children = document.getElementById("report").getElementsByTagName("LI");
if (isHidden(children)) {
document.getElementById("report").style.display = "none";
};
You can use the the .is(':visible')
See the code:
(function($) {
$(document).ready(function() {
var $mainLinks = $('#MenuSection > ul > li');
$.each($mainLinks, function() {
if (!$(this).find('li').is(':visible')) {
$(this).hide();
}
});
});
})(jQuery);
#MenuSection > ul > li:last-child li {
display: none;
}
#MenuSection > ul > li:first-child li:first-child {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="MenuSection">
<ul>
<li>Master // Main Menu
<ul>
<li>Master1</li>
<li>Master2</li>
<li>Master3</li>
</ul>
</li>
<li>Transaction // Main Menu
<ul>
<li>Transaction1</li>
<li>Transaction2</li>
<li>Transaction3</li>
</ul>
</li>
<li>Report // Main Menu
<ul>
<li>Report1</li>
<li>Report2</li>
<li>Report3</li>
</ul>
</li>
</ul>
</div>

Finding Child of Parent Jquery

I am have a link in a li and when you click on it, it should open a ul, also contained in the li. I can't seem to get it to select the right element though. Code below
HTML
<ul>
<li>
hi
<ul>
<li class="hidden">more stuff</li>
</ul>
</li>
</ul>
CSS
.hidden{display:none;}
Js
$( "a" ).click(function() {
$(this).parent("li").children("ul").css("display","block");
});
Since the ul is the next sibling to the a, you'd use next to access it. Then you can look at the ul's children (children) or descendants (find) for the .hidden one and remove the class (removeClass):
$(this).next().children(".hidden").removeClass("hidden");
Live Example:
$("a").on("click", function() {
$(this).next().children(".hidden").removeClass("hidden");
return false;
});
.hidden {
display: none;
}
<ul>
<li>
one
<ul>
<li class="hidden">more stuff</li>
</ul>
</li>
<li>
two
<ul>
<li class="hidden">more stuff</li>
</ul>
</li>
<li>
three
<ul>
<li class="hidden">more stuff</li>
</ul>
</li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
In your code you are trying to make ul displayed although it is visible and it does not effect the li under it so you need to access that li like this. Removing the hidden class of the element to make it displayed is a better approach than assigning inline style as the commentators said
$(this).parent("li").children("ul").children("li").removeClass("hidden");
check here fiddler link...
hope it will help you....
$( "a" ).click(function() {
$(this).next().children(".hidden").removeClass("hidden");
});

avoid closing the menu if submenu items is clicked

This is a multilevel menu. When i click the link "About" it opens the submenu which contains 3 links Johnny, Julie & Jamie.
When i click "About" again, it closes the menu. Clicking the submenu also closes the menu, and that i want to avoid.
How do i avoid closing the opened submenu, if i click the submenu (Johnny, Julie & Jamie) ?
$('li.parent').click(function() {
$(this).find('.sub-nav').toggleClass('visible');
});
#nav ul.sub-nav {
display: none;
}
#nav ul.visible {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul id="nav">
<li class="parent">About
<ul class="sub-nav">
<li>Johnny
</li>
<li>Julie
</li>
<li>Jamie
</li>
</ul>
</li>
<li class="parent">AnotherLink
<ul class="sub-nav">
<li>Martin
</li>
<li>Rasmus
</li>
<li>Morten
</li>
</ul>
</li>
</ul>
Alternative to stopPropagation approach for child elements would be adding a small check if the clicked element is the current one (and not it's descendants):
$('li.parent').click(function(e) {
if (this === e.target)
$(this).find('.sub-nav').toggleClass('visible');
});
$('li.parent').click(function(e) {
if (this === e.target)
$(this).find('.sub-nav').toggleClass('visible');
});
#nav ul.sub-nav {
display: none;
}
#nav ul.visible {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul id="nav">
<li class="parent">About
<ul class="sub-nav">
<li>Johnny
</li>
<li>Julie
</li>
<li>Jamie
</li>
</ul>
</li>
<li class="parent">AnotherLink
<ul class="sub-nav">
<li>Martin
</li>
<li>Rasmus
</li>
<li>Morten
</li>
</ul>
</li>
</ul>
You need to stopPropagation of event on child anchor elements:
$("li.parent a").click(function(e) {
e.stopPropagation();
});
You need to prevent the click on the .sub-nav element to be transmitted to your event handler: https://api.jquery.com/event.stoppropagation/

How to get all parents of <li> tag onclick of it?

I am designing dynatree so nodes are place in ul and li tags. the problem I am getting is I am not getting parents of clicked li element.
Here is my html code,
<ul class="bulk">
<li>gp1
<ul>
<li>gp2
<ul>
<li>gp3
<ul>
<li>c1
<li>c2
<li>c3
</ul>
<li>gp4
</ul>
</ul>
<li>gp5
<ul>
<li>gp6
<ul>
<li>gp7
<ul>
<li>c4
<ul>
<li>c5
<li>c6
</ul>
</ul>
<li>gp8
<li>gp9
</ul>
<li>gp10
</ul>
</ul>
Here is my jquery method
$('ul.bulk li').click(function(e)
{
//alert($(this).find("span.t").text());
alert(e.html());
});
Here is my fiddel http://jsfiddle.net/raghavendram040/ojnLrcjz/
The problem I am getting is if click on gp3 it alerts me 3 times, but I want if I click on gp3 it should alert its parents(gp1 and gp2). Here I place all li and ul dynamically except tag. How to achive this please help me in this
You can do something like
$(function () {
$('ul.bulk li').click(function (e) {
if($(e.target).is(this)){
$(this).parentsUntil('.bulk', 'li').each(function(){
alert(this.firstChild.nodeValue)
})
}
});
});
Demo: Fiddle

Categories

Resources