Alec
Alec

Reputation: 9575

Receiving NaN when trying to make calculations using numbers retrieved from textboxes in JS

I am trying to make a simple calculator in javascript. Whenever I click the add, subtract, multiply, or divide buttons, however, I get the result NaN. I know that the numbers are successfully retrieved, however, because I am able to alert(input1, input2) if I put that code in. I don't understand why it doesn't let me operate on the two variables, however. I do not receive any errors in the JS console.

<!DOCTYPE html>
<html lang="en">

<head>
  <title>Calculator</title>
  <link rel="stylesheet" href="calculator.css" />
  <script>
    var input1, input2

    function getNumbers() {
      input1 = Number(document.getElementById("imp1").value);
      input2 = Number(document.getElementById("imp2").value);
    }

    function sum(input1, input2) {
      getNumbers();
      var sum = input1 + input2;
      alert(sum);
    }

    function diff(input1, input2) {
      getNumbers();
      var diff = input1 - input2;
      alert(diff);
    }

    function prod(input1, input2) {
      getNumbers();
      var prod = input1 * input2;
      alert(prod);


    }

    function quot(input1, input2) {
      getNumbers();
      var quot = input1 / input2;
      alert(quot);
    }
  </script>


  <div id="calc">
    <form name="calc_input">
      <input type="text" id="imp1" />
      <input type="text" id="imp2" />
      <!-- buttons -->
      <button onclick="sum()" id="add" value="sum">Add</button>
      <button onclick="diff()" id="subtract" value="diff">Subtract</button>
      <button onclick="prod()" id="multiply" value="prod">Multiply</button>
      <button onclick="quot()" id="divide" value="quot">Divide</button>

    </form>
  </div>

</head>

</html>

Upvotes: 0

Views: 1262

Answers (2)

Rajesh
Rajesh

Reputation: 24935

function sum(input1, input2) { This is causing issue.

Here params will take precedence over global variable and as you are not passing any value, they will remain undefined and hence NaN

All you have to do is remove these arguments as you wish to use global variables.

<!DOCTYPE html>
<html lang="en">

<head>
  <title>Calculator</title>
  <link rel="stylesheet" href="calculator.css" />
  <script>
    var input1, input2

    function getNumbers() {
      input1 = Number(document.getElementById("imp1").value);
      input2 = Number(document.getElementById("imp2").value);
    }

    function sum() {
      getNumbers();
      var sum = input1 + input2;
      alert(sum);
    }

    function diff() {
      getNumbers();
      var diff = input1 - input2;
      alert(diff);
    }

    function prod() {
      getNumbers();
      var prod = input1 * input2;
      alert(prod);


    }

    function quot() {
      getNumbers();
      var quot = input1 / input2;
      alert(quot);
    }
  </script>


  <div id="calc">
    <form name="calc_input">
      <input type="text" id="imp1" />
      <input type="text" id="imp2" />
      <!-- buttons -->
      <button onclick="sum()" id="add" value="sum">Add</button>
      <button onclick="diff()" id="subtract" value="diff">Subtract</button>
      <button onclick="prod()" id="multiply" value="prod">Multiply</button>
      <button onclick="quot()" id="divide" value="quot">Divide</button>

    </form>
  </div>

</head>

</html>

Alternate approach

  • You can remove global variables and return an array of numbers from getNumbers. By making a generic pattern to fetch inputs using a composite selector and not IDs, you can add/remove any number of inputs.
  • You can have a generic function that will process the inputs as structure for all are same.
  • Accept operator and process accordingly.

function getNumbers() {
  var inputs = document.querySelectorAll('form[name="calc_input"] input[type="text"]');
  var nums = [];
  for(var i = 0; i< inputs.length; i++){
    nums.push(Number(inputs[i].value))
  }
  return nums;
}

function operate(operator){
  var nums = getNumbers();
  var result = nums.reduce(function(p,c){
    switch(operator){
      case "+": return p+c;
      case "-": return p-c;
      case "*": return p*c;
      case "/": return p/c
    }
  })
  alert(result);
}
<div id="calc">
  <form name="calc_input">
    <input type="text" id="imp1" />
    <input type="text" id="imp2" />
    <!-- buttons -->
    <button onclick="operate('+')" id="add" value="sum">Add</button>
    <button onclick="operate('-')" id="subtract" value="diff">Subtract</button>
    <button onclick="operate('*')" id="multiply" value="prod">Multiply</button>
    <button onclick="operate('/')" id="divide" value="quot">Divide</button>
  </form>
</div>

Upvotes: 2

Milan Parekh
Milan Parekh

Reputation: 163

You have to pass your all variable into integer.. it display now as a string thats why its not calculate as you want.here is code you may check...

<!DOCTYPE html>
<html lang="en">

<head>
  <title>Calculator</title>
  <link rel="stylesheet" href="calculator.css" />
  <script>


    function sum(input1, input2) {
      input1 = Number(document.getElementById("imp1").value);
  input2 = Number(document.getElementById("imp2").value);
      var sum = parseInt(input1) + parseInt(input2);
      alert(sum);
    }


  </script>


  <div id="calc">
    <form name="calc_input">
      <input type="text" id="imp1" />
      <input type="text" id="imp2" />
      <!-- buttons -->
      <button onclick="sum()" id="add" value="sum">Add</button>
      <button onclick="diff()" id="subtract" value="diff">Subtract</button>
      <button onclick="prod()" id="multiply" value="prod">Multiply</button>
      <button onclick="quot()" id="divide" value="quot">Divide</button>

    </form>
  </div>

</head>

</html>

Upvotes: 0

Related Questions