1

I have to do a small calculation using values from form fields with the use of javascript. The formula for the calculation is below:

totalIncome = income1 + income2 *0.7 + income3/48 + (income4 * 0.7)/48;

The values of income1, income2, income3 and income4 can be zero and the fields can be empty.

My code is below:

 <tr id="row">
  <td>No. of Dependant(s)</td>
  <td><input type="text" id="income1" value=""></td>
  <td><input type="text" id="income2" value=""></td>
  <td><input type="text" id="income3" value=""></td>
  <td><input type="text" id="income4" value=""></td>
  <td><input type="text" id="totalIncome" readonly></td>
</tr>

The formular script I have used for my formula is below:

var income1 = document.getElementById("income1");
var income2 = document.getElementById("income2");
var income3 = document.getElementById("income3");
var income4 = document.getElementById("income4");
var totalIncome = document.getElementById("totalIncome");

var inputs = Array.prototype.slice.call(document.querySelectorAll("td > input"));

inputs.forEach(function(input){

  input.addEventListener("blur", function(){
    // Always supply the second argument to parseInt() (the radix) so you
    // dont' get non-base 10 answers.
    totalIncome.value = parseInt(income1.value, 10) + parseInt(income2.value, 10)* 0.7  + parseInt(income3.value, 10)/48 + (parseInt(income4.value, 10)*0.7)/48;


  });

});

However, I am not sure why the totalIncome will become NaN when some of the fields are empty.

Angelos Chalaris
  • 6,611
  • 8
  • 49
  • 75
xhinvis
  • 201
  • 4
  • 15

4 Answers4

5

You can use ||0 in combination with your parseInt() call to make sure that the returned value is always a number and, in the case of empty <input> field, a 0.

var income1 = document.getElementById("income1");
var income2 = document.getElementById("income2");
var income3 = document.getElementById("income3");
var income4 = document.getElementById("income4");
var totalIncome = document.getElementById("totalIncome");

var inputs = Array.prototype.slice.call(document.querySelectorAll("td > input"));

inputs.forEach(function(input) {

  input.addEventListener("blur", function() {
    totalIncome.value =
      (parseInt(income1.value, 10) || 0) +
      (parseInt(income2.value, 10) || 0) * 0.7 +
      (parseInt(income3.value, 10) || 0) / 48 +
      ((parseInt(income4.value, 10) || 0) * 0.7) / 48;
  });
});
<table>
  <tr id="row">
    <td>No. of Dependant(s)</td>
    <td><input type="text" id="income1" value=""></td>
    <td><input type="text" id="income2" value=""></td>
    <td><input type="text" id="income3" value=""></td>
    <td><input type="text" id="income4" value=""></td>
    <td><input type="text" id="totalIncome" readonly></td>
  </tr>
</table>

Update

After OP asked for it, you can display toFixed(2), slightly altering the calculation for totalIncome.value like so:

totalIncome.value = (
  (parseInt(income1.value, 10) || 0) +
  (parseInt(income2.value, 10) || 0) * 0.7 +
  (parseInt(income3.value, 10) || 0) / 48 +
  ((parseInt(income4.value, 10) || 0) * 0.7) / 48).toFixed(2);
Angelos Chalaris
  • 6,611
  • 8
  • 49
  • 75
3

As is described here

An integer number parsed from the given string. If the first character cannot be converted to a number, NaN is returned.

So you need to specify default value (e.g. 0) if it returns null. Use parseInt(income.value || 0) may help.

var income1 = document.getElementById("income1");
var income2 = document.getElementById("income2");
var income3 = document.getElementById("income3");
var income4 = document.getElementById("income4");
var totalIncome = document.getElementById("totalIncome");

var inputs = Array.prototype.slice.call(document.querySelectorAll("td > input"));

inputs.forEach(function(input){

  input.addEventListener("blur", function(){
    // Always supply the second argument to parseInt() (the radix) so you
    // dont' get non-base 10 answers.
    totalIncome.value = parseInt(income1.value || 0, 10) 
                + parseInt(income2.value || 0, 10)* 0.7 
                + parseInt(income3.value || 0, 10)/48 
                + (parseInt(income4.value || 0, 10)*0.7)/48;

  });

});
<table>
<tr id="row">
    <td>No. of Dependant(s)</td>
  <td><input type="text" id="income1" value=""></td>
  <td><input type="text" id="income2" value=""></td>
  <td><input type="text" id="income3" value=""></td>
  <td><input type="text" id="income4" value=""></td>
  <td><input type="text" id="totalIncome" readonly></td>
</tr>
</table>
Yongfeng
  • 666
  • 7
  • 22
2

Just provide a default value when the value in textbox is NaN.

var income1 = document.getElementById("income1");
var income2 = document.getElementById("income2");
var income3 = document.getElementById("income3");
var income4 = document.getElementById("income4");
var totalIncome = document.getElementById("totalIncome");

var inputs = Array.prototype.slice.call(document.querySelectorAll("td > input"));

inputs.forEach(function(input){
  input.addEventListener("blur", function(){
    // Always supply the second argument to parseInt() (the radix) so you
    // dont' get non-base 10 answers.
    totalIncome.value = (parseInt(income1.value, 10) || 0) + (parseInt(income2.value, 10) || 0 )* 0.7  + (parseInt(income3.value, 10)|| 0)/48 + ((parseInt(income4.value, 10) || 0 )*0.7)/48;

  console.log(totalIncome.value);
  });

});
<table>
<tr id="row">
  <td>No. of Dependant(s)</td>
  <td><input type="text" id="income1" value=""></td>
  <td><input type="text" id="income2" value=""></td>
  <td><input type="text" id="income3" value=""></td>
  <td><input type="text" id="income4" value=""></td>
  <td><input type="text" id="totalIncome" readonly></td>
</tr>
</table>
Hassan Imam
  • 21,956
  • 5
  • 41
  • 51
1

From: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/parseInt

An integer number parsed from the given string. If the first character cannot be converted to a number, NaN is returned.

You should convert empty values to default values, before attempting to use them in parseInt.

As well as validating the result from parseInt, before using it in the math expression, in case you want to show an error for bad values.

Ryan Leach
  • 4,262
  • 5
  • 34
  • 71