Javascript foreach loop on list items - javascript

I have a basic HTML list like below...
<ul class="test_ul">
<li class="item" id="item1">
Item 1
</li>
<li class="item" id="item2">
Item 2
</li>
<li class="item" id="item3">
Item 3
</li>
<li class="item" id="item4">
Item 4
</li>
</ul>
I am using javascript to try and grab the id of each list item and then use a loop to check each one against a string. I have this so far..
var myvariable
myvariable = "item2"
items = document.getElementsByClassName("item");
for (i = 0; i < items.length; i++) {
console.log(i);
console.log(item[i]);
}
This isn't working for me, is it because it is not really an array?

You're logging the index i, instead, use items[i].id to get the id of the matched element. Something like this
var items = document.getElementsByClassName("item");
for (i = 0; i < items.length; i++) {
console.log(items[i].id);
}
<ul class="test_ul">
<li class="item" id="item1">
Item 1
</li>
<li class="item" id="item2">
Item 2
</li>
<li class="item" id="item3">
Item 3
</li>
<li class="item" id="item4">
Item 4
</li>
</ul>

You could borrow Array#map for an array like object and return just the id property of the objects.
var result = [].map.call(document.getElementsByClassName("item"), function(o) {
return o.id;
});
console.log(result);
<ul class="test_ul">
<li class="item" id="item1">Item 1</li>
<li class="item" id="item2">Item 2</li>
<li class="item" id="item3">Item 3</li>
<li class="item" id="item4">Item 4</li>
</ul>

My understanding is, you want to loop through this list of items and find a match of the item based on a specified string.
What you've done so far with the classes is good. This will allow you to reference all the list items, but there isn't really a need for the IDs based on what I think it is that you're trying to do.
If I were you, I would utilize a querySelectorAll, which returns an iterable array of HTML nodes that we can do whatever we want with.
Here's my code.
let listItemArray = document.querySelectorAll('.item');
console.log(listItemArray);
const SEARCH_STRING = 'Item 1'
for(let i=0; i<listItemArray.length; i++) {
if(listItemArray[i].innerText === SEARCH_STRING) {
console.log(`The item was found! ${listItemArray[i]}`); // This syntax is called a query string. Powerful stuff. Look them up.
}
}
<ul class="test_ul">
<li class="item" id="item1">
Item 1
</li>
<li class="item" id="item2">
Item 2
</li>
<li class="item" id="item3">
Item 3
</li>
<li class="item" id="item4">
Item 4
</li>
</ul>

Add ID ="lstUsers" to ul element < you're registered with DOM now
for (var i = 0; i < lstUsers.children.length; i++) {
alert( lstUsers.children[i].innerText);
}
#lstUsers <--css with your id you shrink your HTML down this way...

While all of the answers here are equally good, and this qs is old(2017)
I am posting this for knowledge sharing
We can use:
items = document.querySelectorAll(".item");//Get items
items.forEach(function(item) {
console.log(item);/*Use variable item for any need*/
});
If you need the index of item as well then use
items = document.querySelectorAll(".item");//Get items
items.forEach(function(item,index) {
console.log(item, index);/*Use variable item & index for any need*/
});
The best of this is that it doesn't need any loop or extra variable like i. Also, it do not make use of a loop like for or while, but a function like forEach(), where forEach is a human-readable word
Note: forEach() cannot be used with getElementsByClassName() ,it supports only querySelectorAll()
Working snippet:
items = document.querySelectorAll(".item");//Get items
items.forEach(function(item) {
console.log(item);/*Use variable item for any need*/
});
console.log("The below log is with index");
items = document.querySelectorAll(".item");//Get items
items.forEach(function(item,n) {
console.log(n,item);/*Use variable item for any need*/
});
<ul class="test_ul">
<li class="item" id="item1">Item 1</li>
<li class="item" id="item2">Item 2</li>
<li class="item" id="item3">Item 3</li>
<li class="item" id="item4">Item 4</li>
</ul>

Using ES6 (might need to transpile or add polyfills for older browsers):
// Get the DOMCollection of node corresponding to the item class
var items = document.getElementsByClassName("item")
// Transform the DOMCollection to an array and map item.id
, ids = Array.from(items).map(item => item.id);
;
console.log(ids);
<ul class="test_ul">
<li class="item" id="item1">
Item 1
</li>
<li class="item" id="item2">
Item 2
</li>
<li class="item" id="item3">
Item 3
</li>
<li class="item" id="item4">
Item 4
</li>
</ul>
Using ES5 only:
var items = document.getElementsByClassName("item")
, ids = []
;
for(var i = 0, c = items.length; i<c; i++) {
ids.push(items[i].id);
}
console.log(ids);
<ul class="test_ul">
<li class="item" id="item1">
Item 1
</li>
<li class="item" id="item2">
Item 2
</li>
<li class="item" id="item3">
Item 3
</li>
<li class="item" id="item4">
Item 4
</li>
</ul>

Related

JavaScript or jQuery compare two ordered lists using data-attribute

I want to be able to compare two lists using data attribute in either Javascript or jQuery. I can't find an example of this anywhere and don't know how to go about it.
The first list is static and the second list is sortable. Once the user sorts the lists in the right order, [data-compare 1 to 4] in both lists, they click a button to check if they got the matches correct.
There are examples of setting the correct order 1 to X in a single list, but, none I can find to compare two lists.
The basic HTML:
<ul>
<li data-compare="1">Bananas</li>
<li data-compare="2">tomatoes</li>
<li data-compare="3">carrots</li>
<li data-compare="4">dates</li>
</ul>
<ul>
<li data-compare="1">Tree</li>
<li data-compare="4">Palm tree</li>
<li data-compare="2">Bush</li>
<li data-compare="3">In the ground</li>
</ul>
If an ordered list has data-compare attributes with the values 1, 2, 3, 4, you can just check if the the value of the data-compare is identical to the list item's index + 1:
function checkOrdered(list) {
return Array.from(list).every((item, i) => item.getAttribute('data-compare') == (i + 1));
}
console.log(checkOrdered(document.querySelectorAll('#list1 > li')));
console.log(checkOrdered(document.querySelectorAll('#list2 > li')));
<ul id="list1">
<li data-compare="1">Tree</li>
<li data-compare="4">Palm tree</li>
<li data-compare="2">Bush</li>
<li data-compare="3">In the ground</li>
</ul>
<ul id="list2">
<li data-compare="1">Tree</li>
<li data-compare="2">Bush</li>
<li data-compare="3">In the ground</li>
<li data-compare="4">Palm tree</li>
</ul>
You can do the same thing using another list as the compare basis:
function checkOrdered(list1, list2) {
return Array.from(list1).every((item, i) =>
item.getAttribute('data-compare') === list2[i].getAttribute('data-compare'));
}
const src = document.querySelectorAll('#src > li');
const target1 = document.querySelectorAll('#target1 > li');
const target2 = document.querySelectorAll('#target2 > li');
console.log(checkOrdered(src, target1));
console.log(checkOrdered(src, target2));
<ul id="src">
<li data-compare="1">Bananas</li>
<li data-compare="2">tomatoes</li>
<li data-compare="3">carrots</li>
<li data-compare="4">dates</li>
</ul>
<ul id="target1">
<li data-compare="1">Tree</li>
<li data-compare="4">Palm tree</li>
<li data-compare="2">Bush</li>
<li data-compare="3">In the ground</li>
</ul>
<ul id="target2">
<li data-compare="1">Tree</li>
<li data-compare="2">Bush</li>
<li data-compare="3">In the ground</li>
<li data-compare="4">Palm tree</li>
</ul>
You can first get two arrays with data-compare values and then use every method to check if each element is the same in both arrays.
const getData = arr => {
return arr.map(function() {
return $(this).attr('data-compare')
}).get();
}
const l1 = getData($('ul:nth-of-type(1) li'))
const l2 = getData($('ul:nth-of-type(2) li'))
const check = l1.every((e, i) => l2[i] == e);
console.log(check)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li data-compare="1">Bananas</li>
<li data-compare="2">tomatoes</li>
<li data-compare="3">carrots</li>
<li data-compare="4">dates</li>
</ul>
<ul>
<li data-compare="1">Tree</li>
<li data-compare="4">Palm tree</li>
<li data-compare="2">Bush</li>
<li data-compare="3">In the ground</li>
</ul>

Append array to a class in javascript

I have an array in javascript called menuElm that has <ul> elements in it:
<ul id="1"></ul>
<ul id="2"></ul>
<ul id="3"></ul>
I have a page in HTML that has the following:
<ul id="menu">
<li class="menu-item"></li>
<li class="menu-item"></li>
<li class="menu-item"></li>
</ul>
I want to add the elements of menuElm to the HTML page so it would look like this:
<ul id="menu">
<li class="menu-item">
<ul id="1"></ul>
</li>
<li class="menu-item">
<ul id="2"></ul>
</li>
<li class="menu-item">
<ul id="3"></ul>
</li>
</ul>
I have tried the following, but the <ul> elements just wont show up in the page nor in the code:
function CreateMenu() {
var menuElm;
var k = 0;
menuElm = createElm("ul");
menuElm.id = ++k;
for (var i = 0; i < menuElm.length; ++i) {
document.getElementsByClassName("menu-item")[i].appendChild(menuElm[i]);
}
}
I am new with JavaScript, what am I doing wrong?
menuElm.length
The ul element doesn't have a length, so you are looping from 0 to 0, which is 0 iterations.
menuElm = createElm("ul");
This function isn't defined. You need document.createElement('ul');
menuElm = createElm("ul");
menuElm.id = ++k;
You appear to be creating one list item, and then changing its ID and appending it multiple times.
You need a new list item each time you go around the loop.
appendChild(menuElm[i]);
You've been treating menuElm as an element previously. It isn't an array, [i] makes no sense here.
$("#menu").find('li').each(function(i){
$(this).append(menuElm[i]);
});
/* if you want to use jquery here is the code to append */

How to get all decendant li of ul even under another ul

how can i get "all" attr("class") of li under ul#div and return it as array with out repeating same value of class?
<ul id="div">
<li class="a"></li>
<li class="aa">
<ul id="set">
<li class="aa1"></li>
<li class="aa2"></li>
</ul>
</li>
<li class="aaa"></li>
<li class="aaa"></li>
<li class="aaa"></li>
<li class="a"></li>
</ul>
im looking for return like this:
return class in array(a,aa,aa1,aa2,aaa)
Get all <li> descendants of <ul> that have a class attribute, make it into a standard array, then get classes of each one.
var classes = $('ul li[class]').toArray().map(function(el) { return el.className });
console.log(classes);
<!-- results pane console output; see http://meta.stackexchange.com/a/242491 -->
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="div">
<li class="a"></li>
<li class="aa">
<ul id="set">
<li class="aa1"></li>
<li class="aa2"></li>
</ul>
</li>
<li class="aaa"></li>
<li class="aaa"></li>
<li class="aaa"></li>
<li class="a"></li>
</ul>
With pure JavaScript, you could do something like this
var node = document.getElementById("div");
var children = node.childNodes;
var output = [];
for (var i = 0; i < children.length; i++)
{
if (typeof children[i].className !== "undefined")
output.push(children[i].className);
}

How to get the prev and next elements of a particular class which are not siblings

Here is my code :
<ul>
<li class="active">
<div class="course_video_heading"><span class="minus"></span> Introduction <div class="course_duration" align="right">1m 21s</div></div>
<ul>
<li class="course_video viewed">
Welcome <div class="course_duration" align="right">1m 21s</div>
</li>
<li class="course_video viewed">
I need to select this <div class="course_duration" align="right">1m 21s</div>
</li>
</ul>
</li>
<li>
<div class="course_video_heading"><span class="plus"></span> Warm up <div class="course_duration" align="right">1h 15m</div></div>
<ul>
<li class="course_video viewed current">
Roll down <div class="course_duration" align="right">57s</div>
</li>
<li class="course_video">
Roll down with demi pointe variation <div class="course_duration" align="right">57s</div>
</li>
<li class="course_video" data-file="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" data-image="http://content.bitsontherun.com/thumbs/nPripu9l-480.jpg">
Side roll down <div class="course_duration" align="right">57s</div>
</li>
<li class="course_video">
Side roll down variation with contraction <div class="course_duration" align="right">57s</div>
</li>
<li class="course_video">
Class exercise <div class="course_duration" align="right">57s</div>
</li>
</ul>
</li>
<li>
<div class="course_video_heading"><span class="plus"></span> Brushes <div class="course_duration" align="right">1h 5m</div></div>
<ul>
<li class="course_video">
Welcome <div class="course_duration" align="right">1m 21s</div>
</li>
</ul>
</li>
</ul>
My requirement : There is a element, <li class="course_video viewed current">, I need the previous li which has course_video class. In this case it would be :
<li class="course_video viewed">
I need to select this <div class="course_duration" align="right">1m 21s</div>
</li>
What have I tried :
$(".current").prev(".course_video")
This is not working as it is in different li
Note : It is not the duplicate of following questions :)
jQuery to find nearest Div of Parent
Getting next closest select element with jquery
jquery find closest previous sibling with class
Try this : read the index of current li and if it is 0 then find the previous li of its parent li and then find the course_video. And if index is not 0, then find previous li using prev()
var index = $(".current").index();
if(index==0)
{
var previousLi = $(".current").closest('li').prev('li').find("li.course_video:last");
}
else
{
var previousLi = $(".current").prev(".course_video");
}
var vindex;
$().ready(function () {
$("li .course_video").each(function (index) {
if ($(this).hasClass('current')) {
vindex = index;
}
});
$("li .course_video").each(function (index) {
if (index == vindex - 1) {
alert($(this)[0].outerHTML);
}
});
});
this code will help you.
$('.current').parents('li').prev().find('li:last')
Here's the jsFiddle
You can do it easily with a function that checks the index of the item: if the index is 0 then you'll select the last li in the previous ul.
Element.prototype.previousLi = function() {
var i = $(this).index(),
n = this.parentElement.previousSibling.children.length;
if (i) return this.parentElement.children[i-1];
else return this.parentElement.previousSibling.children[n-1];
}
Then you can do:
var el = $(".course_video.viewed.current")[0];
var previous = el.previousLi();
Try this code , it will give you the desired result :
<script>
var currentLI = $("li.current");
prevLi=$(currentLI).parent('ul').parent('li').prev('li').find('li.viewed:last');
alert($(prevLi).html());
</script>

Looking for elements with specific depth in JavaScript

I need to write a function in pure JavaScript witn no framework to get all specific tags, but only from first level under parent.
For example: I need to call some function on first <ul> and get all <li> from first level of it (<li> with text 1.2 and <li> with text 2.1)
<div id="sideNavigation">
<ul>
<li class=" act open ">
1.2
<ul>
<li class=" ">
1.2
<ul>
<li class=" ">
1.3
<ul>
<li class=" ">1.4</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li class=" ">
2.1
<ul>
<li class=" ">2.2.1</li>
<li class=" ">2.2.2</li>
<li class=" ">2.2.3</li>
</ul>
</li>
</ul>
</div>
I've been trying to do it like this:
var allLi = document.getElementById("sideNavigation").getElementsByTagName("li");
but it returns all <li> in this div not only first level <li>. Do you have any quick method to solve my problem or do I have to implement a new function to detect depth of nodes
You can use the attribute .children to get those "li"
var firstDepthLi = document.getElementById("sideNavigation").children[0].children;
If you want a generic function you can create something like:
var getElementsByDepth = function(el, tagname, depth) {
var children = el.children;
var res = new Array();
for(var i=0; i<children.length; i++) {
if (children[i].tagName == tagname) {
res.push(children[i]);
if (depth > 0)
res.concat(getElementsByDepth(children[i], tagname, depth-1));
}
}
return res;
}
Try:
var allLi = document.getElementById("sideNavigation").getElementsByTagName("li")[0];
That should return the first li element out of all li's on the page. Change the zero at the end to a different number to get a different element. You could even set a variable for the value:
var liNum = 0;
var allLi = document.getElementById("sideNavigation").getElementsByTagName("li")[liNum];
And in a function:
function getLi(depth) {
var specificLi = document.getElementById("sideNavigation").getElementsByTagName("li")[depth];
return specificLi;
}
var firstLi = getLi(0);
console.log(firstLi);
<div id="sideNavigation">
<ul>
<li>First list tag</li>
<li>Second list tag</li>
<li>Third list tag</li>
</ul>
</div>
And to make the function even shorter, you could just do:
function getLi(depth) {
return document.getElementById("sideNavigation").getElementsByTagName("li")[depth];
}
That should work. :)

Categories

Resources