Tutorials/Power Apps/Build Smarter Form Validation in Canvas Apps
Power Appsintermediate

Build Smarter Form Validation in Canvas Apps

Ensure accurate data entry with real-time validation patterns in Power Apps forms.

NA
Narmer Abader
@narmer · Published June 3, 2026

Instead of a single submission-time error summary, guiding users as they move through each field reduces frustration and improves data quality. In this article we’ll build a self-contained validation system for a loaner equipment request form. Each field—Employee Name, Email, Phone, Pickup Date, and Equipment Category—will show a clear success/failure indicator the moment the user leaves it.

Scenario: Equipment Loan Request Form

Your organization allows employees to borrow IT equipment for short projects. Every request must include:

  • Employee Name – mandatory
  • Email – must follow the standard user@domain.com pattern
  • Phone Number – optional, but if supplied it must be in the format (###) ###-####
  • Pickup Date – must be a future weekday (Monday–Friday)
  • Equipment Category – choose one from a predefined list (not blank)

We’ll make the validation appear only after the user has left the field (OnChange). This avoids prematurely showing errors while the person is still typing.

Setting Up the Screen and Variables

Start with a blank canvas app and add a Screen. Insert the controls listed below and rename them for clarity:

Control TypeName
Text InputtxtName
Text InputtxtEmail
Text InputtxtPhone
Date PickerdpPickup
DropdownddCategory

For each field we’ll use a dirty flag to decide whether validation has been triggered. Add the following code to the Screen’s OnVisible property:

powerfxInitialize dirty flags
Set(varNameDirty, false);
Set(varEmailDirty, false);
Set(varPhoneDirty, false);
Set(varDateDirty, false);
Set(varCategoryDirty, false);

Validating Each Field

We’ll use a combination of an icon and a label for each field. The icon shows a checkmark or an “X”, and the label below it describes the problem when validation fails.

Required Field – Employee Name

  • Icon name: icoName
  • Label name: lblNameError

Set the Icon property of icoName:

powerfxIcon for Name validation
If(IsBlank(txtName.Text), Icon.Cancel, Icon.Check)

Visible property:

powerfxVisibility of icon
varNameDirty

Fill property (to color the icon):

powerfxFill color
Switch(icoName.Icon,
 Icon.Check, Color.Green,
 Icon.Cancel, Color.Red
)

Label lblNameError – visible only when the field is invalid and dirty:

powerfxError label visibility
varNameDirty And IsBlank(txtName.Text)

Set its Text property to "Employee name cannot be blank" and Color to Red.

Finally, inside txtName.OnChange set the dirty flag:

powerfxMark Name as dirty
Set(varNameDirty, true)

Pattern Matched – Email

  • Icon name: icoEmail
  • Label name: lblEmailError

Use the built-in Match.Email pattern. On the icon:

powerfxIcon for Email validation
If(IsMatch(txtEmail.Text, Match.Email), Icon.Check, Icon.Cancel)

Its Visible property: varEmailDirty. Error label visible when: varEmailDirty And !IsMatch(txtEmail.Text, Match.Email).

Set txtEmail.OnChange:

powerfxMark Email as dirty
Set(varEmailDirty, true)

Optional Pattern – Phone Number

Because the phone is optional, the validation should pass if the field is blank or if it matches the custom pattern (###) ###-####.

  • Icon name: icoPhone
  • Label name: lblPhoneError
powerfxIcon for Phone validation (optional)
If(
  IsBlank(txtPhone.Text) Or
  IsMatch(
      txtPhone.Text,
      "(" & Match.Digit & Match.Digit & Match.Digit & ") " &
      Match.Digit & Match.Digit & Match.Digit & "-" &
      Match.Digit & Match.Digit & Match.Digit & Match.Digit
  ),
  Icon.Check,
  Icon.Cancel
)

Visible property: varPhoneDirty.

Error label text: "Phone number must be in the format (555) 123-4567". Visible when: varPhoneDirty And !IsBlank(txtPhone.Text) And icoPhone.Icon = Icon.Cancel.

Don’t forget to set the dirty flag on txtPhone.OnChange:

powerfxMark Phone as dirty
Set(varPhoneDirty, true)

Future Weekday – Pickup Date

  • Icon name: icoDate
  • Label name: lblDateError

Requirements: date must be in the future and fall on Monday–Friday.

powerfxIcon for Date validation
If(
  dpPickup.SelectedDate > Today()
  And Weekday(dpPickup.SelectedDate, StartOfWeek.Monday) <= 5,
  Icon.Check,
  Icon.Cancel
)

Visible property: varDateDirty.

The error label should be more helpful and indicate which condition failed:

powerfxError label with specific message
If(
  dpPickup.SelectedDate <= Today(),
  "Pickup date must be a future date",
  Weekday(dpPickup.SelectedDate, StartOfWeek.Monday) > 5,
  "Pickup date must be a weekday (Monday–Friday)",
  "No date selected"
)

Make the label visible when varDateDirty And icoDate.Icon = Icon.Cancel.

Set dpPickup.OnChange:

powerfxMark Date as dirty
Set(varDateDirty, true)
  • Icon name: icoCategory
  • Label name: lblCategoryError

We only need to ensure that a value is actually chosen (no blank selection).

powerfxIcon for Category validation
If(IsBlank(ddCategory.Selected.Value), Icon.Cancel, Icon.Check)

Visible property: varCategoryDirty.

Error label visible when varCategoryDirty And IsBlank(ddCategory.Selected.Value). Text: "Please select an equipment category".

Set ddCategory.OnChange:

powerfxMark Category as dirty
Set(varCategoryDirty, true)

Enabling the Submit Button

The Submit button should be disabled until all fields are passing their respective rules. Use its DisplayMode property:

powerfxSubmit button DisplayMode
If(
  IsBlank(txtName.Text) Or
  !IsMatch(txtEmail.Text, Match.Email) Or
  (!IsBlank(txtPhone.Text) And
     !IsMatch(txtPhone.Text,
            "(" & Match.Digit & Match.Digit & Match.Digit & ") " &
            Match.Digit & Match.Digit & Match.Digit & "-" &
            Match.Digit & Match.Digit & Match.Digit & Match.Digit
     )
  ) Or
  (dpPickup.SelectedDate <= Today() Or
     Weekday(dpPickup.SelectedDate, StartOfWeek.Monday) > 5) Or
  IsBlank(ddCategory.Selected.Value),
  DisplayMode.Disabled,
  DisplayMode.Edit
)

Security & Performance Considerations

Client-side validation improves user experience, but always treat it as a first line of defense. An attacker can still send malformed data directly to your API. Always validate input again in your data source (for example, using column constraints or a Power Automate flow).

Performance wise, the formulas above are lightweight because they only react to a single control or a static pattern. Avoid adding delegation‑sensitive data sources inside these validation expressions—they are evaluated eagerly and could slow down the form.

Common Mistakes and Troubleshooting

MistakeSymptomSolution
Dirty flags not initializedValidation icons appear immediately on app startSet all dirty flags to false in OnVisible or OnStart
Using UpdateContext inside a control that also resets the contextIcon visibility flickersUse Set for global variables or manage context carefully with Patch
Forgetting to escape & in pattern stringsISMatch returns unexpected resultsWrite the pattern inside double quotes and use Match.Digit etc. as expressions
Error label not updatingText remains staleBind the label’s Text property to a dynamic formula, not a static string

Final Recommendation

For forms that need precise control over error timing and messaging, this icon + label + dirty flag technique is simple to implement and maintain. While Power Apps also offers a built-in Validate function, that works best when connected to a data source that exposes column metadata. When you can’t rely on that (or when you need custom rules), building validation as shown here gives you complete flexibility.

References