new to mudblazor but here goes.
I have a form. If the user is filling out data and decides to leave, I'm trying to popping up a unsaved changes flag with options dialog.
My issue is when the user decides to disregard their changes and continue to go to different page. The NavigateTo url is empty.
Here is the method for LocationChange
private ValueTask HandleAppPageMove(LocationChangingContext ctx)
{
var desiredNavRoute = ctx.TargetLocation;
foreach (var item in AnswersByQuestionIds.Values)
{
if(item.Answer == string.Empty)
{
DialogService.ShowAsync<NotificationDialog>("Invalid Form",
new DialogParameters() { { nameof(NotificationDialog.RedirectLink), ctx.TargetLocation } },
new DialogOptions { NoHeader = true, BackdropClick = false, CloseOnEscapeKey = false });
break;
StateHasChanged();
ctx.PreventNavigation();
}
}
return ValueTask.CompletedTask;
}
This is the button for the dialog discard
private void Discard( )
{
NavManager.NavigateTo(RedirectLink);
MudDialog.Close(DialogResult.Ok(true));
}
if I inspect the redirect link its a valid link with in the application. Yet the NavigateTo in the console has null object reference error. Any help is so greatly appreciated. I'm obviously missing something but not sure what?
new to mudblazor but here goes.
I have a form. If the user is filling out data and decides to leave, I'm trying to popping up a unsaved changes flag with options dialog.
My issue is when the user decides to disregard their changes and continue to go to different page. The NavigateTo url is empty.
Here is the method for LocationChange
private ValueTask HandleAppPageMove(LocationChangingContext ctx)
{
var desiredNavRoute = ctx.TargetLocation;
foreach (var item in AnswersByQuestionIds.Values)
{
if(item.Answer == string.Empty)
{
DialogService.ShowAsync<NotificationDialog>("Invalid Form",
new DialogParameters() { { nameof(NotificationDialog.RedirectLink), ctx.TargetLocation } },
new DialogOptions { NoHeader = true, BackdropClick = false, CloseOnEscapeKey = false });
break;
StateHasChanged();
ctx.PreventNavigation();
}
}
return ValueTask.CompletedTask;
}
This is the button for the dialog discard
private void Discard( )
{
NavManager.NavigateTo(RedirectLink);
MudDialog.Close(DialogResult.Ok(true));
}
if I inspect the redirect link its a valid link with in the application. Yet the NavigateTo in the console has null object reference error. Any help is so greatly appreciated. I'm obviously missing something but not sure what?
Share Improve this question asked Mar 20 at 16:01 Troy BryantTroy Bryant 1,0248 gold badges30 silver badges62 bronze badges1 Answer
Reset to default 0Here's code to show you how to address the issue. I've kept it simple - I have no idea what AnswersByQuestion
is. You don't need to pass links around, just await the result of the dialog and take the appropriate action.
However, getting this working only addresses half the problem. The user can still navigate away from site - cancelling the LocationChangingContext
only addresses internal SPA navigation.
Home page:
@page "/"
@inject NavigationManager NavManager
@inject IDialogService DialogService
@implements IDisposable
<PageTitle>Home</PageTitle>
<MudText Typo="Typo.h3" GutterBottom="true">Hello, world!</MudText>
<MudText Class="mb-8">Welcome to your new app, powered by MudBlazor and the .NET 8 Template!</MudText>
<MudPaper>
<MudButton Color="_buttonColor" OnClick="this.OnStateChanged">Toggle Edit State</MudButton>
</MudPaper>
<NavigationLock ConfirmExternalNavigation="_isFormDirty" />
@code {
private IDisposable? _navigationHandler;
private bool _isFormDirty = false;
private Color _buttonColor => _isFormDirty ? Color.Secondary : Color.Primary;
protected override void OnInitialized()
{
_navigationHandler = NavManager.RegisterLocationChangingHandler(HandleAppPageMove);
}
private void OnStateChanged()
{
_isFormDirty = !_isFormDirty;
}
private async ValueTask HandleAppPageMove(LocationChangingContext ctx)
{
if (!_isFormDirty)
return;
var dialog = await DialogService.ShowAsync<SimpleDialog>("Exit",
new DialogParameters(),
new DialogOptions { NoHeader = true, BackdropClick = false, CloseOnEscapeKey = true });
var result = await dialog.Result;
if (result?.Canceled ?? false)
ctx.PreventNavigation();
}
public void Dispose()
{
_navigationHandler?.Dispose();
}
}
And SimpleDialog.razor
<MudDialog>
<TitleContent>
Dialog Title
</TitleContent>
<DialogContent>
Do you really want to discard the form changes?
</DialogContent>
<DialogActions>
<MudButton OnClick="Cancel">Cancel</MudButton>
<MudButton Color="Color.Primary" OnClick="Submit">Discard</MudButton>
</DialogActions>
</MudDialog>
@code {
[CascadingParameter] private IMudDialogInstance? MudDialog { get; set; }
private void Submit() => MudDialog?.Close(DialogResult.Ok(true));
private void Cancel() => MudDialog?.Cancel();
}
This leads on to another problem - detecting if the form is dirty. You can read my solution to that problem here:
- https://www.codeproject/Articles/5357594/A-Blazor-Edit-State-Tracker
- https://github/ShaunCurtis/Blazr.EditStateTracker