If li has ul inside - javascript

<ul>
<li>
<ul></ul>
</li>
<li></li>
<li></li>
<li></li>
<li>
<ul></ul>
</li>
</ul>
How do I add class="parent" only for li, which has ul inside it?

You can use :has() in your selector, like this:
$("li:has(ul)").addClass("parent")

Related

how to get last li element using javascript?

I am trying to get last li element of list . but it is not giving correct output. here is my markup
<div class="abc">
<ul>
<li>1</li>
<ul><li>1.1</li><li>1.2</li></ul>
<li>2</li>
<ul><li>2.1</li><li>2.2</li></ul>
<li>3</li>
<ul><li>3.1</li><li>3.2</li></ul>
</ul>
</div>
trying like this
console.log(document.querySelector('.abc ul li:last-child').innerHTML)
output Element
<li>1.2</li>
Expected output
<li>3</li>
There are 2 problems
Your HTML Is invalid as ul is not a valid child of ul so the nested ones need to be actually inside a li
Use the > modifier to find direct descendents only in the selector
console.log(document.querySelector('.abc>ul>li:last-child').innerHTML)
<div class="abc">
<ul>
<li>
1
<ul>
<li>1.1</li>
<li>1.2</li>
</ul>
</li>
<li>
2
<ul>
<li>2.1</li>
<li>2.2</li>
</ul>
</li>
<li>
3
<ul>
<li>3.1</li>
<li>3.2</li>
</ul>
</li>
</ul>
</div>
If you do just want the text (and not the nested ul) you could put that text in a span and select that only
console.log(document.querySelector('.abc>ul>li:last-child span').innerHTML)
<div class="abc">
<ul>
<li>
<span>1</span>
<ul>
<li>1.1</li>
<li>1.2</li>
</ul>
</li>
<li>
<span>2</span>
<ul>
<li>2.1</li>
<li>2.2</li>
</ul>
</li>
<li>
<span>3</span>
<ul>
<li>3.1</li>
<li>3.2</li>
</ul>
</li>
</ul>
</div>
If you do just want the text (and not the nested ul) you could put that text in a span and select that only
You can just go for the javascript way like this.
li = document.querySelectorAll('.abc>ul>li');
console.log(li[li.length-1].innerText);
console.log(document.querySelector('.abc ul li:last-child').innerHTML)
This syntax of giving white space instead of adjacent selectors like ">" is used when we want to apply common styles to multiple class.
So replacing your whitespace with adjacent selectors like > will work in your case to select all its descendent childs.
console.log(document.querySelector('.abc>ul>li:last-child').innerHTML)
<div class="abc">
<ul>
<li>
1
<ul>
<li>1.1</li>
<li>1.2</li>
</ul>
</li>
<li>
2
<ul>
<li>2.1</li>
<li>2.2</li>
</ul>
</li>
<li>
3
<ul>
<li>3.1</li>
<li>3.2</li>
</ul>
</li>
</ul>
</div>

Remove link from parent menu if it has sub menu

How to remove link from parent menu anchor if it has submenus
<ul class="sitemap-ul">
<li> Home</li>
<li> about Us <!-- Remove link-->
<ul>
<li>mission</li>
<li>vission</li>
</ul>
</li>
<li> Media <!-- Remove link-->
<ul>
<li>news</li>
</ul>
</li>
<li> Contact</li>
</ul>
You can use jQuery :has() pseudo-class selector.
$('.sitemap-ul > li:has(ul) > a').remove()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="sitemap-ul">
<li> Home</li>
<li> about Us <!-- Remove link-->
<ul>
<li>mission</li>
<li>vission</li>
</ul>
</li>
<li> Media <!-- Remove link-->
<ul>
<li>news</li>
</ul>
</li>
<li> Contact</li>
</ul>
UPDATE : In case you just want to replace a tag with text then use contents() method with unwrap() method.
$('.sitemap-ul > li:has(ul) > a')
// get children element
.contents()
// unwrap them
.unwrap()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="sitemap-ul">
<li> Home</li>
<li> about Us
<!-- Remove link-->
<ul>
<li>mission</li>
<li>vission</li>
</ul>
</li>
<li> Media
<!-- Remove link-->
<ul>
<li>news</li>
</ul>
</li>
<li> Contact</li>
</ul>
Assuming you want to remove the <a> elements themselves but leave behind their text content you can use :has() to get the relevant li with submenus, then replaceWith() on the child a elements, like this:
$('.sitemap-ul > li:has(ul) > a').replaceWith(function() {
return $(this).text();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="sitemap-ul">
<li>Home</li>
<li>
About Us
<ul>
<li>mission</li>
<li>vission</li>
</ul>
</li>
<li>
Media
<ul>
<li>news</li>
</ul>
</li>
<li>Contact</li>
</ul>
$('.sitemap-ul > li').each(function(){
if($('ul', this).length > 0){
$(this).closest("a").click(function(e){
e.preventDefault();
});
}
});
I have a solution by using vanilla js for you.
var elements = document.querySelectorAll(".sitemap-ul li")
Array.from(elements).forEach(function(el) {
if (el.children.length > 1) {
el.removeChild(el.children[0])
}
});

Can't find a way to select specific elements with JQuery

I'm trying to select theses elements with JQuery :
<div attribute="distinct-value"> <!-- i only want links in this one, select based on the attribute -->
<div>
<div>
<div class="col1">
<ul>
<li>
<!-- i want this -->
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
</ul>
</li>
</ul>
</div>
<div class="col2">
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
<li></li>
</ul>
</li>
</ul>
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
</div>
<!-- col3, col4, etc, etc... -->
</div>
</div>
</div>
<div attribute="another-distinct-value">
<!-- same content structure has 'distinct-value div' -->
</div>
<div attribute="another-other-distinct-value">
<!-- same content structure has 'distinct-value div' -->
</div>
I want the first link in the first li of every ul markups that are not inside a li, for every div that has a "col" class. I hope everything is clear..
Can someone help me out ?
Loop through your elements like so
$('div[attribute="distinct-value"] [class^=col] li:has(ul) > a').each(function(index) {
console.log( index + ": " + $( this ).text() );
});
console.log($('div[class^=col] > ul > li > a'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div attribute="distinct-value">
<div>
<div>
<div class="col1">
<ul>
<li>
<!-- i want this -->
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
</ul>
</li>
</ul>
</div>
<div class="col2">
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
<li></li>
</ul>
</li>
</ul>
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
</div>
<!-- col3, col4, etc, etc... -->
</div>
</div>
</div>
You can target li that has ul in it along with immediate child selector(>) to target immediate child anchor element:
$('[class^=col] li:has(ul) > a');
You can iterate over above set of elements and perform the task. If you want to get all the hrefs of anchor element, you need to use .map() with .get():
var allhref = $('[class^=col] li:has(ul) > a').map(function(){
return $(this).attr('href');
}).get();
var allhref = $('[class^=col] li:has(ul) > a').map(function(){
return $(this).attr('href');
}).get();
alert(allhref);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div attribute="distinct-value">
<div>
<div>
<div class="col1">
<ul>
<li>
<!-- i want this -->
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
</ul>
</li>
</ul>
</div>
<div class="col2">
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
<li></li>
</ul>
</li>
</ul>
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
</div>
<!-- col3, col4, etc, etc... -->
</div>
</div>
</div>
Try this:
$('div[class^=col] > ul > li > a').each(function() {
doSomething( $(this) );
});

Give li elements class based on above ul class

I have a set of li elements and I want to give all li elements below the ul container an extra class based on the .login class. The login element isn't a parent element but in the same container. Would this be possible with jQuery or vanilla js?
<ul class="submenu" id="sub0">
<li class="menugroup dcjq-parent-li">
<ul class="rightmenu login">
<li></li>
<li></li>
</ul>
</li>
<li></li> <-----new class
<li></li> <-----new class
<li></li> <-----new class
<li></li> <-----new class
<li></li> <-----new class
<li></li> <-----new class
</ul>
You can use the following code:
$("ul.login")
.parents("li")//get ancestor li element
.nextAll()//get all next li elements
.addClass("active");//add desire class
.active {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="submenu" id="sub0">
<li class="menugroup dcjq-parent-li">
<ul class="rightmenu login">
<li>
</li>
<li>
</li>
</ul>
</li>
<li>
</li>
<li>
</li>
<li>
</li>
<li>
</li>
<li>
</li>
<li>
</li>
</ul>
References
.nextAll()
.addClass()
.parents()

How to hide a div when another div is empty

I'm new to jQuery and I've hit a bit of a snag.
Here is my HTML:
<div id="mainpage-tabs-area">
<ul class="nav cf">
<li class="tb-one">BTN1</li>
<li class="tb-two">BTN2</li>
<li class="tb-three">BTN3</li>
<li class="tb-four">BTN4</li>
</ul>
<div class="list-wrap">
<ul id="description">
<li>Hello, I am a description</li>
</ul>
<ul id="tabtwo" class="hide">
<li></li>
</ul>
<ul id="tabthree" class="hide">
<li></li>
</ul>
<ul id="tabfour" class="hide">
<li></li>
</ul>
</div> <!-- END List Wrap -->
</div> <!-- END Organic Tabs -->
And here is my current jQuery:
$(document).ready(function () {
var tabContent = $('ul.list-wrap').find('li').text();
if ($.trim(tabContent) === "") {
$('ul.nav li').hide();
}
});
What I want to be able to do is just the jQuery to check every li in .list-wrap and if that li is empty then remove the corresponding li in .nav as this is for a tab system where if no content is entered, they don't want it displaying.
Any suggestions for a newbie?
Nick
I'd iterate through the list items, check the length of each node's text, and hide the corresponding tab with:
$('.list-wrap li').each(function(i){
if(!$(this).text().length) $('#mainpage-tabs-area li').eq(i).hide();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="mainpage-tabs-area">
<ul class="nav cf">
<li class="tb-one">BTN1
</li>
<li class="tb-two">BTN2
</li>
<li class="tb-three">BTN3
</li>
<li class="tb-four">BTN4
</li>
</ul>
<div class="list-wrap">
<ul id="description">
<li>Hello, I am a description</li>
</ul>
<ul id="tabtwo" class="hide">
<li></li>
</ul>
<ul id="tabthree" class="hide">
<li></li>
</ul>
<ul id="tabfour" class="hide">
<li></li>
</ul>
</div>
<!-- END List Wrap -->
</div>
<!-- END Organic Tabs -->
The i in the each() function is the index of the element that the loop is on, and that allows you to target the corresponding tab element and hide it.
This should do the job:
$('.list-wrap ul li').each(function(){
var cnt = $('.list-wrap ul li').index( $(this) );
var txt = $(this).text();
if ($.trim(txt)==''){
$('.nav li').eq(cnt).hide();
}
});
jsFiddle Demo
I would suggest this If you are not making infinite lists
$('.tb-two').hide(); //if tabtwo is empty
$('.tb-hree').hide(); //if tabthree is empty
and so on...

Categories