question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Blazor] Add support for confirming navigations

See original GitHub issue

Summary

Support for Location change event is a very popular ask from our users. Unfortunately, given the nature of the event adding support for it that uses browser intrinsic is going to be difficult / impossible. https://github.com/dotnet/aspnetcore/pull/24417/ attempted to solve this by hijacking browser navigation and managing it via Blazor. This is a fairly involved solution, with possible significant perf overhead, and we’d like to determine if using a narrower solution would suffice here.

A popular theme in the issue focused on preventing navigation to avoid losing unsaved changes in a component. A well-upvoted comment provides a sample for just this - https://github.com/ShaunCurtis/Blazr.Demo.EditForm/tree/master/Blazr.NavigationLocker. This spec is a way to determine if this is something we could get away with.

Motivation and goals

  • Most popular issue for Blazor at the time of writing.

In-scope

  • Add an API that allows components to prevent navigation in a platform-independent way.
  • Provide turnkey solution that integrates with EditForm

Out-of-scope

  • Not a general purpose location changing event handler.

Proposed solution

We introduce an API on NavigationManager that allows users to confirm when a navigation is to occur.AddNavigationConfirmationAsync returns an IAsyncDisposable which prompts for a confirmation until the returned value is disposed.

public class NavigationManager
{
+   public ValueTask<IAsyncDisposable> AddNavigationConfirmationAsync(string message, CancellationToken cancellationToken);
}

Here’s an example of it in use:

@inject NavigationManager Nav

<form @oninput="OnInput" @onvalidsubmit="OnSubmit">
    ...
    <button type="submit">Submit</button>
</form>

@code {
    IAsyncDisposable? _navigationConfirmation;

    async Task OnInput()
    {
        _navigationConfirmation ??= await Nav.AddNavigationConfirmationAsync("Are you sure you want to exit without saving?");
    }
    
    async Task OnSubmit() => await RemoveNavigationConfirmationAsync();

    ValueTask IAsyncDisposable.DisposeAsync() => RemoveNavigationConfirmationAsync();
    
    ValueTask ClearConfirmationAsync() => await (_navigationConfirmation?.DisposeAsync() ?? default);
}

The implementation relies on window.confirm for a navigation that is handled via Blazor’s routing and beforeunload event for all other navigation. The message parameter is used as part of the confirm dialog, but is likely to be ignored by the unload event since browsers do not consistently support specifying it.

In addition to this, we introduce a LockNavigationWhenDirty component that uses EditContext’s dirty state (IsModified() / MarkAsUnmodified()`) to add / remove navigation confirmations. Here is what this component looks like:

public class LockNavigationWhenDirty : IAsyncDisposable
{
    public LockNavigationWhenDirty(NavigationManager navigationManager);
    [EditorRequired, Parameter] public string Message { get; set; }
}

Usage:

<EditForm ... @onvalidsubmit="OnValidSubmit">
    <LockNavigationWhenDirty /> 
    ...
</EditForm>

@code {
    async OnValidSubmit()
    {
        // Save content
        repository.SaveAsync(..);
        
        // Release the lock now that we're satisfied
        editContext.MarkAsUnmodified();
    }
}

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:12
  • Comments:20 (5 by maintainers)

github_iconTop GitHub Comments

15reactions
DaveNaycommented, Feb 11, 2022

Can the use of window.confirm be replaced with a generic callback that can be handled in user code? The browser dialogs are pretty ugly and do not fit with custom site theming.

8reactions
americansloncommented, Apr 21, 2022

Has some plan of action been decided on this? This is an essential feature that is sorely lacking.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ASP.NET Core Blazor routing and navigation
This article explains how to manage Blazor app request routing and how to use the NavLink component to create navigation links.
Read more >
Controlling and Preventing Navigation Events in Blazor Using ...
On a page that has user input, add a NavigationLock component · Set ConfirmExternalNavigation based on whether there are changes on the page...
Read more >
Blazor's New LocationChanging Events in .NET 7
The New LocationChanging Event · Any navigation triggered within your Blazor application to another “page” within your Blazor application · Any ...
Read more >
Blazor Basic: Navigation Lock (.Net 7) - YouTube
Today we will be discussing the NavigationLock component added in .NET 7. So this essentially does what it sounds, allows you to control...
Read more >
.NET 7 Blazor New NavigationLock Component - YouTube
NET 7 Blazor New NavigationLock 01:42 Create the Blazor ... 08:46 Test the NavigationLock 09:07 Lock External Navigation MANY THANKS TO ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found