Get each element's attribute through $.each() - javascript

Trying to do $('div').attr('data', 'ip') through a .each() just returns undefined.
Let's say I have 4 divs
<div class="box" data-ip="ipvalue">content</div>
<div class="box" data-ip="ipvalue">content</div>
<div class="box" data-ip="ipvalue">content</div>
<div class="box" data-ip="ipvalue">content</div>
and I need to iterate each one and get the data-ip value.
My code, it just returns undefined (server, serverObj, are variables).
var serversObj = $('.server');
serversObj.each(function(index, el) {
return $(this).data('ip');
});
What am I doing wrong?

You want to use map if you want to get all of the values of all of the elements
var ips = $(".box") //get all of the elements
.map(
function(){
return $(this).data("ip"); //get the value from the attribute
}
).get(); //returns an Array
Fiddle

Here is what the code should be for the markup sample you gave.
var serversObj = $('.box'),
Ipvals = [];
serversObj.each(function(index, el) {
Ipvals.push( $(this).data('ip'));
});
console.log( Ipvals);
You can also use $.map() to return the same array.

$('.box').each(function(){
console.log($(this).attr('data-ip'));
});

First off, this is totally wrong:
$('div').attr('data', 'ip')
This is setting an attribute called data to a value of "ip", it does nothing involving data attributes. Effectively, you're doing this: <div data='ip'>.
If you want to access a data attribute called data-ip, you want
$('div').data('ip')
If you want to access it for a series of elements, you can't just return it out of a .each loop. That value is discarded. You need to map your input set of elements to a set of outputs:
$('.server').map(function () { return $(this).data('ip') })
This will produce an array that has each element matched by .server's data-ip attribute.

Related

How to get the value of a div using javascript in a foreach loop

I have many divs that were generated in a foreach, and i have to get the value of this divs.
#model Recall
#foreach (var veiculo in Model)
{
<div value="#veiculo.Veiculo.Vin" class="chassi-importado" id="myDiv">
#veiculo.Veiculo.Vin
<i name="icon-remover-um-chassi" class="bx bx-x-circle"></i>
</div>
}
I´ve trying to use the following code in javascript, but i am getting a null value in the list. How can i get the correct value?
let veiculos = [];
$.each($('.chassi-importado'),
function () {
veiculos.push({ vin: $(".chassi-importado").val() });
});
According to documentation https://api.jquery.com/each/ $.each passes index and element params into the callback provided by you but you don't use them. Also, instead of val() you need to use text() to retrieve innerText value. val() is used mostly for inputs.
Here is what you need to do instead:
let veiculos = [];
$.each($('.chassi-importado'),
function (index, element) {
veiculos.push({ vin: $(element).text() });
}
);
Even better would be to utilize map because you are not just traversing through elements but extracting their values.
Here is how you can do this:
let veiculos = $.map($('.chassi-importado'), (el) => $(el).text());

Javascript: Iterate through array and modify items inside the array

I'm trying to set up a function on my page that will iterate through a series of news titles and will strikethrough the title if it contains a specific marker.
The titles are pulled from a WordPress post database and displayed within a <div> with ID="news". Each specific title is a link <a> with class="title".
I am first collecting all the titles into an array so I can iterate through them but for some reason, it doesn't work properly.
My code is:
<script type="text/javascript">
//first I create the array
var test_DOM = document.getElementById("news").getElementsByClassName("title");
//then I set the marker
var marker = "[X]"
//then I wirte the function to iterate through the array://
function checkX() {
for(i in test_DOM){
if (i.includes(marker)) {
i = "<del>", i, "</del>";
console.log(test_DOM[i], "changed")
}
console.log(test_DOM[i].innerHTML)
}
};
//and I call the function
checkX()
An expected result would be to see the list of news to change from
[x] News 1
[EG] News 2
to
[x] News 1 <- struck through
[EG] News 2 <- still the same
However, nothing happens. I know that getElementsByClassName gets me an array of objects and that I should use .innerHTML and some point, but using it inside the function like
function checkX() {
for(i in test_DOM){
if (i.innerHTML.includes(marker)) {
i.innerHTML = "<del>", i, "</del>";
console.log(test_DOM[i], "changed")
}
console.log(test_DOM[i].innerHTML)
}
};
gives an error of "TypeError: i.innerHTML is undefined"
I think I understand what you're trying to do and have a solution for you. There are a few things that need to be updated to get the script working as you described:
Your DOM query can be shortened using document.querySelectorAll.
When using String.includes(), it is case sensitive. This means that [x] is not equal to [X], so be sure to check the correct version for your test.
As #2pha mentioned in their comment, test_DOM will return a NodeList, which is an array-like structure, but not quite an array. To convert it to an array that can be looped over as you intend, you can use [].slice.call(test_DOM).
As #VLAZ mentioned in their comment, the comma operator will not combine strings. You should use the 'string' + 'string' syntax to combine strings.
Also as #VLAZ mentioned, the for...in loop is more intended for objects, in which it will output the keys of the object, not the values, so this isn't appropriate for your use case. You can use Array.forEach() instead.
As you alluded to, the Array.includes() check should use innerHTML for its check, and innerHTML should be used to then reset the value of the element.
I included a snippet below with some modifications.
var test_DOM = document.querySelectorAll('#news .title');
var marker = '[x]';
function checkX() {
[].slice.call(test_DOM).forEach(function(elem, i) {
if(elem.innerHTML.includes(marker)) {
elem.innerHTML = '<del>' + elem.innerHTML + '</del>';
}
});
}
checkX()
<div id="news">
<h1 class="title">[x] News 1</h1>
<h1 class="title">[EG] News 2</h1>
</div>
Follow on from my comment.
ie. "getElementsByClassName() returns a "NodeList" object, not an array as may be expected". But does have a length property.
The minimal changes to your code to get it to work.
//first I create the array
var test_DOM = document.getElementById("news").getElementsByClassName("title");
//then I set the marker
var marker = "[X]"
//console.log(test_DOM);
//then I wirte the function to iterate through the array://
function checkX() {
for(i = 0; i < test_DOM.length; i++){
if (test_DOM[i].innerHTML.includes(marker)) {
test_DOM[i].innerHTML = "<del>" + test_DOM[i].innerHTML + "</del>";
//console.log(test_DOM[i], "changed")
}
//console.log(test_DOM[i].innerHTML)
}
};
//and I call the function
checkX();
<div id="news">
<h2 class="title">title 1</h2>
<h2 class="title">[X]title 2</h2>
<h2 class="title">title 3</h2>
</div>

convert .each (jquery) to Pure Javascript

I'm trying to convert a function writing on jquery to javascript vanilla
i know that .each() is .forEach() on pure javascript but i dont understand what i'm missing with my code !
here the jquery code :
addClickItems: function(classe) {
$(classe).each(function (index) {
$(classe + ":eq(" + (index) + ")").click(function () {
if (classe === ".droite") {
});
});
},
and here the javascript code :
clickImages : function (classe) {
//classe = new Object(diaporama);
Object.keys(classe).forEach(index => {
classe[index].addEventListener("click", function () {
});
});
},
thanks for help !
The jQuery.each() method enumerates all the individual DOM elements that are contained within the jQuery wrapped set of elements that you call it on:
$("div").each(function(index, value){
console.log(index, value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="one">one</div>
<div id="two">two</div>
<div id="three">three</div>
Your attempt at conversion goes to using Object.keys(class).forEach, where Object.keys is not a set of elements, but keys/properties of an Object.
var myObj = {
key1: 10,
key2: true,
key3: "foo"
};
Object.keys(myObj).forEach(function(key, index){
console.log(index, key, myObj[key]);
});
So, the two uses of each are not analogous.
If you do indeed have DOM elements to enumerate, you need to get them into a JavaScript array and then you can call .forEach() on that array.
NOTE 1: Most modern browsers allow you to call .forEach on node lists/HTML Collections directly, but for compatibility with those browsers that do not, you need to convert the node list/HTML Collection into an array to be sure that the code will work. This is shown below.
NOTE 2: Be mindful that the callback function you pass to jQuery.forEach() is, itself, passed two arguments: index and value, where for the vanilla JavaScript Array.forEach(), the callback is passed value and index (reversed order).
var elements = document.querySelectorAll("div"); // Get all the elements into a node list
var elArray = Array.prototype.slice.call(elements); // Convert node list to array
// Now, enumerate the array with .forEach()
elArray.forEach(function(value, index){
console.log(index, value);
});
<div id="one">one</div>
<div id="two">two</div>
<div id="three">three</div>
In the original code classe appears to be a jQuery selector. You need to use document.querySelectorAll() to search for all the matching elements and iterate over that:
document.querySelectorAll(classe).forEach(elt => elt.addEventListener("click", function() {
...
});

Read html's elements attributes like an array?

I'm thinking for develop a web component form, so... I was wondering my self if it's possible read attributes from a html elements. For example:
<my-component input="3" data-input='"name", "address", "email"' textarea="1" data-textarea='"mensaje"'></my-component>
<script>
while i <= elementattributes.length{
elementattributes[i]
}
</script>
I know that I can access through .getAttribute, but this way will take more code... I just want to be something smart :P
Sorry, my english is poor... I hope you can understand what I want to do :P
:)
If you want to get all of the attributes and their values, you can do something like this:
function getElementAttrs(el) {
var attributes = [].slice.call(el.attributes);
return attributes.map(function(attr) {
return {
name: attr.name,
value: attr.value
}
});
}
var allAttrs = getElementAttrs(document.querySelector('my-component'));
console.log(allAttrs);
<my-component input="3" data-input='name,address,email' textarea="1" data-textarea='"mensaje"'></my-component>
The function getElementAttrs returns an array of objects to you with attribute name-value pairs as keys on the object so that you can loop over it, or just pull by key.
You can use dataset to get specific data attribute
var data = document.querySelector('my-component').dataset.input.split(',');
data.forEach(function(e) {
console.log(e)
})
<my-component input="3" data-input='name,address,email' textarea="1" data-textarea='"mensaje"'></my-component>
If you want to return all attributes from element you can use attributes which return array-like object, but you can create object with name-value from that
var data = document.querySelector('my-component').attributes, attr = {};
Array.from(data).forEach(function(e) {
attr[e.name] = e.value;
});
console.log(attr['data-input']);
<my-component input="3" data-input='name,address,email' textarea="1" data-textarea='mensaje'></my-component>
You can just use .attributes:
document.getElementById("ELEMENT_ID").attributes
This will return an object containing each attribute with its associated value. You can then index the attributes array for specific attributes and use .value for it's corresponding value.

Calling in multiple attributes

still quite new to jQuery / Javascript and am struggling a little.
I have created an attribute called catno that I have assigned to several links. Then I want all instances inside banner-1 to be called into another link separated by a comma. i.e
New Link
I'm just struggling in making this happen. The code I have right now only returns the first catno.
Any help would be great!
JSFIDDLE
<div id="banner-1>
New Link
</div>
$sd('.buy-outfit').attr('href', function() {
return $sd("#banner-1 .add-catno").attr('catno') + ',';
});
Fiddle Demo
var arr_catno = $("#banner-1 a").map(function () { //create array using .map
return $(this).attr('catno'); // add element attribute catno to array
}).get().join(); //use .join() to get comma separated string of array
$('.new-link').attr('href', arr_catno); //assign it to href
.map()
Updated after OP's Comment
Fiddle Demo
$('[id^=banner-] .new-link').attr('href', function () {
return $(this).parent().find('a').map(function () {
return $(this).attr('catno');
}).get().join();
});
Attribute Starts With Selector [name^="value"]
.parent()
.find()
[id^=banner-] --> select all the elements with id starting with banner-
Use $.map to produce an array of catnos and them join them into a string.
$('.new-link').attr('href', function() {
return $.map($(".add-catno"), function (el) {
return $(el).data('catno');
}).join(',');
});
Note in the example that I've changed the catnos attributes to data attributes. Using data is considered good practice for when you want to add arbitrary data to your HTML.
Fiddle

Categories

Resources