Laura Mewoo
Laura Mewoo

Reputation: 9

Sum numbers in html inputs, Javascript

I am just learning to code, I am at the very beginning. I am trying to code this calculator for my job, I have tried for days, and even researching, I just can't make it work. It's probably the simplest thing ever...I am just in te deepest forest regarding functions! I changed this code so many times I don't even know where I'm at. I'm a mess, help!

function myF() {
  var a = document.getElementById("a").value;
  var b = document.getElementById("b").value;
  var c = document.getElementById("c").value;
  var d = document.getElementById("d").value;
  var e = document.getElementById("e").value;
  var f = document.getElementById("f").value;
  var g = document.getElementById("g").value;
  var h = document.getElementById("h").value;
  var i = document.getElementById("i").value;

  var tot = document.getElementById("result").value = a + b + c + d + e + f + g + h + i;
}
body {
  background: url(img/Construction-Wallpaper-8.jpg) no-repeat center center;
  background-size: 100% 100%;
}

form {
  width: 530px;
  align-content: center;
  margin: 0 auto;
  border: solid 1px darkslategrey;
  padding: 10px 10px 10px 10px;
  display: block;
}

input {
  float: right;
  clear: both;
  position: relative;
  top: -4;
}

label {
  padding: 8px 10px;
  font-family: "Gabriola Regular", arial, sans-serif;
  font-size: 18px;
  font-weight: bolder;
  color: black;
  display: block;
}

input#result {
  position: relative;
  right: 18px;
  top: 6px;
}

button#Total {
  position: relative;
  left: 10px;
  top: 5px;
  background: linear-gradient(to right, darkslategrey, white);
  font-family: "Gabriola Regular", arial, sans-serif;
  font-size: 25px;
  width: 100px;
  height: 30;
  text-align: center;
  text-transform: uppercase;
  box-shadow: 1px 1px 3px;
  border: solid 1px black;
}

button#Total:active {
  position: relative;
  top: 6px;
  cursor: pointer;
}

button#Total:hover {
  cursor: pointer;
}

p#title {
  font-size: 50px;
  text-align: center;
  padding: 16px 0 0 0;
  font-family: "Gabriola Regular", arial, sans-serif;
  color: #333;
  font-weight: bolder
}

img#Logo {
  width: 70px;
  display: inline-block;
  position: absolute;
  top: 8px;
  right: 9px;
}

p#Logo {
  font-family: "Gabriola Regular", arial, sans-serif;
  font-size: 20px;
  display: inline-block;
  width: 50px;
  height: 30px;
  position: absolute;
  top: -10px;
  right: 105px;
}
<p id="title">&#8226; Payment Schedule &#8226;</p>
<div id="companyName">
  <p id="Logo">Christopher Crawford Const.
  </p>
  <img src="img/Logo_Crawford1ps.png" id="Logo">
</div>


<form>
  <label>I.Downpayment 5/14 <input id="a" type="text"></label>
  <label>II.Progress payment end of week2, @15% 5/30<input id="b" type="text"> </label>
  <label>III.Progress payment end of week4, @15% 6/13<input id="c" type="text"></label>
  <label>IV.Progress payment end of week6, @15% 6/27<input id="d" type="text"></label>
  <label>V.Progress payment end of week8, @15% 7/11<input id="e" type="text"></label>
  <label id="f">VI.Progress payment end of week10, @15% 7/25<input id="f" type="text"></label>
  <label>VII.Progress payment end of week11, @7.5% 8/1<input id="g" type="text"></label>
  <label>VIII.Progress payment end of week12, @7.5% 8/8<input id="h" type="text"></label>
  <label>IX.Final Payment @10%<input id="i" type="text"></label>
  <button id="Total" value="Add Numbers" onclick="myF()">Total</button>
  <input type="text" id="result">
</form>

Upvotes: 1

Views: 172

Answers (5)

Yosvel Quintero
Yosvel Quintero

Reputation: 19070

Notice that you have two elements with the same id="f"

Also I suggest a code refactor using Array.prototype.reduce() to get the result and as all the inputs are strings, I have created some methods to check if it is a number.

Code:

document.querySelector('#Total').addEventListener('click', function (e) {
  e.preventDefault();
  const arr = ['a', 'b', 'c', 'd','e', 'f', 'g', 'h', 'i'];
  const getValue = id => !Number.isNaN(+document.querySelector('#' + id).value) 
    ? +document.querySelector('#' + id).value
    : 0;
  const result = arr.reduce((a, c) => a + getValue(c), 0);
  document.querySelector('#result').value = result;
})
form {width: 530px;align-content: center;margin: 0 auto;border: solid 1px darkslategrey;padding: 10px 10px 10px 10px;display: block;}input {float: right;clear: both;position: relative;top: -4;}label {padding: 8px 10px;font-family: "Gabriola Regular", arial, sans-serif;font-size: 18px;font-weight: bolder;color: black;display: block;}input#result {position: relative;right: 18px;top: 6px;}button#Total {position: relative;left: 10px;top: 5px;background: linear-gradient(to right, darkslategrey, white);font-family: "Gabriola Regular", arial, sans-serif;font-size: 25px;width: 100px;height: 30;text-align: center;text-transform: uppercase;box-shadow: 1px 1px 3px;border: solid 1px black;}button#Total:active {position: relative;top: 6px;cursor: pointer;}button#Total:hover {cursor: pointer;}
<p id="title">&#8226; Payment Schedule &#8226;</p>

<form>
  <label>I.Downpayment 5/14 <input id="a" type="text"></label>
  <label>II.Progress payment end of week2, @15% 5/30<input id="b" type="text"> </label>
  <label>III.Progress payment end of week4, @15% 6/13<input id="c" type="text"></label>
  <label>IV.Progress payment end of week6, @15% 6/27<input id="d" type="text"></label>
  <label>V.Progress payment end of week8, @15% 7/11<input id="e" type="text"></label>
  <label>VI.Progress payment end of week10, @15% 7/25<input id="f" type="text"></label>
  <label>VII.Progress payment end of week11, @7.5% 8/1<input id="g" type="text"></label>
  <label>VIII.Progress payment end of week12, @7.5% 8/8<input id="h" type="text"></label>
  <label>IX.Final Payment @10%<input id="i" type="text"></label>
  <button id="Total" value="Add Numbers">Total</button>
  <input type="text" id="result">
</form>

Upvotes: 1

Wild Beard
Wild Beard

Reputation: 2927

Adding Strings vs Integers

When you pull a value from an input with Javascript it is assumed to be a text, or string, value. Even if the text is numeric visually Javascript is going to attempt to concatenate them together as a string.

a = '1', b = '2', c = a+b where c is now 12 instead of 3.

What you can do to avoid this is use parseInt(val). parseInt takes a string input and returns the numeric value of it. If it cannot convert the input to a number it will return NaN or Not a Number.

Your document.getElementById('id').value lines should become parseInt(document.getElementById('id')) or when you go to add them together at the end use parseInt on your variables: parseInt(a) + parseInt(b).

Stoping the Form from Submitting

As other's have mentioned in comments your form is being submitted and taking you to a new page. You can prevent this, like they said, by changing the type on your button to button, <button type="button" onclick="myF()">. Alternatively you can prevent the default submit action with Javascript:

document.getElementById('myForm').addEventListener('submit', myF);

And change your myF declaration to

function myF(event) {
  event.preventDefault(); // Stops the default action for the event from firing
  ..

When assigning a function to an event listener an event parameter is automatically passed in to the function. This is where event comes from even though we didn't specify it in addEventListener.

IDs

In HTML an ID must be unique. You have two f IDs in your example. If you want to bind a label to an input you can use <label for="id"> in this case <label for="f">. If you want to group elements that are similar in style/display use a class. Classes can be applied as many elements on a page.

Don't Repeat Yourself

Is a pretty common practice. Why type document.getElementById(..) 10 times if you don't have to? Assign your inputs you want to sum together a class. If you want a more complex solution follow Yosvel's answer. I'll be taking a bit simpler approach.

var toAdd = document.querySelectorAll('.to-add');
var total = 0;
toAdd.forEach(function(input) {
  if ( !Number.isNaN(input.value) ) {
    total += input.value;
  }
});

querySelectorAll takes in a selector and returns all elements that match. In our case we want all inputs with the class to-add. querySelectorAll returns an NodeList which we can use as an array to loop over with forEach. On each itteration of the loop we check if the input's value is valid (!Number.isNaN) and if it is we add it to our total value.

document.querySelector('#myForm').addEventListener('submit', myF);

function myF(event) {

  event.preventDefault();

  var toAdd = document.querySelectorAll('.to-add');
  var total = 0;

  toAdd.forEach(function(input) {

    if (!Number.isNaN(input.value)) {
      total += Number(input.value);
    }

  });

  document.getElementById('result').value = total;

}
label {
  display: block;
}
<form id="myForm">
  <label>I.Downpayment 5/14 <input class="to-add" type="text"></label>
  <label>II.Progress payment end of week2, @15% 5/30<input class="to-add" type="text" pattern="(\d+)"> </label>
  <label>III.Progress payment end of week4, @15% 6/13<input class="to-add" type="text"></label>
  <label>IV.Progress payment end of week6, @15% 6/27<input class="to-add" type="text"></label>
  <label>V.Progress payment end of week8, @15% 7/11<input class="to-add" type="text"></label>
  <label>VI.Progress payment end of week10, @15% 7/25<input class="to-add" type="text"></label>
  <label>VII.Progress payment end of week11, @7.5% 8/1<input class="to-add" type="text"></label>
  <label>VIII.Progress payment end of week12, @7.5% 8/8<input class="to-add" type="text"></label>
  <label>IX.Final Payment @10%<input class="to-add" type="text"></label>
  <button id="Total" type="submit" value="Add Numbers">Total</button>
  <input type="text" id="result">
</form>

document.getElementById('myForm').addEventListener('submit', myF);

function myF(event) {
  event.preventDefault();
  var a = parseInt(document.getElementById("a").value);
  var b = parseInt(document.getElementById("b").value);
  var c = parseInt(document.getElementById("c").value);
  var d = parseInt(document.getElementById("d").value);
  var e = parseInt(document.getElementById("e").value);
  var f = parseInt(document.getElementById("f").value);
  var g = parseInt(document.getElementById("g").value);
  var h = parseInt(document.getElementById("h").value);
  var i = parseInt(document.getElementById("i").value);

  var tot = document.getElementById("result").value = a + b + c + d + e + f + g + h + i;
}
body {
  background: url(img/Construction-Wallpaper-8.jpg) no-repeat center center;
  background-size: 100% 100%;
}

form {
  width: 530px;
  align-content: center;
  margin: 0 auto;
  border: solid 1px darkslategrey;
  padding: 10px 10px 10px 10px;
  display: block;
}

input {
  float: right;
  clear: both;
  position: relative;
  top: -4;
}

label {
  padding: 8px 10px;
  font-family: "Gabriola Regular", arial, sans-serif;
  font-size: 18px;
  font-weight: bolder;
  color: black;
  display: block;
}

input#result {
  position: relative;
  right: 18px;
  top: 6px;
}

button#Total {
  position: relative;
  left: 10px;
  top: 5px;
  background: linear-gradient(to right, darkslategrey, white);
  font-family: "Gabriola Regular", arial, sans-serif;
  font-size: 25px;
  width: 100px;
  height: 30;
  text-align: center;
  text-transform: uppercase;
  box-shadow: 1px 1px 3px;
  border: solid 1px black;
}

button#Total:active {
  position: relative;
  top: 6px;
  cursor: pointer;
}

button#Total:hover {
  cursor: pointer;
}

p#title {
  font-size: 50px;
  text-align: center;
  padding: 16px 0 0 0;
  font-family: "Gabriola Regular", arial, sans-serif;
  color: #333;
  font-weight: bolder
}

img#Logo {
  width: 70px;
  display: inline-block;
  position: absolute;
  top: 8px;
  right: 9px;
}

p#Logo {
  font-family: "Gabriola Regular", arial, sans-serif;
  font-size: 20px;
  display: inline-block;
  width: 50px;
  height: 30px;
  position: absolute;
  top: -10px;
  right: 105px;
}
<p id="title">&#8226; Payment Schedule &#8226;</p>
<div id="companyName">
  <p id="Logo">Christopher Crawford Const.
  </p>
  <img src="img/Logo_Crawford1ps.png" id="Logo">
</div>


<form id="myForm">
  <label>I.Downpayment 5/14 <input id="a" type="number"></label>
  <label>II.Progress payment end of week2, @15% 5/30<input id="b" type="text" pattern="(\d+)"> </label>
  <label>III.Progress payment end of week4, @15% 6/13<input id="c" type="text"></label>
  <label>IV.Progress payment end of week6, @15% 6/27<input id="d" type="text"></label>
  <label>V.Progress payment end of week8, @15% 7/11<input id="e" type="text"></label>
  <label>VI.Progress payment end of week10, @15% 7/25<input id="f" type="text"></label>
  <label>VII.Progress payment end of week11, @7.5% 8/1<input id="g" type="text"></label>
  <label>VIII.Progress payment end of week12, @7.5% 8/8<input id="h" type="text"></label>
  <label>IX.Final Payment @10%<input id="i" type="text"></label>
  <button id="Total" type="submit" value="Add Numbers">Total</button>
  <input type="text" id="result">
</form>

Upvotes: 2

ramoncs11
ramoncs11

Reputation: 63

You need to import your script file (the file that contains your javascript function "myF" to your html landing page like this:

<script type="text/javascript" src="script.js"></script>

put this line in your inside head tags

your html need look like this:

<form>
    <label >I.Downpayment 5/14 <input id="a" type="text"></label>
    <label >II.Progress payment end of week2, @15% 5/30<input id="b" type="text"> </label>
    <label >III.Progress payment end of week4, @15% 6/13<input id="c" type="text"></label>
    <label >IV.Progress payment end of week6, @15% 6/27<input id="d" type="text"></label>
    <label >V.Progress payment end of week8, @15% 7/11<input id="e" type="text"></label>
    <label >VI.Progress payment end of week10, @15% 7/25<input id="f" type="text"></label>
    <label >VII.Progress payment end of week11, @7.5% 8/1<input id="g" type="text"></label>
    <label >VIII.Progress payment end of week12, @7.5% 8/8<input id="h" type="text"></label>
    <label >IX.Final Payment @10%<input id="i" type="text"></label>        
    <button type="button" id="Total" onclick="myF()">Total</button>
    <input type="text" id="result">
</form>

and your javascript file looks like this:

function myF() {
    var a = parseInt(document.getElementById("a").value);
    var b = parseInt(document.getElementById("b").value);
    var c = parseInt(document.getElementById("c").value);
    var d = parseInt(document.getElementById("d").value);
    var e = parseInt(document.getElementById("e").value);
    var f = parseInt(document.getElementById("f").value);
    var g = parseInt(document.getElementById("g").value);
    var h = parseInt(document.getElementById("h").value);
    var i = parseInt(document.getElementById("i").value);
    var tot = a+b+c+d+e;
    document.getElementById("result").value = tot;
}

parsetInt() is a function that do the trick. This convert your "5" to 5.

Upvotes: 0

skylerfenn
skylerfenn

Reputation: 354

Welcome to coding!

A few things:

1) Your form is submitting (and refreshing the page which loses input data) when you click total. Button elements are a type of "submit" by default. Change the property by adding type="button" to your button. Alternatively, you can also use onsubmit for the action on the form but be sure to use e.preventDefault. With onsubmit, don’t add type="button", onsubmit needs the button type to be submit.

2) You have two "F" ids. On your "VI." label, remove id="f". Remember, ids must be unique within the HTML document.

3) You will likely want to validate your input fields, since you only want numbers.

Upvotes: 2

jcubic
jcubic

Reputation: 66490

The problem you may have is that the value return strings and if you use + it will concatenate them, in order to have sum you need to parse the strings.

You can use trick like +document.getElementById("a").value or parseInt. If the value is float use parseFloat.

function myF() {
  var a = parseInt(document.getElementById("a").value);
  var b = parseInt(document.getElementById("b").value);
  var c = parseInt(document.getElementById("c").value);
  var d = parseInt(document.getElementById("d").value);
  var e = parseInt(document.getElementById("e").value);
  var f = parseInt(document.getElementById("f").value);
  var g = parseInt(document.getElementById("g").value);
  var h = parseInt(document.getElementById("h").value);
  var i = parseInt(document.getElementById("i").value);

  var tot = document.getElementById("result").value = a + b + c + d + e + f + g + h + i;
}

Upvotes: 2

Related Questions