Skip to content

fix: Validation with validateEditContexts for GoToStepAsync in FluentWizard #2939

@bejulian

Description

@bejulian

🐛 Bug Report

When custom buttons are used for navigation in FluentWizard, GoToStepAsync(int step, bool validateEditContexts = false) should be used according to the documentation. If this code is used with validateEditContexts = true validation is not executed for the current step, but for the next step to be navigated to. As a result, it is no longer possible to navigate to a step with validation, but a step with validation is not validated.

💻 Repro or Code Sample

If current step index is 0 and step 1 has validation, navigating there can be done with
Wizard.GoToStepAsync(1, true).
Within this method, Value is set to 1, then validation is executed:

public Task GoToStepAsync(int step, bool validateEditContexts = false)
{
    Value = step;
    return ValidateAndGoToStepAsync(step, validateEditContexts);
}

As a result, the current step is never validated:

internal async Task ValidateAndGoToStepAsync(int targetIndex, bool validateEditContexts)
{
    var stepChangeArgs = await OnStepChangeHandlerAsync(targetIndex, validateEditContexts);
    var isCanceled = stepChangeArgs?.IsCancelled ?? false;

    if (!isCanceled)
    {
        Value = targetIndex;
        await ValueChanged.InvokeAsync(targetIndex);
        StateHasChanged();
    }
}

protected virtual async Task<FluentWizardStepChangeEventArgs> OnStepChangeHandlerAsync(int targetIndex, bool validateEditContexts)
{
    var stepChangeArgs = new FluentWizardStepChangeEventArgs(targetIndex, _steps[targetIndex].Label);

    if (validateEditContexts)
    {
        var allEditContextsAreValid = _steps[Value].ValidateEditContexts(); // Value was already set to targetIndex in GoToStepAsync
        stepChangeArgs.IsCancelled = !allEditContextsAreValid;

        if (!allEditContextsAreValid)
        {
            await _steps[Value].InvokeOnInValidSubmitForEditFormsAsync();
        }
        if (!stepChangeArgs.IsCancelled && allEditContextsAreValid)
        {
            // Invoke the 'OnValidSubmit' handlers for the Edit Forms
            await _steps[Value].InvokeOnValidSubmitForEditFormsAsync();
        }

        await _steps[Value].InvokeOnSubmitForEditFormsAsync();
    }

    return await OnStepChangeHandlerAsync(stepChangeArgs);
}

🤔 Expected Behavior

GoToStepAsync should validate the current step.

😯 Current Behavior

The next step is validated. Since this validation will fail in most cases, wizard is stuck with no option to navigate to next step. On the other hand, if the current step required validation, it will not execute validation.

💁 Possible Solution

In my opinion, the first line in the following method can be removed:

public Task GoToStepAsync(int step, bool validateEditContexts = false)
{
    Value = step;
    return ValidateAndGoToStepAsync(step, validateEditContexts);
}

The new value for step will be set within ValidateAndGoToStepAsync if validation is successful.
I would be happy to open a PR with the described change if that is appreciated.

🔦 Context

I tried to create a wizard with custom ButtonTemplate where two steps require validation with FluentEditForm. While testing the behavior, this bug was discovered.

🌍 Your Environment

  • OS & Device: Windows 10 on Laptop
  • Browser: Google Chrome
  • .NET and Fluent UI Blazor library Version: 8.0.300 and 4.10.4

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions