Smart Statistics · Practical Power Apps tutorial
Power Apps Save and Cancel: Keep Form Edits Safe
A button press is not proof that a record was saved. Give users a clear result, preserve their work when something fails, and make discarding edits a deliberate choice.
By Smart Statistics ·
The form journey, made visible
Illustrative example · fictional acceptance-test dashboardTest outcomes
Illustrative example · all chart valuesRequired behaviour
Editing: values remain available
Saving: repeat clicks blocked
Success: saved record confirmed
Failure: explanation stays visible
Build a small form with a clear contract
Imagine a facilities coordinator correcting a maintenance request before handing it to an engineer. If the app closes the form too soon, the coordinator may assume the change reached SharePoint. A missing description can then become a repeat visit, a telephone chase or duplicated administration.
This tutorial builds an online canvas app using a classic Edit form. It handles new requests and edits to existing ones. It does not provide offline drafts, guaranteed duplicate prevention or simultaneous-edit conflict resolution. Use a separate design for those requirements.
Work in a test app and a test SharePoint list first. You need maker access, a working SharePoint connection and permission to create and update items. Confirm licensing and environment policies with your administrator.
Set up the list and three screens
Create a SharePoint list named Maintenance Requests. Keep Title as required single-line text. Add Description as plain multiple lines of text. Use fictional records only. Connect the list to the app.
| Screen | Controls and settings |
|---|---|
| scrRequests | Gallery galRequests; New button; an Edit button inside the gallery template. |
| scrEdit | Classic Edit form frmRequest, Save and Cancel buttons, error label, and a discard confirmation container with two buttons. |
| scrSaved | Confirmation label and a Back to requests button. |
Add Title and Description to the form through Edit fields. Keep the generated card bindings and validation labels. Do not add an OnVisible formula that resets the form whenever scrEdit appears.
galRequests.Items and frmRequest.DataSource — set each property to:
'Maintenance Requests'
frmRequest.Item
varRequest
Open a record intentionally
New button on scrRequests — OnSelect
Set(varSaving, false);
Set(varDiscard, false);
Set(varSaveError, Blank());
Set(varRequest, Defaults('Maintenance Requests'));
NewForm(frmRequest);
Navigate(scrEdit, ScreenTransition.None)
Edit button inside galRequests — OnSelect
Set(varSaving, false);
Set(varDiscard, false);
Set(varSaveError, Blank());
Set(varRequest, ThisItem);
EditForm(frmRequest);
Navigate(scrEdit, ScreenTransition.None)
Set the gallery’s visible title label to ThisItem.Title. Selecting the record explicitly keeps the form tied to the intended request. Always enter through these buttons during this tutorial.
Save now; leave only after success
The Save button starts submission. The form’s success handler decides when to leave. Do not put an unconditional Navigate or ResetForm after SubmitForm in the Save button.
Save button — OnSelect
If(
!varSaving,
If(
frmRequest.Valid,
Set(varSaveError, Blank());
Set(varSaving, true);
SubmitForm(frmRequest),
Set(varSaveError, "Complete the required fields before saving.")
)
)
Save button — DisplayMode
If(varSaving || varDiscard, DisplayMode.Disabled, DisplayMode.Edit)
Save button — Text
If(varSaving, "Saving…", "Save request")
frmRequest.OnSuccess
Set(varRequest, frmRequest.LastSubmit);
Set(varSaving, false);
Set(varSaveError, Blank());
Navigate(scrSaved, ScreenTransition.None)
frmRequest.OnFailure
Set(varSaving, false);
Set(
varSaveError,
Coalesce(frmRequest.Error, "Save failed. Check your connection and try again.")
)
While submission runs, prevent further editing. For each editable data card, set DisplayMode to the formula below; leave its child input’s DisplayMode as Parent.DisplayMode. Apply the same lock to any custom navigation controls.
Title and Description data cards — DisplayMode
If(varSaving || varDiscard, DisplayMode.Disabled, Parent.DisplayMode)
Error label — Text
Coalesce(varSaveError, "")
Error label — Visible
!IsBlank(varSaveError)
Set the error label’s AutoHeight to true and Live to Live.Polite. Leave room below it in an auto-layout container. Preserve the form on failure: resetting it here would destroy the values the user needs to correct.
Confirmation label on scrSaved — Text
"Request saved. Reference: " & Text(varRequest.ID)
Back to requests button — OnSelect
Navigate(scrRequests, ScreenTransition.None)
Make Cancel a choice, not a trap
Use an inline confirmation panel on scrEdit. This avoids pretending that a visual overlay alone is an accessible modal. Put the panel after Cancel in the keyboard order, and give it a clear heading: “Discard these changes?”
Cancel button — DisplayMode
If(varSaving || varDiscard, DisplayMode.Disabled, DisplayMode.Edit)
Cancel button — OnSelect
If(
frmRequest.Unsaved,
Set(varDiscard, true),
ResetForm(frmRequest);
Navigate(scrRequests, ScreenTransition.None)
)
Confirmation container — Visible
varDiscard
Keep editing button — OnSelect
Set(varDiscard, false)
Discard changes button — OnSelect
ResetForm(frmRequest);
Set(varDiscard, false);
Set(varSaveError, Blank());
Navigate(scrRequests, ScreenTransition.None)
Set the confirmation heading’s Live property to Live.Polite. Ensure its buttons are reachable by keyboard and have descriptive text. Remove other in-app exits from this screen, or route them through the same decision. This pattern does not intercept browser close, device shutdown or every host Back action; unsaved changes are not durable drafts.
Test the failure paths as carefully as the happy path
Required field missing
Leave Title empty and press Save. Stay on scrEdit, see a clear message, and confirm no item was created. Correct the field and submit again.
Server rejects the save
In the test environment, use an account that can read but cannot update. Edit a request and submit. Confirm the failure message, retained values and re-enabled controls. Restore authorised access before retrying.
Discard versus keep
Change Description, choose Cancel, then Keep editing. The changed text must remain. Repeat and choose Discard changes; reopening must show the saved value.
New versus existing
Create a request and confirm the displayed reference exists in SharePoint. Edit it and confirm the same item changed. Test rapid repeat clicks and both keyboard and touch use.
For uncertain network outcomes, inspect the list before retrying a new request. Disabling a button reduces repeated clicks in this session; it is not an exactly-once write guarantee. Capture expected result, actual result and evidence for each test.
Give the pattern an owner
The app owner maintains formulas and release tests. The list owner controls permissions and required fields. A facilities supervisor approves the wording and confirms the handover works with real tasks. SharePoint permissions enforce access; disabling a button does not.
Measure abandoned entries, save-related support cases and verified duplicate requests before and after release. If reliable event logging is added, distinguish save attempts from confirmed successes. Do not claim time saved from button clicks alone: observe the rework that actually disappears.
Show users the three states—editing, saving and saved—and explain what to do after a failure. Review changes to cards, navigation and list validation together, since each can alter the experience.
Check your release evidence
Common questions
Does this save drafts automatically?
No. Values remain in the open form until submission or discard. Closing the app can lose unsaved work. Durable drafts require a separate design.
Does a disabled Save button prevent every duplicate?
No. It reduces repeated clicks while this submission is running. Cross-session retries and uncertain network outcomes need additional controls.
Where should navigation after saving go?
Put navigation that depends on a successful save in the form’s OnSuccess property. Keep the user on the edit screen when saving fails.
Can I use these formulas in a live app unchanged?
Use the exact control and data-source names in this tutorial, then test in a copy of your app. Adapt existing navigation, validation and security deliberately before release.
Make every save trustworthy.
Smart Statistics helps UK teams build Power Apps that make the next action clear, protect working data and fit the process people actually use.