Skip to content

Instantly share code, notes, and snippets.

@loonylou
Last active June 12, 2018 01:20
Show Gist options
  • Save loonylou/37cb8272d1621ae91ad7a5fbcf7d06ef to your computer and use it in GitHub Desktop.
Save loonylou/37cb8272d1621ae91ad7a5fbcf7d06ef to your computer and use it in GitHub Desktop.
Calculator - FCC
Calculator V2
-------------
For FreeCodeCamp
A [Pen](https://codepen.io/loonylou/pen/XYJqza) by [Louise Quinn](https://codepen.io/loonylou) on [CodePen](https://codepen.io).
[License](https://codepen.io/loonylou/pen/XYJqza/license).
<body>
<div id="calcBox">
<div id="calc" class="col-md-4">
<div id="displayBox" class="col-md-12">
<span id="calculation" class="col-md-12"> </span>
<span id="display" class="col-md-12"></span>
</div>
<div class="buttonRow">
<button type="button" role="del" id="clear" class="btn btn-danger btn-clear">AC</button>
<button type="button" role="del" id="backButton" class="btn btn-danger btn-clear">CE</button>
<button type="button" role="op" value="/" id="divide" class="btn btn-dark btn-op">&#247;</button>
<button type="button" role="op" value="*" id="multiply" class="btn btn-dark btn-op">&#215;</button>
</div>
<div class="buttonRow">
<button type="button" role="num" value="7" id="seven" class="btn btn-dark btn-no">7</button>
<button type="button" role="num" value="8" id="eight" class="btn btn-dark btn-no">8</button>
<button type="button" role="num" value="9" id="nine" class="btn btn-dark btn-no">9</button>
<button type="button" role="op" value="-" id="subtract" class="btn btn-dark btn-op">&#8722;</button>
</div>
<div class="buttonRow">
<button type="button" role="num" value="4" id="four" class="btn btn-dark btn-no">4</button>
<button type="button" role="num" value="5" id="five" class="btn btn-dark btn-no">5</button>
<button type="button" role="num" value="6" id="six" class="btn btn-dark btn-no">6</button>
<button type="button" role="op" value="+" id="add" class="btn btn-dark btn-op">&#43;</button>
</div>
<div class="buttonRow">
<button type="button" role="num" value="1" id="one" class="btn btn-dark btn-no">1</button>
<button type="button" role="num" value="2" id="two" class="btn btn-dark btn-no">2</button>
<button type="button" role="num" value="3" id="three" class="btn btn-dark btn-no">3</button>
<button class='invisible'>N</button>
</div>
<div class="buttonRow">
<button type="button" role="num" value="0" class="btn btn-dark btn-no" id="zero">0</button>
<button type="button" role="decimal" value="." class="btn btn-dark btn-op" id="decimal">.</button>
<button type="button" role="end" id="equals" class="btn btn-dark btn-op" id="buttonEqual">&#61;</button>
</div>
</div>
</div>
</body>
// BUGS
// Allows equal as first entry
var display = document.getElementById("display");
var calculationDisplay = document.getElementById("calculation");
var btns = document.querySelectorAll('.btn');
var calcPress = '', // Button pressed
calcString = '', // Current number being input
calculation = '', // The full calculation for evaluation
lastClickRole = '';
display.innerHTML = '0';
btns.forEach(element => {
element.addEventListener("click", buttonClicked);
});
function buttonClicked(b) {
var calcPress = this.value;
var role = this.getAttribute('role');
updateCalculator(calcPress, role);
}
function updateCalculator(calcPress, role) {
switch(role) {
case ('num'):
handleInputNumber(calcPress);
break;
case ('decimal'):
handleInputDecimal(calcPress);
break;
case ('op'):
handleInputOperator(calcPress);
break;
case ('del'):
handleInputDelete();
break;
case ('end'):
handleInputEnd();
break;
default:
// Cannot process - show error
calcString = '';
screen.innerHTML = 'ERR';
break;
}
lastClick = calcPress;
lastClickRole = role;
}
// Handle input cases
function handleInputNumber(calcPress) {
// Remove any leading zeroes and replace with input
if(calcString == '0' && calcPress != 0) {
calcString = calcPress;
updateDisplay(calcPress);
}
// Don't allow multiple zeroes at the start of digits
else if (calcString == '0' && calcPress == 0) {
calcString = 0;
updateDisplay(calcPress);
}
// Handle negative numbers - keep the minus
// else if (calcString == '-') {
// console.log('negative number');
// negString = '-'+calcPress;
// console.log(negString);
// addToCalcString(negString);
// updateDisplay(calcString);
// }
else { // Otherwise add digits to display
addToCalcString(calcPress);
}
}
function handleInputOperator(calcPress) {
// Only minus allowed as first operator
if(calcString == '') {
if(calcPress == '-') {
calcString = calcPress;
calculation = calcPress;
updateDisplay(calcString);
updateCalculationDisplay(calculation);
}
}
// Multiple operators: use new operator & remove previous
else if(lastClickRole == 'op') {
calcString = calcString.slice(0, -1) + calcPress;
calculation = calculation.slice(0, -1) + calcPress;
updateDisplay(calcString);
updateCalculationDisplay(calculation);
}
// At end of prev calc: tack new digits onto that calculation
else if(lastClickRole == 'end') {
calculation = result + calcPress;
updateCalculationDisplay(result + calcPress);
updateDisplay(calcPress);
addOperatorToCalcString(calcPress);
}
else {
calculation = calculation + calcString + calcPress;
updateCalculationDisplay(calculation);
updateDisplay(calcPress);
addOperatorToCalcString(calcPress);
}
// // Allow first key operator if minus
// if (calcString == '') {
// if(calcPress == '-') {
// makeCalcString(calcPress);
// break;
// }
// }
// else { // Else add to the current display
// makeCalcString(calcPress);
// }
}
function handleInputDecimal(calcPress) {
// If already a decimal don't allow another
let decimalCheck = calcString.indexOf(".");
if (decimalCheck != 1) {
// If first digit add a zero & allow decimal
if(calcString == "") {
calcString = 0+calcPress;
updateDisplay(calcString);
}
// If number is an integer allow decimal
else if(Number.isInteger(Number(calcString))) {
calcString = calcString+calcPress;
updateDisplay(calcString);
}
// If last entry was an operator add a zero & allow decimal
else if(lastClickRole == 'op') {
calcString = '0'+calcPress;
updateDisplay(calcString);
}
}
}
function handleInputDelete() {
calcPress = '';
role = '';
calcString = '';
calculation = '';
lastClickRole;
updateDisplay(0);
updateCalculationDisplay('');
}
function handleInputEnd() {
if(lastClickRole != 'end') {
calculation = calculation + calcString;
result = eval(calculation);
updateDisplay(result);
newCalculation = calculation + "=" + result;
updateCalculationDisplay(newCalculation);
}
}
// Update calculations & displays
function addToCalcString(calcPress) {
calcString = calcString+calcPress;
updateDisplay(calcString);
}
function addOperatorToCalcString(calcPress) {
calcString = calcString+calcPress;
updateCalculationDisplay(calcString);
}
function updateDisplay(displayString) {
display.innerHTML = displayString;
}
function updateCalculationDisplay(displayString) {
calculationDisplay.innerHTML = displayString;
}
<script src="https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.min.js"></script>
#calc {
padding: 25px 35px;
margin: auto;
top: 50px;
background-color: #888;
min-width: 355px;
min-height: 370px;
max-width: 355px;
max-height: 370px;
border-radius: 5px;
box-shadow: 5px 5px 10px 2px #666;
}
#displayBox {
display: grid;
border: 1px solid #888;
border-radius: 5px;
height: 60px;
margin-bottom: 10px;
background-color: #556b2f;
color: #caff70;
font-family: 'Orbitron', sans-serif;
overflow: hidden;
padding: 4px;
}
#display, #calculation {
text-align: right;
width: 100%;
padding: 7px;
letter-spacing: 5px;
text-overflow: ellipsis;
overflow: hidden;
}
#calculation {
color: #edf7c5;
font-size: 14px;
padding: 2px 0px 0px 0px;
}
#display {
font-size: 22px;
padding: 0px;
}
button {
width: 60px;
height: 45px;
padding: 30px;
margin: 4px;
border-color: #343a40;
box-shadow: 3px 3px 0 0 #666;
outline: none !important;
}
.btn-danger, .btn-dark {
font-size: 18px;
}
.btn-dark:focus, .btn-dark.focus, .btn-danger:focus, .btn-danger.focus {
box-shadow: 0 0 0 0 rgba(52, 58, 64, 0.5), 3px 3px 0 0 rgba(52, 58, 64, 0.5);
transition:.2s ease-in box-shadow;
}
.btn-dark:active {
background-color: #343a40;
box-shadow: 3px 3px 0 0 #888 !important;
transition:.2s ease-out box-shadow;
}
.btn-dark:not(:disabled):not(.disabled):active,
.btn-dark:not(:disabled):not(.disabled).active,
.show > .btn-dark.dropdown-toggle,
.btn-dark:hover {
background-color: #343a40;
}
.btn-danger:not(:disabled):not(.disabled):active,
.btn-danger:not(:disabled):not(.disabled).active,
.show > .btn-danger.dropdown-toggle,
.btn-danger:hover {
background-color: #dc3545;
border-color: #dc3545;
}
.btn-danger:active {
background-color: #dc3545;
border-color: #dc3545;
}
#equals {
height: 98px;
position: absolute;
right: 36px;
top: 254px;
}
#zero {
width: 132px;
}
#decimal {
position: absolute;
right: 108px;
}
.invisible {
display: none;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Orbitron" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment