I have several divs that looks like this:
<div class='popupDiv' data-layergroup='layer1'>divcontent 1</div>
<div class='popupDiv' data-layergroup='layer1'>divcontent 2</div>
<div class='popupDiv' data-layergroup='layer2'>divcontent 3</div>
<div class='popupDiv' data-layergroup='layer2'>divcontent 4</div>
I'm a bit stumped as to how to loop through all popupDiv divs, and then loop through each layergroup separately. I want to end with a single array for each layergroup. I'd need something like:
var mainArray = [];
$('.popupDiv').each(function(){
var tempArray = [];
$([unique layer value]).each(function(){
// Put div values from layergroup in tempArray
});
mainArray.push(tempArray);
});
return mainArray;
But I don't know the syntax I'm looking for. What do I do?
<div class='popupDiv' data-layer='layer1'></div>
<div class='popupDiv' data-layer='layer1'></div>
<div class='popupDiv' data-layer='layer2'></div>
<div class='popupDiv' data-layer='layer2'></div>
Loop through the elements
$('.popupDiv[data-layer]').each(function(){
});
to loop through each group seperately, you can use below logic
//create an array to store processed data-layer type
var dataArray = new Array();
$('.popupDiv').each(function(){
var dataLayer = $(this).data('layer');
//check if data-layer already processed
if(!dataArray.indexOf(dataLayer))
{
//update data array
dataArray.push(dataLayer);
$('.popupDiv[data-layer="'+ dataLayer +'"]').each(function(){
//do your stuff here
});
}
});
You can loop through each of the div having attribute 'data-layer' as follows:
$('.popupDiv').each(function(i) {
if ($(this).attr('data-layer') == 'layer' + i + 1) {
$(this).each(function() {
alert($(this).attr('data-layer'));
//change this to whatever you want
});
}
});
So this will check for 'layer1', 'layer2' and so on.
You do not need two each loops here. You can use Has Attribute Selector. you are also having duplicate IDs for divs. IDs should be unique, use class name instead:
$('[data-layergroup]').each(function(){
// Do stuff with each div
console.log($(this).data('layergroup'));//current data layer value
});
For iterating over the values(FYI-BAD APPROACH):
$.each($("[data-layergroup]").map(function() { return $(this).data('layergroup');}).get(), function(index, item) {
// item
});
use class instead of id:
<div class='popupDiv' data-layer='layer1'></div>
<div class='popupDiv' data-layer='layer1'></div>
<div class='popupDiv' data-layer='layer2'></div>
<div class='popupDiv' data-layer='layer2'></div>
Then you can loop each layer seperatly:
for (var i = 1; i <= 2; i++) {
$(".popupDiv[data-layer|='layer"+i+"']").each(function(){
// do stuff with layer i
});
}
Related
think I have some class of same content
<div class="parentclass">
<div class="childClass">
</div>
<div class="childClass">
</div>
<div class="childClass">
</div>
</div>
<div class="parentclass">
<div class="childClass">
</div>
<div class="childClass">
</div>
<div class="childClass">
</div>
</div>
I can get all the parent class object in an array by
var pClassList= document.getElementsByClassName("parentclass");
My question is how can I access the child classes "childClass" from pClassList array calling it index like
var childClassList1= pClassList[0].getElementsByClassName("childClass");
var childClassList2= pClassList[1].getElementsByClassName("childClass");
Simply loop over the initial collection and use index of each iteration to access individual elements
var pClassList= document.getElementsByClassName("parentclass");
for(var i=0; i < pClassList.length; i++){
var parentElement = pClassList[i];
// do something to each parent as needed
// access children of parent element
var childClassList= parentElement.getElementsByClassName("childClass");
// do something with `childClassList`
for (var j= 0; j < childClassList.length; j++){
var child = childClassList[j];
// do something with each child here
}
}
Could be:
var childClassList1= pClassList[0].getElementsByClassName("childClass")[0];
var childClassList2= pClassList[1].getElementsByClassName("childClass")[0];
I prefer to use JQuery, in this case it would be.
var pClassList = $(".parentclass")
var childClassList1 = $(pClassList[0]).children().first()
var childClassList2 = $(pClassList[1]).children().first()
The following will retrieve child nodes with classname="childClass" for the first element in pClassList array:
for (var i = 0; i < pClassList[0].childNodes.length; i++) {
if (pClassList[0].childNodes[i].className == "childClass") {
//Do something with pClassList[0].childNodes[i]
}
}
You can do the same for the rest of the elements in pClassList array by iterating over each of them.
An alternative I think is you select as you want childClass is like :
var childClassList1= document.querySelector('.childClass:nth-child(2)');
So... I have four divs on a page. All four of them belong to the class foobar. What I wanna do here is give each of them a value from a certain Array in JavaScript. Do note I am using jQuery 3.2.1.
My JavaScript:
var $elements = jQuery.makeArray($(".foobar"));
[1,2,3,4].forEach(function (x) {
$elements.forEach(function (y) {
y.text(x.toString());
});
});
My HTML:
<div class="foobar"></div>
<div class="foobar"></div>
<div class="foobar"></div>
<div class="foobar"></div>
And as always, it does not work. Basically what I wanna do here is give each Number in that Array as the text() for each div.
You are setting the same text to every element inside inner loop. Try this
var $elements = $(".foobar");
[1,2,3,4].forEach(function (x, i) {
$($elements[i]).text(x)
});
Or use .text(func)
var texts = [1,2,3,4];
var $elements = $(".foobar").text(function(i) {
return texts[i];
})
Check this fiddle. https://jsfiddle.net/bj3s92gr/
Bassicaly you have to bucle the divs with class foobar, and assing the position of the array in the html.
var $elements = $(".foobar");
$arr = [1,2,3,4];
$elements.each(function(e){
$(this).html($arr[e]);
});
Create an array of numbers, traverse thru all the .foobar elements, and assign a value from the array.
var $elements = jQuery.makeArray($(".foobar"));
var numbers = [1, 2, 3, 4];
var count = 0;
$(".foobar").each(function() {
$(this).text(numbers[count]);
count++;
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
My HTML:
<div class="foobar"></div>
<div class="foobar"></div>
<div class="foobar"></div>
<div class="foobar"></div>
I want to find div element that contain custom attribute mod than append that div to list item. But first I have to remove divs that contain duplicate mod value. Here's what I have done
<div class="list"></div>
<div class="container">
<div mod="dog"></div>
<div mod="man"></div>
<div mod="woman"></div>
<div mod="dog"></div>
<div mod="bird"></div>
<div mod="insects"></div>
<div mod="dog"></div>
</div>
this is my script
modArr($('.container').find('[mod]'))
function modArr(el){
var filterArray = [] // store mod
, modNames = [] // store mod value
, arrIndex = [] // store non duplicate index
, li = [] // store
modArray = el
// store mod value
for(var i=0; i < modArray.length; i++){
modNames.push($(modArray[i]).attr('mod')) // get mod value from div
}
// search for non duplicate mod value and get the index of none duplicate mod
for(var i=0; i < modArray.length; i++){
if(filterArray.indexOf(modNames[i]) === -1){
filterArray.push(modNames[i])
arrIndex.push(i) // push non duplicate index value
}
}
filterArray = [] // reset filterArray
// push module from modArray to filterArray using index in arrIndex
for(var i=0; i < arrIndex.length; i++){
filterArray.push(modArray[arrIndex[i]])
}
// push to li array
$.each(filterArray,function(i,el){
li[i] = '<li>'+ el.outerHTML +'</li>'
})
$('<ul></ul>')
.append(li.join(''))
.appendTo('.list')
}
What you can see is that I've used to many loops, is there any simple way to do this. Thanks!
We can use an object as a map for checking duplicates, see comments (I've added text to the mod divs so we can see them):
modArr($('.container').find('[mod]'));
function modArr(elements) {
// A place to remember the mods we've seen
var knownMods = Object.create(null);
// Create the list
var ul = $("<ul></ul>");
// Loop the divs
elements.each(function() {
// Get this mod value
var mod = this.getAttribute("mod");
// Already have one?
if (!knownMods[mod]) {
// No, add it
knownMods[mod] = true;
ul.append($("<li></li>").append(this.cloneNode(true)));
}
});
// Put the list in the .list element
ul.appendTo(".list");
}
<div class="list"></div>
<div class="container">
<div mod="dog">dog</div>
<div mod="man">man</div>
<div mod="woman">woman</div>
<div mod="dog">dog</div>
<div mod="bird">bird</div>
<div mod="insects">insects</div>
<div mod="dog">dog</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
We can also just use the DOM to check for duplicates, but it's a bit slower (not that it matters for the number of elements here):
modArr($('.container').find('[mod]'));
function modArr(elements) {
// Create the list
var ul = $("<ul></ul>");
// Loop the divs
elements.each(function() {
// Get this mod value
var mod = this.getAttribute("mod");
// Already have one?
if (ul.find('div[mod="' + mod + '"]').length == 0) {
// No, add it
ul.append($("<li></li>").append(this.cloneNode(true)));
}
});
// Put the list in the .list element
ul.appendTo(".list");
}
<div class="list"></div>
<div class="container">
<div mod="dog">dog</div>
<div mod="man">man</div>
<div mod="woman">woman</div>
<div mod="dog">dog</div>
<div mod="bird">bird</div>
<div mod="insects">insects</div>
<div mod="dog">dog</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Note: I used this.cloneNode(true) rather than outerHTML because there's no need to take a roundtrip through markup. If you want more jQuery there, it's $(this).clone(); ;-) Similarly, if you don't like this.getAttribute("mod"), there's $(this).attr("mod").
I'd be remiss if I didn't point out that mod is an invalid attribute name for div elements. You can use any name you want starting with data-, though, so perhaps use <div data-mod="dog"> instead.
Try this, only adds if an element with mod is not already in list:
$('.list').append('<ul>');
$('.container [mod]').each(function(index, el) {
if($('.list [mod=' + $(el).attr('mod') + ']').length === 0) {
$('.list ul').append($('<li>' + el.outerHTML + '</li>'));
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="list"></div>
<div class="container">
<div mod="dog">Dog1</div>
<div mod="man">Man1</div>
<div mod="woman">Woman1</div>
<div mod="dog">Dog2</div>
<div mod="bird">Bird1</div>
<div mod="insects">Insect1</div>
<div mod="dog">Dog3</div>
</div>
Following code produces nothing but an error. I wish to retrieve REL attribute values of each of the DIVs. No idea, why I can'y do it.
Error I see in console: Uncaught TypeError: Object # has no method 'getAttribute'
<div class="boxes">
<div rel="first" class="box">Box 1</div>
<div rel="second" class="box">Box 2</div>
<div rel="third" class="box">Box 3</div>
</div>
<script>
$(function(){
var i = 0;
var allDivs = document.getElementsByClassName('box');
var arr = [];
arr.push(allDivs);
setInterval(function(){
console.log(arr[i].getAttribute('rel'));
i++;
}, 1000);
});
</script>
you're pushing an array (NodeList to be exact) into an array and trying to get the attribute from the NodeList object instead of the individual elements. Try this:
<div class="boxes">
<div rel="first" class="box">Box 1</div>
<div rel="second" class="box">Box 2</div>
<div rel="third" class="box">Box 3</div>
</div>
<script>
$(function(){
var i = 0;
var allDivs = document.getElementsByClassName('box');
var arr = [];
arr.push(allDivs);
setInterval(function(){
console.log(arr[0][i].getAttribute('rel'));
i++;
}, 1000);
});
</script>
By pushing the NodeList into the other array, you are essentially creating this:
var arr = [[<div element 1>, <div element 2>, <div element 3>]];
What you are probably wanting to do is to change your push line to:
arr.push.apply(arr, allDivs);
That will append all the individual elements inside the allDivs collection onto arr. Then you can access arr like you expected before: arr[i].getAttribute('rel') (arr's contents will be [<div element 1>, <div element 2>, <div element 3>];)
Replace the script with this:
$(function(){
var i = 0;
var allDivs = document.getElementsByClassName('box');
//allDivs itself is an array and there is no need to push the result to an array.
setInterval(function(){
console.log(allDivs[i].getAttribute('rel'));
i++;
}, 1000);
});
I am having a bunch of div tags in my html page. Now I need to write a jQuery to calculate the grid's value. In the below example I will be using grid0 as the base id and I want the count in that series which is 1 here.
<div id="grid00">0</div>
<div id="grid01">0</div>
<div id="grid02">0</div>
<div id="grid03">1</div>
<div id="grid04">0</div>
<div id="grid05">0</div>
In another example given below I will be using id's starting with grid1 and the total value is 6. Please guide me!
<div id="grid10">5</div>
<div id="grid11">0</div>
<div id="grid12">0</div>
<div id="grid13">1</div>
<div id="grid14">0</div>
<div id="grid15">0</div>
I tried this jQuery("div[id^='grid0']"). But this is giving me all the elements. But I need the count using the value inside them.
Thanks!
Start by selecting the divs with the starts-with selector and loop through the results and tally up the text values casted to integers.
function GetSum(prefix) {
var sum = 0;
$("div[id^='" + prefix + "']").each(function(){
sum += parseInt($(this).text());
});
return sum;
}
var grid0Total = GetSum("grid0");
var grid1Total = GetSum("grid1");
Or if you wanted to take it a step further with a jQuery function:
jQuery.extend({
gridSum: function(prefix) {
var sum = 0;
if(!!prefix) {
$("div[id^='" + prefix + "']").each(function(){
sum += parseInt($(this).text());
});
}
return sum;
}
});
then you could write:
var grid0Total = jQuery.gridSum("grid0");
var grid1Total = jQuery.gridSum("grid1");
You could also use the map() function like so:
var sum = 0;
$("div[id^='" + prefix + "']").map(function(){
return sum += parseInt($(this).text());
});
return sum;
See them all in action here: http://jsfiddle.net/FpmFW/1/
Try:
function total(idPrefix) {
var total = 0;
$('div[id^="' + idPrefix + '"]').each(function() {
total += parseInt($(this).text());
});
return total;
}
var grid0total = total('grid0'),
grid1total = total('grid1');
See: http://jsfiddle.net/Au8Fr/
I'd give all grid divs one commmon class. Something like this:
<div class="grid" id="myGrids">
<div class="grid" id="grid10">5</div>
<div class="grid" id="grid11">0</div>
<div class="grid" id="grid12">0</div>
<div class="grid" id="grid13">1</div>
<div class="grid" id="grid14">0</div>
<div class="grid" id="grid15">0</div>
</div>
Now you can easily count their values:
var count=0;
$(".grid").each(function(){
count+=parseInt($(this).text())
})
You can loop through all of your grid0X divs like this:
var countOnes = 0;
$('div[id^=grid0]').each(function() {
if ($(this).text() === "1") {
++countOnes;
}
});
That finds all div elements whose ID starts with grid0 (so, grid00, grid01, etc.). The loop counts how many of them contain just the text "1", which is what I think you were after in your question; if not, the loop logic is easily manipulated.
Similarly, for grid1X, just change the selector to use 1 instead of 0.
Alternately, though, if these divs are in some kind of container, you could use a selector to find the container and then loop through its children, e.g.:
HTML:
<div id="grid0">
<div>0</div>
<div>0</div>
<div>0</div>
<div>1</div>
<div>0</div>
<div>0</div>
</div>
JavaScript:
$("#grid0 > div").each(...);
...and avoid having all those IDs.