1

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>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • 3
    What is the issue? What specific problem are you having trouble with? –  May 16 '18 at 14:14
  • 1
    Instead of onclick, use onsubmit of the form and return false in the function. OR make the button `type="button"` - Also look at parseInt before concatenating the values – mplungjan May 16 '18 at 14:14
  • `document.querySelector("form").onsubmit=myF; ` and add `return false;` to the myF function at the end – mplungjan May 16 '18 at 14:16
  • I would suggest you to change the function `document.getElementById("a")` to `document.getElementsByClassName('sum')` which is going to return a list of all elements with that classname (`sum`). Plus, add the classname `sum` to all your inputs. – Gabriel Heming May 16 '18 at 14:16
  • 1
    Careful, there's a label with `id="f"`! You should not use same ID more than once (it's used for the input too). If you want to link a label to the input, use the `for="f"` attribute on label, instead of ID. – Fabio Lolli May 16 '18 at 14:17
  • @GabrielHeming - better would be `document.querySelectorAll(".sum")` – mplungjan May 16 '18 at 14:17
  • @mplungjan is there a problem with "live node" or I missed something? BTW, thanks for the tip. – Gabriel Heming May 16 '18 at 14:19
  • @mplungjan are you sure? https://stackoverflow.com/a/26757629/4944774 seems like querySelectorAll is a more expensive method? – Fabio Lolli May 16 '18 at 14:21
  • You are concating strings not numbers. – epascarello May 16 '18 at 14:24
  • @FabioLolli & GabrielHeming interesting that the querySelectorAll is not live. I did not know that. I only use it immediately and have never needed to update the DOM it was pointing at and then reuse the collection. – mplungjan May 16 '18 at 14:57
  • Thanks everybody, you were all useful. I managed to make it work! This was a big step for me! Thanks for the help! – Laura Mewoo May 18 '18 at 23:34

5 Answers5

2

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.

skylerfenn
  • 354
  • 3
  • 10
  • 1
    I suggest adding an expanation for #2. Something along the lines of "IDs must be unique" or somesuch. –  May 16 '18 at 14:25
2

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;
}
jcubic
  • 61,973
  • 54
  • 229
  • 402
2

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>
Wild Beard
  • 2,919
  • 1
  • 12
  • 24
1

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>
Yosvel Quintero
  • 18,669
  • 5
  • 37
  • 46
0

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.

ramoncs11
  • 63
  • 7