I'm new to JavaScript and programming in general. I've taken a challenge of building a calculator usign HTML/CSS and JavaScript, I've already managed to add the sum function so the two numbers split by ' ' are summed and the result shows up in the same text input. But I can't seem to get it working for the other operations. For example, whenever I try to subtract, let's say 5-3, the result is -8...
Also, if I make a different operation first, the other operations I try to make after will display 'NaN' in the text input. For example, if I operate a sum first and then try to operate a subtraction, the result will not be "-8", it will display 'NaN' instead, and vice versa...
var equals = document.querySelector('#equals');
// The textfield element
var visor = document.getElementById("visor");
// The reset button
var resetBtn = document.getElementById("reset");
// Get all the buttons to an Array
var buttons = document.getElementsByClassName("key");
// Get all operators button
var plus = document.getElementById("plus");
var subtract = document.getElementById("subtract");
var multiply = document.getElementById("multiply");
var divide = document.getElementById("divide");
function numbersAndOperators() {
Array.prototype.forEach.call(buttons, (button) => {
button.addEventListener("click", () => {
visor.value = button.innerText
})
})
// Add click event listener to reset button
resetBtn.addEventListener("click", () => {
visor.value = null
})
}
plus.addEventListener('click', function() {
equals.addEventListener('click', function() {
var valAdd = visor.value.split(' ');
visor.value = valAdd.reduce((a, c) => a Number(c), 0);
});
});
subtract.addEventListener('click', function() {
equals.addEventListener('click', function() {
var valSub = visor.value.split('-');
visor.value = valSub.reduce((a, c) => a - Number(c), 0);
});
});
multiply.addEventListener('click', function() {
equals.addEventListener('click', function() {
var valMul = visor.value.split('*');
visor.value = valMul.reduce((a, c) => a * Number(c), 0);
});
});
divide.addEventListener('click', function() {
equals.addEventListener('click', function() {
var valDiv = visor.value.split('/');
visor.value = valDiv.reduce((a, c) => a / Number(c), 0);
});
});
document.addEventListener("DOMContentLoaded", numbersAndOperators);
<body>
<div >
<div>
<h1>Calc</h1>
</div>
<div >
<p>Theme</p><input type="range" min="0" max="2" id="range"></div>
</div>
<div >
<div><input type="text" id="visor"></div>
</div>
<div>
<div >
<button >7</button><button >8</button><button >9</button><button id="del">DEL</button>
</div>
<div >
<button >4</button><button >5</button><button >6</button><button id="plus"> </button>
</div>
<div >
<button >1</button><button >2</button><button >3</button><button id="subtract">-</button>
</div>
<div >
<button >.</button><button >0</button><button id="divide">/</button><button id="multiply">*</button>
</div>
<div >
<button id="reset">RESET</button><button id="equals">=</button>
</div>
</div>
</body>
Previously, the JS for the equals button was like that:
equals.addEventListener('click', function(){
if (visor.value.split(' ')){
visor.value = visor.value.split(' ').reduce((a,c) => a Number(c), 0);
}
if (visor.value.split('-')){
visor.value = visor.value.split('-').reduce((a,c) => a - Number(c), 0);
}
if (visor.value.split('*')){
visor.value = visor.value.split('*').reduce((a,c) => a * Number(c), 0);
}
if (visor.value.split('/')){
visor.value = visor.value.split('/').reduce((a,c) => a / Number(c), 0);
}
});
document.addEventListener("DOMContentLoaded", numbersAndOperators);
CodePudding user response:
The problem is with the way you're using reduce()
. You're starting with an initial value 0
, then using reduce()
to subtract each number from it. So 5-3
is being treated as 0-5-3
.
After splitting, you should use the first value as the initial value, then subtract the rest. So change
visor.value = valSub.reduce((a, c) => a - Number(c), 0);
to
visor.value = valSub.slice(1).reduce(a, c) => c - Number(c), Number(valSub[0]));
CodePudding user response:
Alright, I managed to solve the issue with a friend based on @Barmar's contribution. All I had to do was change the parameters from Number() to parseFloat(), but I had to do it on both parameters, something like that: parseFloat(a) - parseFloat(c).
´´´ equals.addEventListener('click', function(){ if (visor.value.split('-')){ visor.value = visor.value.split('-').slice(1).reduce((a, c) => parseFloat(a) - parseFloat(c), (visor.value.split('-')[0])); } if (visor.value.split(' ')){ visor.value = visor.value.split(' ').slice(1).reduce((a, c) => parseFloat(a) parseFloat(c), (visor.value.split(' ')[0])); } if (visor.value.split('')){ visor.value = visor.value.split('').slice(1).reduce((a, c) => parseFloat(a) * parseFloat(c), (visor.value.split('*')[0])); } if (visor.value.split('/')){ visor.value = visor.value.split('/').slice(1).reduce((a, c) => parseFloat(a) / parseFloat(c), (visor.value.split('/')[0])); } }) ´´´