Well, if there is an experimental feature, let’s experiment!
Having read through that page, I thought “wow.. can I create some kind of confirmation dialog using those components?” (Hint: if you are wondering how that worked out, scroll down to the bottom to see the recording)
That was a crazy idea, I can readily admit it now, but it did not seem that crazy at the time.
Here is how it went..
First of all, you need to take a few steps:
- It is an experimental feature, so you have to be working in the “Preview” region (this feature won’t be available in your regular region)
- And, then, you need to enable components in the app properties (under the “preview” settings)
If you look at the link above, you’ll see how it’s all supposed to be set up, so here I just wanted to emphasize those two steps.
Once I had components enabled for the application, I figured I’d do something like this:
- There would be a screen
- There would be a button on that screen
- There would be a component with a couple of buttons (Cancel/Ok)
- There would be a message label in that component
- And the component would be hidden by default
- So, when the users clicks that button on the screen, I’d like the component to show up and display a custom message so that the user could choose “OK” or “Cancel”, and, then, something else would happen on the main screen.
Would not that be cool? I could use the same component for different screen to confirm various delete actions, for example..
It did not take long to realize, though, that components do not share context variables with the parent screen, they do not share global variables with the rest of the application, and they don’t have any kind of “OnSelect”, “OnDisplay”, “OnVisible” events. They are encapsulated in their own context which seems to be very different from what it normally looks like.
Actually, if you try to invoke UpdateContext function in the component, you will get an error from the IntelliSense:
Although, as you can see from the same screenshot “Set” will work just fine there. Except that it won’t be touching application global variables – those will be some kind of component-specific variables.
So how was I supposed to organize the sequence of “events”? Here is what I knew:
- I could hide and show my component on the screen using “Visible” property.
- I could also adjust X & Y coordinates so that the confirmation message would show up in the middle of the parent screen
- I could create input/output parameters for the component to pass values in and out
- However, since , at this point, PowerApps components are not exposing any events, there seem to be no way to easily respond to the click of the “OK”/”Cancel” buttons
And the solution was? Timers! Mind you, it’s not an ideal solution. But it did get me very close to what I wanted to do.
Here is how my component looks like:
There are two buttons, there is a message label, and there is a timer.
There are two input properties: Message (Text) and NavigateOnClose (Screen). And there is one output property: Result (Number)
In the Time “OnTimerEnd” event, the component is setting DlgResult variable to 0:
And the time itself is configured this way:
In the “OnSelect” event of the “OK” button, the same variable is set to 2:
Finally, in the “OnSelect” event of the “Cancel” button, the same variable is set to 1:
You’ll also notice that both Cancel and OK buttons will use NavigateOnClose property to Navigate away from the component.
Component’s result property will be sources from the DlgResult variable:
But what’s the purpose of the timer?
It will simply reset DlgResult variable to 0 every 587 milliseconds(it’s not a magic number.. it’s just something to hopefully avoid collisions with the other timer – you’ll see it below). Problem is, I have to reset that variable somehow(otherwise, every time I show this component, it’ll already have a result value corresponding to either “Cancel” or “OK”), and I don’t have access to that variable from the main screen. Yet I don’t have any other event to use in this case.
Now off to the main screen:
There is my component, there is a button to show it, and.. there is another timer!
Component’s visibility is source from the variable:
X and Y properties of the component are sourced from the variables, too:
When the button is selected, I’ll set ConfirmDlgVisible to true, and I’ll also adjust X & Y coordinates:
In the OnVisible property of the screen, I am hiding the dialog:
And, finally, what’s that timer is doing? It’s checking “result” property of the component. Yep, periodically. If you have followed me this far, you may still remember there was another timer that’s actually resetting the result, so the idea is that the timer on the screen should be checking “Result” frequently, and the other timer should be resetting it not so frequently (but, still, frequently enough to reset the result before the confirmation message is required again).
So, here is how this timer is set up:
And here is what’s happening in the OnTimerEnd:
Basically, it’s all about checking the result and hiding the dialog. I could add another If condition there to verify if the value of the result property corresponds to the “OK” button and do something if it does (as in, I could call Remove on some data source)
So.. Let’s just hide the timers (set Visible to “false” on both of them) and see how everything looks like. I’ve also added a label to the component to create a visual border:
As you are watching the recording below, notice how there are different numbers showing up just above the button (they will be 0, 1, or 2). That’s a label linked to the component’s “result” property.
BTW, if you were watching carefully, you’ve probably noticed how the first time I clicked “OK” there two timers actually ran into one another, so the click was not processed correctly. Had to click “OK” twice that time. It was an interesting experiment, though, which just proves there are things we can do with the Canvas apps which, maybe, we were not even meant to do