odin-calculator/script.js

264 lines
7.2 KiB
JavaScript

const viewDiv = document.querySelector("#view");
const signGui = viewDiv.querySelector("#sign");
const valueGui = viewDiv.querySelector("#value");
function add(a, b) {
return a + b;
}
function substract(a, b) {
return a - b;
}
function multiply(a, b) {
return a * b;
}
function divide(a, b) {
if (b == 0) {
return "Dividing by 0? That's illegal!";
}
return a / b;
}
const operationInitial = {
a: "0",
operator: "",
b: "",
addToA: true,
displayA: true,
readyForEquasion: false,
outputOfEquasion: false,
}
let operation = {};
Object.assign(operation, operationInitial);
function operate(equals) {
switch(equals.operator) {
case "+":
return add(+equals.a, +equals.b);
case "-":
return substract(+equals.a, +equals.b);
case "*":
return multiply(+equals.a, +equals.b);
case "/":
return divide(+equals.a, +equals.b);
}
}
// check if number is valid
function checkNumber(number) {
return number == " " ? false : !isNaN(+number);
}
// handlers for actions
function addPoint() {
if (operation.addToA) {
if (!operation.a.includes(".")) {
operation.a += ".";
}
} else {
if (!operation.b.includes(".")) {
operation.b += ".";
}
}
}
function handleNumbers(value) {
if (operation.outputOfEquasion) {
operation.a = value;
operation.outputOfEquasion = false;
operation.addToA = true;
} else {
if (operation.addToA) {
if (operation.a == "0") {
operation.a = "";
}
operation.a += value;
operation.displayA = true;
} else {
if (operation.b == "0") {
operation.b = "";
}
operation.displayA = false;
operation.b += value;
operation.readyForEquasion = true;
}
}
}
function handleBackspace() {
if (!operation.outputOfEquasion) {
if (operation.addToA) {
operation.a = operation.a.substring(0, operation.a.length - 1);
if (operation.a.length < 1) {
operation.a = "0";
}
} else {
operation.b = operation.b.substring(0, operation.b.length - 1);
if (operation.b.length < 1) {
operation.b = "0";
}
}
} else {
clear();
}
}
function handleOperators(value) {
if (operation.operator == "") {
operation.addToA = !operation.addToA;
operation.operator = value;
}
if (operation.addToA) {
operation.operator = value;
}
if (operation.readyForEquasion) {
execute(operation);
operation.addToA = !operation.addToA;
operation.operator = value;
}
operation.outputOfEquasion = false;
}
function execute(operation) {
if (operation.readyForEquasion) {
const result = operate(operation);
operation.displayA = true;
operation.addToA = true;
operation.readyForEquasion = false;
operation.operator = "";
operation.a = `${result}`;
operation.b = "";
operation.outputOfEquasion = true;
}
}
function clear() {
Object.assign(operation, operationInitial);
signGui.textContent = "";
valueGui.textContent = operation.a;
}
function display(operation) {
signGui.textContent = `${operation.operator}`;
if (operation.displayA) {
if (operation.a[operation.a.length - 1] == ".") {
valueGui.textContent = `${operation.a}`;
} else {
valueGui.textContent = `${Math.round(parseFloat(operation.a) * 100000) / 100000}`;
}
} else {
if (operation.b[operation.b.length - 1] == ".") {
valueGui.textContent = `${operation.b}`;
} else {
valueGui.textContent = `${Math.round(parseFloat(operation.b) * 100000) / 100000}`;
}
}
}
// handling presses on keyboard and buttons
function handleAction(e) {
if (!e.keyCode) {
// when the press comes from button, makes it
// compatible with code for keyboard with no rewrites
e = {key: e}
}
let action = true;
let passLetter = e.key.toLowerCase();
if (!checkNumber(operation.a) || !checkNumber(operation.b)) {
clear();
}
if (passLetter == " "
|| passLetter == ".") {
addPoint();
} else if (!isNaN(+passLetter)) {
handleNumbers(passLetter);
} else if (passLetter == "backspace"
|| passLetter == "x") {
handleBackspace();
} else if (passLetter == "+"
|| passLetter == "-"
|| passLetter == "*"
|| passLetter == "/") {
handleOperators(passLetter);
} else if (passLetter == "enter"
|| passLetter == "=") {
execute(operation);
} else if (passLetter == "escape"
|| passLetter == "c") {
clear();
} else {
action = false;
}
if (action) {
display(operation);
e.preventDefault();
};
}
document.addEventListener("keydown", handleAction);
// create buttons
function generateGui() {
const allButtons = [
[
{ id: "C", width: 1, height: 1, display: "C", },
{ id: "X", width: 1, height: 1, display: "X", },
{ id: "+", width: 1, height: 1, display: "+", },
{ id: "-", width: 1, height: 1, display: "-", },
],
[
{ id: "7", width: 1, height: 1, display: "7", },
{ id: "8", width: 1, height: 1, display: "8", },
{ id: "9", width: 1, height: 1, display: "9", },
{ id: "*", width: 1, height: 1, display: "*", },
],
[
{ id: "4", width: 1, height: 1, display: "4", },
{ id: "5", width: 1, height: 1, display: "5", },
{ id: "6", width: 1, height: 1, display: "6", },
{ id: "/", width: 1, height: 1, display: "/", },
],
[
{ id: "1", width: 1, height: 1, display: "1", },
{ id: "2", width: 1, height: 1, display: "2", },
{ id: "3", width: 1, height: 1, display: "3", },
{ id: "=", width: 1, height: 2, display: "=", },
],
[
{ id: "0", width: 2, height: 1, display: "0", },
{ id: ".", width: 1, height: 1, display: ".", },
],
];
const buttonsDiv = document.querySelector("#buttons");
const table = document.createElement("table");
table.id = "table";
allButtons.forEach(row => {
const tableRow = document.createElement("tr");
row.forEach(buttonProperties => {
const button = document.createElement("td");
button.setAttribute("value", buttonProperties.id);
button.setAttribute("colspan", buttonProperties.width);
button.setAttribute("rowspan", buttonProperties.height);
button.textContent = buttonProperties.display;
button.addEventListener("click", (event) => {
handleAction(event.target.getAttribute("value"));
});
tableRow.append(button);
});
table.append(tableRow);
});
buttonsDiv.append(table);
}
generateGui();