Skip to content
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

Support canceling of navigation #5620

Closed
Peter-Juhasz opened this issue Oct 29, 2018 · 6 comments
Closed

Support canceling of navigation #5620

Peter-Juhasz opened this issue Oct 29, 2018 · 6 comments
Labels
area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one
Milestone

Comments

@Peter-Juhasz
Copy link

There is an event OnLocationChanged on IUriHelper, it would be great to have support for canceling or more particularly confirming unintentional navigation.

The use case is a simple form that users can change, but to don't lose any changes unintentionally, if the user tries to navigate away and the form has changed, we would like to ask him to confirm or cancel navigation.

@aspnet-hello aspnet-hello transferred this issue from dotnet/blazor Dec 17, 2018
@aspnet-hello aspnet-hello added this to the Backlog milestone Dec 17, 2018
@aspnet-hello aspnet-hello added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates enhancement This issue represents an ask for new feature or an enhancement to an existing one area-blazor Includes: Blazor, Razor Components labels Dec 17, 2018
@mkArtakMSFT mkArtakMSFT removed area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels May 9, 2019
@mguma
Copy link

mguma commented Aug 29, 2019

It would be great if this feature will be included in the ASP.NET Core 3.0 Release.

@pranavkm
Copy link
Contributor

pranavkm commented Jul 6, 2020

In Blazor Server, event handling is entirely async and browsers require that certain handlers, which includes navigation, finish synchronously. Unfortunately this is not a feature we could support. If this is absolutely necessary, we recommend using JS / JSInterop in your application to handle this.

@pranavkm pranavkm closed this as completed Jul 6, 2020
@Peter-Juhasz
Copy link
Author

Then what is your recommendation to prevent the user from navigation away when they have unsaved changes on a form? This is a super common scenario. Especially in LOB applications we use Blazor primarily for.

@nikonthethird
Copy link

Maybe there could be a hidden InProcessNavigationManager (like we have IJSInProcessRuntime) for Blazor WASM?

It could support Blazor WASM navigation use-cases.

@Peter-Juhasz
Copy link
Author

Peter-Juhasz commented Jul 21, 2020

I was able to implement a partial solution, but it's still pretty messy. This is the way it works:

  • JavaScript: subscribe globally to beforeunload event (deploy custom script)
  • Blazor: subscribe to the OnFieldChange event of EditContext on OnParametersSet (also, don't forget to handle previous subscriptions as the component may be reused)
  • Blazor: in the event handler, evaluate whether the form/model has effectively changed
  • Blazor: communicate the state asynchronously via JS interop and set a flag like formHasPendingChanges = true
  • JavaScript: check flag in event handler and prompt if neccessary
  • Blazor: revert flag on OnParametersSet to false, because the component may be reused
  • Blazor: revert flag on Component Dispose to false
  • Blazor: unsubscribe from OnFieldChange on Dispose to prevent leaving unwanted references to a dead component

This is not only a lot of custom code, but also very inefficient. If I reevaluate the state of the form at every keystroke and even push the change asynchronously to the JS side, it would burn a lot of resources. So, on top of this, I had to introduce Reactive Extensions, to Throttle and DistinctUntilChanged the changes and give some relief after quick changes. But this approach introduces a delay as well, so if somebody is too fast or simply presses the wrong key accidentally, they may close the form before we would recognize it has changed.

Also, it handles only events initiated by the browser, so like: closing of tab (or window), refresh, navigating away to a different site. But it doesn't handle the majority of cases, when the route changes inside Blazor to another component without "unloading" the site.

If anybody has a better approach, it would worth sharing, at least I would be very happy to see what is the recommended way of implementing this feature properly, which is again: pretty common in any application where you input any data.

@nikonthethird
Copy link

There is a new issue and even a pull request over at #23886

@ghost ghost locked as resolved and limited conversation to collaborators Aug 29, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one
Projects
None yet
Development

No branches or pull requests

6 participants