2023-10-08 10:31:02 -04:00
|
|
|
let display = document.querySelector('.display');
|
2023-10-04 21:52:07 -04:00
|
|
|
const buttons = document.querySelectorAll('.btn');
|
2023-10-03 23:06:45 -04:00
|
|
|
|
2023-10-04 21:52:07 -04:00
|
|
|
const ops = {
|
|
|
|
firstNum: String(),
|
|
|
|
secondNum: String(),
|
|
|
|
operator: undefined,
|
2023-10-14 06:58:55 -04:00
|
|
|
lastOperator: undefined,
|
2023-10-04 21:52:07 -04:00
|
|
|
numFlag: false,
|
2023-10-08 10:31:02 -04:00
|
|
|
onSecondNumber: false,
|
2023-10-12 17:17:14 -04:00
|
|
|
stringLength: 8,
|
|
|
|
periodClicked: false,
|
2023-10-14 06:58:55 -04:00
|
|
|
result: String(),
|
2023-10-03 23:06:45 -04:00
|
|
|
|
2023-10-04 21:52:07 -04:00
|
|
|
toggleNumFlag: function() {
|
|
|
|
this.numFlag = !this.numFlag
|
|
|
|
},
|
|
|
|
clear: function(){
|
2023-10-05 23:44:22 -04:00
|
|
|
this.firstNum = String();
|
|
|
|
this.secondNum = String();
|
2023-10-04 21:52:07 -04:00
|
|
|
this.operator = undefined;
|
|
|
|
this.numFlag = false;
|
2023-10-08 10:31:02 -04:00
|
|
|
this.onSecondNumber = false;
|
2023-10-14 06:58:55 -04:00
|
|
|
this.result = String();
|
2023-10-08 10:31:02 -04:00
|
|
|
display.textContent = "0";
|
2023-10-12 17:17:14 -04:00
|
|
|
},
|
|
|
|
appendNumber: function(num) {
|
2023-10-12 20:54:41 -04:00
|
|
|
if(num === "0" && display.textContent.trim() === "0") return
|
2023-10-12 17:17:14 -04:00
|
|
|
if(!ops.numFlag && ops.checkLength(ops.firstNum)) {
|
|
|
|
ops.firstNum += num;
|
|
|
|
updateDisplay(ops.firstNum);
|
|
|
|
} else if(this.numFlag) {
|
|
|
|
if (this.checkLength(ops.secondNum)) {
|
|
|
|
ops.secondNum += num;
|
|
|
|
updateDisplay(ops.secondNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
checkLength: function(string) {
|
|
|
|
return string.length < this.stringLength;
|
2023-10-04 21:52:07 -04:00
|
|
|
}
|
|
|
|
};
|
2023-10-03 14:05:11 -04:00
|
|
|
|
|
|
|
function add(x, y) {
|
2023-10-04 21:52:07 -04:00
|
|
|
return x + y;
|
2023-10-03 14:05:11 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
function subtract(x, y) {
|
|
|
|
return x - y;
|
|
|
|
}
|
|
|
|
|
|
|
|
function multiply(x, y) {
|
|
|
|
return x * y;
|
|
|
|
}
|
|
|
|
|
2023-10-08 10:31:02 -04:00
|
|
|
function divede(x, y) {
|
2023-10-03 14:05:11 -04:00
|
|
|
if (x === 0) {
|
|
|
|
return 0
|
|
|
|
} else if (y === 0) {
|
|
|
|
alert("Cannot divide by 0!");
|
2023-10-08 10:31:02 -04:00
|
|
|
return "Error"
|
2023-10-03 14:05:11 -04:00
|
|
|
}
|
|
|
|
return x / y;
|
|
|
|
}
|
|
|
|
|
|
|
|
function operate(firstNum, secondNum, operator) {
|
|
|
|
switch (operator) {
|
|
|
|
case '+':
|
|
|
|
return add(firstNum, secondNum);
|
|
|
|
case '-':
|
|
|
|
return subtract(firstNum, secondNum);
|
|
|
|
case '*':
|
|
|
|
return multiply(firstNum, secondNum);
|
|
|
|
case '/':
|
2023-10-08 10:31:02 -04:00
|
|
|
return divede(firstNum, secondNum);
|
2023-10-03 14:05:11 -04:00
|
|
|
}
|
|
|
|
}
|
2023-10-03 23:06:45 -04:00
|
|
|
|
2023-10-05 23:44:22 -04:00
|
|
|
function handleOperation() {
|
2023-10-14 06:58:55 -04:00
|
|
|
const first = Number(ops.firstNum);
|
|
|
|
const second = Number(ops.secondNum);
|
2023-10-05 23:44:22 -04:00
|
|
|
let result = operate(first, second, ops.operator);
|
2023-10-14 06:58:55 -04:00
|
|
|
|
2023-10-12 17:32:20 -04:00
|
|
|
if (result === "error") {
|
|
|
|
ops.clear();
|
|
|
|
return;
|
|
|
|
}
|
2023-10-14 06:58:55 -04:00
|
|
|
|
2023-10-12 22:11:49 -04:00
|
|
|
result = roundThreeDecimals(result);
|
2023-10-05 23:44:22 -04:00
|
|
|
updateDisplay(result);
|
2023-10-14 06:58:55 -04:00
|
|
|
|
|
|
|
// store result
|
|
|
|
ops.result = result;
|
|
|
|
|
|
|
|
if (ops.lastOperator === '=') {
|
|
|
|
ops.firstNum = String();
|
|
|
|
ops.secondNum = String();
|
2023-10-08 10:31:02 -04:00
|
|
|
ops.numFlag = false;
|
2023-10-14 06:58:55 -04:00
|
|
|
ops.onSecondNumber = !ops.onSecondNumber;
|
2023-10-08 10:31:02 -04:00
|
|
|
} else {
|
2023-10-14 06:58:55 -04:00
|
|
|
ops.firstNum = ops.result;
|
|
|
|
ops.secondNum = "";
|
2023-10-08 10:31:02 -04:00
|
|
|
ops.onSecondNumber = true;
|
|
|
|
}
|
2023-10-14 06:58:55 -04:00
|
|
|
// ops.operator = undefined;
|
2023-10-05 23:44:22 -04:00
|
|
|
}
|
|
|
|
|
2023-10-03 23:06:45 -04:00
|
|
|
function updateDisplay(displayValue) {
|
2023-10-08 10:31:02 -04:00
|
|
|
display.textContent = displayValue;
|
2023-10-04 21:52:07 -04:00
|
|
|
}
|
|
|
|
|
2023-10-12 22:11:49 -04:00
|
|
|
function roundThreeDecimals(number) {
|
|
|
|
if (!Number.isInteger(number) && Number.isFinite(number)
|
|
|
|
) {
|
|
|
|
return parseFloat(number.toPrecision(3));
|
|
|
|
} else {
|
|
|
|
return number;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-05 22:24:31 -04:00
|
|
|
function handleOperatorClick(operatorClicked) {
|
2023-10-14 06:58:55 -04:00
|
|
|
|
|
|
|
ops.lastOperator = operatorClicked;
|
2023-10-05 22:24:31 -04:00
|
|
|
// TODO handle ops for = or clear
|
2023-10-08 10:31:02 -04:00
|
|
|
if (operatorClicked === 'cls') {
|
|
|
|
ops.clear();
|
|
|
|
return;
|
|
|
|
} else if (operatorClicked === '=') {
|
2023-10-14 06:58:55 -04:00
|
|
|
ops.lastOperator = '=';
|
2023-10-08 10:31:02 -04:00
|
|
|
handleOperation();
|
2023-10-14 06:58:55 -04:00
|
|
|
return;
|
2023-10-08 11:14:17 -04:00
|
|
|
} else if (operatorClicked === '+/-') {
|
|
|
|
negateNumber();
|
2023-10-14 07:29:07 -04:00
|
|
|
return;
|
2023-10-08 11:14:17 -04:00
|
|
|
} else if (operatorClicked === '%') {
|
|
|
|
percentageNumber();
|
2023-10-14 07:29:07 -04:00
|
|
|
return;
|
2023-10-08 10:31:02 -04:00
|
|
|
} else {
|
|
|
|
if(ops.secondNum && ops.numFlag){
|
2023-10-05 23:44:22 -04:00
|
|
|
handleOperation();
|
2023-10-14 07:29:07 -04:00
|
|
|
return;
|
2023-10-05 23:44:22 -04:00
|
|
|
}
|
2023-10-05 22:24:31 -04:00
|
|
|
}
|
2023-10-14 07:50:19 -04:00
|
|
|
|
|
|
|
|
2023-10-05 22:24:31 -04:00
|
|
|
ops.operator = operatorClicked;
|
|
|
|
//TODO fix this conditional should be if numFlag and a check if = or additional ops
|
2023-10-14 07:29:07 -04:00
|
|
|
if(!ops.onSecondNumber ){
|
2023-10-08 10:31:02 -04:00
|
|
|
ops.numFlag = true;
|
2023-10-14 07:50:19 -04:00
|
|
|
if (ops.result !== "" ) {
|
|
|
|
console.log('this is running the ops.result');
|
|
|
|
ops.firstNum = ops.result;
|
|
|
|
ops.onSecondNumber = true;
|
|
|
|
return
|
|
|
|
}
|
2023-10-14 07:29:07 -04:00
|
|
|
}
|
2023-10-08 10:31:02 -04:00
|
|
|
ops.onSecondNumber = !ops.onSecondNumber;
|
2023-10-05 22:24:31 -04:00
|
|
|
}
|
|
|
|
|
2023-10-04 21:52:07 -04:00
|
|
|
function calculator(event){
|
|
|
|
|
|
|
|
if(event.target.dataset.ops === "") {
|
2023-10-05 22:24:31 -04:00
|
|
|
handleOperatorClick(event.target.value);
|
2023-10-12 17:17:14 -04:00
|
|
|
} else if (event.target.value === '.') {
|
|
|
|
if (display.textContent.includes('.')) {
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
ops.appendNumber(event.target.value)
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if(event.target.dataset.num === "") {
|
|
|
|
ops.appendNumber(event.target.value)
|
2023-10-03 23:06:45 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-08 11:14:17 -04:00
|
|
|
function negateNumber(){
|
|
|
|
// returns a negated number
|
|
|
|
let negated;
|
|
|
|
if (!ops.numFlag || !ops.onSecondNumber) {
|
|
|
|
negated = Number(ops.firstNum) * -1;
|
|
|
|
ops.firstNum = String(negated);
|
|
|
|
} else {
|
|
|
|
negated = Number(ops.secondNum) * -1;
|
|
|
|
ops.secondNum = String(negated);
|
|
|
|
}
|
|
|
|
updateDisplay(negated);
|
|
|
|
}
|
|
|
|
|
|
|
|
function percentageNumber() {
|
|
|
|
let percent;
|
2023-10-14 07:50:19 -04:00
|
|
|
if ((!ops.numFlag || !ops.onSecondNumber) && !ops.result) {
|
2023-10-08 11:14:17 -04:00
|
|
|
percent = Number(ops.firstNum) / 100;
|
|
|
|
ops.firstNum = String(percent);
|
2023-10-14 07:50:19 -04:00
|
|
|
} else if (ops.result !== "" ) {
|
|
|
|
percent = Number(ops.result) / 100;
|
2023-10-08 11:14:17 -04:00
|
|
|
} else {
|
|
|
|
percent = Number(ops.secondNum) / 100;
|
|
|
|
ops.secondNum = String(percent);
|
|
|
|
}
|
|
|
|
updateDisplay(percent);
|
|
|
|
}
|
|
|
|
|
2023-10-03 23:06:45 -04:00
|
|
|
buttons.forEach(btn => {
|
2023-10-04 21:52:07 -04:00
|
|
|
btn.addEventListener('click', calculator);
|
2023-10-12 22:11:49 -04:00
|
|
|
});
|