4

I have some input fields with a specific class. They all have a data attribute, say data-somedata with an integer value. I have to calculate the sum of these data attributes. I tried to use getAttribute in combination with getElementsByClassName, but that doesn't work.

I'm using this code:

<input class="datainput" value="The 1st input" type="text" data-somedata="8"/>
<input class="datainput" value="The 2nd input" type="text" data-somedata="15"/>
<div id="result"></div>
var fields = document.getElementsByClassName('datainput');
var result = 0;
for (var i in fields) {
    result += fields[i].getAttribute('data-somedata');
}
document.getElementById('result').innerHTML = 'The sum is: ' + result;

See it live on jsFiddle

In the (firefox) console, I get:

TypeError: fields[i].getAttribute is not a function

Why is this? And how can I fix it?

I do not want to use jQuery unless absolutely necessary (I don't suppose it is).

4 Answers4

9

Instead of using the for-in statement, use a simple for statement as in:

var fields = document.getElementsByClassName('datainput');
var result = 0;
for (var i = 0; i < fields.length; i ++) {
    var val = parseInt(fields[i].getAttribute('data-somedata'), 10);
    result += val;
}
document.getElementById('result').innerHTML = 'The sum is: ' + result;

Also, the result of getAttribute is a string, you must cast it into an integer using parseInt() before performing an add operation. Otherwise a string concatenation will be performed making your result:

The sum is: 0815

Updated Fiddle

The reason why the for-in statement didn't work is for-in iterates over properties of the target object, which in your case is HTMLCollection(result of getElementsByClassName). In fact, you can make it work with a for-in using this ugly snippet:

var c = 0;

for(var i in fields) {
    if(c == fields.length) break;
    c ++;    
    console.log(fields[i].getAttribute('data-somedata'));
}

The first n = fields.length properties of HTMLCollection are its items' indices.

c.P.u1
  • 16,664
  • 6
  • 46
  • 41
3

Check this:

var fields = document.getElementsByClassName('datainput');
var result = 0;

for (var i = 0; i < fields.length; i++) {        
    result += parseInt(fields[i].getAttribute('data-somedata'));
}
document.getElementById('result').innerHTML = 'The sum is: ' + result;

On jsfiddle

YD1m
  • 5,845
  • 2
  • 19
  • 23
1

As far as the reason, the for-in loop will cycle over all properties of the object, including functions (and inherited properties).

Brett Zamir
  • 14,034
  • 6
  • 54
  • 77
0

<!DOCTYPE html>
<html>
<body>

<h1>HTML DOM Attributes</h1>
<h2>The value Property</h2>
<p>The value property returns the value of an attribute:</p>

<ins class="demo" data-ad-slot="ciao"></ins>
<ins id="demob"></ins>

<script>
const element = document.getElementsByClassName('demo')[0];
let value = element.attributes["data-ad-slot"].value;

document.getElementById("demob").innerHTML = value;
</script>

</body>
</html>
Babbo Natale
  • 81
  • 1
  • 3
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 04 '23 at 12:20