While you are getting the values of the input
elements prior to doing the calculations. You are storing them in local variables that are not accessible outside of the getVals
function and your various calculation functions are expecting the two values to be passed into them as arguments, but when you call them, you aren't passing anything.
One solution is to declare the input
variables at a higher scope and just use them directly without any function arguments.
// By declaring the variables at a higher scope than any function that
// will use them, they beconme available to all of them.
let val1 = null;
let val2 = null;
function getVals() {
val1 = parseInt(document.getElementById('number1').value,10);
val2 = parseInt(document.getElementById('number2').value,10);
}
function addNumber() {
var total = Number(val1) + Number(val2);
document.getElementById('result').innerHTML = (total);
return total;
}
function subtractNumber() {
var total = val1 - val2;
document.getElementById('result').innerHTML = (total);
return total;
}
function multiplyNumber() {
var total = val1 * val2;
document.getElementById('result').innerHTML = (total);
return total;
}
function divideNumber() {
var total = val1 / val2;
document.getElementById('result').innerHTML = (total);
return total;
}
function exponentiation() {
var total = val1 ** val2;
document.getElementById('result').innerHTML = (total);
return total;
}
<!doctype html>
<html>
<head>
<h1>Calculator</h1>
<body>
<input id="number1" placeholder="Enter text" onblur="getVals()">
<input id="number2" placeholder="Enter text" onblur="getVals()"><br>
<br>
<input type="submit" onclick="addNumber()" value="+">
<input type="submit" onclick="subtractNumber()" value="-">
<input type="submit" onclick="multiplyNumber()" value="x">
<input type="submit" onclick="divideNumber()" value="÷">
<input type="submit" onclick="exponentiation()" value="^"><br>
<br>
<b>Calculation:</b><br>
<p id="result"></p>
<script src="calculator.js"></script>
</body>
</html>
Now, beyond that you can only return one value from a function so return val1, val2
is only going to return val2
.
Also, since all your calculation functions do the same thing, but with different math, you can combine all of them into a single function and eliminate much of the duplication.
Next, you shouldn't be scanning the DOM for the same elements over and over within a function and instead get the references just one when the page loads and then just use those references over and over.
Finally, you should not be using inline event attributes, such as onclick
as these are 25+ year old ways of doing event registration before there were any standards. Instead, you should be separating your HTML and JavaScript and hooking up your event handlers with .addEventListener()
.
Putting all those things in place, we get:
// By declaring these varaibles outside of the various functions that will
// use them, they are available (scoped) to all of them.
let val1 = null;
let val2 = null;
// Get the DOM element references you'll need just once
// rather than every time a function is executed.
const num1 = document.getElementById('number1');
const num2 = document.getElementById('number2');
// Set up event handlers in JavaScript, not HTML
// Here, we are using "event delegation" and just setting
// up one event handler at the document level for any click
// event within it. Those events will "bubble up" to the
// document and be handled here.
document.addEventListener("click", function(evt){
// We can check the element that triggered the event
// and see if it's one we really want to handle.
if(evt.target.classList.contains("operation")){
calculate(evt.target.value);
}
});
function calculate(operation) {
// When using parseInt, always supply the second (optional) radix argument
// which specifies what numerical base system you are working with, otherwise
// some values (i.e. 0x) could be processed as hex or base 8.
val1 = parseInt(num1.value,10);
val2 = parseInt(num2.value,10);
// switch checks the argument passed to it (operation in this case)
// and tests it against each case and if it matches, performs the code
// in that case branch
switch (operation){
case "+":
// Don't use .innerHTNL when the content you are working with isn't HTML
result.textContent = val1 + val2;
break;
case "-":
result.textContent = val1 - val2;
break;
case "*":
result.textContent = val1 * val2;
break;
case "/":
result.textContent = val1 / val2;
break;
case "^":
result.textContent = val1 ** val2;
break;
}
// There's no need to return anything from this function since
// you are putting the result into an element on the page.
}
<!doctype html>
<html>
<head>
<h1>Calculator</h1>
<body>
<!-- If you use type="number", it will avoid non-numeric data from being inputted -->
<input type="number" id="number1" placeholder="Enter number">
<input type="number" id="number2" placeholder="Enter number"><br>
<br>
<!-- type="submit" is for submitting form data. You aren't doing that
here and so should just be using type="button" -->
<input type="button" class="operation" value="+">
<input type="button" class="operation" value="-">
<input type="button" class="operation" value="*">
<input type="button" class="operation" value="/">
<input type="button" class="operation" value="^"><br>
<br>
<b>Calculation:</b><br>
<p id="result"></p>
<script src="calculator.js"></script>
</body>
</html>