Javascript/Jquery: Number nested list - javascript

I have a nested list:
<ul>
<li id="1">first</li>
<li id="2">second</li>
<ul>
<li id="2-1">second nested first element</li>
<li id="2-2">second nested secondelement</li>
<li id="2-3">second nested thirdelement</li>
<ul>
<li id="2-3-1">Other</li>
</ul>
</ul>
<li id="3"i>third</li>
<li id="4">fourth</li>
</ul>
Each element has an id that indicates the position within the list. How do I generate it automatically?
Thank you.
UPDATE:
html is generated by Apache velocity without ID. I'm trying to create a method for updating the id if you move elements with jquery sortable. The structure of the id must be "1" for the first item "1-1" for the first element of the first "li". I tried using index () but I can't generate the id in the form that I need

It's not clear what you exactly want to do here, but here's an example of generating dynamic li's with dynamic id's:
HTML:
<ul id="autoGenerated">
</ul>
JS:
for(var i = 1; i < 3 ;i++){
$("#autoGenerated").append("<li id=2-" + i + ">Testing " + i + "</li>")
}
$('#autoGenerated li').click(function(){
alert($(this).attr("id"));
})
Fiddle.

Related

Count the number of list elements on page that have an id attribute

I have a list and I want to count only the items in that list that have an id attribute. For example, this is my code:
<ul class="members-list">
<li id="newmember1"></li>
<li id="newmember2"></li>
<li data-empty-index="3"></li>
<li data-empty-index="4"></li>
</ul>
The list counts how many members are associated with an account and a user can add and delete members themselves. When they add a member, they are given an id. I want to count the number of unused accounts they have, i.e. the list items here that aren't associated with an id (the bottom 2).
I have the following code already to count how many list items altogether:
var listOfMembers = $(".members-list").children();
var numberOfMembers = listOfMembers.length;
However I don't know how to get the ones that don't have an id, and separate them from the group? I'm not even sure if this is possible, but would really grateful for any pointers please :)
this should work for you.
var listOfMembers = $(".members-list").find("li[id]")
You can use querySelectorAll():
let count = document.querySelectorAll('ul li[id]').length;
You can use .find() with :not()
var listOfMembers = $(".members-list").find(":not(li[id])");
var numberOfMembers = listOfMembers.length;
console.log(numberOfMembers);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="members-list">
<li id="newmember1"></li>
<li id="newmember2"></li>
<li data-empty-index="3"></li>
<li data-empty-index="4"></li>
</ul>
OR: You can use .filter() to filter out the elements not having an id attribute.
var listOfMembers = $(".members-list li").filter((_, el) => !$(el).attr('id'));
var numberOfMembers = listOfMembers.length;
console.log(numberOfMembers);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="members-list">
<li id="newmember1"></li>
<li id="newmember2"></li>
<li data-empty-index="3"></li>
<li data-empty-index="4"></li>
</ul>
Simple. This can be done using the :not selector combined with targeting all li's with an id attribute.
$(function() {
var listItems = $('li:not([id])');
console.log(listItems.get(), 'Number of elements: ' + listItems.length)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="members-list">
<li id="newmember1"></li>
<li id="newmember2"></li>
<li data-empty-index="3"></li>
<li data-empty-index="4"></li>
</ul>

Add extra pair of UL using JavaScript/JQuery

I have done coding the first part HTML then JavaScript/JQuery. Now I want to surround the final common list with a UL need to be done using JavaScript/JQuery. So the final common list will be surrounded by two UL instead of one. Eg
Final Outcome
<ul id="CommonLister">
<ul> <!--Need to add this-->
<li class="columnItem">John</li>
<li class="columnItem">Mark</li>
</ul><!--Need to add this-->
</ul>
Current Code
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul id="listOne">
<li class="columnItem">John</li><!--will be removed and put under CommonLister-->
<li class="columnItem">James</li>
<li class="columnItem">Mary</li><!--will be removed and put under CommonLister-->
</ul>
<ul id="listTwo">
<li class="columnItem">John</li><!--will be removed and put under CommonLister-->
<li class="columnItem">Mark</li>
<li class="columnItem">Mary</li><!--will be removed and put under CommonLister-->
</ul>
<ul id="CommonLister">
<li class="columnItem">John</li>
<li class="columnItem">Mark</li>
</ul>
</div>
$(function() {
$('#run-code').on('click', function(e) {
e.preventDefault();
//What were you doing? nope.
var currentItems = {}; //Blank object
var $mergeColumn = $('#CommonLister'); //Common list reference
$('.columnItem').each(function(i, el) {
var $el = $(el); //Notation I use to differentiate between the regular HTML Element and jQuery element
if (!currentItems.hasOwnProperty($el.html())) {
//Has this name come up before? if not, create it.
currentItems[$el.html()] = []; //Make it equal to a brand spanking new array
}
currentItems[$el.html()].push(el);
//Add the item to the array
});
$.each(currentItems, function(name, data) {
//Loop through each name. We don't actually use the name variable because we don't care what someone's name is
if (data.length > 1) {
//Do we have more than 1 element in our array? time to move some stuff
$.each(data, function(i, el) {
var $el = $(el); //See note above
if (i == 0) {
//If this is the first element, let's just go ahead and move it to the merge column ul
$el.appendTo($mergeColumn);
} else {
$el.remove(); //Otherwise, we've already got this element so delete this one.
} //end if/else
}); //end $.each(data)
} //end if data.length >1
}); //end $.each(currentItems)
}); //end $.on()
}); //end $(
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="run-code" class="btn btn-success">Click Me</button>
<h4>List 1</h4>
<ul id="listOne">
<li class="columnItem">John</li>
<!--will be removed and put under CommonLister-->
<li class="columnItem">James</li>
<li class="columnItem">Mary</li>
<!--will be removed and put under CommonLister-->
</ul>
<h4>List 2</h4>
<ul id="listTwo">
<li class="columnItem">John</li>
<!--will be removed and put under CommonLister-->
<li class="columnItem">Mark</li>
<li class="columnItem">Mary</li>
<!--will be removed and put under CommonLister-->
</ul>
<h4>Common List</h4>
<ul id="CommonLister">
<!--Extra ul will be added here-->
</ul>
It's invalid nesting a ul directly in a ul like this but if you have to, you could use jquery wrapAll:
$( "li" ).wrapAll( "<ul></ul>" );
See fiddle: https://jsfiddle.net/9xLt6d9f/
I agree with charlietfl that it seems strange to do it this way. However, to answer your question, the best way to force this improperly formatted HTML code would be hardcode it into your original file. Try the following code for the end of your file:
<h4>Common List</h4>
<ul id="CommonLister">
<ul id="CommonListerSub">
<!--Extra ul will be added here-->
</ul>
</ul>
Then, simply change one line of your code:
var $mergeColumn = $('#CommonListerSub'); //Common list reference
This will force it to list the list items under the nested ul tags.
I hope this is an acceptable solution. If for some reason it doesn't work, please comment as to what additional limitations you have, and perhaps share the link of the page that is giving you the required template or format specifications.

How to get ul id(level_1) from below snippet by using JavaScript?

<ul id="level_1">
<li id="one">ONE</li>
<li id="two">TWO</li>
<li>
<ul id="level_2">
<li id="aaa">AAA</li>
<li id="bbb">BBB</li>
</ul>
</li>
</ul>
I have ul id(level_2) in my code, based on level_2 I need to get level_1 using JavaScript.
You can use .closest() if you don't know the id name:
var firstLevelUL = $('#level_2').closest('ul');
if you know the id then simply use:
var firstLevelUL = $('#level_1');
You can try using eq() with parents(). eq() is zero base index so first element will have zero index and third element will have 2 index.
$(this).parents().eq(3).attr('id');

JQuery .each only returning one <li>

I have the following HTML:
<ul id="sortable1 venuetags" class="connectedSortable">
<li id="venuetagli">fried</li>
<li id="venuetagli">garlic</li>
<li id="venuetagli">rosemary</li>
<li id="venuetagli">new potatoes</li>
</ul>
And am trying to get the values of each using JQuery:
$('#venuetagli').each(function(j,li) {
console.log(j,li)
})
However, from the console I am only getting the first value returned.
The ids are supposed to must be unique that is why you are getting single element use class selector instead. Also the id of UL would not have space.
Html
<ul id="sortable1 venuetags" class="connectedSortable">
<li class="venuetagli">fried</li>
<li class="venuetagli">garlic</li>
<li class="venuetagli">rosemary</li>
<li class="venuetagli">new potatoes</li>
</ul>
Javascript
$('.venuetagli').each(function(j,li) {
console.log(j,li)
});
You can simple get the li with ul using parent-child selector
$('#sortable1 li').each(function(j,li) {
console.log(j,li)
});
Just for the test and never recommended way, you can get elements having same id using attribute selector.
$('[id=venuetagli]').each(function(j,li) {
console.log(j,li);
});
Id must be assign to a single element in complete page else it will return only one of those element or unexpected result:
Here is demo with class
<ul id="sortable1 venuetags" class="connectedSortable">
<li class="venuetagli">fried</li>
<li class="venuetagli">garlic</li>
<li class="venuetagli">rosemary</li>
<li class="venuetagli">new potatoes</li>
</ul>
and jQuery:
$('.venuetagli').each(function(j,li) {
console.log(j,li)
})

Copying certain levels from an unordered list?

I'm a beginner programmer and I'm stuck with the following problem:
If I have a nested unordered list, how can I copy only the elements up
to a certain level? For example if I want to reduce this unordered list to the first two levels:
<ul>
<li>A</li>
<ul>
<li>C<br>
</li>
<li>D<br>
</li>
<ul>
<li>E<br>
</li>
<li>F<br>
</li>
<ul>
<li>G<br>
</li>
<li>H<br>
</li>
</ul>
</ul>
<li>E<br>
</li>
</ul>
<li>B</li>
</ul>
to
<ul>
<li>A</li>
<ul>
<li>C<br>
</li>
<li>D<br>
</li>
<li>E<br>
</li>
</ul>
<li>B</li>
</ul>
Is there any easy way to achieve this?
Simple version:
$('ul ul ul').remove();
jsFiddle Demo
I also wrote a little function that lets you specify a root element and a level also:
function reduce(root, selector, level) {
var use = root;
for (var i = 0; i <= level; i++) {
use += ' ' + selector;
}
$(use).remove();
}
Use by calling:
//if the lists are in an element with the id 'root', see Demo
reduce('#root', 'ul', 2);
​
jsFiddle Demo
This should be something like $('ul ul ul').remove(), but you'd better enclose it in for example div with id or class so you can do local purge $('div.twolvls ul ul ul').remove()
If you're simply removing 3rd level unordered lists, you could use $(ul ul ul).remove().

Categories

Resources