Skip to content

Boostrap form validation doesn't work #1193

@rwb196884

Description

@rwb196884

I added validation like this
https://docs.blazorbootstrap.com/forms/number-input#validations

Expecting this
https://getbootstrap.com/docs/5.3/forms/validation/

to happen.

But nothing happens. The form elements never get coloured.
The form never gets the needs-validation was-validated classes.

Is this supposed to work?

This is as close as I can get.

There's quite a lot of work to do --- surely this should be out-of-the-box behaviour?

Annoyingly, the form always shows the green valid message. I can't work out why.

@page "/"
@rendermode InteractiveServer

@using BlazorBootstrap
@using System.ComponentModel.DataAnnotations
@using System.Linq.Expressions

@code {
    class FormModel
    {
        [Required]
        [MinLength(3, ErrorMessage = "Custom error message: minimum length 3.")]
        public string TextValue { get; set; }

        [Required]
        [Range(8, 21, ErrorMessage = "Must be between 8 and 21; preferably 13.")]
        public int IntValue { get; set; }
    }

    FormModel Model { get; set; }
    EditContext? EditContext { get; set; }
    ValidationMessageStore? ValidationMessageStore { get; set; }

    protected override void OnParametersSet()
    {
        if (Model == null)
        {
            Model = new FormModel();
        }
        EditContext = new EditContext(Model);
        //EditContext.OnValidationRequested += OnEditContextValidationRequested;
        EditContext.OnValidationStateChanged += OnEditContextValidationStateChanged;
        ValidationMessageStore = new ValidationMessageStore(EditContext);

        base.OnParametersSet();
    }

    void OnEditContextValidationStateChanged(object? sender, ValidationStateChangedEventArgs e)
    {
        // Seems to be impossible to get the actual validation value, so guess...
        IsValid = !EditContext.GetValidationMessages().Any();
    }

    public void Dispose()
    {
        if (EditContext is not null)
        {
            // VERY IMPORTANT to unregister event handlers in Blazor!
            EditContext.OnValidationStateChanged -= OnEditContextValidationStateChanged;
        }
    }

    async Task OnClickValidSubmit()
    {
        throw new NotImplementedException();
    }

    bool? IsValid { get; set; }

    string BootstrapFormValidationClasses
    {
        get
        {
            if (IsValid.HasValue)
            {
                return "was-validated " + (IsValid.Value ? "is-invalid" : "is-invalid");
            }
            return "";
        }
    }

    string GetFormElementValidationClass(Expression<Func<object>> accessor)
    {
        if (IsValid.HasValue)
        {
            return EditContext.IsValid(accessor) ? "is-valid" : "is-invalid";
        }
        return "";
    }
}

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.


<Card>
    <CardHeader>This is BlazorBootstrap.Card</CardHeader>
    <CardBody>
        <EditForm FormName="BlazorBootstrapFormWithValidation" EditContext="EditContext" OnValidSubmit="OnClickValidSubmit" class="@BootstrapFormValidationClasses">
            <DataAnnotationsValidator />
            <div class="mb-3">
                <label class="form-label" for="input-TextValue">Text value</label>
                <TextInput @bind-Value="@Model.TextValue" Id="input-TextValue" Class="@GetFormElementValidationClass(() => Model.TextValue)" />
                <div id="help-TextValue" class="form-text">Enter the text value.</div>
                <div class="valid-feedback">OK</div>
                <ValidationMessage For="@(() => Model.TextValue)" class="invalid-feedback" />
            </div>
            <div class="mb-3">
                <label class="form-label" for="input-IntValue">Integer value</label>
                <NumberInput @bind-Value="@Model.IntValue" Id="input-IntValue" Class="@GetFormElementValidationClass(() => Model.IntValue)" />
                <div id="help-IntValue" class="form-text">Enter the integer value.</div>
                <div class="valid-feedback">OK</div>
                <ValidationMessage For="@(() => Model.IntValue)" class="invalid-feedback" />
            </div>
            <button type="submit" class="btn btn-primary">Submit</button>
        </EditForm>
    </CardBody>
</Card>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions