#PowerApps: Numeric Up/Down control with persisted button press event using components

I just recently returned from the Microsoft MVP Global Summit 2019 where I had a chance to meet some of the top minds in the Microsoft PowerApps and Flow space. This was a truly exciting moment as I have been learning from the very same MVPs I met - yes, we do learn from each other!

In one of my hallway discussions, I ran into my buddy Mehdi Slaoui Adaloussi, Principal Program Manager at Microsoft, who I first met at Microsoft Build 2018. I had read Mehdi's recent article on reusable components and, in particular, that I had been playing with his version of the Numeric Up/Down Control.

See 10 Reusable Components: tab control, calendar, dialog box, map control and more.

I must start by saying that the components Mehdi put in place expose some very clever implementation techniques, so I highly recommend you download the msapp files and load them up in your environment and study them.

The Numeric Up Down control in particular, caught my attention as it required multiple and repeated individual clicks to advance the value up or down, which could take away from the user experience, so I decided to build from where Mehdi left off, by changing a few things.

NOTE: my implementation does not account for the control stylistic settings added by Mehdi, but this is sure an easy feat to accomplish.

Getting Started

NOTE: You will need to enable the Components experimental feature, before you can follow these steps.

1. Create a new component

Click on New Component under the Components tab to create your component. Rename the default name to NumericUpDn.

Components tab

2. Add the controls needed to create this component.

For this control, we will need the following 6 controls:

  • 2 button controls (from the toolbar)
  • The Up icon (from the Icon gallery)
  • The Down icon (from the Icons gallery)
  • A Timer control (from the Controls gallery)
  • A Text Input control (from the Text gallery)
I always recommend you worry about the layout and aesthetics at the very end of the implementation. Nonetheless, I keep the controls close for ease of organization at the end of the implementation. 

Controls
The most important thing right now is to get the needed controls. I will also explain the use of each control as we go along. 


3. Add Component custom properties

For the Numeric Up Down control, we will need 5 custom properties as follow:

Custom Properties

Default
: Number / Input. This will serve to seed our numeric initial text input value when the control is first loaded within an app.

Min: Number / Input. This will be the lower limit for our numeric up/down control. When clicking the down button, we will check to ensure the control value itself never gets below the minimum value.

Max: Number / Input. This will be the upper limit for our numeric up/down control. When clicking the up button, we will check to ensure the control value itself never exceeds the maximum value.

Sensitivity: Number / Input. this will control how fast or slow the button press behaves to increase or decrease the numeric value in the text input field.

Value: Number / Output. This will be the value returned by the control to the calling app. 

4. Rename the Controls

Now that we have all the controls and custom properties in place, we will begin by renaming the controls for readability sake and ease of following - it's also a good practice.

Button1, rename to BtnUp
Button2, rename to BtnDn
Icon1, rename to IcnUp
Icon2, rename to IcnDn
TextInput1, rename to NumValue

Rename component controls

NOTE: renaming the Timer control seems to break the timer itself - this is a bug I have reported to the PowerApps team.

5. Add some logic

NumValue control: for this control, change the Format to Number. We will want to ensure the text input control Default property is set to the incoming Default custom property value if the initial value is blank, as follows:



Timer1 control: this is perhaps the most important control on the component, since it will basically control the overall behavior of the timer. First, let's set some properties:

  • Start property. We will want to start the timer when either the BtnUp or BtnDn pressed events are fired. Since the Start property is a true/false control (boolean) we can set the property to BtnUp.Pressed || BtnDn.Pressed

  • Duration property. We will set this property to NumericUpDn.Sensitivity. Basically, we are setting a delay between each increment or decrement of the NumValue control.

  • Repeat property. Set to true. Since we want to persist the button press event, we want the timer to restart each time after the Duration cycle is completed.

  • Reset property. We need the Timer to reset each time either button is released from a Pressed state. Hence, we can use the same true/false state as the Start property, BtnUp.Pressed || BtnDn.Pressed.

Timer control Data settings

Phew! We are done with the basic settings for the timer control settings.

Next, the timer must perform a couple actions: 1) on start, it will evaluate which button was pressed, and based on the button, increase or decrease the value in the text control. 2) on end, it will evaluate whether we've reached the lower or upper limits established by the Min and Max custom properties, respectively.

For the OnTimerStart event,

OnTimerStart

For the OnTimerEnd event,

OnTimerEnd event

BtnUp and BtnDn controls: we also want a user to retain the ability to click the buttons without persisting the pressed event, effectively advancing the NumValue control one by one until the upper or lower limits are reached. Hence we must also add some validation to the OnSelect event of each button.

For the BtnUp OnSelect event,

BtnUp OnSelect event

For the BtnDn OnSelect event,

BtnDn OnSelect event

6. Now some aesthetics

We have completed our low code implementation. Now, we are off to setting organize the controls and set some properties that will make this a useful control.

a) Select the BtnUp control and set the size to 62 width and 24 height; set the x and y positions to 257 and 2, respectively. Set the Border Radius property to 5. Set the Fill property to RGBA(56, 96, 178, 0). Set the BorderColor, HoverColor, and HoverFill properties to BtnUp.Fill. Clear the Text property (blank).

b) Select the BtnDn control and set the size to 62 width and 24 height; set the x and y positions to 257 and 26, respectively. Set the Border Radius property to 5. Set the Fill property to RGBA(56, 96, 178, 0). Set the BorderColor, HoverColor, and HoverFill properties to BtnDn.Fill. Clear the Text property (blank).

c) Select the IcnUp control and set the size to 64 width and 25 height; set the x and y positions to 256 and 1, respectively. Set the Fill property to RGBA(0, 18, 107, 1); set the Color property to RGBA(255, 255, 255, 1).

d) Select the IcnDn cotrol and set the size to 64 width and 26 height, set the x and y positions to 256 and 26. Set the Fill property to RGBA(0, 18, 107, 1); set the Color property to RGBA(255, 255, 255, 1).

NOTE: By setting these properties, the buttons and the icons are now overlaid on each other. To further access these control properties, use the control navigation pane on the left of the Design Studio.

e) Select the NumValue control and set the size to 256 width and 51 height, set the x and y positions to 0 and 1

f) Finally, set the NumericUpDn component size to 322 width and 57 height.

You should now have something that look like this:

NumericUpDn component (shown at 150%)

7. Testing the Component

To test the component, I have added the control from the Components gallery, a slider for the timer sensitivity, and a couple Text Input boxes, along with a label to track the output from the componentized control. You can quickly guess what goes to what.

NOTE: please ensure the Text Input boxes are of numeric type.

Test Screen 

The end result can be appreciated in this video.


You can download the component control from the PowerApps Community Apps Gallery, here.

Until next post,

MG.-
Mariano Gomez, MVP

Comments

Heath said…
Have you thought how this might be able to do the same thing but using a sharepoint column value instead of numerals? Do you think that could work? If so it could solve the problem of not being able to move between records when not on a gallery page I would think.
Mariano Gomez said…
Heath,
Really haven't given it much thought. Let me see what I dig up :) Thanks for the readership and suggestion.

Popular posts from this blog

DBMS: 12 Microsoft Dynamics GP: 0 error when updating to Microsoft Dynamics GP 2013 R2

Do I have to use those "Z-" currency IDs in GP?

Microsoft Dynamics GP Scrolling Windows and Line Sequence Numbers