Welcome to another implementation of Real Time Salesforce Project Scenario, where we will implement a custom Calculator in Lightning. If you want to check other implementations in Real Time Salesforce Project Scenario series, you can check it here.
In this implementation, we will create a Calculator in Lightning using Aura Components. This scenario will give you a good understanding of how to develop Aura Components and work with UI and JavaScript Controllers.
Implementation
Real Time Salesforce Project Scenario
Create a Calculator that will perform basic operations like Addition, Subtraction, Multiplication, Division, and Clear.
Before getting into the coding, this is how our implementation will look like:

As you have already seen in the above screenshot, most part of the Calculator looks like a table. So, let’s use the <table> tag to display all the numbers and operators. Use <div> tag to display Input String and Result.
We need the below attributes:
- lstNumbers: To list all the numbers (operands)
- strOperator: To save the operation (operator)
- strCurrentNumber: To store the current number
- strInput: To display all the operators and operand entered for current operation.
- result: To display the result.
This is how our component would look like:
Calculator.cmp
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes" access="global" >
<aura:attribute name="lstNumbers" type="List" default="[]"/>
<aura:attribute name="strOperator" type="String"/>
<aura:attribute name="strCurrentNumber" type="String" default=""/>
<aura:attribute name="strInput" type="String" default=""/>
<aura:attribute name="result" type="Integer" default="0"/>
<lightning:card title="Calculator">
<div id="mainDiv" class="slds-p-around_medium">
<div id="ioDiv">
<div id="inputDiv">{!v.strInput}</div>
<div id="outputDiv">{!v.result}</div>
</div>
<div id="operationsDiv">
<table>
<tr>
<td onclick="{!c.numberClicked}">7</td>
<td onclick="{!c.numberClicked}">8</td>
<td onclick="{!c.numberClicked}">9</td>
<td class="operator" onclick="{!c.operatorClicked}">/</td>
</tr>
<tr>
<td onclick="{!c.numberClicked}">4</td>
<td onclick="{!c.numberClicked}">5</td>
<td onclick="{!c.numberClicked}">6</td>
<td class="operator" onclick="{!c.operatorClicked}">x</td>
</tr>
<tr>
<td onclick="{!c.numberClicked}">1</td>
<td onclick="{!c.numberClicked}">2</td>
<td onclick="{!c.numberClicked}">3</td>
<td class="operator" onclick="{!c.operatorClicked}">+</td>
</tr>
<tr>
<td onclick="{!c.numberClicked}">0</td>
<td onclick="{!c.clearClicked}">C</td>
<td onclick="{!c.calculate}">=</td>
<td class="operator" onclick="{!c.operatorClicked}">-</td>
</tr>
</table>
</div>
</div>
</lightning:card>
</aura:component>
We have added onclick event to each <td>. The strCurrentNumber is used to store the current number. We have to get the operator to know what operation to perform.
Also Read:
JavaScript Controller
Create below functions in JavaScript controller:
numberClicked function
First, we will reset the strInput and strOperator after performing an operation if strOperator is =. Then, store the clicked number into strCurrentNumber.
Once we save the number clicked in strCurrentNumber, we need to update the strInput to display it on the UI as well.
operatorClicked function
After the operator is clicked, we need to update the strInput again to reflect it on UI. Then, update the number in lstNumbers by first converting strCurrentNumber to Number.
calculate function
Again, we need to update the strInput again to reflect it on UI. Then, update the number in lstNumbers by first converting strCurrentNumber to Number. Pass the strOperator to SWITCH statement. Have the multiple Cases for SWITCH statement for each operand.
Based on the operand, loop through lstNumbers to calculate the result and update the result attribute. Remember to reset the lstNumbers and strCurrentNumber for the next operations. Also, set the strOperator to = so that strInput can be reset after the number is clicked in numberClicked function.
Also Read:
clearClicked function
This function will be used to reset all the attributes.
This is how our JavaScript controller would look:
CalculatorController.js
({
numberClicked : function(component, event, helper) {
// Reset strInput and strOperator
if(component.get("v.strOperator") === '='){
component.set("v.strInput", "");
component.set("v.strOperator", "NA");
}
// Get the clicked number and store it in strCurrentNumber
let numClicked = event.target.innerText;
component.set("v.strInput", component.get("v.strInput") + numClicked);
let strCurrentNumber = component.get("v.strCurrentNumber");
if(strCurrentNumber){
component.set("v.strCurrentNumber", strCurrentNumber + numClicked);
}else{
component.set("v.strCurrentNumber", numClicked);
}
},
calculate : function(component, event, helper) {
let lstNumbers = component.get("v.lstNumbers");
let result = 0;
lstNumbers.push(Number(component.get("v.strCurrentNumber")));
component.set("v.lstNumbers", lstNumbers);
switch(component.get("v.strOperator")){
case '+':
for(let num of lstNumbers){
result = result + num;
}
break;
case '-':
result = lstNumbers[0];
for(let i in lstNumbers){
if(i==0){
continue;
}
result = result - lstNumbers[i];
}
break;
case '/':
result = lstNumbers[0];
for(let i in lstNumbers){
if(i==0){
continue;
}
result = result / lstNumbers[i];
}
break;
case 'x':
result = lstNumbers[0];
for(let i in lstNumbers){
if(i==0){
continue;
}
result = result * lstNumbers[i];
}
break;
default:
component.set("v.result", 0);
console.log("Invalid Operator");
}
component.set("v.result", result);
component.set("v.lstNumbers", []);
component.set("v.strCurrentNumber", "");
component.set("v.strOperator", '=');
},
operatorClicked : function(component, event, helper) {
let op = event.target.innerText;
component.set("v.strInput", component.get("v.strInput") +' ' +op +' ');
component.set("v.strOperator", op);
let lstNumbers = component.get("v.lstNumbers");
lstNumbers.push(Number(component.get("v.strCurrentNumber")));
component.set("v.lstNumbers", lstNumbers);
component.set("v.strCurrentNumber", "");
},
clearClicked : function(component, event, helper) {
component.set("v.lstNumbers", []);
component.set("v.strCurrentNumber", "");
component.set("v.strInput", "");
component.set("v.strOperator", "NA");
component.set("v.result", 0);
},
})
Also Read:
And here is our CSS to make this Calculator component beautiful.
Calculator.css
.THIS {
}
.THIS #ioDiv{
text-align: right;
background-color: black;
color: white;
height: 110px;
padding-right: 20px;
padding-top: 10px;
}
.THIS #inputDiv{
font-size: 20px;
}
.THIS #outputDiv{
font-size: 40px;
}
.THIS table{
border-collapse: separate;
border-spacing: 0px;
}
.THIS td{
text-align: center;
padding:20px 0px;
font-size: 20px;
background-color: #f2f0f1;
border: 2px solid #ffffff;
cursor: pointer;
transition-property: border;
transition-duration: 0.3s;
transition-delay: 0s;
}
.THIS td:hover {
border: 2px solid #8783eb;
}
.THIS .operator{
background-color: #ab5eeb;
color: white;
}
That is all from this implementation of Real Time Salesforce Project Scenario. This is how we can develop a simple Calculator in Lightning.
If you don’t want to miss the new implementation, you can Subscribe Here.
See you in the next implementation. Thank you!