Real Time Salesforce Project Scenario: Calculator in Lightning

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:

Real Time Salesforce Project Scenario: Calculator in Lightning
Real Time Salesforce Project Scenario: Calculator in Lightning

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!

Leave a Comment