In this article I will show you how to create a re-usable calculator control component in PowerApps. We will use buttons and text label controls to create a responsive calculator as a custom component with low code no code.
Let’s get started!
To create the components in the PowerApps app studio, we first have to enable ‘Components’ in the experimental features tab from the advanced settings of the app.
Currently, if you have a requirement of any floating values for calculations and then updating/ filling data through the canvas apps, you might have to use the device based calculator switching from the app etc. In this component, we will develop a calculator control that is based on buttons and text labels. The calculator pops up on the screen on the press of the calculator icon on the screen. The main element of this component is a collection that stores the data and performs the calculation upon the press of operator buttons on the calculator.
Significance of the collection in this component: This collection will contain atmost 3 rows. The first and last rows will contain numbers and the second row will contain operands. How this works is when a number button is pressed, we will check if there is any operand in the collection and if there is an operand in the second row of the collection then a third row is created with the selected button text. If there is no operand in the collection, the selected button text is concatenated with the text in the last row of the collection. When there are three rows present in the collection, and then any operator is selected, all the three rows are computed accordingly and the result is stored in a variable. The collection is cleared and the first element is populated with the resultant variable.
1. This is the calculator component in which the button and text controls have been added. The background of this component is colorless, which allows screen overlay when the calculator pops up.
2. This is the text label that displays the result from the calculator. The expression used on the Text property of this control is:
If(CountRows(ValuesCollection) = 1,Value(First(ValuesCollection).Value),"0")
Explanation: This displays the calculated result from the inputs of the calculator stored in the collection. This control displays "0" by default.
3. This is an image control (PNG image of a calculator). The OnSelect property of this control sets the visibility of the calculator control.
Note: As this is a custom image and these media types are not included while exporting the component, it needs to be manually added after importing.
4. This is a custom property that returns the result from the calculations performed. Expression used on this custom property is:
If(CountRows(ValuesCollection) = 1,Value(First(ValuesCollection).Value))
Explanation: Return the calculated value from the inputs stored in the collection.
5. This is a text input control (view only mode) that shows the selections made through the buttons on the calculator. The expression used on the Default property of this control is:
If(CountRows(ValuesCollection) <=2,Value(First(ValuesCollection).Value),Value(Last(ValuesCollection).Value))
Explanation: This checks the number of rows in the collection and if less than 2, it displays the first row element. If it is greater than 2, then it displays the last row element from the collection.
6. This is a button control (view only mode) that displays the chosen operand. The expression used on the Text property of this control is:
Last(FirstN(ValuesCollection,2)).Value
Explanation: Based on the collection schema, the operator will always be stored in the second row and the same is being displayed here.
The expression used on the Visible property of this control is:
ShowCalculator && Last(ValuesCollection).Value in ["%","/","*","-","+"]
Explanation: This button will only be displayed if the ShowCalculator variable is set to true (which also sets the visibility of the calculator and result text) and there is value in the second row of the collection.
7. This is the return button that sets the visibility of the calculator to false.
Number buttons on the calculator (grey area): The expression used on the OnSelect property of all the buttons with the numbers is:
If(Last(ValuesCollection).Value in ["%","/","*","-","+"],Collect(ValuesCollection,"0"),Collect(ValuesCollection,Concatenate(Last(ValuesCollection).Value,"0"));If(CountRows(ValuesCollection)>1,Remove(ValuesCollection,First(LastN(ValuesCollection,2)))))
Explanation: This checks if there is an operator in the second row and if so, it will add a third row else, it will concatenate the selected item with the already present value.
Operator buttons on the calculator (orange area): The expression used on the OnSelect property of all the operator buttons is:
If(CountRows(ValuesCollection)=1,Collect(ValuesCollection,"+"),CountRows(ValuesCollection)=2,Remove(ValuesCollection,Last(ValuesCollection));Collect(ValuesCollection,"+"),CountRows(ValuesCollection)=3,Switch(Last(FirstN(ValuesCollection,2)).Value,"+",Set(CalculatedResult,Value(First(ValuesCollection).Value)+Value(Last(ValuesCollection).Value));ClearCollect(ValuesCollection,Text(CalculatedResult)),"-",Set(CalculatedResult,Value(First(ValuesCollection).Value)-Value(Last(ValuesCollection).Value));ClearCollect(ValuesCollection,Text(CalculatedResult)),"*",Set(CalculatedResult,Value(First(ValuesCollection).Value)*Value(Last(ValuesCollection).Value));ClearCollect(ValuesCollection,Text(CalculatedResult)),"/",Set(CalculatedResult,Value(First(ValuesCollection).Value)/Value(Last(ValuesCollection).Value));ClearCollect(ValuesCollection,Text(CalculatedResult)),"");Collect(ValuesCollection,"+"))
Explanation: This checks if there is only one row in the collection and if so, it adds a row for the operator. If there are two rows, then it removes the existing operator and adds the currently selected one. If there are three rows, it will perform the calculation and clear the collection, add the result as a first row in the collection and the operator as the second row.
Expression used on the OnSelect property of the '=' button:
If(CountRows(ValuesCollection)=3,Switch(Last(FirstN(ValuesCollection,2)).Value,"+",Set(CalculatedResult,Value(First(ValuesCollection).Value)+Value(Last(ValuesCollection).Value));ClearCollect(ValuesCollection,Text(CalculatedResult)),"-",Set(CalculatedResult,Value(First(ValuesCollection).Value)-Value(Last(ValuesCollection).Value));ClearCollect(ValuesCollection,Text(CalculatedResult)),"*",Set(CalculatedResult,Value(First(ValuesCollection).Value)*Value(Last(ValuesCollection).Value));ClearCollect(ValuesCollection,Text(CalculatedResult)),"/",Set(CalculatedResult,Value(First(ValuesCollection).Value)/Value(Last(ValuesCollection).Value));ClearCollect(ValuesCollection,Text(CalculatedResult)),""))
Explanation: This will only work if there are three rows in the collection. It computes the inputs in the collection based on the switch control and then finally clears the collection and places the result as a first row in the collection.
First row buttons (light grey area): Expression used on the OnSelect property of the clear button:
If(Button6.Text = "C",Remove(ValuesCollection,Last(ValuesCollection)),Button6.Text = "AC",Clear(ValuesCollection))
Explanation: This control is being used to remove the row/ entire collection based on the current selections and status.
Expression used on the OnSelect property of '+/-' button:
If(!(Last(ValuesCollection).Value in ["%","/","*","-","+"]),Patch(ValuesCollection,Last(ValuesCollection),{Value:If(Left(Last(ValuesCollection).Value,1) = "-",Right(Last(ValuesCollection).Value,2),Concatenate("-",Last(ValuesCollection).Value))}), Patch(ValuesCollection,Defaults(ValuesCollection),{Value:"-0"}))
Explanation: This changes the sign of the last element of the collection.
Expression used on the OnSelect property of '%' button:
If(!(Last(ValuesCollection).Value in ["%","/","*","-","+"]),Patch(ValuesCollection,Last(ValuesCollection),{Value:Value(Last(ValuesCollection).Value) * 0.01}))
Explanation: This divides the last element by 100.
Component in Action:
In this article I have shown how to create a PowerApps re-usable component. This component can be used for immediate calculations on Canvas Apps and can be hidden as a label on the app itself. Similarly, based on scenarios, such re-usable custom control components can be created with the available controls and used as components across applications. Attached is the exported component for this calculator.
I hope you found this interesting and it helped you. Thank you for reading!