Tutorials/Power Apps/Power Apps Form UX Mastery: Input Restrictions, Validation, and Error Handling
Power Appsintermediate

Power Apps Form UX Mastery: Input Restrictions, Validation, and Error Handling

Learn how to enforce data entry rules, validate form fields, manage submission errors, and prevent accidental data loss in canvas apps.

NA
Narmer Abader
@narmer · Published June 3, 2026

More than just data capture, a well-designed canvas app form influences how quickly users complete their work and how likely they are to trust the tool. Small UX details — like preventing invalid keystrokes, showing clear error messages, and protecting unsaved edits — dramatically reduce mistakes and frustration.

This article builds a real scenario: an Equipment Inventory app for tracking office hardware. We’ll walk through five concrete improvements: restricting control input, validating data before submission, handling server‑side errors, preventing accidental loss of changes, and reusing a single form for view, edit, and create modes.

All examples reference a SharePoint list or Dataverse table called EquipmentInventory with the following fields:

FieldData TypeConstraints
EquipmentNameTextRequired
SerialNumberText (max 30)Required, unique
PurchaseDateDateRequired, not future
PurchaseCostCurrencyRequired, ≤ 100,000
AssignedToPerson/UserOptional
StatusChoice (Active/Retired)Default “Active”
NotesMulti‑line textOptional

Step 1: Configuring Text Inputs for Accuracy

Set the Format property of a Text input to Number when the field expects numeric data only. For PurchaseCost, this immediately blocks any non‑numeric characters.

Similarly, use the MaxLength property to match the maximum length defined in the data source. For SerialNumber (30 characters), either set a static value or retrieve it dynamically:

powerfxSet MaxLength from source metadata
MaxLength:
  If(
      IsBlank(DataSourceInfo(EquipmentInventory, DataSourceInfo.MaxLength, "SerialNumber")),
      30,
      DataSourceInfo(EquipmentInventory, DataSourceInfo.MaxLength, "SerialNumber")
  )
Note

DataSourceInfo may not be available for all connectors. When it returns blank, fall back to a hard‑coded number that matches your back‑end constraint.

For fields with complex patterns (phone numbers, postal codes), replace a plain Text input with the Masked input control to show format placeholders while the user types.

Step 2: Validating the Form Before Submission

Client‑side validation gives immediate feedback. You can check each field on the change event or run all checks when the user presses Submit. A combined approach works best:

  1. Display a list of errors at the top of the form.
  2. Highlight invalid fields with a red border.
  3. Keep the submit button enabled but show why it will fail.

The following Submit button OnSelect gathers errors and either submits or notifies:

powerfxSubmit button with inline validation
// Clear previous errors
Set(varErrors, "");

// Check required fields
If(IsBlank(TextInput_EquipmentName.Text),
  Set(varErrors, varErrors & "Equipment Name is required." & Char(10))
);
If(IsBlank(TextInput_SerialNumber.Text),
  Set(varErrors, varErrors & "Serial Number is required." & Char(10))
);
If(IsBlank(DatePicker_PurchaseDate.SelectedDate),
  Set(varErrors, varErrors & "Purchase Date is required." & Char(10))
);

// Check length and range
If(Len(TextInput_SerialNumber.Text) > 30,
  Set(varErrors, varErrors & "Serial Number must be 30 characters or less." & Char(10))
);
If(Value(TextInput_PurchaseCost.Text) > 100000,
  Set(varErrors, varErrors & "Purchase Cost cannot exceed 100,000." & Char(10))
);

// Submit if no errors, else display them
If(varErrors = "",
  SubmitForm(Form1),
  Notify("Please fix the following issues:" & Char(10) & varErrors, NotificationType.Error)
)

To mark individual controls, switch their BorderColor based on the error variable — for example, If(IsBlank(TextInput_EquipmentName.Text) && varErrors <> "", Color.Red, Color.Black).

UX caution

Do not disable the submit button until all fields are valid. The Smashing Magazine article linked in the references explains why disabled buttons hide the reason for failure and frustrate users. Instead, always show the validation errors and let the user know what needs fixing.

Step 3: Graceful Error Handling After Submission

Never assume a form submitted successfully. Server‑side errors (e.g. duplicate keys, permission failures) can happen even when client validation passes. If you use the Form control, trap errors in OnSuccess and OnFailure:

powerfxForm control success / failure handlers
// OnSuccess
Set(varSubmitSuccess, true);
Notify("Record saved.", NotificationType.Success);
Navigate(InventoryScreen);  // or refresh your gallery

// OnFailure
Set(varLastError, First(Errors(Form1)).Message);
Notify("Submission failed: " & varLastError, NotificationType.Error);

For Patch‑based forms (no form control), wrap the Patch call with an IfError function:

powerfxIfError with Patch
IfError(
  Patch(EquipmentInventory, Gallery1.Selected, {EquipmentName: TextInput_EquipmentName.Text}),
  Notify("Update failed: " & FirstError.Message, NotificationType.Error),
  Notify("Update succeeded.", NotificationType.Success)
)

Always include a fallback that prevents the user from navigating away until the error is resolved. This can be a simple Set(varSubmitAttempted, false) check in the screen OnHidden.

Step 4: Guarding Against Accidental Data Loss

A user may accidentally navigate away while the form contains unsaved edits. The Unsaved property of the form control returns true when changes have not been committed.

Add this check to the screen’s OnHidden or to a Back button:

powerfxPrompt before leaving with unsaved data
Set(varShowDiscard, Form1.Unsaved);
If(varShowDiscard,
  Set(varShowDiscardDialog, true),
  Navigate(PreviousScreen)
)

When varShowDiscardDialog becomes true, show an overlay with two buttons: Continue editing (hides the dialog) and Discard changes (cancels the form and navigates). Use a Group control or Dialog component for the pop‑up. Clear the form with ResetForm(Form1) before leaving if the user chooses discard.

Step 5: Reusing a Single Form for All Interactions

Maintaining three separate forms (create, edit, view) for the same data source is unnecessary. Use one form control and switch its mode with NewForm, EditForm, and ViewForm. This reduces code duplication and ensures a consistent layout.

  • View mode: show all controls with DisplayMode.View.
  • Edit mode: allow edits.
  • Create mode: same as edit, but starts with a blank record.

Pass the selected record from a gallery to the form:

powerfxEditing the selected record
Set(varSelectedRecord, Gallery_Equipment.Selected);
EditForm(Form1);
powerfxViewing a record (no editing)
Set(varSelectedRecord, Gallery_Equipment.Selected);
ViewForm(Form1);

For Patch‑based forms you must manually toggle the DisplayMode of every control. Consider wrapping that logic in a simple Set(varFormMode, "Edit") variable and setting each control’s DisplayMode to If(varFormMode = "View", DisplayMode.View, DisplayMode.Edit).

Security and Performance Considerations

  • Client validation is never a substitute for server rules. Power Apps enforces data source constraints on submission, but always use appropriate permissions and column validation in SharePoint or Dataverse.
  • DataSourceInfo is not delegated. It returns metadata from the source when the app starts, not during a large batch. Use it sparingly and fall back to static values for performance‑critical screens.
  • Heavy formulas in OnChange can cause sluggish typing. For real‑time character counting or length checks, stick to simple Len(…) comparisons.

Common Pitfalls and How to Avoid Them

MistakeSolution
Errors not appearing after submissionCheck that Errors(Form1) is not empty and that OnFailure is wired correctly.
Disabled submit button without explanationUse Notify or a label to show why the button is disabled while keeping it enabled.
Forgetting to reset validation variables on a new formSet(varErrors, "") at the start of NewForm or ResetForm.
Unsaved changes dialog not showingVerify Form.Unsaved is being checked on the correct screen event (OnHidden, not OnVisible).
Single form shows empty fields on initial gallery selectCall EditForm or ViewForm after setting the selected record, not before.

Final Thoughts

Great form UX is built by combining small but intentional checks: restrict what users can type, validate before submitting, handle errors gracefully, protect unsaved work, and reuse the same form to stay consistent. These patterns are easy to implement and pay off immediately in user confidence and data quality.

Start with the equipment inventory scenario in this article, adapt the validation rules to your own data, and watch your app move from functional to delightful.

References