0

in my class we are using firstChild.nodeValue to display text if a user enters in an incorrect value. However, I can't get my two other fields to display the error message and only the first one. What am I doing wrong? When I run it in the code snipped is says that the nodeValue is null. I have the error messages display through a span and they are being used by the firstChild.nodeValue.

var $ = function (id) {
    return document.getElementById(id);
}
var calculateClick = function () {
    var investment = parseInt( $("investment").value);
    var rate = parseFloat( $("rate").value);
    var years = parseInt($("years").value);

    //var amount = interest * rate * years;
    if (investment==="" || investment < 100 || investment > 100000){ 
     $("investment_error").firstChild.nodeValue="Must be an integer from 100 - 100,000";
    } 
    
    
    else if (rate ==="" || rate <0.1 || rate >12){
     $("rate_error").firstChild.nodeValue="Must be a value from .1 - 12";
    } 
    

    else if (years ==="" || years <1 || years > 50){
     $("years_error").firstChild.nodeValue="Must be an integer from 1 - 50";
    } 

    var nt = 4*years;
    var amount = investment * (1 + (rate/4)) ** nt;

    $("future_value").value=amount.toFixed(2);
    
}
var clear_fields = function (){
 $("investment").value="";
 $("rate").value="";
 $("years").value="";
 $("future_value").value="";
}
window.onload = function () {
    $("calculate").onclick = calculateClick;
    $("calculate").ondblclick=clear_fields;
    $("investment").focus();
}
body {
    font-family: Arial, Helvetica, sans-serif;
    background-color: white;
    margin: 0 auto;
    width: 48%;
    padding: 0 1em .5em;    
    border: 3px solid blue;
}
h1 {
 margin: .5em 0;
    text-align: center;
}
label {
 float: left;
    width: 10em;
    text-align: right;
    padding-bottom: .5em;
}
input {
    margin-left: 1em;
    margin-bottom: .5em;
}
span {
    color: blue;
}
<!DOCTYPE html>
<html>
 <head>
  <title>Future Value Calculator</title>
     <link rel="stylesheet" href="future_value.css">
     <script src="future_value.js"></script>
</head>

<body>
 <main>
        <h1 id="heading">Future Value Calculator</h1>
        
        <label for="investment">Investment Amount:</label>
        <input type="text" id="investment">
        <span id="investment_error"> </span><br>
        
        <label for="rate">Annual Interest Rate:</label>
        <input type="text" id="rate">
        <span id="rate_error"></span><br>
        
        <label for="years">Number of Years:</label>
        <input type="text" id="years">
        <span id="years_error"></span><br>
        
        <label for="future_value">Future Value:</label>
        <input type="text" id="future_value" disabled="disabled"><br>
        
        <label>&nbsp;</label>
        <input  type="button" id="calculate" value="Calculate"><br>
    </main>
</body>
</html>
Sébastien
  • 11,860
  • 11
  • 58
  • 78
the_crouton
  • 53
  • 1
  • 8
  • possible duplicate of https://stackoverflow.com/questions/3977636/javascript-nodevalue-returns-null – john_h Mar 29 '18 at 19:47
  • Why are you not just setting the textContent of the span?? What is the difference in your code? Whitespace – epascarello Mar 29 '18 at 19:49

3 Answers3

0

$("rate_error").firstChild returns null because it has no childrne (not even whit space), and so does not have a nodeValue property.

You could just use innerHTML instead of firstChild.nodeValue.

Also you don't need the else, just tell the user immediately all they have to fix.

var $ = function(id) {
  return document.getElementById(id);
}
var calculateClick = function() {
  var investment = parseInt($("investment").value);
  var rate = parseFloat($("rate").value);
  var years = parseInt($("years").value);

  //var amount = interest * rate * years;
  if (investment === "" || investment < 100 || investment > 100000) {
    $("investment_error").innerHTML = "Must be an integer from 100 - 100,000";
  }

  if (rate === "" || rate < 0.1 || rate > 12) {
    $("rate_error").innerHTML = "Must be a value from .1 - 12";
  }

  if (years === "" || years < 1 || years > 50) {
    $("years_error").innerHTML = "Must be an integer from 1 - 50";
  }

  var nt = 4 * years;
  var amount = investment * (1 + (rate / 4)) ** nt;

  $("future_value").value = amount.toFixed(2);

}
var clear_fields = function() {
  $("investment").value = "";
  $("rate").value = "";
  $("years").value = "";
  $("future_value").value = "";
}
window.onload = function() {
  $("calculate").onclick = calculateClick;
  $("calculate").ondblclick = clear_fields;
  $("investment").focus();
}
body {
  font-family: Arial, Helvetica, sans-serif;
  background-color: white;
  margin: 0 auto;
  width: 48 %;
  padding: 0 1em .5em;
  border: 3px solid blue;
}

h1 {
  margin: .5em 0;
  text-align: center;
}

label {
  float: left;
  width: 10em;
  text-align: right;
  padding-bottom: .5em;
}

input {
  margin-left: 1em;
  margin-bottom: .5em;
}

span {
  color: blue;
}
<!DOCTYPE html>
<html>

<head>
  <title>Future Value Calculator</title>
  <link rel="stylesheet" href="future_value.css">
  <script src="future_value.js"></script>
</head>

<body>
  <main>
    <h1 id="heading">Future Value Calculator</h1>

    <label for="investment">Investment Amount:</label>
    <input type="text" id="investment">
    <span id="investment_error"> </span><br>

    <label for="rate">Annual Interest Rate:</label>
    <input type="text" id="rate">
    <span id="rate_error"></span><br>

    <label for="years">Number of Years:</label>
    <input type="text" id="years">
    <span id="years_error"></span><br>

    <label for="future_value">Future Value:</label>
    <input type="text" id="future_value" disabled="disabled"><br>

    <label>&nbsp;</label>
    <input type="button" id="calculate" value="Calculate"><br>
  </main>
</body>

</html>
Sébastien
  • 11,860
  • 11
  • 58
  • 78
0

Its working on the first span becouse you have space between the span tags as:

with space

<span id="investment_error"> </span>

without

<span id="rate_error"></span>

In any case you should use innerHTML instead.

first child is good in case you already have a child in the html tags like this

<div>
    <p id="i_am_div_first_child"> first child</p>
</div>

please hit correct answer if that was helpfull.

Goor Lavi
  • 412
  • 3
  • 16
0

So what is the difference? A simple test will show you why.

console.log("1:", document.querySelector("#s1").firstChild)
console.log("2:", document.querySelector("#s2").firstChild)
<span id="s1"> </span>
<span id="s2"></span>

The one has a whitespace in it, the others do not the one with the whitespace has a firstChild, the others do not.

What should you do? I would just set the textContent or innerHTML of the span and not set the nodeValue.

And another issue with your code, is you have

var rate = parseFloat( $("rate").value);

and

if ( rate==="")

That empty string check is not going to happen to be true ever since parseFloat is going to return NaN.

epascarello
  • 204,599
  • 20
  • 195
  • 236