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();