Adding Confirmation Popup for any Unsaved Changes when Navigating Away or Dirty State by using The NavigationLock component in ASP.Net Blazor
When we're navigating away from a page or application and there are unsaved changes (often referred to as "dirty" state), it's important to handle it carefully to avoid losing data. ASP.Net Blazor provides NavigationLock component to handle this situation. In this artilcle we will discuss about NavigationLock component and it's implementation.
Prerequisites
- .NET 8.0 or greater
- Visual Studio 2022 or greater
[A] Here’s a general approach to manage this situation
- Detect Unsaved Changes:
Track changes to form fields or any other data that might be modified by the user. This can be done using JavaScript by setting a flag when changes are detected. - Prompt the User:
Use the beforeunload event to prompt the user if they attempt to leave the page with unsaved changes. - Example in JavaScript:
window.addEventListener('beforeunload', function (e) {
if (isDirty) { // Check if there are unsaved changes
e.preventDefault();
e.returnValue = ''; // Standard for most browsers
}
});
[B] NavigationLock Component approach to manage this situation
In a Blazor application, handling unsaved changes and preventing navigation away from a page with dirty state involves using the NavigationManager to intercept navigation attempts. Here’s how you can create a NavigationLock component in Blazor to manage dirty states and prompt users when they try to navigate away.
NavigationLock parameters:
- ConfirmExternalNavigation sets a browser dialog to prompt the user to either confirm or cancel external navigation. The default value is false. Displaying the confirmation dialog requires initial user interaction with the page before triggering external navigation with the URL in the browser's address bar. For more information on the interaction requirement, see Window: beforeunload event (MDN documentation). https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
- OnBeforeInternalNavigation sets a callback for internal navigation events.
Example
Suppose we want navigation lock or confirmation dialog before moving away in a form page (say 'NavLockPage.razor' in the above example) then we can add NavigationLock component in the page as we can see in the example.
- An attempt to follow the link to Microsoft's website must be confirmed by the user before the navigation to https://www.microsoft.com succeeds.
- PreventNavigation is called to prevent navigation from occurring if the user declines to confirm the navigation via a JavaScript (JS) interop call that spawns the JS confirm dialog.
NavLockPage.razor:
@page "/nav-lock-page"
@inject IJSRuntime JSRuntime
@inject NavigationManager Navigation
<NavigationLock ConfirmExternalNavigation="true"
OnBeforeInternalNavigation="OnBeforeInternalNavigation" />
<p>
<button @onclick="NavigateInternal">Navigate Internal</button>
</p>
<p>
<a href="https://www.microsoft.com">Microsoft homepage</a>
</p>
@code {
private void NavigateInternal()
{
Navigation.NavigateTo("/");
}
private async Task OnBeforeInternalNavigation(LocationChangingContext context)
{
var isConfirmed = await JSRuntime.InvokeAsync<bool>("confirm",
"Are you sure you want to navigate to away?");
if (!isConfirmed)
{
context.PreventNavigation();
}
}
}
Runnable Code: https://blazorrepl.telerik.com/GSuDbmEz40Z32hEb39
Output:
Explanation
- @inject IJSRuntime JSRuntime:
This line injects the IJSRuntime service into the component, allowing it to call JavaScript functions. - @inject NavigationManager Navigation:
This line injects the NavigationManager service, which provides methods for programmatic navigation in the Blazor application. - <NavigationLock>:
- This component is used to manage navigation within the application. It prevents or confirms navigation based on the parameters passed.
- ConfirmExternalNavigation="true":
This parameter indicates that the navigation lock should prompt the user to confirm if they navigate away from the page to an external URL (e.g., clicking on external links). - OnBeforeInternalNavigation= "OnBeforeInternalNavigation":
This parameter specifies a callback method to be invoked before internal navigation (navigation within the Blazor app) happens. This allows you to implement custom logic to confirm or prevent navigation.
Conclusion
In this article we demonstrated navigation lock component - how to use it when we're navigating away from a page or application and there are unsaved changes.
great!
Priya
25-Sep-2024 at 22:44