Skip to content

Added new kb article form-prompt-unsaved-changes #2853

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions knowledge-base/form-prompt-unsaved-changes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
---
title: How to Prompt Users for Unsaved Changes on Navigation
description: A guide on how to implement a warning for unsaved changes when attempting to navigate away from a TelerikForm in Blazor applications.
type: how-to
page_title: How to Prompt Users for Unsaved Changes in Blazor TelerikForm
slug: form-kb-prompt-unsaved-changes
tags: blazor, form, navigation, unsaved changes
res_type: kb
ticketid: 1682122, 1629951
---

## Environment

<table>
<tbody>
<tr>
<td>Product</td>
<td>Form for Blazor</td>
</tr>
</tbody>
</table>

## Description

This knowledge base article answers the following questions:

- How to detect unsaved changes in a Blazor TelerikForm?
- How to prompt users before navigating away from unsaved changes in Form?
- How to conditionally navigate away from a form?

## Solution

To prompt the users with a warning message when they attempt to navigate away from a page with unsaved changes in a TelerikForm, follow these steps:

1. Inject [`NavigationManager`](https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/routing?view=aspnetcore-7.0#handleprevent-location-changes) to handle navigation
2. Register a handler using `NavigationManager.RegisterLocationChangingHandler()` to intercept navigation attempts
3. Use the [`LocationChangingHandler`](https://www.telerik.com/blogs/blazor-new-locationchanging-events-dotnet-7) to check if the form has unsaved changes
4. Add a [`<TelerikDialog>`](slug:dialog-overview) to prompt the user when there are unsaved changes
5. Implement a `PreventLeaving()` method and `ProceedNavigation()` method to close the dialog without navigating and to manually navigate to the stored URL if the user confirms

`````RAZOR
@implements IDisposable
@inject NavigationManager NavigationManager

<TelerikForm @ref="@FormRef"
Model="@Employee"
Width="300px">
<FormItems>
<FormItem Field="@nameof(Person.Id)" Enabled="false"></FormItem>
<FormAutoGeneratedItems />
</FormItems>
</TelerikForm>

<TelerikButton OnClick="@(() => NavigateToExternalPage())">
Go To Other Page
</TelerikButton>


<TelerikDialog @bind-Visible="@ShowNavigationDialog"
Title="Confirm Navigation">
<DialogContent>
You have unsaved changes. Are you sure you want to leave this page?
</DialogContent>
<DialogButtons>
<TelerikButton OnClick="@PreventLeaving">No</TelerikButton>
<TelerikButton ThemeColor="@ThemeConstants.Button.ThemeColor.Primary" OnClick="@ProceedNavigation">Yes</TelerikButton>
</DialogButtons>
</TelerikDialog>

@code {
private Person Employee = new Person();
private TelerikForm? FormRef { get; set; }
private IDisposable? NavEventRegistration;
private bool ShowNavigationDialog = false;
private string? NextUrl;
private bool isNavigationConfirmed = false; // Flag to track navigation confirmation

private ValueTask LocationChangingHandler(LocationChangingContext args)
{
// Prevent the confirmation dialog from appearing again once the user confirmed navigation
if (isNavigationConfirmed)
{
return ValueTask.CompletedTask;
}

if (FormRef?.EditContext.IsModified() ?? false)
{
// Prevent navigation and store the target URL
args.PreventNavigation();
NextUrl = args.TargetLocation;
ShowNavigationDialog = true;

// Force Blazor to re-render
InvokeAsync(StateHasChanged);
}

return ValueTask.CompletedTask;
}

private void NavigateToExternalPage()
{
NavigationManager.NavigateTo("https://www.telerik.com/blazor-ui/documentation/introduction", forceLoad: true);
}

private void PreventLeaving()
{
// Simply close the dialog without changing the page
ShowNavigationDialog = false;
StateHasChanged();
}

private void ProceedNavigation()
{
// Set the flag to indicate navigation is confirmed
isNavigationConfirmed = true;

// Navigate manually to the stored target URL
if (!string.IsNullOrEmpty(NextUrl))
{
NavigationManager.NavigateTo(NextUrl);
}

// Close the dialog after confirming navigation
ShowNavigationDialog = false;
}

protected override void OnInitialized()
{
Employee = new Person()
{
Id = 1,
FirstName = "John",
LastName = "Doe",
BirthDate = DateTime.Today.AddYears(-30)
};

// Register the navigation handler
NavEventRegistration = NavigationManager.RegisterLocationChangingHandler(LocationChangingHandler);
}

public void Dispose()
{
NavEventRegistration?.Dispose();
}

public class Person
{
public int Id { get; set; }
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public DateTime BirthDate { get; set; } = DateTime.Today;
}
}
`````

## See Also

- [Blazor Form Overview](slug:form-overview)
- [Blazor Dialog Overview](slug:dialog-overview)
Loading