Skip to content

Custom validation class in Blazor is not working as expected to apply CSS library validation styles. #30496

@TanvirArjel

Description

@TanvirArjel

To apply the Bootstrap validation styles in Blazor If we extend the FieldCssClassProvider as follows:

public class BootstrapValidationClassProvider : FieldCssClassProvider
{
    public override string GetFieldCssClass(EditContext editContext, in FieldIdentifier fieldIdentifier)
    {
        bool isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();

        return isValid ? "is-valid" : "is-invalid"; // Bootstrap validation class
    }
}

and use as follows:

<EditForm EditContext="@editContext" OnSubmit="@HandleSubmit">

    <button type="submit">Submit</button>
</EditForm>

@code {
    private SetUserPasswordModel SetUserPasswordModel = new SetUserPasswordModel();
    private EditContext editContext;

    protected override void OnInitialized()
    {
        editContext = new EditContext(SetUserPasswordModel);
        editContext.SetFieldCssClassProvider(new BootstrapValidationClassProvider());
    }

    private async Task HandleSubmit()
    {
      .....
    }
}

Then the form initially renders as follows:
InkedCapture_LI

Although the form inputs have not been touched yet, the validation has been applied this is because FieldCssClassProvider is setting is-valid class even before the form is touched which should not be. So currently setting a custom validation class of any CSS library would not work with this. I hope you understood. Validation state class should only be set if the input field is touched and actual validation is done.

To overcome this If do as follows:

public class BootstrapValidationClassProvider : FieldCssClassProvider
{
    public override string GetFieldCssClass(EditContext editContext, in FieldIdentifier fieldIdentifier)
    {
        if (editContext == null)
        {
            throw new ArgumentNullException(nameof(editContext));
        }

        if (!editContext.IsModified())
        {
            return string.Empty;
        }

        bool isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();

        return isValid ? "is-valid" : "is-invalid";
    }
}

Then "is-valid" and "is-invalid" classes are not applied on the form submit because on form submit without touching the input fields editContext.IsModified() returns false. If editContext.IsModified() would have returned true on form submit and marked all fields as modified then It would have worked as expected.

I have also found that there is no way to mark editContext as modified on the form submit. Angular and React have this option to mark the form and its inputs as modified on form submit manually.

Possible Solution:

  1. Trigger the FieldCssClassProvider only if the input field is touched or the form is submitted.
  2. Mark the editContext and all the inputs as modified if the form is submitted or add an option to mark editContext and all the inputs as modified on the form submit like Angular and React. Surprisingly, there is a EditContext.MarkAsUnmodified() method but no EditContext.MarkAsModified() method. How was that possible?. Adding EditContext.MarkAsModified() methods would solve the issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-blazorIncludes: Blazor, Razor ComponentsenhancementThis issue represents an ask for new feature or an enhancement to an existing onefeature-blazor-builtin-componentsFeatures related to the built in components we ship or could ship in the future

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions