How to get ul inside an li - javascript

<li class="cate-item">
<button class="cate-label" >item 1 </button>
<ul class="sub-categ">
<li> sub item 1</li>
<li> sub item 2</li>
<li> sub item 3</li>
<li> sub item 4</li>
</ul>
</li>
<li class="cate-item">
<button class="cate-label" >item 2 </button>
<ul class="sub-categ">
<li> sub item 1</li>
<li> sub item 2</li>
<li> sub item 3</li>
<li> sub item 4</li>
</ul>
</li>
This li item is generated dynamically I want to toggle li on the cate-label button click. for that, I did the following code
$(document).on("click", "#categoryList > li .cate-label", function () {
var currentItem = $(this).closest("li");
ItemToHide = $("#categoryList > li").not(currentItem);
ItemToHide.removeClass("active-item");
ItemToHide.find(".sub-cate").hide();
currentItem.toggleClass("active-item");
}
);
when I try to hide item using ItemToHide.find(".sub-cate").hide(); it didn't hide anything . I tried to find the length of the item using ItemToHide.find(".sub-cate").length but it returned 0.

Lower your event handling to something closer. I wrapped everything in a <menu> tag and registered the click event to it instead of document. It doesn't make much of a difference performance wise but I suggest it because it's looks as if your perspective is skewed if dealing with a larger view of the DOM and you'll be error prone:
var currentItem = $(this).closest("li");
ItemToHide = $("#categoryList > li").not(currentItem);
ItemToHide.removeClass("active-item");
ItemToHide.find(".sub-cate").hide();
currentItem.toggleClass("active-item");
That nightmare is now:
$(this).next('.sub-categ').toggle('ease-out');
$('menu').on("click", ".cate-label", toggleList);
function toggleList(e) {
$(this).next('.sub-categ').toggle('ease-out');
};
<menu>
<li class="cate-item">
<button class="cate-label">item 1 </button>
<ul class="sub-categ">
<li> sub item 1</li>
<li> sub item 2</li>
<li> sub item 3</li>
<li> sub item 4</li>
</ul>
</li>
<li class="cate-item">
<button class="cate-label">item 2 </button>
<ul class="sub-categ">
<li> sub item 1</li>
<li> sub item 2</li>
<li> sub item 3</li>
<li> sub item 4</li>
</ul>
</li>
</menu>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Actually, the name of the class is not correct. Should be 'sub-cate', not 'sub-categ'.
$(document).on("click", "#categoryList > li .cate-label", function () {
var currentItem = $(this).closest("li");
ItemToHide = $("#categoryList > li").not(currentItem);
ItemToHide.removeClass("active-item");
ItemToHide.find(".sub-cate").hide();
currentItem.toggleClass("active-item");
});
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<div id="categoryList">
<li class="cate-item">
<button class="cate-label" >item 1 </button>
<ul class="sub-cate"><!--rename the class name-->
<li> sub item 1</li>
<li> sub item 2</li>
<li> sub item 3</li>
<li> sub item 4</li>
</ul>
</li>
<li class="cate-item">
<button class="cate-label" >item 2 </button>
<ul class="sub-cate"><!--rename the class name-->
<li> sub item 1</li>
<li> sub item 2</li>
<li> sub item 3</li>
<li> sub item 4</li>
</ul>
</li>
</div>

Related

Get li Element Text When Click on that Element

I have this code. When I click on any li element then the first alert it shows its value, then show its parent then again that parent and so on. I just want to show the text of the clicked li element. How can I do that?
$('#container li').on('click', function() {
alert($(this).text());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<ul class="xyz">
<li>Grand Parent 1</li>
<li>
<ul class="xyz">
<li>Parent 1</li>
<li>Parent 2
<ul class="xyz">
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
<li>Child 4</li>
</ul>
</li>
<li>Parent 3</li>
<li>Parent 4</li>
</ul>
</li>
</ul>
</div>
Your first issue is that you need to stop the proprgation of the event from the clicked li to the parent li elements. You can call stopPropagation on the passed event handler to do that.
Secondly, I assume you only want to retrieve the child text value of the li, not the text of it's descendants, in which case you would need to use contents()[0] to access it. Try this:
$('#container li').on('click', function(e) {
e.stopPropagation();
var text = $(this).contents()[0].nodeValue.trim();
console.log(text);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<ul class="xyz">
<li>Grand Parent 1</li>
<li>
<ul class="xyz">
<li>Parent 1</li>
<li>
Parent 2
<ul class="xyz">
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
<li>Child 4</li>
</ul>
</li>
<li>Parent 3</li>
<li>Parent 4</li>
</ul>
</li>
</ul>
</div>

how to select the children of clicked element by class

In my html page, there is a list of all the categories. Each category has some subcategories. I want that as a list item is clicked, its subcategories are toggled i.e. if they are visible, they should be hidden and vice versa. Also at one time, only one list item should be able to show its subcategories. I have tried this answer, but it doesn't help. I won't mind in using either JS, JQuery etc or changing the syntax altogether.
My work till now is
<ul>
<li class="outer-list-element">
category 1
<ul class="inner-list" id="inner-list">
<li>sub category 1</li>
<li>sub category 2</li>
</ul>
</li>
<li class ="outer-list-element">
category 3
<ul class="inner-list" id="inner-list">
<li>sub category 1</li>
<li>sub category 2</li>
</ul>
</li>
css
li {
margin-bottom: 8px;
}
.inner-list {
margin-top: 10px;
display: none;
}
Script
$('.outer-list-element').click(function () {
$(this).children().toggle();
})
$(".outer-list").click(function() {
$(this).siblings('.inner-list').toggle();
return false;
});
Feel free to update this fiddle
https://jsfiddle.net/7vmtd2px/1/
Please try following code.
$('.outer-list').click(function () {
//Hide other ul
$('ul .inner-list').not($(this).parent('li').find('ul')).hide();
//Toggle clicked ul
$(this).parent('li').find('ul').toggle();
});
li {
margin-bottom: 8px;
}
.inner-list {
margin-top: 10px;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="outer-list-element">
category 1
<ul class="inner-list">
<li>sub category 1</li>
<li>sub category 2</li>
</ul>
</li>
<li class="outer-list-element">
category 2
<ul class="inner-list">
<li>sub category 1</li>
<li> sub category 2</li>
</ul>
</li>
<li class ="outer-list-element">
category 3
<ul class="inner-list">
<li>sub category 1</li>
<li>sub category 2</li>
</ul>
</li>
</ul>
You can create a class(showInnerList in this case) with display:block property. So on click of element you can add this class to the DOM which you want to show.
Also I am using addClass & removeClass instead of toggle. The reason is on click of any DOM,I intend to find the element which has showInnerClass and remove this same class from it & then add this same class to the sibling
HTML
<ul class="myList">
<li class="outer-list-element">
category 1
<ul class="inner-list" id="inner-list">
<li>sub category 1</li>
<li>sub category 2</li>
</ul>
</li>
<li class="outer-list-element">
category 2
<ul class="inner-list" id="inner-list_1">
<li>sub category 1</li>
<li> sub category 2</li>
</ul>
</li>
<li class="outer-list-element">
category 3
<ul class="inner-list" id="inner-list_2">
<li>sub category 1</li>
<li>sub category 2</li>
</ul>
</li>
</ul>
JS
$('.outer-list-element a').click(function() {
$('.myList').find('ul.showInnerList').removeClass('showInnerList');
$(this).next('ul.inner-list').addClass('showInnerList');
})
Also note that you are using same id for ul class="inner-list". id need to be unique
JSFIDDLE
try With this..
$(document).on('click', ".outer-list", function() {
$('.inner-list').hide(); //first hide all the element having class inner-list
//$(this).siblings('.inner-list').toggle();
$(this).next('ul').toggle(); // here is the trick
return false;
});
and HERE is the FIDDLE
Thanks Mohit
Here's the same thing as Sarath's answer, but with the additional functionality of automatically collapsing the present list if it's clicked twice.
<ul>
<li class="outer-list-element">
category 1
<ul class="inner-list" id="inner-list">
<li>sub category 1</li>
<li>sub category 2</li>
</ul>
</li>
<li class="outer-list-element">
category 2
<ul class="inner-list" id="inner-list">
<li>sub category 1</li>
<li> sub category 2</li>
</ul>
</li>
<li class ="outer-list-element">
category 3
<ul class="inner-list" id="inner-list">
<li>sub category 1</li>
<li>sub category 2</li>
</ul>
</li>
</ul>
CSS:
li {
margin-bottom: 8px;
}
.inner-list {
margin-top: 10px;
display: none;
}
jQuery:
$(document).on('click', ".outer-list", function()
{
$(this).parents().siblings().children(".inner-list").hide();
$(this).siblings('.inner-list').toggle();
});
Here's the jsFiddle in case you want to see it in action.

Javascript from onmouseover to onclick

I'm using this piece of code for my website to implement a dropdown menu:
<script>
var menu=function(){
var t=15,z=50,s=6,a;
function dd(n){this.n=n; this.h=[]; this.c=[]}
dd.prototype.init=function(p,c){
a=c; var w=document.getElementById(p), s=w.getElementsByTagName('ul'), l=s.length, i=0;
for(i;i<l;i++){
var h=s[i].parentNode; this.h[i]=h; this.c[i]=s[i];
h.onmouseover=new Function(this.n+'.st('+i+',true)');
h.onmouseout=new Function(this.n+'.st('+i+')');
}
}
dd.prototype.st=function(x,f){
var c=this.c[x], h=this.h[x], p=h.getElementsByTagName('a')[0];
clearInterval(c.t); c.style.overflow='hidden';
if(f){
p.className+=' '+a;
if(!c.mh){c.style.display='block'; c.style.height=''; c.mh=c.offsetHeight; c.style.height=0}
if(c.mh==c.offsetHeight){c.style.overflow='visible'}
else{c.style.zIndex=z; z++; c.t=setInterval(function(){sl(c,1)},t)}
}else{p.className=p.className.replace(a,''); c.t=setInterval(function(){sl(c,-1)},t)}
}
function sl(c,f){
var h=c.offsetHeight;
if((h<=0&&f!=1)||(h>=c.mh&&f==1)){
if(f==1){c.style.filter=''; c.style.opacity=1; c.style.overflow='visible'}
clearInterval(c.t); return
}
var d=(f==1)?Math.ceil((c.mh-h)/s):Math.ceil(h/s), o=h/c.mh;
c.style.opacity=o; c.style.filter='alpha(opacity='+(o*100)+')';
c.style.height=h+(d*f)+'px'
}
return{dd:dd}
}();
</script>
and
<div style="margin-left:150px">
<ul class="menu" id="menu">
<li>Dropdown One
<ul>
<li>Navigation Item 1</li>
<li>
Navigation Item 2
<ul>
<li class="topline">Navigation Item 1</li>
<li>Navigation Item 2</li>
<li>Navigation Item 3</li>
<li>Navigation Item 4</li>
<li>Navigation Item 5</li>
</ul>
</li>
<li>
Navigation Item 3
<ul>
<li class="topline">Navigation Item 1</li>
<li>Navigation Item 2</li>
<li>
Navigation Item 3
<ul>
<li class="topline">Navigation Item 1</li>
<li>Navigation Item 2</li>
<li>Navigation Item 3</li>
<li>Navigation Item 4</li>
<li>Navigation Item 5</li>
<li>Navigation Item 6</li>
</ul>
</li>
<li>Navigation Item 4</li>
</ul>
</li>
<li>Navigation Item 4</li>
<li>Navigation Item 5</li>
</ul>
</li>
</ul>
</div>
<script type="text/javascript">
var menu=new menu.dd("menu");
menu.init("menu","menuhover");
</script>
I tried to convert h.onmouseover and h.onmouseout in h.onclick because i want the menu to expand when the user clicks on it.
How can i do that? I'm newbie in Javascript.
try this:
change from
h.onmouseover=new Function(this.n+'.st('+i+',true)');
h.onmouseout=new Function(this.n+'.st('+i+')');
change to
h.onclick=new Function(this.n+'.st('+i+',true)');

jquery selector first child of ul tag

I have a menu structure like this:
<ul>
<li>One
</li>
<li class="active">Two
<ul>
<li>Sub One
<ul>
<li>Sub One One...</li>
<li>Sub One Two
</li>
</ul>
</li>
<li>Sub Two
<ul>
<li>Sub Two One
</li>
<li>Sub Two Two
</li>
</ul>
</li>
<li>Sub Tree
</li>
</ul>
</li>
<li>Tree
</li>
</ul>
Now... How can i select all sub first "ul" tags in class "active" ?
sample, active > "ul" (sub one) > "ul" (sub one one) ... etc.
You can select like this
JQuery
$('ul li.active>ul')
OR
$('li.active').children('ul')
CSS
ul li.active ul {}
$("li.active").find("ul") will do the trick. Following is the simple code where you can log all the UL elements inside active li.
var ulArr = $("li.active").find("ul");
console.log("First UL of active li is: " + ulArr[0]);
$.each(ulArr, function(index, element) {
console.log("Child UL number " + index + " is: " + element);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>One
</li>
<li class="active">Two
<ul>
<li>Sub One
<ul>
<li>Sub One One...</li>
<li>Sub One Two
</li>
</ul>
</li>
<li>Sub Two
<ul>
<li>Sub Two One
</li>
<li>Sub Two Two
</li>
</ul>
</li>
<li>Sub Tree
</li>
</ul>
</li>
<li>Tree
</li>
</ul>
try
$("li.active >ul:first")
$('.active ul>li>a').first()
$(function() {
var active = $('.active ul>li>a').first().addClass('red');
});
.red {
color:red !important
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<ul>
<li>One
</li>
<li class="active">Two
<ul>
<li>Sub One
<ul>
<li>Sub One One...</li>
<li>Sub One Two
</li>
</ul>
</li>
<li>Sub Two
<ul>
<li>Sub Two One
</li>
<li>Sub Two Two
</li>
</ul>
</li>
<li>Sub Tree
</li>
</ul>
</li>
<li>Tree
</li>
</ul>

JQuery slideToggle for multicolumn list

I`ve got a big list with the width of li 33%, so there are 3 columns.
computers monitors hi-fi
sex-toys pancakes scissors
In each of them there is UL hidden, which on click slideToggle.
JQuery
$('.subCategory > .parentleaf:has(ul) > .categoryicon').click(function() {
$(this).siblings('ul').slideToggle('fast');
});
The problem that dont slide as I want, they rebuld the list every time, like so
computers monitors hi-fi
[li]cars sex-toys pancakes
[li]dogs scissors
I want to slide them this way:
computers monitors hi-fi
[li]cars pancakes scissors
[li]dogs
sex-toys
How can I achieve this??
jsFiddle
jsFiddle 2 - in this case need the red bg color be for 3 columns
I added a clearer div between every three li
<ul class="subCategory">
<li class="parentleaf">
<span class="categoryicon">click</span>
<span class="categoryname">Cars</span>
<ul class="submenu">
<li>Car 1</li>
<li>Car 2</li>
<li>Car 3</li>
<li>Car 4</li>
</ul>
</li>
<li class="parentleaf">
<span class="categoryicon">click</span>
<span class="categoryname">Phones</span>
<ul class="submenu">
<li>Phone 1</li>
<li>Phone 2</li>
<li>Phone 3</li>
<li>Phone 4</li>
</ul>
</li>
<li class="parentleaf">
<span class="categoryicon">click</span>
<span class="categoryname">Guns</span>
<ul class="submenu">
<li>Gun 1</li>
<li>Gun 2</li>
<li>Gun 3</li>
<li>Gun 4</li>
</ul>
</li>
<div class="clearer"></div>
<li class="parentleaf">
<span class="categoryicon">click</span>
<span class="categoryname">Notebooks</span>
<ul class="submenu">
<li>Notebook 1</li>
<li>Notebook 2</li>
<li>Notebook 3</li>
<li>Notebook 4</li>
</ul>
</li>
CSS
.clearer
{
clear:both;
}
You can also get the index of the current clicked li and with some math add a clearer div on click and remove it when needed but there I think there is no need for this

Categories