-2

Im trying to convert characters to integers then add them. I have a JS input tag to take in the the text, then convert it to an integer using the parse int. Unfortunately, it gives back NaN when i enter in the value a, which is the only one . have declared right now. Here is my code

<!DOCTYPE HTML>
<html>

<head>
</head>

<body>
   <center>
    <div class="">

     Enter the first number: <input type="text" id="txt1" ><br > 

     Enter the seccond number: <input type="text" id="txt2" ><br > 

     Enter the third number: <input type="text" id="txt3" ><br >

     Enter the fourth number: <input type="text" id="txt4" ><br > 

     Enter the fifth number: <input type="text" id="txt5" ><br >

     Enter the sixth number: <input type="text" id="txt6" ><br >
    </div>
  </center>



  <center><input type="button" onclick="call()" value="Add" > 
  </center> 

  <p id="output"> "Grade 1"</p>

  <script>

    var a = parseInt("4")

    function call() {
        var y = parseInt(document.getElementById("txt1").value);
        var yy = parseInt(document.getElementById("txt2").value);
        var yyy = parseInt(document.getElementById("txt3").value);
        var yyyy = parseInt(document.getElementById("txt4").value);
        var yyyyy = parseInt(document.getElementById("txt5").value);
        var yyyyyy = parseInt(document.getElementById("txt6").value);

        var result = (y + yy + yyy + yyyy + yyyyy + yyyyyy) / 6 ;


        document.getElementById("output").innerHTML = result;
    }

  </script>
</body>
</html>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Jack Maalouf
  • 61
  • 1
  • 8
  • I don't see anywhere in which you do, or could, enter the variable a into your function. It takes no arguments, and it only fishes for data from DOM elements. – CodeAt30 Feb 03 '18 at 19:15
  • 1
    The official specification of JavaScript says that `parseInt("a")` should be NaN. Were you hoping for something else? What would you like to have happen? – Ray Toal Feb 03 '18 at 19:15
  • If the first character cannot be converted to a number, parseInt() returns NaN. Have a look at this example var a = parseInt("10") + "
    "; //10 var b = parseInt("10.00") + "
    "; //10 var c = parseInt("10.33") + "
    "; //10 var d = parseInt("34 45 66") + "
    "; //35 var e = parseInt(" 60 ") + "
    "; //60 var f = parseInt("40 years") + "
    "; //40 var g = parseInt("He was 40") + "
    "; NaN
    – Vicky charanpahari Feb 03 '18 at 19:20
  • This screams for an array or a loop. – Jonas Wilms Feb 03 '18 at 19:42

3 Answers3

2

Your problem is that you're attempting to parse the letter 'a' as a number, which it isn't, instead you could store your value mappings in an object and use the input character as a key to reference the value you want (note this example only has values for 'a', 'b', 'c', other characters, empty strings, numbers, etc. will still cause a NaN):

var values = {
  a: 4,
  b: 5,
  c: 8
}

function call() {
  var y = values[document.getElementById("txt1").value];
  var yy = values[document.getElementById("txt2").value];
  var yyy = values[document.getElementById("txt3").value];
  var yyyy = values[document.getElementById("txt4").value];
  var yyyyy = values[document.getElementById("txt5").value];
  var yyyyyy = values[document.getElementById("txt6").value];
  var result = (y + yy + yyy + yyyy + yyyyy + yyyyyy) / 6;
  document.getElementById("output").innerHTML = result;
}
<center>
  <div class="">
    Enter the first number: <input type="text" id="txt1"/><br/> 
    Enter the seccond number: <input type="text" id="txt2"/><br/> 
    Enter the third number: <input type="text" id="txt3"/><br/>
    Enter the fourth number: <input type="text" id="txt4"/><br/>
    Enter the fifth number: <input type="text" id="txt5"/><br/>
    Enter the sixth number: <input type="text" id="txt6"/><br/>
  </div>
</center>
<center><input type="button" onclick="call()" value="Add" />
</center>
<p id="output"> "Grade 1"</p>

Alternatively, if you wanted to add some error handling and allow numbers to be input as well you could improve the code:

var values = {
  a: 4,
  b: 5,
  c: 8
}

function call() {
  var result = 0
  for(var i = 1; i <= 6; i++) {
    var k = document.getElementById("txt" + i).value;
    if(k in values) {
      result += values[k];
    }else if(!isNaN(document.getElementById("txt" + i).value)){
      result += parseInt(document.getElementById("txt" + i).value);
    }
  }
  document.getElementById("output").innerHTML = result / 6;
}
<center>
  <div class="">
    Enter the first number: <input type="text" id="txt1"/><br/> 
    Enter the seccond number: <input type="text" id="txt2"/><br/> 
    Enter the third number: <input type="text" id="txt3"/><br/>
    Enter the fourth number: <input type="text" id="txt4"/><br/>
    Enter the fifth number: <input type="text" id="txt5"/><br/>
    Enter the sixth number: <input type="text" id="txt6"/><br/>
  </div>
</center>
<center><input type="button" onclick="call()" value="Add" />
</center>
<p id="output"> "Grade 1"</p>
Nick is tired
  • 6,860
  • 20
  • 39
  • 51
1

You can't parse an integer from a number. parseInt() is doing exactly what it should in this case because a is Not A Number.

But, if you set up a simple set of key/value pairs the letter grade can be mapped to a corresponding number.

Also, do all your event handling in JavaScript. Don't use inline HTML event attributes (onclick, etc.) as there are many reasons not to use this ancient (25 years old) technique.

// We will store the possible grades in a simple object for key/value mapping
var grades = {
  a:4,
  b:3,
  c:2,
  d:1
}

// Get all the input elements into an array
var inputs = Array.prototype.slice.call(document.querySelectorAll("input[type=text]"));

// Get a reference to the button
var btn = document.querySelector("input[type=button]");

// Set up your event handler in JavaScript, not in HTML
btn.addEventListener("click", function() {
  var sum = 0;
  // Loop over the inputs
  inputs.forEach(function(input){
     sum += grades[input.value.toLowerCase()] || 0;  
  });
  // As long as there is a sum, go ahead and divide it.
  document.getElementById("output").textContent = sum / 6;
});
<div class="">
  Enter the first grade: <input type="text" id="txt1"><br> 
  Enter the seccond grade: <input type="text" id="txt2"><br> 
  Enter the third grade: <input type="text" id="txt3"><br>
  Enter the fourth grade: <input type="text" id="txt4"><br> 
  Enter the fifth grade: <input type="text" id="txt5"><br>
  Enter the sixth grade: <input type="text" id="txt6"><br>
</div>
<input type="button" value="Add">
<p id="output">"Grade 1"</p>

Now, you'll still have issues with this because what if a user enters z or puts their number grade 100 in? When building user interfaces, we must always assume the user will do something stupid. The best way to solve those issues is to limit the user input to only what is expected. In this case, dropdown lists of acceptable letter grades would work. Or, even better, range controls as shown below:

// We'll set up two arrays with the same amount of elements and
// each position in each array corresponds to the value in the 
// same index position in the other array.
var scores = [4,   3,   2,   1,   0];
var grades = ["a", "b", "c", "d", "f"];

// Get all the sliders elements into an array
var inputs = Array.prototype.slice.call(document.querySelectorAll("input[type=range]"));

// Loop over the sliders and set up event handlers for each
inputs.forEach(function(input){
  input.addEventListener("input", function(){
    input.nextElementSibling.textContent = grades[input.value].toUpperCase();
  });
});

// Get a reference to the button
var btn = document.querySelector("input[type=button]");

// Set up your event handler in JavaScript, not in HTML
btn.addEventListener("click", function() {
  var sum = 0;
  // Loop over the inputs
  inputs.forEach(function(input){
     sum += scores[input.value];  
  });
  // As long as there is a sum, go ahead and divide it.
  document.getElementById("output").textContent = (sum / 6).toFixed(2);
});
.lbl { display:inline-block; width: 15em; }
input + span { display:inline-block; margin-left:1em; }
<div class="">
  <span class="lbl">Enter the first grade:</span><input type="range" min="0" max="4"><span>C</span><br> 
  <span class="lbl">Enter the seccond grade:</span><input type="range" min="0" max="4"><span>C</span><br> 
  <span class="lbl">Enter the third grade:</span><input type="range" min="0" max="4"><span>C</span><br>
  <span class="lbl">Enter the fourth grade:</span><input type="range" min="0" max="4"><span>C</span><br> 
  <span class="lbl">Enter the fifth grade:</span><input type="range" min="0" max="4"><span>C</span><br>
  <span class="lbl">Enter the sixth grade:</span><input type="range" min="0" max="4"><span>C</span><br>
</div>
<input type="button" value="Add">
<p id="output">"Grade 1"</p>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • 1
    I'm pretty sure he wants to access the value of the variable named `a` by typing "a" into the input field – Daniel Feb 03 '18 at 19:26
  • 1
    Yea, thank you daniel for clarifying, this will eventually be a GPA calculator, so i want the user to be able to enter the value a – Jack Maalouf Feb 03 '18 at 19:28
  • @JackMaalouf - Oh NOW we see! You don't want a, b, and c to be variables, you want them to be keys of an object! There is a nice, clean way to do this: use `const grades = {A: 90, B: 80, C:70, D:60, F:0};` Can you take it from here? – Ray Toal Feb 03 '18 at 19:36
  • @JackMaalouf Please see my updated answer for a much simpler solution. – Scott Marcus Feb 03 '18 at 19:40
  • @ScottMarcus This solution also works very well, thank you! – Jack Maalouf Feb 03 '18 at 19:47
  • @JackMaalouf See my updated answer for a second solution that really is the best way to go. – Scott Marcus Feb 03 '18 at 19:58
1

If you are asking the user to enter the name of something in a textbox, and then you want to look up a numeric value associated with that name, then you should be using object properties, not variables to store your data.

For example:

const grades = {A: 4, B: 3, C: 2, D: 1, F: 0};

Then when you get input from a textbox, you look up the value like so:

const y = grades[document.getElementById("txt1")];

If you enter garbage into the text field, you will get NaN.

Consider using radio buttons and save yourself much pain.

Ray Toal
  • 86,166
  • 18
  • 182
  • 232