Get <li> with child <ul> from <ul> child of <li> - javascript

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)

Related

Slide up multiple <ul> elements using jQuery

I am trying to construct a jquery statement that will slideUp() all <ul> elements whose siblings don't contain a set of specific classes (.clicked, .chosen).
Suppose I have the following nested <ul> structure:
<ul class="mainmenu">
<li>Dogs</li>
<ul>
<li>Fido</li>
<li class="chosen">Barney</li>
<li>Turbo</li>
</ul>
<li>Cats</li>
<ul>
<li>Sylvester</li>
<li>Felix</li>
<li>Garfield</li>
</ul>
<li class="clicked">Hamsters</li>
<ul>
<li>Chubbs</li>
<li>Oreo</li>
<li>Ruby</li>
</ul>
</ul>
For the above example, I would like to slideUp() only the 'Cats' <ul> element ('Sylvester', 'Felix', 'Garfield') because none of it's elements use the 'chosen' or 'clicked' classes.
My current jquery statement reads:
$('.mainmenu').first().siblings().not('.clicked, .chosen').slideUp();
This, and everything else I have tried, returns nothing. Suggestions?
You HTML looks challenging :) but somehow, I've managed to create a query to perform what you're looking for.
And if you want to check multiple class for particular element you can use is() as well.
//Check li doesn't have clicked class and then filter ul next to the li
$('.mainmenu > li').not('.clicked').next('ul').filter(function(){
//Find the ul, if it's any of li doesn't have chosen class
if(!$(this).find('li').hasClass('chosen'))
{
return $(this);
}
}).slideUp();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="mainmenu">
<li>Dogs</li>
<ul>
<li>Fido</li>
<li class="chosen">Barney</li>
<li>Turbo</li>
</ul>
<li>Cats</li>
<ul>
<li>Sylvester</li>
<li>Felix</li>
<li>Garfield</li>
</ul>
<li class="clicked">Hamsters</li>
<ul>
<li>Chubbs</li>
<li>Oreo</li>
<li>Ruby</li>
</ul>
</ul>

select li element based on the ul

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>

Get the size of the parent LI inside an UL?

How can I modify the below code so that I get only the parent li within the first ul and then with another variable get the sub li of the given sub ul?
$(function () {
var vULSize = $("ul li").size();
console.log(vULSize);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul>
<li>First</li>
<li>Second
<ul>
<li>Second Sub 1</li>
<li>Second Sub 2</li>
</ul>
</li>
<li>Third</li>
<li>Third
<ul>
<li>Third Sub 1</li>
<li>Third Sub 2</li>
</ul>
</li>
</ul>
Fiddle: http://jsfiddle.net/0sp9pohr/
You can ignore all li's that are descendants of an li like
$(function() {
var vULSize = $("ul li:not(li li)").size();
snippet.log(vULSize);
});
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>First</li>
<li>Second
<ul>
<li>Second Sub 1</li>
<li>Second Sub 2</li>
</ul>
</li>
<li>Third</li>
<li>Third
<ul>
<li>Third Sub 1</li>
<li>Third Sub 2</li>
</ul>
</li>
</ul>
First you need to wrap it all in something, say for instance a div with the id container. Then you can do something like this:
var vULSize = $("#container > ul > li").length;
The > selector gives you only the direct descendants.
If you want to count the number of list elements one level down, this will give you an array with the result:
var counts = $("#container > ul > li").map(function() {
return $(this).find("li").length
}).get();
As pointed out in comments, you should use .length instead of .size().

Jquery to create hierarchy with unordered list

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}

click on li if no leaf node its append in another div

I have one Activity xml file and I am try to get from activity when click on activity there child display. Its look like end of the all click.
<ul id="firstLevelChild">
<ul id="ul">
<li id="4">Activities
<ul class="ul">
<li id="10066">Physical1
<ul class="ul">
<li id="10067">Cricket
<ul class="ul">
<li id="10068">One Day</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</ul>
Now I want that if li have no leaf node then its display in other another div. Something like:
Click on Acitivities there have child node Physical1 and there also child Cricket and there chil One Day now one day have no child when click on one day its display in my <div id="result"></div>
I would add this as a comment, but I don't have enough rep. ChildNodes() isn't a function - since it looks like you're using jQuery, try children() instead.
I think javascript could helpr you there. A part from the fact that you first build your DOM correct ;)
The hasChildNodes() method returns TRUE if the current element node has child nodes, and FALSE otherwise.
http://www.w3schools.com/dom/met_element_haschildnodes.asp
Assuming the markup you provided is how it's going to be always i.e. ul as child for all li. You just check if ul exists inside the current li. See fiddle
HTML
<div id="content">
<ul id="firstLevelChild">
<li>
<ul id="ul">
<li id="4">Activities
<ul class="ul">
<li id="10066">Physical1
<ul class="ul">
<li id="10067">Cricket
<ul class="ul">
<li id="10068">One Day</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<h2>Result</h2>
<ul id="result"></ul>
JS
$('#content li').each(function (i) {
//for display purpose only
$('#content').append('<span class="list">li(' + i + '):' + $('ul', $(this)).length + '</span>');
//the code you needed
if ($('ul', $(this)).length < 1) {
$(this).on('click', function () {
$('#result').append($(this).parent().html());
});
}
});

Categories

Resources