I'm currently developing a compact calculator application using Vue 3 and implementing some custom CSS.
For the most part, everything seems to be functioning correctly, except for when the results are long numbers that extend beyond the display limit.
const calculatorApp = {
data() {
return {
operationsTrack: [],
operations: [],
calculation: null,
currentVal: "",
isOperatorClicked: false,
isEquaSignClicked: false
};
},
methods: {
appendDot() {
if (this.currentVal.indexOf(".") === -1) {
this.appendNumber(".");
}
},
appendNumber(clickedVal) {
if (this.isOperatorClicked) {
this.currentVal = "";
this.isOperatorClicked = false;
}
if (!this.isEquaSignClicked) {
this.currentVal = `${this.currentVal}${clickedVal}`;
} else {
this.currentVal = clickedVal;
this.operationsTrack = [];
}
this.operationsTrack.push(clickedVal);
},
doOperation(operator, operatorLabel) {
this.isEquaSignClicked = false;
this.isOperatorClicked = true;
this.operations.push(this.currentVal);
this.operations.push(operator);
this.operationsTrack.push(operatorLabel);
},
doCalculation() {
// push the last value to the operations array
this.operations.push(this.currentVal);
let opt = this.operations.map((i) => {
if (!isNaN(i)) {
return Number(i);
}
return i;
});
// Make the calulations string
this.calculation = opt.join(" ");
// Compute the calculations
this.currentVal = eval(this.calculation);
// Empty the operations array
this.operations = [];
// Update equal sign flag
this.isEquaSignClicked = true;
},
clearDisplay() {
this.currentVal = "";
this.operations = [];
this.operationsTrack = [];
this.calculation = null;
this.isOperatorClicked = false;
this.isEquaSignClicked = false;
}
},
computed: {
operationsTrackDisplay() {
return this.operationsTrack.join(" ");
}
}
};
Vue.createApp(calculatorApp).mount("#myCalculator");
body {
padding: 0;
margin: 0;
}
body * {
box-sizing: border-box;
}
.container {
min-height: 100vh;
}
.calculator {
font-family: Montserrat, sans-serif;
width: 100%;
max-width: 360px;
min-width: 300px;
margin: 10px auto;
padding: 36px;
background: #efefef;
border-radius: 10px;
}
.display {
position: relative;
font-weight: bold;
display: flex;
flex-direction: column;
background: #c3c3c3;
border-radius: 10px;
margin-bottom: 34px;
padding: 10px 20px;
}
.result,
.track {
display: flex;
justify-content: flex-end;
}
.result {
margin-top: 3px;
font-size: 48px;
}
.track {
position: absolute;
top: 5px;
left: 20px;
right: 20px;
font-size: 12px;
}
.buttons-container ol {
list-style-type: none;
padding: 0;
margin: 0;
color: #242424;
display: grid;
grid-template-columns: repeat(4, 1fr);
column-gap: 10px;
row-gap: 10px;
}
.buttons-container li,
.buttons-container .clear {
display: flex;
justify-content: center;
align-items: center;
font-size: 36px;
height: 60px;
font-weight: 600;
background: #e7e7e7;
border-radius: 7px;
border: 1px solid rgba(0, 0, 0, 0.1);
cursor: pointer;
}
.buttons-container li {
width: 60px;
}
.buttons-container .clear {
margin-top: 10px;
text-transform: uppercase;
font-weight: 600;
}
.buttons-container .orange {
background: #ff9800;
color: #fff;
}
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500,600&display=swap" rel="stylesheet">
<script src="https://unpkg.com/vue@next"></script>
<div class="container">
<div class="calculator" id="myCalculator">
<div class="display">
<div class="track">
<span>{{operationsTrack.length ? operationsTrackDisplay + ' =' : ''}}</span>
</div>
<div class="result">
{{currentVal || 0}}
</div>
</div>
<div class="buttons-container">
<ol>
<li @click="appendNumber('7')">7</li>
<li @click="appendNumber('8')">8</li>
<li @click="appendNumber('9')">9</li>
<li @click="doOperation('/', '÷')">÷</li>
<li @click="appendNumber('4')">4</li>
<li @click="appendNumber('5')">5</li>
<li @click="appendNumber('6')">6</li>
<li @click="doOperation('*', '×')">×</li>
<li @click="appendNumber('1')">1</li>
<li @click="appendNumber('2')">2</li>
<li @click="appendNumber('3')">3</li>
<li @click="doOperation('-', '-')">-</li>
<li @click="appendNumber('0')">0</li>
<li @click="appendDot('.')">·</li>
<li @click="doOperation('+', '+')">+</li>
<li @click="doCalculation" class="orange">=</li>
</ol>
<div @click="clearDisplay" class="clear orange">Clear</div>
</div>
</div>
</div>
The Issue at Hand
Encountering problems with displaying lengthy floating point numbers in arithmetic operations, such as 1 5 ÷ 9
resulting in 1.6666666666666667
, causing overflow outside of the display area.
Utilizing toFixed()
as a fix is not ideal since it converts values into strings:
<div class="result">
{{currentVal.toFixed(6) || 0}}
</div>