Krehem Krehem - 12 days ago 5
Javascript Question

parseFloat of input value returns NaN

I'm trying to write a script that dynamically calculates a total from 4 inputs that are editable by the user.

I'm having some trouble when I use parseFloat on my input values. They return as

NaN
.

So far, I've tried using
parseInt
instead of
parseFloat
, used
.val()
instead of
.value
, using
name
attributes instead of
id
attributes, and a couple of other things, that I can't remember off hand.

I haven't seen any other answers to similar questions, that have worked for me yet, so if you wouldn't mind taking a look at my code to see where I might've gone wrong, I'd appreciate it. Thanks!



<!DOCTYPE HTML>

<html>
<head>
<meta charset="utf-8">
<title>Calc</title>
<style>

</style>
</head>

<body>
<table width = "250" border="1">
<tr>
<th align="left">A</th>
<th align="left">B</th>
</tr>
<tr>
<td>Rent</td>
<td id="rent" align="right">
<input type="text" size="7" value="0" onchange="calc()"></td>
</tr>
<tr>
<td>Food</td>
<td id="food" align="right">
<input type="text" size="7" value="0" onchange="calc()"></td>
</tr>
<tr>
<td>Entertainment</td>
<td id="ent" align="right">
<input type="text" size="7" value="0" onchange="calc()"></td>
</tr>
<tr>
<td>Transportation</td>
<td id="trans" align="right">
<input type="text" size="7" value="0" onchange="calc()"></td>
</tr>
<tr>
<th align="left">Total</th>
<td id="total" align="right"></td>
</tr>
</table>
<script>
function calc() {
var w = parseFloat(document.getElementById("rent").value);
var x = parseFloat(document.getElementById("food").value);
var y = parseFloat(document.getElementById("ent").value);
var z = parseFloat(document.getElementById("trans").value);

document.getElementById("total").innerHTML=w+x+y+z;
}
</script>
</body>
</html>




Answer

You were giving your cells (<td> tags) id attributes, rather than your actual input fields.

Moving the id attributes to the input elements solves the issue.

In addition, since your are going to call the calc function repeatedly, it would make more sense to just scan the document once to get the references to the elements you are going to want to use over and over.

Lastly, it's best not to hook your HTML elements up to the JavaScript functions that should fire when an event happens in the HTML itself. You can see in my code snippet how I've removed that from the HTML and put it into the JavaScript.

// Wait until the DOM is fully loaded
window.addEventListener("DOMContentLoaded", function(){
  
   // Declare and initialze variable references to needed elements:
   var wElement = document.getElementById("rent");
   var xElement = document.getElementById("food");
   var yElement = document.getElementById("ent");
   var zElement = document.getElementById("trans");

   // Wire elements to event handlers:
   wElement.addEventListener("change", calc);
   xElement.addEventListener("change", calc);
   yElement.addEventListener("change", calc);
   zElement.addEventListener("change", calc);

   // Event handler:
   function calc() {
         var w = parseFloat(wElement.value);
         var x = parseFloat(xElement.value);
         var y = parseFloat(yElement.value);
         var z = parseFloat(zElement.value);
         
         document.getElementById("total").textContent = w + x + y + z;
   } 
});
<table width = "250" border="1">
      <tr>
        <th align="left">A</th>
        <th align="left">B</th>
      </tr>
      <tr>
        <td>Rent</td>
        <td  align="right">
           <input type="text" id="rent" size="7" value="0"></td>
      </tr>
      <tr>
        <td>Food</td>
        <td  align="right">
           <input type="text" id="food" size="7" value="0"></td>
      </tr>
      <tr>
        <td>Entertainment</td>
        <td  align="right">
           <input type="text" id="ent" size="7" value="0"></td>
      </tr>
      <tr>
        <td>Transportation</td>
        <td  align="right">
           <input type="text" id="trans" size="7" value="0"></td>
      </tr>
      <tr>
        <th align="left">Total</th>
        <td id="total" align="right"></td>
      </tr>
   </table>

Comments