I was wondering if it was possible to get the index of a single <li> in a multilevel <ul>...
Let's say I have the following unordered list:
<ul>
<li>1</li>
<li>
2
<ul>
<li>2.1</li>
<li>2.2</li>
</ul>
</li>
<li>3</li>
<li id="position">4</li>
</ul>
When I use $('#position').index(); It returns 3 (zero based, 4th element), but I want it to return 5; since it's the 6th <li> in the <ul>.
Any ideas on how to do this?
Thanks in advance!
By setting the context of the index to all the li's in the ul :
$('#position').index('ul li');
FIDDLE
or even the other way around:
$('ul li').index($('#position'));
or specific to this UL only:
$('#position').closest('ul').find('li').index($('#position'));
Related
How could I add toggle class? When I click on anchor tag it should add class to only next sibling element ( .treeUlChild ). i tried a lot and try to find solution but couldn't. I am new and this is my first project in javascript.
here is my html code.
<div id="treeList" class="treeDiv">
<ul class="treeUl">
<li>
GUIDELINES
<ul class="treeUlChild treeLevel2">
<li> Guidlines 1</li>
<li> Guidlines 2</li>
<li> Guidlines 3</li>
<li> Guidlines 4</li>
</ul>
<!-- End Child Ul -->
</li>
<li>
AFTER-SALES
<ul id="test" class="treeUlChild treeLevel2">
<li>xyz</li>
<li>
def
<ul class="treeUlChild treeLevel3">
<li>
ASSETS
<ul class="treeLevel4">
<li>DIGITAL</li>
<li>OOH</li>
<li>POS</li>
<li>PRINT</li>
<li>SOCIAL GIF</li>
<li>SOCIAL VIDEOS</li>
</ul>
<!-- End Child Ul -->
</li>
</ul>
<!-- End Child Ul -->
</li>
</ul>
<!-- End Child Ul -->
</li>
</ul>
<!-- End treeUl -->
</div>
This is my javascript code.
document.querySelector('#treeList ul li a').addEventListener("click", function(){
document.querySelector('.treeUlChild').nextSibling.classList.toggle('done');
});
One issue is nextSibling returns a node object, it's better you use nextElementSibling which returns an element node. The other issue is querySelector will always return the first element with the specified selector, so the changes will always be reflected on the same element whichever link you clicked. You may rather use querySelectorAll which returns all the elements as a node list, and loop through each element and apply the changes. Another thing is, it's better to use event.target to get clicked element and rather than using a selector again.
document.querySelectorAll('#treeList ul li a').forEach(elem => elem.addEventListener("click", function(){
event.target.nextElementSibling.classList.toggle('done');
}));
There is very simple way using Bootstrap by the way.
But if you want to do that with pure Javascript, you're on the right way to it.
So first, transform your query selector into a object e.g:
var el = document.querySelector('#treeList ul li a');
forEach method, querying the single object clicked in the array of multiple objects:
el.forEach(yourFunctionName());
Add functions to your elements:
<li><a onclick="yourFunctionName()" href="#"> Guidlines 1</a></li>
<li><a onclick="yourFunctionName()" href="#"> Guidlines 2</a></li>
<li><a onclick="yourFunctionName()" href="#"> Guidlines 3</a></li>
<li><a onclick="yourFunctionName()" href="#"> Guidlines 4</a></li>
ps: you can simplify this.
Structure your function:
function myFunctionName(){
document.querySelector('.treeUlChild').nextSibling.classList.toggle('done');
}
I have some dom like
.....
<ul>*
<li>
<ul>
Sone html here
</ul>
</li>
</ul>
.....
<ul>*
<li>
<ul>
<li>
<ul>
Some html here
</ul>
</li>
</ul>
</li>
</ul>
......
How can I find the first <ul> elements (marked by *) using jQuery?
I used something like
$('body ul:first-child')
but this returns only one element
You need to use immediate child selector to target elements that are immediate child of their parent:
$('body > ul')
I don't know why few person recomended to delete answer bnu right answer is
$('ul:not(ul ul)')
we need to exclude ul included in ul in this case we get ul only on top level (marked by *)
This is my menu layout in html
<ul>
<li>1
<ul>
<li>1-1</li>
<li>1-2</li>
</ul>
</li>
<li>2</li>
<li>3
<ul>
<li>3-1
<ul>
<li>3-1-1</li>
<li>3-1-2</li>
</ul>
</li>
<li>3-2</li>
</ul>
</li>
<li>4</li>
<li>5</li>
</ul>
How to convert this layout to Multi-dimensional associative JS array and keep items values ?
To do this with a custom function, first you'd need code that gets the top ul, and iterates through all children. I wrote some sample code for this here, if it's useful:
getElementById doesn't work on a node
Then, when building a data structure, use these rules:
1. ul maps to a []
2. li maps to { "text value of li": children }
3. if there are no children, children is null
I have an uncertain amount of nested ul and li tags like:
<ul>
<li>5
<ul>
<li>2
<ul>
<li>1
</li>
<li>4
<ul>
<li>3
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>7
<ul>
<li>9
<ul>
<li>14
<li>
</ul>
<li>11
</li>
</ul>
</li>
</ul>
I'm using Kendo ui treeview and it returns me the element where the l was dropped (it might be a element inside the li because I have some spans in each one).
What I need is to know the previous and next li through DOM and Javascript to save the new order of elements.
Can anyone help please?
You didn't specify which event you were using, but it should be "dragend". That way you should be able to detect the parent li and then just get all of it's children to reorder.
Check out this fiddle here. Is this closer to what you are looking for?
http://jsfiddle.net/burkeholland/CrRUz/
Using jQuery:
var parentLi = $(e).closest('li');
var previousLi = parentLi.prev()
var nextLi = parentLi.next();
Where e is the element receiving the drop.
I have a unordered list like the one below:
<ul id="tabs">
<li>latest news</li>
<li class="active">latest posts</li>
<li>latest posts</li>
<li>latest posts</li>
</ul>
I can't find a jQuery selector that gets the next list item from the one whith the .active class, so if .active is the second one the jQuery selector will give me the third list item.
Thank's
In one step: jQuery('li.active + li');
See adjacent sibling selectors.
$('ul#tabs li.active').next();