How to find number of <ul> inside each div - javascript

I have a large file of this form [similar div's throughout]. I want to be able to select a div, find the number of ul's in it and traverse through each of them to get value of each li in it.
<div class="experiment">
<div class="experiment-number">5</div>
<ul class="data-values">
<li><div></div> 14</li>
<li><div></div> 15</li>
</ul>
<ul class="data-values">
<li><div></div> 16</li>
</ul>
</div>
I have tried looping through all experiment divs, then select the uls, but it selects all the ul in the page, not only the ones under current div.
$('experiment ul').eq('$i');

Your HTML is currently incorrect, since you're simply starting new <div> and <ul> elements rather than closing the existing ones. Ignoring that because it's trivial to fix, we'll move on to the real issue.
You need to select all of the <div class="experiment"> elements, then iterate through them. To do that you can use the .each() function. It might look something like this:
var experiments = $('.experiment'); // all of them
experiments.each(function(i, val) { // will iterate over that list, one at a time
var experiment = $(this); // this will be the specific div for this iteration
console.log("Experiment: " + experiment.find('.experiment-number').text());
// outputs the experiment number
console.log("Experiment ULs: " + experiment.find('ul').length);
// number of <ul> elements in this <div>
var total = 0;
experiment.find('ul.data-values li').each(function() {
total += parseInt($(this).text(), 10);
});
console.log("Experiment total: " + total);
// outputs the total of the <li> elements text values
});
Take a look at this jsFiddle demo.

to get all the ul inside div.experiment
var ul = $('.experiment').find('ul');
and to get all li elements inside each ul found above
ul.each(function(list) {
var li = $(list).find('li');
});

$('.experiment').each(function() {
var cnt = $(this).children('ul').length;
$(this).find('.experiment-number').text(cnt);
});

First of all you need to work out the correct selector for each DIV.
The selector you want is:
".experiment"
Notice the . to denote a class selector.
This will allow you access to each DIV element. If you then want to loop though each of these, you can do so like this:
$(".experiment").each(function(){
var div = $(this);
var elementsInThisDiv = div.find("ul");
//you now have a list of all UL elements in the current DIV only
var numberOfElements = elementsInThisDiv.length;
//you now have a count of UL elements belonging to this DIV only
//you can loop the UL elements here
$(elementsInThisDiv).each(function(){
var ul = $(this);
//do something with the UL element
//like get the LI elements...
var liElements = ul.find("li");
});
});
IMPORTANT: There is also an error with your HTML, you need to close your <ul> elements correctly using </ul>

Related

Append an item to a list that is stored in a variable with JS/jQuery

I have this variable:
item = "<li>TEXT<ul class='sublist'></ul></li>";
Now I want to add <li>s to the sublist <ul>.
Something like
item.('.sublist').append('<li>Sublist item 1</li>');
This code, of course, does not work. How should the code like like?
Later I want to add this item to a list:
$('#order-list').append(item);
Easy, if you add the element to the DOM first:
let item = $("<li>TEXT<ul class='sublist'></ul></li>");
$(item).find('ul').append('<li>Sublist item 1</li>');
Note, this element does not show up anywhere on the page because it has not been appended to an in-view element.
The drawback, of-course, is that it is no longer a string.
Since item is not an html element, you may first transform it to html then insert the desired html there:
item = "<li>TEXT<ul class='sublist'></ul></li>";
parsed = $.parseHTML(item); // or, you may simply used $(item)
parsed.find('ul').append('<li>Sublist item 1</li>');
And if you want it back to string:
parsed.prop('outerHTML')
Ah, you want this:
Later I want to add this item to a list:
$('#order-list').append(item);
Then, why don't you simply create element like:
sublist = '<li>Sublist item 1</li>';
$('<li />', {
html: 'TEXT<ul class="sublist">'+sublist+'</ul>'
}).appendTo('#order-list');
You need to either add that Item to the dom, or if it is already in the dom just select the item and use appendChild.
This example it is already apart of the dom
let li = document.createElement('li')
li.textContent = 'Sublist item 1'
document.querySelector('.sublist').appendChild(li)
<ul>
<li>TEXT
<ul class='sublist'></ul>
</li>
</ul>
We can use innerHTML and pass a string instead of creating an element, but then we can't append things to the ul.
document.querySelector('.sublist').innerHTML = '<li>Sublist item 1</li>'
<ul>
<li>TEXT
<ul class='sublist'></ul>
</li>
</ul>
This example we add it to the dom (for simplicity I'm just adding it to the body):
let item = '<ul><li>TEXT<ul class="sublist"></ul></li></ul>'
document.body.innerHTML = item
let li = document.createElement('li')
li.textContent = 'Sublist item 1'
document.querySelector('.sublist').appendChild(li)
There is also a way To do that in one line of code .. using .end()
var item = "<li>TEXT<ul class='sublist'></ul></li>";
item = $(item).find('.sublist').append('<li>Sublist item 1</li>').end().prop('outerHTML');
$('#order-list').append(item);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="order-list"></ul>
Explanation
var item = "<li>TEXT<ul class='sublist'></ul></li>";
item = $(item)
.find('.sublist') // find the sub list
.append('<li>Sublist item 1</li>') // append li
.end() // return to the item parent li
.prop('outerHTML'); // get outer html
$('#order-list').append(item); // append to the oreder list
Your variable is not a DOM element. It is a string. In order to create a DOM element you have to either use document.createElement("ul") or since you are using jQuery use $("<ul class="sublist"></ul>). Then append the list items. The first one can seem like more work because jQuery abstracts most of the DOM manipulation away.
var item = $("<ul class="sublist"></ul>");
//And then
$(item).append("<li>Sublist item 1</li>");
Then you can append that to the DOM.
$(body).append(item);
A pattern that I use to do similar things:
create an array of the items you'd like to append
var fruits = ["apple", "orange", "banana"]
get a reference to a DOM element
var myList = document.querySelector("#myList")
use innerHTML, map, and join to wrap an unordered list around your mapped elements and inject it into your DOM reference
myList.innerHTML = '<ul>' +
items.map(fruit => '<li>' + fruit + '</li>')
.join('') + '</ul>'

jQuery, count number of dynamicly added <li> in <ul>

I have a list of LI in a UL, they are all dynamically added via jQuery. I am trying to alert the number of LI in this list. Right now I can only get it to alert 0. I think it is because its trying to count the original number on load? here is my code and fiddle:
https://jsfiddle.net/ts7Lwbfs/1
<ul id="list">
<li>original</li>
</ul>
var familly = []
familly.push('<li>1</li>');
familly.push('<li>2</li>');
familly.push('<li>3</li>');
familly.push('<li>4</li>');
$('#list').prepend(familly);
$('#list').on('click', 'li', function(ev){
var howMany = $('#list').length;
alert(howMany);
});
How can I get it to alert the total number of LI after they are dynamically added?
The selector $('#bet_slip') matches an element with the ID bet_slip, and as ID's are unique jQuery doesn't expect there to be more than one, and as none of your elements have that ID, you get zero?
Seems like what you want is to count the number of LI's in the #list list
$('#list').on('click', 'li', function(ev){
var howMany = $('#list li').length;
alert(howMany);
});
FIDDLE
Note that this counts all LI's currently present, including the one that was there originally.
If you are trying to find only the count of newly added li ( excluding the original ) , you can filter the li and exclude the first one using :not:first expression.
$('#list').on('click', function(ev){
var howMany = $(this).find('li:not(:first)').length;
alert(howMany);
});
https://jsfiddle.net/DinoMyte/ts7Lwbfs/4/
You can count the total number of list items this way:
$('#list').on('click', function(){
var howMany = $('#list li').length;
alert(howMany);
});
To get the number of added list items, first capture the count of original list items before you add new ones, and then subtract the total in your function from the original count.
var originalCnt = $('#list li').length;
$('#list').prepend(familly);
$('#list').on('click', function(){
var howMany = $('#list li').length - originalCnt;
alert(howMany);
});
Fiddle Demo

Hide same elements in a list

I have a problem I want to solve with jQuery. In a list, I want to check if two items have the same text, and if so I want to delete the second one.
I am not really sure how to go about it.
The markup is simple, kinda like this
<ul>
<li>Text1</li>
<li>Text2</li>
<li>Text1</li>
<li>Text3</li>
<li>Text3</li>
<li>Text4</li>
<ul>
I cannot use an active/inactive class because this list is dynamic and I don't know in advance how it's going to be populated.
Any idea?
$.inArray for a tmp array would work.
$(document).ready(function(){
var tmparr = [];
$('.list li').each(function(i,item){
if($.inArray($(this).text(), tmparr) >= 0){
$(this).remove();
}else{
tmparr.push($(this).text());
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list">
<li>Text1</li>
<li>Text2</li>
<li>Text1</li>
<li>Text3</li>
<li>Text3</li>
<li>Text4</li>
<ul>
You can achieve this e.g. like this:
var unique = {};
$('li').each(function() {
var txt = $(this).text();
if (unique[txt])
$(this).remove();
else
unique[txt] = true;
});
Fiddle
As explanation: unique is initialized as object. While each() iterates over all li elements, the if (unique[txt]) is true in case it was previously set to true for the text of the li currently processed. In this case the current li will be removed. If not, unique[txt] for the text of the current li is set to true and added to unique. As it might not be clear what unique finally contains: { Text1=true, Text2=true, Text3=true, Text4=true }
You will need to iterate over your li elements and store their text in an array. If the text for the ith element is already in the array, skip it. Once you have an array of unique text strings, remove all li elements and generate new ones from the information in your array.
http://jsfiddle.net/k255o52e/1/
$('ul li').each(function () {
var txt = $(this).text();
// finds all LI that contain the same text
// excludes the first element
var $li = $('li:contains("' + txt + '"):not(:first)');
// and removes the other
$li.remove();
})
UPDATE:
$('ul li').each(function () {
var txt = $(this).text();
var $li = $('li:contains("' + txt + '"):not(:first)').filter(function(index)
{
return $(this).text() === txt;
});
$li.remove();
})

DOM Manipulation

Newbie question - Is this code eloquent enough to create four list items? or Should I be using documentFragment instead? The code seems to work fine - JsFiddle.
Created list and li variables
var list = document.getElementById("myList");
var li = null;
Created x number of list elements and companion text nodes
for(var i=1; i<=4; i++){
var li = document.createElement("li");
li.appendChild(document.createTextNode("Number " + i));
Add li to list
list.appendChild(li);
}
Based entirely on the JSFiddle demo you've provided: No. What you currently have is semantically incorrect. You're currently appending your li to the body, not the ul element:
<ul></ul>
<li>Number 1</li>
Change:
document.body.appendChild(li);
To:
list.appendChild(li);
JSFiddle demo.
As for the code you've provided in the question, you also need to change it so that your li elements get appended to your ul element. You also need to change your class into an ID, as getElementById("myList") pulls an element with an ID of "myList", whereas your current ul has no such ID.
Actually there is an error, because you're adding the lis to the body instead of the ul
also the markup is not well created, change
<ul class="myList"></ul>
with
<ul id="myList"></ul>
To use an id and then:
var list = document.getElementById("myList");
var li = null;
for(var i=1; i<=4; i++){
var li = document.createElement("li");
li.appendChild(document.createTextNode("Number " + i));
//document.body.appendChild(li); **error here**
list.appendChild(li); //fix
}

Whether particular li with a specific text exists inside a ul using JQUERY

I have a code
like
<ul id="uploadedfiles">
<li>
A_001
</li>
<li>
B_001
</li>
</ul>
Now i want to insert a new li but i want to check that something that whether a li with a text say A_ exist in that ul. If it exists than remove the older and add the new li.
Say if i add C_001 it is added with no issue
But if i add A_002 then it replace the A_001 with A_002.
Please provide the code for the same if possible.
Any help is appreciated!
Added:
The real data in li have text like control20_a.jpg , control21_b.jpg .....
Then when adding a new li say control20_c.jpg the code must replace control20_a.jpg. But add a new li if it does not exists
This is probably not very idiomatic jQuery, but it seems to do the job.
Working Example
var add = function(entry) {
var match = $('#uploadedfiles li:contains(' + entry.slice(0, entry.indexOf('_')) + ')');
if (match.length > 0) {
match.text(entry);
} else {
$('#uploadedfiles').append($('<li>' + entry + '</li>'));
}
}
I would add a class to the li (like <li class="a"> and <li class="b">
When adding the new LI i would strip the first char of the name and find the LI
If no li, I would create it else change the innerHTML for the new one.
Good luck
UPDATE:
if the elements are from 001 to 002 etc you could do
$("ul li").each(function() {
var firstChar = $(this).text().substring(0,1);
var removeElms = $("ul li:contains('"+firstChar+"'):not(:last)");
removeElms.remove();
});

Categories

Resources