I am making a calculator for the FreeCodeCamp Project for Front End Development Libraries. I am stuck now with creating a function where I can use the "-" button also for negative values (e.g. 5*-5). I made it work with a +/- button, like on a normal calculator, but this doesn’t pass the test of FCC even though it works. They want you to use the "-" for both subtract and negative values.
How could I do that? I am stuck on it for 2 days now but have no idea how to solve it.
Here is the html code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
<script>
let trailingResult = 0;
let operationOptions = ['divide', 'multiply', 'subtract','add'];
let workingOperation ="";
function updateDisplay(input) {
let display = document.getElementById("display");
if (display.innerHTML === "0" && operationOptions.indexOf(input) === -1) {
if (input === 'decimal') {
display.innerHTML = "0.";
} else {
display.innerHTML = input;
}
} else if (operationOptions.indexOf(input) >= 0){
// dealing without initial operand
if (workingOperation === "") {
workingOperation = input;
trailingResult = display.innerHTML;
display.innerHTML = 0;
} else if (operationOptions.indexOf(display.innerHTML.slice(-1)) >= 0) {
workingOperation = input;
}
// dealing with a set operand
else {
trailingResult = calculate(trailingResult, display.innerHTML, workingOperation);
display.innerHTML = 0;
workingOperation = input;
}
} else if (input === "equals") {
let result = calculate(trailingResult, display.innerHTML, workingOperation);
display.innerHTML = result;
trailingResult = parseFloat(result);
workingOperation = "";
} else if (input === "decimal"){
if (display.innerHTML.indexOf(".") === -1){
display.innerHTML += ".";
}
} else {
display.innerHTML += input;
}
}
function clearDisplay() {
let display = document.getElementById("display");
display.innerHTML = 0;
}
function calculate(firstNumber, secondNumber, operation) {
let result;
firstNumber = parseFloat(firstNumber);
secondNumber = parseFloat(secondNumber);
switch (operation) {
case "add":
result = firstNumber + secondNumber;
break;
case "subtract":
result = firstNumber - secondNumber;
break;
case "multiply":
result = firstNumber * secondNumber;
break;
case "divide":
result = firstNumber / secondNumber;
break;
default:
// code block
}
return result;
}
</script>
</head>
<body>
<title>Calculator by Diemer</title>
<div class="calculator-grid">
<div class="display" id="display">
<div class="previous-operand"></div>
<div class="current-operand"> </div>
</div>
<button onclick="clearDisplay()" id="clear" class="span-two">AC</button>
<button onclick="updateDisplay('divide')" id="divide">/</button>
<button onclick="updateDisplay('multiply')"id="multiply">*</button>
<button onclick="updateDisplay(7)" id="seven">7</button>
<button onclick="updateDisplay(8)" id="eight">8</button>
<button onclick="updateDisplay(9)" id="nine">9</button>
<button onclick="updateDisplay('subtract')" id="subtract">-</button>
<button onclick="updateDisplay(4)" id="four">4</button>
<button onclick="updateDisplay(5)" id="five">5</button>
<button onclick="updateDisplay(6)" id="six">6</button>
<button onclick="updateDisplay('add')" id="add">+</button>
<button onclick="updateDisplay(1)" id="one">1</button>
<button onclick="updateDisplay(2)" id="two">2</button>
<button onclick="updateDisplay(3)" id="three">3</button>
<button onclick="updateDisplay('decimal')" id="decimal">.</button>
<!-- <button onclick="updateDisplay('-')" id="negative-value">+/-</button> -->
<button onclick="updateDisplay(0)" id="zero">0</button>
<button onclick="updateDisplay('equals')" class="span-two" id="equals">=</button>
</div>
</body>
<script src="https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous"></script>
</html>
CSS:
*, *::before, *::after {
box-sizing: border-box;
}
body {
margin: 0;
background: linear-gradient(to right, #00aaff, #00ff6c);
}
.calculator-grid {
display: grid;
margin-top: 4rem;
margin-bottom: 4rem;
justify-content: center;
grid-template-columns: repeat(4, 6rem);
grid-template-rows: minmax(7rem, auto) repeat(5, 6rem);
}
.calculator-grid > button {
cursor: pointer;
font-size: 2rem;
border: 1px solid white;
outline: none;
background-color: rgba(255,255,255, .75);
}
.calculator-grid > button:hover,
.calculator-grid > button:focus {
background-color: rgba(255,255,255, .9);
}
.span-two {
grid-column: span 2;
}
.display {
grid-column: 1 / -1;
background-color: rgb(0,0,0);
color: white;
font-size: 1,5rem;
display: flex;
flex-direction: column;
align-items: flex-end;
justify-content: space-around;
padding: .75rem;
word-wrap: break-word;
word-break: break-all;
}
I already googled it, checked the FCC forum, tried chatGPT and made most of this calculator along with a video of Useful Programmer but he didn’t made a video on how to solve this.
2
Answers
Use
parseFloat()
to parse the input.parseFloat
will parse the input up to the first character that can’t be interpreted as a number.For the example input
5*-5
, to extract the first operandparseFloat(5*-5)
will return5
as a number. Convert that to a string, find how long the string is, and truncate that length from the start of the input to leave an input*-5
.Then, to get the operator, get the first character of the remaining input, which is
*
. Truncate the first character to be left with the input for the remaining operand.To allow the "-" button to be used for both subtraction and negative values, you can modify the updateDisplay function to handle the input differently depending on the context.
If the "-" button is pressed when the display is empty, it should be interpreted as the start of a negative number. If it is pressed after an operator, it should also be interpreted as the start of a negative number. If it is pressed after a number, it should be interpreted as a subtraction operator.