dani herrera
dani herrera

Reputation: 51645

Blazor Navigationmanager cancel navigation on locationchanged

Question:

Is there a way on Blazor to cancel navigation?

Let's supose a siple a href like this:

<a href="/some/other/blazor/spa/page">Go</a>

I would like to cancel navigation (for example if we are editing a form)

What I have tried.

Via JS

I set onbeforeunload dom delegate via JSInterop:

window.onbeforeunload = function(){
        return 'Vols abandonar aquesta pàgina?';
      };

but blazor bypass it.

Via locationchanged

I tried unsuccessfully to intercept navigation on locationchanged event:

@implements IDisposable
@inject NavigationManager NavigationManager

...

protected override void OnInitialized()
{
    NavigationManager.LocationChanged += HandleLocationChanged;
}

private void HandleLocationChanged(object sender, LocationChangedEventArgs e)
{
    // Cancel Navigation Here
}

public void Dispose()
{
    NavigationManager.LocationChanged -= HandleLocationChanged;
}

Upvotes: 11

Views: 9568

Answers (4)

tomRedox
tomRedox

Reputation: 30403

This functionality was added in .NET 7, the documentation can be found in the 'Handle/prevent location changes' section of the 'Routing and navigation' page.

The example below from that documentation shows code to handle the navigation commencing (in the OnLocationChanging method) and then cancels that navigation (with context.PreventNavigation()) if the user tries to navigate to the counter page:

NavigationManager Navigation

<p>
    <button @onclick="@(() => Navigation.NavigateTo("/"))">
        Home (Allowed)
    </button>
    <button @onclick="@(() => Navigation.NavigateTo("/counter"))">
        Counter (Prevented)
    </button> </p>

@code {
    private IDisposable? registration;

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            registration = 
                Navigation.RegisterLocationChangingHandler(OnLocationChanging);
        }
    }

    private ValueTask OnLocationChanging(LocationChangingContext context)
    {
        if (context.TargetLocation == "/counter")
        {
            context.PreventNavigation();
        }

        return ValueTask.CompletedTask;
    }

    public void Dispose() => registration?.Dispose(); } 

Upvotes: 7

Ogglas
Ogglas

Reputation: 69928

Update to @PeterMorris answer.

As of 2021-05-17 a location changing event for NavigationManger is now committed for .NET 6.0. I hope it will be possible to catch this event on a global level in the application.

enter image description here

https://github.com/dotnet/aspnetcore/issues/14962

Upvotes: 1

raphadesa
raphadesa

Reputation: 471

have you tried to put your js file in the index.html or _host.cshtml page ?

Upvotes: -2

Peter Morris
Peter Morris

Reputation: 23224

Currently no, this feature is being discussed for .NET V5 - and has a community contribution pull-request so hopefully will make it in. https://github.com/dotnet/aspnetcore/pull/24417

The page is not changed when you navigate in Blazor, so there is no unload in order to trigger onbeforeunload.

Upvotes: 5

Related Questions