1

I am making a calculation tool. I am not very familiar with javascript, so my code looks a bit off. What edits should be made to make this tool work? I want the input numbers calculated just like the equation below:

calculate = function()
{
  var x = document.getElementById('a').value;
  var y = document.getElementById('b').value;
  var z = document.getElementById('c').value; 
  document.getElementById('result').value = x * 588 + y * 28 + z + 44032
}
<input type="number" id="a" oninput="calculate()"/> × 588 +
<input type="number" id="b" oninput="calculate()"/> × 28 +
<input type="number" id="c" oninput="calculate()"/> + 44032 =
<input type='text' id="result"/>

equation: (x × 588) + (y × 28) + z + 44032 = result

Dai
  • 141,631
  • 28
  • 261
  • 374
Henry
  • 154
  • 10
  • 1
    does adding the parentheses in the equation to the code help? – James Jan 06 '21 at 07:25
  • 1
    Code looks good but the missing semicolon. What default value you want for each input ? 0 ? For example, for 0, use var x = document.getElementById('a').value || 0; Yo, your input value will be a string, you need to convert it to an int/float to use it safely in an equation. – Loenix Jan 06 '21 at 07:26
  • @Loenix The semicolon isn't "missing", see here: https://stackoverflow.com/questions/2846283/what-are-the-rules-for-javascripts-automatic-semicolon-insertion-asi – Dai Jan 06 '21 at 07:36

2 Answers2

3
  • When you use document.getElementById to get an <input /> element it returns a JavaScript object of type HTMLInputElement which has the .value property (which you are using).
  • However, the HTMLInputElement.value property returns a string value, not a number value.
    • You might be aware of the valueAsNumber property, however this does not work for <input type="text" /> - only <input type="number" /> (which your HTML is, fortunately), but always check for NaN!
  • JavaScript is often described as being "loosely-typed" but I prefer to refer to it as being "wtfy-typed" because its rules for implicit type conversions are inconsistent.
    • A common "feature" in loosely-typed languages like JavaScript and PHP is implicit conversion of string values to number values, but it's best to avoid depending on that behaviour entirely and stick to always explicitly converting string values to number values using parseInt(string,radix), parseFloat(string) or Number(any).

So do this:

var calculate = function()
{
    const x = parseFloat( document.getElementById('a').value );
    const y = parseFloat( document.getElementById('b').value );
    const z = parseFloat( document.getElementById('c').value );
    const o = document.getElementById('result');

    if( isNaN(x) || isNaN(y) || isNaN(z) ) {
        o.value = "Invalid input.";
    }
    else {
        const result = x * 588 + y * 28 + z + 44032;
        o.value = result.toString();
        // If `result` will be fractional then use `toFixed` instead of `toString`.
        // This is to avoid very long string representations of imprecise floating-point numbers due to how IEEE-754 works.
    }
}
input[type=number] {
    text-align: right;
    width: 5em;
}
input#result {
    text-align: right;
    width: 10em;
}
<input type="number" id="a" oninput="calculate()" /> × 588 +
<input type="number" id="b" oninput="calculate()" /> × 28 +
<input type="number" id="c" oninput="calculate()" /> + 44032 =
<input type='text' id="result" readonly />
Dai
  • 141,631
  • 28
  • 261
  • 374
1

Javascript Types are playing games with you :), It is actually performing concatination. when you read the values you have to just cast it to actual type which is number. Here is the working code

<input type="number" id="a" oninput="calculate()"/> × 588 +
<input type="number" id="b" oninput="calculate()"/> × 28 +
<input type="number" id="c" oninput="calculate()"/> + 44032 =
<input type='text' id="result"/>
<script>
calculate = function()
{
  var x = Number(document.getElementById('a').value);
  var y = Number(document.getElementById('b').value);
  var z = Number(document.getElementById('c').value); 

  document.getElementById('result').value = (x * 588) + (y * 28) + z + 44032
}
</script>

There are other ways to achive the same like ParseInt and ParseFloat. If you want the string to fail with NaN if it has other characters in it, Number() may actually be a better choice.

Because

Number('1234'); // returns 1234
Number('12.34'); // returns 12.34
Number('3.4040blahblahblac'); // returns NaN
Number('49cm'); // returns NaN
Aravind.HU
  • 9,194
  • 5
  • 38
  • 50
  • `parseInt` and `parseFloat` both also return `NaN` when they fail - except they have different rules for failure (`Number` parses the entire input string whereas `parseFloat`/`parseInt` allow strings that start with valid number text: https://thisthat.dev/number-constructor-vs-parse-int/ – Dai Jan 06 '21 at 07:32
  • Yes you are right, I actually meant in the cases where I don't know exactly what type it is – Aravind.HU Jan 06 '21 at 07:34