0

I'm trying to multiply 2 numbers and i get NaN as result, why?

function myFunction() {
  var x = document.getElementsByClassName("input1").value;
  var y = document.getElementsByClassName("input2").value;
  var result = x * y;
  document.getElementById("results").innerHTML = result;
}
<input type="text" class="input1">
<input type="text" class="input2">
<button onclick="myFunction()">Submit</button>
<br>
<p id="results">Results</p>
j08691
  • 204,283
  • 31
  • 260
  • 272
  • Because the value of an `input` is a string, not a number (NaN). And `getElementsByClassName()` gets a list of elements, not just one, which doesn't have a value in the first place. You have to convert those values to numbers first. – Scott Marcus Jul 18 '17 at 14:36
  • 3
    A few seconds with a debugger will work wonders. Check the values of `x` and `y` before you multiply them. – Raymond Chen Jul 18 '17 at 14:37
  • 1
    There are several answers, so more of a troubleshooting tip: did you try any `console.log` statements to investigate? `console.log(foo)` and `console.log(typeof foo)` might be useful starting points. – shabs Jul 18 '17 at 14:37
  • just from seeing a few oversimplified comments / answers: the `input` value being of type `string` doesn't necessarily mean that the value will be `NaN`, the values are implicitly converted to `number` during the operation so if the input contains a string that is not a number, then `NaN` will be the value, i.e. `"2" * "2" = 4` but `"2" * "2a" = NaN` – Patrick Barr Jul 18 '17 at 14:45

7 Answers7

1

Because when using getElementsByClassName you get an array-like object returned and need to specify the element similar to the way you specify the index of an array element, e.g. getElementsByClassName("input1")[0] . If you were using a unique identifier, like an ID, then you wouldn't need to worry about that.

Try:

function myFunction() {
  var x = document.getElementsByClassName("input1")[0].value;
  var y = document.getElementsByClassName("input2")[0].value;
  var result = x * y;
  document.getElementById("results").innerHTML = result;
}
<input type="text" class="input1">
<input type="text" class="input2">
<button onclick="myFunction()">Submit</button>
<br>
<p id="results">Results</p>
j08691
  • 204,283
  • 31
  • 260
  • 272
1

It's because getElementsByClassName doesn't return an HTML object like jQuery, it returns an HTML collection(array like), and you have to use document.getElementsByClassName("input1")[0] to access the element:

function myFunction() {
  var x = document.getElementsByClassName("input1")[0].value;
  var y = document.getElementsByClassName("input2")[0].value;
  var result = x * y;
  document.getElementById("results").innerHTML = result;
}
<input type="text" class="input1">
<input type="text" class="input2">
<button onclick="myFunction()">Submit</button>
<br>
<p id="results">Results</p>

Document.getElementsByClassName(): Returns an array-like object of all child elements which have all of the given class names. When called on the document object, the complete document is searched, including the root node. You may also call getElementsByClassName() on any element; it will return only elements which are descendants of the specified root element with the given class names.

You can read more about this here.

Ionut Necula
  • 11,107
  • 4
  • 45
  • 69
0

You are using getElementsByClassName which return a collection. You need to refer the 0 index to get it's value. Else you can use id attribute

function myFunction() {
  var x = document.getElementsByClassName("input1")[0].value;
  var y = document.getElementsByClassName("input2")[0].value;
  var result = x * y;
  document.getElementById("results").innerHTML = result;
}
<input type="text" class="input1">
<input type="text" class="input2">
<button onclick="myFunction()">Submit</button>
<br>
<p id="results">Results</p>
brk
  • 48,835
  • 10
  • 56
  • 78
0

Your problem is because document.getElementsByClassName returns an array. If you want to add together the values of 2 specific text boxes you're much better referring to them by unique IDs. I've changed the inputs to have unique id attributes, and the code to use document.getElementById which returns a single element uniquely identified by its ID.

function myFunction() {
  var x = document.getElementById("input1").value;
  var y = document.getElementById("input2").value;
  var result = x * y;
  document.getElementById("results").innerHTML = result;
}
<input type="text" id="input1">
<input type="text" id="input2">
<button onclick="myFunction()">Submit</button>
<br>
<p id="results">Results</p>
ADyson
  • 57,178
  • 14
  • 51
  • 63
  • @OrlandoReynoso no problem. If it helps please remember to upvote and/or mark as accepted answer - thanks :-) – ADyson Jul 18 '17 at 15:30
0

This is because document.getElementsByClassName("input1").value; returns a string/text value. Which makes this var result = x * y; impossible since you cannot perform arithmetic operations on text. To solve this problem do this little manipulation

var x = parseInt(document.getElementsByClassName("input1").value);
  var y = parseInt(document.getElementsByClassName("input2").value);
  var result = x * y;
  document.getElementById("results").innerHTML = result;
Lekens
  • 1,823
  • 17
  • 31
0

If you are trying to get a single element, then getElementsByClassName is not the correct method to call because it returns a "live" node list of elements, which is excessive, even in situations where you do want a list of elements.

Instead, since your input elements can be individually identified by the different classes they each use, querySelector() is the correct way to get your hands on each of them, individually.

Additionally, don't use inline HTML event handling attributes (onclick, etc.), here's why.

Now, even when you do get your hands on just the individual elements in question, all HTML elements contain just one type of data, strings. You must convert those strings into numbers before doing math on them.

// Get a reference to the button
var btn = document.getElementById("calc");

// Set up a click event handler for the button
btn.addEventListener("click", myFunction);

function myFunction() {
  // Get just the single elements you need and then trim any leading
  // or trailing spaces off of the user's input and then convert that
  // input into a number:
  var x = parseFloat(document.querySelector(".input1").value.trim());
  var y = parseFloat(document.querySelector(".input2").value.trim());
  var result = x * y;
  
  // Don't use innerHTML when you are suppling HTML as the value
  // use textContent instead. This will perform better.
  document.getElementById("results").textContent = result;
}
<input type="text" class="input1">
<input type="text" class="input2">
<button id="calc">Calculate</button>
<br>
<p id="results">Results</p>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
-2

You are trying to multiply two string. Do this

function myFunction() {
  var x = parseInt(document.getElementsByClassName("input1").val());
  var y = parseInt(document.getElementsByClassName("input2").val());
  var result = x * y;
  document.getElementById("results").innerHTML = result;
}
Mutasim Fuad
  • 606
  • 2
  • 12
  • 31
  • 2
    Isn't `val()` a jQuery method? – shabs Jul 18 '17 at 14:39
  • you missed the fact that document.getElementsByClassName returns an array not a single object. and .val() only works on jQuery objects. At least test your code before you post it. For HTML/JS stuff you can even use the snippet feature right within your answer to make it easy :-) – ADyson Jul 18 '17 at 14:40