Tutorials/Power Apps/Shape-Shifting Forms: Data-Driven UIs in Power Apps
Power Appsintermediate

Shape-Shifting Forms: Data-Driven UIs in Power Apps

Eliminate form sprawl. Build one canvas form that reconfigures itself based on a configuration table. Perfect for adaptable intake processes.

NA
Narmer Abader
@narmer · Published June 3, 2026

Every Power Apps developer eventually hits the wall: your business owner wants a single screen that morphs into different forms based on a selection. Instead of coding ten nearly-identical screens, you can build one form that drives its structure from data. This technique—which I call the Adaptive Form Pattern—relies on a gallery and a configuration table to render the right controls at the right time. We will build an IT access-request intake form that adjusts its fields on the fly.

The Core Idea: Configuration-Driven UI

The principle is straightforward. The Items property of a vertical gallery points to a FormDefinition table. Each row is one field and contains:

  • A Prompt (the label the user sees).
  • A ControlType (Text, Number, Radio, Combo, Date).
  • An Options list for choice-based controls.

Inside the gallery template, you stack the input controls. Each control’s Visible property checks the current row's ControlType. When the gallery renders, it only shows the control that matches the row's definition.

Step 1: Define Your Form Configuration

Let's build the configuration table. For simplicity, we will create it in the app’s OnStart using a collection. Later, you can migrate this to a SharePoint list so business owners can edit the form without opening Power Apps Studio.

powerfxOnStart (or a Button for testing)
ClearCollect(FormConfig,
  { Id: 1, Prompt: "Requester’s Full Name", Type: "Text", Options: Blank() },
  { Id: 2, Prompt: "Employee ID", Type: "Number", Options: Blank() },
  { Id: 3, Prompt: "Department", Type: "Combobox", Options: ["Sales", "Support", "Engineering", "Finance"] },
  { Id: 4, Prompt: "Access Level", Type: "Radio", Options: ["Read Only", "Edit", "Admin"] },
  { Id: 5, Prompt: "Access Expiry Date", Type: "Date", Options: Blank() }
)
  1. Insert a Blank vertical gallery onto your screen.
  2. Set its Items property to FormConfig.
  3. Inside the template, add the following controls:
    • A Label for the prompt.
    • A Text input (rename to txt_PrimaryInput).
    • A Radio button (rename to rdo_Options).
    • A Combo box (rename to cmb_Options).
    • A Date picker (rename to dte_DatePick).

Align the controls so they stack directly on top of each other in the same cell. Because only one control will be visible per row, they share the physical space without overlapping visually.

Step 3: Wire Visibility and Formatting

The logic belongs in the Visible and Format properties.

Label – Display the prompt:

powerfxLabel Text property
ThisItem.Prompt

Text Input – Show for Text and Number types:

powerfxText Input Visible property
ThisItem.Type = "Text" || ThisItem.Type = "Number"

Text Input – Switch keyboard to numeric for Number type:

powerfxText Input Format property
If(ThisItem.Type = "Number", TextFormat.Number, TextFormat.Text)

Radio Button – Visible for Radio type, load choices:

powerfxRadio Visible and Items properties
// Visible
ThisItem.Type = "Radio"

// Items
ThisItem.Options

Combo Box – Visible for Combobox type, load choices:

powerfxCombo Box Visible, Items, and DisplayFields
// Visible
ThisItem.Type = "Combobox"

// Items
ThisItem.Options

// DisplayFields / SearchFields
["Value"]

Date Picker – Visible for Date type:

powerfxDate Picker Visible property
ThisItem.Type = "Date"

Preview the app. The gallery should now show a different control type on each row.

Step 4: Capture and Submit the Data

When the user clicks Submit, we need to:

  1. Loop through the gallery items.
  2. Read the value from whichever control is visible.
  3. Store the responses in a collection.
  4. Persist the data to SharePoint or Dataverse.

A two-step approach avoids concurrency issues that can arise when you Patch inside a ForAll.

powerfxOnSelect of the Submit Button
// Step 1: Collect all responses
Clear(colResponses);
ForAll(gal_AdaptiveForm.AllItems,
  Collect(colResponses,
      {
          Question: ThisRecord.Prompt,
          Answer: Switch(ThisRecord.Type,
              "Text", txt_PrimaryInput.Text,
              "Number", txt_PrimaryInput.Text,
              "Radio", rdo_Options.Selected.Value,
              "Combobox", cmb_Options.Selected.Value,
              "Date", Text(dte_DatePick.SelectedDate, DateTimeFormat.ShortDate)
          )
      }
  )
);

// Step 2: Create the header record
Set(varFormHeaderId,
  Patch(AccessRequests, Defaults(AccessRequests),
      { Title: First(colResponses).Answer, SubmittedOn: Now() }
  ).ID
);

// Step 3: Create the detail records
ForAll(colResponses,
  Patch(AccessRequestDetails, Defaults(AccessRequestDetails),
      {
          RequestId: varFormHeaderId,
          QuestionText: ThisRecord.Question,
          ResponseText: ThisRecord.Answer
      }
  )
);

// Step 4: Reset the form
Reset(gal_AdaptiveForm);
Data Source Setup

In the example above, AccessRequests is the header table and AccessRequestDetails stores the individual question/answer pairs linked via a lookup. Adjust the table and column names to match your actual schema.

Common Mistakes & Troubleshooting

Combo Box Value Extraction cmb_Options.Selected returns a record. Always use .Value (e.g., cmb_Options.Selected.Value) when your Items is a single-column table. If your source comes from a SharePoint choice column, the column name is usually .Title.

Stale Values After Reset Calling Reset(gal_AdaptiveForm) re-renders the gallery but does not clear the values inside the controls. To force a clean slate, recreate the configuration collection after submit:

powerfxHard reset inside the Submit flow
// After the Reset call
ClearCollect(FormConfig, Table(...)); // recreate your definition

Delegation Risk The AllItems property of a gallery is not delegable. For almost all form definitions (usually under 50 rows) this is a non-issue.

Delegation

If your configuration table lives in SharePoint and grows beyond 500 rows, cache it in a local collection on OnStart. The gallery reads from the collection at full speed.

Overlapping Controls Every control inside the gallery must have its Visible property explicitly set. Leaving a control at the default true causes it to overlap with the intended visible control.

Advanced: Taking the Pattern Further

Section Headers Add a Section column to your FormConfig. If the section value changes between rows, show a label that announces the new section. This creates a multi-page feel inside a single gallery.

Conditional Questions Add a DependsOn column. Before making a control visible, check the answer of a previous question. This turns the form into a genuine decision tree.

Reusable Component Export the gallery as a Power Apps Component. Pass FormConfig as a custom input property. Now you have a portable adaptive form that you can drop into any app without recoding a single line.

Recommendation

The Adaptive Form Pattern is one of the highest-leverage techniques in intermediate Power Apps development. It transforms a static screen into a configurable engine. Start with a hard-coded collection to validate the logic, then move the configuration to a SharePoint list where your team can modify fields without ever opening Power Apps Studio.

References