Adv Hands On Lab 2: Creating PowerApps Reusable Components
In this labe you are building a conference management application and need to display registered attendees and be able to cycle through them. Each conference has different information that is important to see about the attendee. For example, virtual conferences show different data than in-person conferences. Therefore, you want to use a template associated with each conference to display the information.
You’ve decided to build a reusable component that will allow viewing of the records in a carousel that can cycle through the records. The user will be able to manually cycle through the records or enable an automated play cycle. The content will be displayed using a dynamic HTML template that will be used to customize the display using an HTML text control. By building a reusable component you believe other app makers will be able to use it for other similar scenarios.
To help ensure the control will work for multiple scenarios, you have chosen to build out the component using a test app that uses Accounts and Contacts and displays a simple business card for each contact.
Things you will learn
- How to build a reusable component
- How to define input/output properties
- How to use simulate behavior properties on a component
- How to dynamically tailor data using substitute
- How to use the timer control to animate the carousel
Exercise 1 – Create Canvas Application
In this exercise, you will create a canvas application and setup the carousel component. The hosting app itself will just be used as a test harness to support development of the reusable component.
Task 1: Create Canvas Application
In this task, you will create a canvas application and enable it for components. The app will have a gallery listing all the accounts from CDS and on the right side will have the component showing the related contacts. The component however could be used with any list of data and by design will not have any dependencies on a specific entity.
- Navigate to https://make.powerapps.com and make sure you are in the correct environment.
- Select Apps, click Create an App, and select Canvas.
- Select Tablet Blank App.
- Rename the screen MainScreen.
- Select the View tab and click Data Sources.
- Click Add Data Source.
- Select Common Data Service.
- Select Accounts and click Connect.
- Close the Data pane.
- Select the Insert tab, click Gallery and select Vertical.
- Rename the gallery accountsList.
- Go to the Properties pane and select Accounts for Items.
- Change the Layout to Title and Subtitle.
- Go to the Data pane, select Main Phone for Subtitle2 and select Account Name for Title2.
- Close the Data pane.
- Resize and reposition the accountsList as shown below.
- Click File and select Advanced Settings.
- Scroll down and turn on Components. Components are currently in preview and must be enabled prior to use in your applications.
- Select the App Name + icon tab and name the application Carousel Component.
- Select the Save tab and click Save.
- Click on the back button.
- You should be back to the app designer. Do not navigate away from this page.
Task 2: Setup the Carousel Component
In this task, you will create a component and set its properties. If you aren’t familiar with carousel type controls, they basically have a display area showing details and allow you to navigate through a collection of items. The display area for our carousel we are going to use the HTML text area for the visual display.
- In the Tree view select the Components tab and click New Component. Note: if you don’t see Components here check your Advanced Settings to ensure the feature is enabled.
- Rename the component Carousel.
-
Next you are going to add some custom properties. Properties define how your component will communicate with the hosting app. You can define input properties that allow the hosting app screen to give the component data and output properties that allow the component to give the hosting app screen data. Think of properties as defining a contract for how your component and app will communicate. Because your component might be used by multiple apps you should try to not make breaking changes to your input and output properties that would impact apps using your component.
The following are the properties you will add:
Property Name |
Description |
Data |
This is a table of data the component will visualize |
Template |
This is the HTML template – this will define the format for the HTML text control |
RefreshData |
This is a Boolean (True/False) used for the app to communicate to the component to refresh data |
Selected |
This is an output property that allows the hosting app to know which record is currently selected by the component |
- Go to the Properties pane and click New Custom Property.
-
Enter the following information and click Create:
- Display name: Data
- Name: Data
- Description: Description of your choice
- Property type: Input
- Data type: Table
- Display name: Data
- Click New Custom Property.
-
Provide the following information and click Create:
- Display name: Template
- Name: Template
- Description: Description of your choice
- Property type: Input
- Data type: Text
- Display name: Template
-
Add another custom property with the following information and click Create.
- Display name: Refresh Data
- Name: RefreshData
- Description: Description of your choice
- Property type: Input
- Data type: Boolean
- Display name: Refresh Data
-
Add one more custom property with the following values and click Create. Make sure this property is an output property type.
- Display name: Selected
- Name: Selected
- Description: Description of your choice
- Property type: Output
- Data type: Record
- Display name: Selected
- Your component should now have 4 custom properties.
- Select the Data property of the Carousel and replace the value with formula below. This sets a default value for the Data property and will allow you to build the component using these column names.
Table({ Record: “Contact”, Values:Table({Col:1,Value:”Full Name”}, {Col:2, Value:”Address 1: Street 1″}) })
- Click File and Save.
- Go back to the app designer by clicking on the back button. Do not navigate away from the app designer.
Exercise 2 – Build and Consume Component
In this exercise, you will build and use the component.
Task 1: Add Controls to Component
In this task, you will add controls to the component.
- Make sure you still have the Carousel component selected.
- Select the Insert tab, click Text and select HTML text.
- Rename the HTML Text control htmlText.
In the next few steps you will ensure that the controls are properly positioned, are automatically resized to take up the available parent’s space and have some margins for readability.
- Select the htmlText control, go to the Home tab, select the Height property and set it to the formula below.
Parent.Height -100
- Select the Width property and set it to the formula below.
Parent.Width -100
- Select the X property and set it to 50.
- The htmlText control layout should now look like the image below.
- Select the Insert tab, click Icons and select Left. We are adding left and right icons to allow the user of the app to manually change the item displayed.
- Rename the left icon previousIcon.
- Select the previousIcon, select the Height property and set it to the formula below.
htmlText.Height
- Select the Width property and set it to 50.
- Select the X property and set it to 0.
- Select the Y property and set it to the formula below.
htmlText.Y
- Select the OnSelect property and set it to the value shown below. This will cause the prior record to be shown if there is one.
If(CurrentIndex > 1,Set(CurrentIndex,CurrentIndex-1))
- Select the Insert tab, click Icons and select Right.
- Rename the right icon nextIcon.
- Select the nextIcon, select the Height property to formula below.
htmlText.Height
- Select the Width property and set it to 50.
- Select the X property and set it to the formula below.
htmlText.Width + 50
- Select the Y property and set it to the formula below.
htmlText.Y
- Select the OnSelect property and set it to the formula below. This will advance to the next record as long as we don’t exceed the number of records in the Data property.
If(CurrentIndex < CountRows(Parent.Data),Set(CurrentIndex,CurrentIndex+1))
- Your component should now look like the image below.
- Select the Insert tab, click Controls, and select Toggle.
You are adding this control to simulate behavior properties, we need a way to run a formula when the data changes. The data property doesn’t have an OnChange property so we are asking the hosting app to change the RefreshData property when there is new data. We will then hookup the RefreshData to the toggle. And finally, our formula will run OnChange of the toggle. You will hide it later because the user never needs to see it, we are just using it to allow running our formula on-demand.
- Move the button to the bottom of the control.
- Set the OnChange property of the toggle button to the formula below. When the hosting app sets the RefeshData property to indicate new data has been set this sets the index variable back to 1
Set(CurrentIndex,1)
- Set the Default property of the toggle button to the formula below. This hooks up the RefreshData property to the hidden toggle control. When the hosting app changes this property value it will cause the OnChange formula above to execute. We are using the toggle control simply to allow the hosting app to run a formula on demand because components don’t have a way to directly have a hosting app run a component formula
Parent.RefreshData
- Click Controls again and select Slider. You are adding this control to simulate behavior properties. You will hide it later.
- Move the slider control to bottom.
- Set the slider Default property to the current index. This sets the value of the slider, when the index changes the slider OnChange behavior will run causing the formula to update the HTML Text control with a new record.
CurrentIndex
- Set the slider Minimum property to 1.
- Set the slider Maximum property to the formula below.
CountRows(Parent.Data)
- Set the slider OnChange property to the formula below. This runs when the CurrentIndex variable is changed.
If(CountRows(Parent.Data) > 0,ClearCollect(
TemplateData,
{
Name: “HtmlTemplate”,
Template: Parent.Template
}
);Set(CurrentRecord,Last(FirstN(Parent.Data, CurrentIndex)));
ForAll(
CurrentRecord.Values,
Patch(
TemplateData,
LookUp(
TemplateData,
Name = “HtmlTemplate”
),
{Template: Substitute(LookUp(TemplateData,Name = “HtmlTemplate”).Template,”{“& Col &”}”,Value)}
)
);Set(OutputHtml,LookUp(TemplateData,Name = “HtmlTemplate”).Template))
The above formula does the following (Each bullet below represents one of the forumlas above):
- Creates a copy of the HTML template so we can customize it for this record.
- Sets CurrentRecord varaiable based on the CurrentIndex. CurrentIndex represents the record number in the set we want to display. You can’t explictly get a record in a Table, so we are using Last and FirstN to help get the specific record. For example if CurrentIndex is 7 and we had 10 records, FirstN of 7 would return us the first 7 records. Last on that would give us just the 7th record. Using this technique you can access a specific record in a set by an index value.
- Loops through all the values that we want to replace in the template, and for each calls Subsitute to replace the value in the template.
- Sets the OutputHtml property with the results and later we will use this to populate the Html Text control.
- Select the htmlText control.
- Set the HtmlText property of the htmlText control to the OutputHtml.
OutputHtml
- Your component will now look like the image below.
- Click File and save your changes.
- Go back to the app designer by clicking on the back button.
Task 2: Consume the Component
In this task, you will consume the component in the hosting app.
- Select the Screens tab.
- Select the MainScreen, go to the Insert tab, click Components, and select the Carousel component you created.
- Set the Template property to the formula below. This is the HTML that will be used to format each record. {1} and {2} are replaceable with data from the record being visualized. This is a very simple template, it could include more styling and layout as needed.
“<H1>{1}</H1><H2>{2}</H2>”
- Set the Data property to selected contacts.
SelectedContacts
- Select accountsList and set the OnSelect property to the formula below.
Set(RefreshContacts, false );Clear(SelectedContacts);ForAll(accountsList.Selected.Contacts,Collect(SelectedContacts,{Record:contactid,Values:Table({Col:1,Value:fullname},{Col:2,Value:jobtitle})}));Set(RefreshContacts, true);
This is preparing the data for the component formatting the contact data into the format expected.
- Place the carousel component on the screen like the image below.
- Click Play.
- Select an account with more than one contact. Alpine Ski House has two related contacts. The Carousel should load the first contact.
- Click on the next button.
- The second contact should load.
- Close the preview.
Task 3: Add Auto Play
In this task, you will add auto play and hide the toggle and slider controls.
- Select the Components tab and select the Carousel component.
- Go to the Insert tab, click Controls, and select Timer.
- Change the timer Duration to 5 seconds. The unit of measure is milliseconds, so to set to 5 seconds, the value you set is 5000.
- Set the timer OnTimerEnd property to the formula below. We are using the timer control to automate rotating the current record being shown by the carousel. Every 5 seconds (based on how you configure the timer) the formula you configure for OnTimerEnd will run. We are using that to increment the index if it is less than the # of records in the data collection and if it reaches the end we are setting it back to the beginning.
If (CurrentIndex < CountRows(Parent.Data),Set(CurrentIndex,CurrentIndex+1),Set(CurrentIndex,1))
- Set the Repeat property of the timer to true.
- Set the Text property of the timer to “Auto Rotate”.
- Set the X property of the timer to the formula below. Next, we are going to adjust the timer play button so if the hosting app changes the size of our component the size of the button will adjust.
(Parent.Width / 2) – (Timer1.Width/2)
- Set the Y property of the timer to the formula below.
Parent.Height – (Timer1.Height + 10)
- Set the Visible property of the toggle and slider controls to false. Since we are using both these controls simply to call our formulas, we can hide them from the user.
- Your component should now look like the image below.
- Click File and save your changes.
- Click on the back arrow to go back to the app designer.
- Select the Screens tab.
- Resize Carousel_1 as shown in the image below.
- Click Play.
- Select Alpine Ski House again.
- Click Auto Rotate.
- The contacts should rotate based on the 5 seconds duration you selected.
- Close the preview.
Task 4: Add Selected Record
In this task, you will set the selected record of the component to current record and display information from the component on the consuming screen. This is useful because otherwise the hosting app doesn’t know what record is selected. This also shows how a component can make data available to the hosting app using output properties.
- Select the Components tab and select the Carousel component.
- Go to the Properties pane and select the Advanced tab.
- Scroll down and click More Options.
- Replace the text in Selected (Output) with CurrentRecord.
CurrentRecord
- Click File and save your changes.
- Go back to the app designer.
- Select the Screens tab, select the MainScreen, go to the Insert tab, and click Label.
- Set the Text property of the label to formula below.
First(Carousel_1.Selected.Values).Value
- Resize and reposition the label as shown in the image below.
- Click Play.
- Select Alpine Ski House. The label should display the selected contact.
- Click Auto Rotate.
- The label should rotate with the selected item in the component.
*This post is locked for comments