I have an unordered list that when clicked shows their children. I am trying to add the feature where when there are children shown from a parent and a sibling of that parent is clicked, the other children close while the new ones open. Here is what I have so far:
<ul class="list">
<li> <a>Categories</a>
<ul>
<li> <a>Parent</a>
<ul>
<li><a>Child</a>
</li>
<li><a>Child</a>
</li>
<li><a>Child</a>
</li>
</ul>
</li>
<li> <a>Parent</a>
<ul>
<li><a>Child</a>
</li>
<li><a>Child</a>
</li>
<li><a>Child</a>
</li>
</ul>
</li>
<li> <a>Parent</a>
<ul>
<li><a>Child</a>
</li>
<li><a>Child</a>
</li>
<li><a>Child</a>
</li>
</ul>
</li>
<li> <a>Parent</a>
<ul>
<li><a>Child</a>
</li>
<li><a>Child</a>
</li>
<li><a>Child</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
This is my jquery:
$(document).ready(function(){
$('.list > li a').click(function(){
$(this).parent().children('ul').toggle();
});
Here is a jfiddle: https://jsfiddle.net/hmsvox5a/
Now if you click parent, the children show up. If you click another parent, its children appear as well. This leaves two sets of children open. I am trying to get the first set of children to close when I open the second. When I try to hide the siblings children, It messes up the whole jquery. Any ideas?
I'm not going to lie and tell you that this will scale or that it isn't awful, but this was the first thing I thought of off the top of my head. There are many ways to solve this.
$(document).ready(function(){
$('.list > li a').click(function(){
$('.open').parent().children('ul').toggle();
$('.open').removeClass('open');
$(this).addClass('open').parent().children('ul').toggle();
});
});
I believe what you want is this perhaps?
$(document).ready(function(){
$('.list > li a').click(function(){
$(this).parent('li').siblings('li').children('ul').hide();
$(this).siblings('ul').toggle().children().show();
});
});
test it out here: http://jsfiddle.net/vgwrqr6c/
I prefer to use CSS on the children to show items when its parent is shown. Then this efficient script works.
It keeps a reference to the last selected parent so it doesn't have to search the whole dom.
$(document).ready(function(){
var $selected;
$('.list > li a').click(function(){
if($selected){
$selected.remove class("open");
}
$selected = $(this).parent();
$selected.add class("open");
});
});
CSS would be something like this.
li ul{ display:none;}
li.open ul{ display: block}
Related
I have a question on Jquery. If I click on Link1, which does not have any ul.children and the class current_page_item will be added(not shown in this code as it will be added automatically by Wordpress), then ul.children in Link2 should be hidden.
If i click on Link 2, which will have both class page_item_has_children current_page_item, in this case ul.children should be shown. I have tried my code bellow, which is i know it is absolutely wrong. Please give me your advices. Many thanks.
if($(.navigation).hasClass(page_item_has_children)){
(.navigation .page_item_has_children .children).hide();
}else if( $(.navigation).hasClass(page_item_has_children) && $(.navigation).hasClass(current_page_item)){
(.navigation .page_item_has_children .children).show();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="navigation">
<li>Link1</li>
<li class="page_item_has_children current_page_item">Link2
<ul class="children">
<li class="page_item">Link3</li>
<li class="page_item ">Link4</li>
</ul>
</li>
</ul>
This solution is a bit more towards your scenario (edited based on comment):
$(".navigation li").on("click", function() {
if ($(this).hasClass("page_item_has_children") && $(this).hasClass("current_page_item")) {
$(".navigation .children").show();
} else {
$(".navigation .children").hide();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="navigation">
<li>Link1
</li>
<li class="page_item_has_children current_page_item links">Link2
<ul class="children">
<li class="page_item">Link3
</li>
<li class="page_item ">Link4
</li>
</ul>
</li>
</ul>
How about simply hiding all nested UL elements, then simply showing the children of the clicked one?
$(".navigation li").each(function() {
// When we first load, hide all nested menus.
$(this).children("ul").hide();
if (localStorage.menuNumber) {
$(".navigation li").eq(localStorage.menuNumber).children().show();
}
})
.on("click", function() {
// When any top-level ul is clicked, hide the
// nested menus then show the current one.
$(this).parent().children().find("ul").hide();
$(this).children().show();
// We also want to persist this selection,
// should the user refresh...
localStorage.menuNumber = $(this).index;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="navigation">
<li>Link1
</li>
<li class="page_item_has_children current_page_item">Link2
<ul class="children">
<li class="page_item">Link3
</li>
<li class="page_item ">Link4
</li>
</ul>
</li>
</ul>
Edited it so that when it initially loads, all nested uls are hidden. Hope this helps! And edited again, to store the clicked menu in local storage. Sadly, for security reasons, this won't work here. See it as a fiddle: https://jsfiddle.net/snowMonkey/fnuvvLwb/
how I can select the second ul li element, I have this structure:
HTML
<ul>
<li></li>
<ul>
<li>I want to select this</li>
</ul>
</ul>
Firstly your HTML is invalid. You cannot have ul as a child of another ul. It must be within an li. Also the text within the ul must also be within a li.
<ul>
<li>
<ul>
<li>I want to select this</li>
</ul>
</li>
</ul>
To then select this in jQuery you can use:
$('ul > li > ul > li:first');
You could also use the less strict: ul ul li:first, depending on how rigidly you need to adhere to the HTML structure you defined.
the structure you provided is not proper, the child <ul> tag should go inside an <li> tag.
then the structure will be like
<ul class="ul">
<li></li>
<li>
<ul>
<li>I want to select this </li>
</ul>
</li>
</ul>
then you can get that child <ul> using jquery as
$(".ul li ul");
hope this helps.
Try this snippet with multiple options.
console.log($('ul > ul > li:eq(0)').text());
//OR
console.log($('ul').find('ul > li:eq(0)').text());
//OR
console.log($('ul').children('ul').find('li:eq(0)').text());
//OR
console.log($('ul > ul').find('li:eq(0)').text());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul><b>First ul</b>
<li>First li</li>
<ul> <b>Second ul</b>
<li>First li in second ul</li>
</ul>
</ul>
First you must add a class or an id to your parent ul :
<ul class="root">
<li></li>
<ul>
I want to select this <li></li>
</ul>
</ul>
Then, either your choose to select the 2nd one because it will always be the second (index 1) :
$(".root").find("li").eq(1)
Or you add a class to your <li>:
<ul class="root">
<li></li>
<ul>
I want to select this <li class="myLi"></li>
</ul>
</ul>
And then
$(".root").find(".myLi")
You can use querySelector to do that. Check below example.
var li = document.querySelector('ul ul li');
console.log(li.innerHTML);
<ul>
<li>Not this</li>
<ul>
<li>I want to select this</li>
</ul>
</ul>
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");
});
I have toggle tree which responds on click i.e. show or hide UL>li. I want to hide all the UL --> li who has parent ul-li. To make it more obvious I have apply css background-color to red which I want to be hidden by when page loads but show when it click back.
https://jsfiddle.net/toxic_kz/vr84pd6u/
<div>
<ul class="treeview">
<li><a>System Administration</a></li>
<li>
<a>System Core</a>
<ul>
<li><a>f2</a></li>
<li>
<a>f3</a>
<ul>
<li><a>f4</a></li>
<li><a>f5</a></li>
<li><a>f6</a></li>
</ul>
</li>
<li>
<a>f7</a>
<ul>
<li>
<a>f8</a>
<ul>
<li>
<a>f10</a>
<ul>
<li><a>f11</a></li>
</ul>
</li>
</ul>
</li>
<li><a>f9</a></li>
</ul>
</li>
</ul>
</li>
<li>
<a>MyFunctionA</a>
<ul>
<li>
<a>f12</a>
<ul>
<li><a>f13</a></li>
<li><a>f14</a></li>
</ul>
</li>
<li><a>f16</a></li>
</ul>
</li>
<li><a>Course Management</a></li>
</ul>
</div>
jQuery
<script type="text/javascript">
$(document).ready(function () {
$('.treeview li').each(function () {
if ($(this).children('ul').length > 0) {
$(this).addClass('parent');
}
});
// $('.treeview li.parent>ul li').css('display', 'none');
$('.treeview li.parent>ul li').css('background-color', 'red');
$('.treeview li.parent > a').click(function () {
$(this).parent().toggleClass('active');
$(this).parent().children('ul').slideToggle('fast');
});
});
</script>
If I understood your question correctly, this is what you want:
$(".treeview").find('ul').hide()
Place this in your $(document).ready function and it'll hide the underlying unordered list upon page load.
I have a very simple example of a menu here:
<ul id="1">
<li>First</li>
<li>Second
<ul id="2">
<li>Second - 1</li>
<li>Second - 2</li>
<li>Second - 3
<ul id="3">
<li>Aaa</li>
<li>Bbb</li>
<li>Ccc</li>
</ul>
</li>
</ul>
</li>
<li>Third</li>
</ul>
I need to get the <li> that has a child <ul> and that is a child of <ul> who is a child of <li>, and apply a style to it.
I know it sounds complicated, but in the example above I want to get only the <li> that says "Second - 3" which is inside a ul, which is a child of a li and has a child ul. I don't want to get any other <li>s.
I can't do this without getting also the li which says "Second", and I don't want that.
$("li > ul").addClass('whatever');
Use $("li ul li:has(ul)")
e.g:
$(function(){
var items = $("li ul li:has(ul)");
alert(items.html());
});
Working example: http://jsfiddle.net/EXzaa/
Try this:
$("li > ul > li").each(function(){
if ( $(this).find("ul").length > 0){
$(this).css({"font-weight":"bold"});
}
});
Unless I get you wrong this is simple. Try something like this:
$('#3').parent('li').addClass('whatever');
This will select the parent node of the ul element with the id = 3 (only if it is an li element)