Build Smarter Form Validation in Canvas Apps
Ensure accurate data entry with real-time validation patterns in Power Apps forms.
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.compattern - 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 Type | Name |
|---|---|
| Text Input | txtName |
| Text Input | txtEmail |
| Text Input | txtPhone |
| Date Picker | dpPickup |
| Dropdown | ddCategory |
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:
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:
If(IsBlank(txtName.Text), Icon.Cancel, Icon.Check)
Visible property:
varNameDirty
Fill property (to color the icon):
Switch(icoName.Icon, Icon.Check, Color.Green, Icon.Cancel, Color.Red )
Label lblNameError – visible only when the field is invalid and dirty:
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:
Set(varNameDirty, true)
Pattern Matched – Email
- Icon name:
icoEmail - Label name:
lblEmailError
Use the built-in Match.Email pattern. On the icon:
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:
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
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:
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.
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:
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:
Set(varDateDirty, true)
Dropdown – Equipment Category
- Icon name:
icoCategory - Label name:
lblCategoryError
We only need to ensure that a value is actually chosen (no blank selection).
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:
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:
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
| Mistake | Symptom | Solution |
|---|---|---|
| Dirty flags not initialized | Validation icons appear immediately on app start | Set all dirty flags to false in OnVisible or OnStart |
Using UpdateContext inside a control that also resets the context | Icon visibility flickers | Use Set for global variables or manage context carefully with Patch |
Forgetting to escape & in pattern strings | ISMatch returns unexpected results | Write the pattern inside double quotes and use Match.Digit etc. as expressions |
| Error label not updating | Text remains stale | Bind 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
- Original source: Data Validation For Power Apps Forms by Matthew Devaney
- Microsoft Learn: IsMatch function in Power Apps
- Microsoft Learn: Working with tables and records (UpdateContext, Patch)