cancel
Showing results for 
Search instead for 
Did you mean: 
Danielkon96

Build a Dynamic Form in Power Apps

Table of Contents

This post will cover the following steps:

  1. Connecting the UI metadata to the PowerApp
  2. Creating a dynamic UI and collecting user input
  3. Exporting user input to Power Automate
0.png

Preparation

To begin, we need to create our UI metadata. What is UI metadata? It is data that describes the UI. This could be UI text, the input type, min/max numbers for sliders, question/section numbers, combo box options and anything else that may be of value to you. The metadata comes from a data source in PowerApps. In this article, we’ll be using a SharePoint List but SQL, Azure, Excel Sheets, and other data sources will work too.

 

Note: It is important to be consistent when creating UI metadata because the Power App will be using this data in If statements and inconsistency will break the UI.

A SharePoint List example containing UI MetadataA SharePoint List example containing UI Metadata

 

Import the UI Metadata

To begin, I’ve created a blank canvas app. Let’s import the UI metadata.

  1. Click the data tab on the left sidebar
  2. Click ‘Add data’ and select the data source containing the UI metadata

Screenshot of data source added to the PowerAppScreenshot of data source added to the PowerApp

Create UI Metadata Collection

Now that the data source is added to the PowerApp, let’s add it to a collection in the OnVisible function of our screen.

  1. Go back to the tree view tab on the left sidebar
  2. Select your screen and navigate to the OnVisible function
  3. Add the following code shown in the screenshot below

Screenshot of our UI metadata added to a collectionScreenshot of our UI metadata added to a collection

Code from screenshot above:

 

 

Refresh('UI Metadata List');
ClearCollect(UIMetadataCollection, 'UI Metadata List');

 

 

Create the User Input Collection

Before we jump into creating the dynamic UI, we need to create a collection that will keep track of user input.

  1. Select your screen and navigate to the OnVisible function
  2. Add the following code shown in the screenshot below

Screenshot of changing OnVisible functionScreenshot of changing OnVisible function

Code from screenshot above:

 

 

Clear(UserInputCollection);
ForAll(
    UIMetadataCollection,
    If(ThisRecord.ui_type <> "label" && ThisRecord.ui_type <> "button",
        Collect(
            UserInputCollection,
            {
                ui_text: ThisRecord.ui_text,
                user_input: "",
                ui_type: ThisRecord.ui_type,
                min_number: ThisRecord.min_number,
                max_number: ThisRecord.max_number
            }
        )
    )
);

 

 

Summary: All the UI metadata (labels, control types, etc) live outside of the canvas app. This gives us the ability to add, edit, or remove UI elements dynamically without changing anything in PowerApps. In this section we’ve connected the data source to our PowerApp and we’ve created a collection that will keep track of all user input in our dynamic form.

 

Create Dynamic UI

Now it’s time to jump into the main reason you’re here, the dynamic UI. This is where the magic really happens. First and foremost, let’s create a flexible gallery.

  1. Create a flexible gallery as shown in the screenshot below

Screenshot of blank flexible galleryScreenshot of blank flexible gallery

2. Change the items property to UIMetadataCollection (the collection that holds the UI metadata imported from the data source) as shown below

Screenshot assigning the items property to UIMetadataCollectionScreenshot assigning the items property to UIMetadataCollection

Note: Click the pencil in the top left corner of the gallery to insert UI elements.

 

Label

  1. Add a label to the flexible gallery
  2. Select the label element and navigate to the Text property
  3. Add the following code shown in the screenshot below

Note: If you don’t see any text show up, refresh your PowerApp screen (save your work first). Another option is to create a second screen, add a button, and use that button to navigate to the Dynamic Form Screen. We need to do this because the OnVisible function of our screen needs to be triggered.

Screenshot changing Text propertyScreenshot changing Text property

Text Input

  1. Add text input to the flexible gallery
  2. Select the text input element and navigate to the Visible property
  3. Add the following if statement shown in the screenshot below

Screenshot changing Visible propertyScreenshot changing Visible property

Code from screenshot above:

 

 

If(ThisItem.ui_type = "text_input", true, false)

 

 

Date Picker

  1. Add date picker to the flexible gallery
  2. Select the date picker element and navigate to the Visible property
  3. Add the following if statement shown in the screenshot below

Screenshot changing Visible propertyScreenshot changing Visible property

Code from screenshot above:

 

 

If(ThisItem.ui_type = "date_picker", true, false)

 

 

Slider

  1. Add slider to the flexible gallery
  2. Before we set visibility, change the Default, Min and Max properties as shown in the screenshot below

Screenshot changing the Default, Min, and Max propertiesScreenshot changing the Default, Min, and Max properties

  1. Now let’s set the visibility property
  2. Select the slider element and navigate to the Visible property
  3. Add the following if statement shown in the screenshot below

Screenshot changing Visible propertyScreenshot changing Visible property

Code from screenshot above:

 

 

If(ThisItem.ui_type = "slider", true, false)

 

 

Checkbox

  1. Add checkbox to the flexible gallery
  2. Before we set visibility, change the Text property as shown in the screenshot below

Screenshot changing Text propertyScreenshot changing Text property

  1. Now let’s set the visibility property
  2. Select the checkbox element and navigate to the Visible property
  3. Add the following if statement shown in the screenshot below

Screenshot changing Visible propertyScreenshot changing Visible property

Code from screenshot above:

 

 

If(ThisItem.ui_type = "checkbox", true, false)

 

 

  1. For the last step, we will want to adjust our label so that it doesn’t display the text twice when a checkbox element is being displayed.
  2. Select the label element and navigate to the Visible property
  3. Add the following if statement shown in the screenshot below

Screenshot changing Visible propertyScreenshot changing Visible property

Code from screenshot above:

 

 

If(ThisItem.ui_type = "checkbox", false, true)

 

 

Button

  1. Add button to the flexible gallery
  2. Select the button element and navigate to the Visible property
  3. Add the following if statement shown in the screenshot below

Screenshot changing Visible propertyScreenshot changing Visible property

Code from screenshot above:

 

 

If(ThisItem.ui_type = "button", true, false)

 

 

Summary: You may be starting to see a pattern here. In this section we made certain elements visible if they matched the ui_type in the metadata table. I challenge you to follow the same steps for the rest of the items in your UI metadata table.

 

Collect User Input

So now that the dynamic UI is built, we need to keep track of user input. This is where the UserInputCollection will be used. We’ll be using Lookup and Patch functions found in PowerApps. Let’s jump right in!

 

Text Input

  1. Select the text input element and navigate to the OnChange function
  2. Add the following code shown in the screenshot below

Screenshot changing OnChange functionScreenshot changing OnChange function

Code from screenshot above:

 

 

Patch(
    UserInputCollection,
    LookUp(
        UserInputCollection,
        ui_text = Label.Text
    ),
    {
        user_input: TextInput.Text
    }
);

 

 

Date Picker

  1. Select the date picker element and navigate to the OnSelect function
  2. In the OnSelect function we will add a variable so that PowerApps does not call OnChange when it is initializing the gallery. Add the variable in the screenshot below

Screenshot changing OnSelect functionScreenshot changing OnSelect function

  1. Next, navigate to the OnChange function
  2. Add the following code shown in the screenshot below

Screenshot changing OnChange functionScreenshot changing OnChange function

Code from screenshot above:

 

 

If(datePickerChange, 
    Set(datePickerChange, false);

    Patch(
        UserInputCollection,
        LookUp(
            UserInputCollection,
            ui_text = Label.Text
        ),
        {
            user_input: Text(DatePicker.SelectedDate)
        }
    );
)

 

 

Slider

  1. Select the slider element and navigate to the OnSelect function
  2. In the OnSelect function we will add a variable so that PowerApps does not call OnChange when it’s initializing the gallery. Add the variable in the screenshot below

Screenshot changing OnSelect functionScreenshot changing OnSelect function

  1. Next, navigate to the OnChange function
  2. Add the following code shown in the screenshot below

Screenshot changing OnChange functionScreenshot changing OnChange function

Code from screenshot above:

 

 

If(sliderChange, 
    Set(sliderChange, false);

    Patch(
        UserInputCollection,
        LookUp(
            UserInputCollection,
            ui_text = Label.Text
        ),
        {
            user_input: Text(Slider.Value)
        }
    );
)

 

 

Checkbox

  1. Select the checkbox element and navigate to the ‘OnCheck’ and ‘OnUncheck’ functions
  2. Add the following code shown in the screenshot below to BOTH functions

Screenshot changing OnCheck & OnUncheck functionsScreenshot changing OnCheck & OnUncheck functions

Code from screenshot above

 

 

Patch(
    UserInputCollection,
    LookUp(
        UserInputCollection,
        ui_text = Label.Text
    ),
    {
        user_input: Text(Checkbox.Value)
    }
);

 

 

Summary: We now keep track of all user input within the dynamic form. My speculation on why this works is that PowerApps keeps track of what gallery element the user is interacting with. As a result, we can use the element’s information to update our UserInputCollection by calling Patch and doing a LookUp using the Label.Text.

 

Export User Input

For our last section, navigate to the button we created earlier in the article.

Add a Power Automate

  1. When you have selected the button, navigate to the Action tab at the top of the page
  2. Select Power Automate and click on Create a new flow as shown below

Screenshot of creating a new flowScreenshot of creating a new flow

  1. Select the flow you want and customize it as you see fit. I have selected a Power Apps Button flow, added a Compose step, and selected Ask in PowerApps as the input as shown in the screenshot below
Screenshot of new flowScreenshot of new flow

2. When you are done creating the flow, go back to the PowerApp and select the flow as shown below

Screenshot of adding a new flowScreenshot of adding a new flow

Export User Input as JSON

When the flow has been added, the last step is passing the UserInputCollection to the flow in JSON format.

  1. Select the button element and navigate to the OnSelect function
  2. Add the following code shown in the screenshot below

Screenshot changing OnSelect functionScreenshot changing OnSelect function

Code from screenshot above

 

 

PowerAppsbutton.Run(    
    JSON(
        UserInputCollection,
        IncludeBinaryData
    )
);

 

 

Note: If you need additional help exporting user input, take a look at this article written by Reza Dorrani. One more note: You can export user data to something else besides JSON as shown in the article.

 

Now that we’re done, save your application and give it a spin! When you click submit, go to your Power Automate and see it run. You can also add, edit, or remove UI metadata and see the UI updated in the PowerApp (after a browser refresh or button navigation).

 

Here is a final walk-through of everything we’ve built:

Final Walkthrough GIFFinal Walkthrough GIF

Happy Coding and God Bless!