Home > Mobile >  Validating forms only on submit with Blazor
Validating forms only on submit with Blazor

Time:12-21

I've recently started using Blazor. Is there a way to trigger form model validation only on submit, instead of live on each change?

Just for clarification, let's say I have something like this:

<EditForm Model="this" OnValidSubmit="SubmitForm">
    <DataAnnotationsValidator />
    <ValidationSummary />
            <Label For="Name">Name</Label>
            <InputText id="Name" name="Name"  @bind-Value="Name"/>
    <button type="submit">Save</button>
</EditForm>

@code {
    [StringLength(10, ErrorMessage="Name too long")]
    public string Name { get; set; }

    private async Task SubmitForm()
    {
        // ...
        // send a POST request
    }
}

By default, it seems like the validity of the field and the error messages displayed in the ValidationSummary get re-evaluated on every change of the text input (e.g. as soon as I delete the 11th character from the input, the "too long" message disappears).

I would prefer if the displayed messages would remain frozen until the Submit button is clicked.

I suppose it would be possible to implement it by removing the ValidationSummary component and implementing a custom solution (e.g. displaying a List of error messages that's refreshed only on submit), but I was wondering if there is some idiomatic solution that I'm not aware of.

CodePudding user response:

When validation occurs is controlled by the Validator you're using.

There are two events that you can receive from EditContext:

OnValidationRequested is invoked either when EditContext.Validate is called or as part of the form submission process.

OnFieldChanged is invoked every time a field value is changed.

A validator uses these events to trigger it's validation process, and outputs the results to the EditContext's ValidationMessageStore.

DataAnnotationsValidator wires up for both events and triggers validation whenever either is invoked.

There are other validators out there, and writing your own is not too difficult. Other than those from the usual control suppliers, there's Blazored, or mine. Mine is documented here - https://shauncurtis.github.io/articles/Blazor-Form-Validation.html. it has a DoValidationOnFieldChange setting!

CodePudding user response:

You can skip using the DataAnnotationsValidator component, and instead do something like this in the SubmitForm method:

private void SubmitForm()
{
    EditContext.AddDataAnnotationsValidation();
    
    EditContext.Validate(); 
}

Here's the complete code...Note that I'm not using the EditForm's Model attribute. Instead I'm using EditForm's EditContext attribute

<EditForm EditContext="@EditContext" OnValidSubmit="SubmitForm">
     <ValidationSummary />

       <div >
        <label for="name">Name: </label>
        <InputText Id="name" Class="form-control" @bind-Value="@Model.Name"></InputText>
        <ValidationMessage For="@(() => Model.Name)" />

    </div>
    <div >
        <label for="body">Text: </label>
        <InputTextArea Id="body" Class="form-control" @bind-Value="@Model.Text"></InputTextArea>
        <ValidationMessage For="@(() => Model.Text)" />
    </div>
    <button type="submit" >Submit</button>
</EditForm>

@code {
   
    private EditContext EditContext;
    private Comment Model = new Comment();

     protected override void OnInitialized()
    {
        EditContext = new EditContext(Model);
        base.OnInitialized();
    }
   
     private void SubmitForm()
    {
       // Adds DataAnnotations validation support to the EditContext. 
       // instead of the removed DataAnnotationsValidator component
       EditContext.AddDataAnnotationsValidation();

       // Validates the EditContext.  
       EditContext.Validate();
    }

     public class Comment
    {
        [Required]
        [MaxLength(10,ErrorMessage="Name too long")]
        public string Name { get; set; }

        [Required]
        public string Text { get; set; }
       
    }
   
}

idiomatic solution

Is my answer an idiomatic solution ? I don't know. Is it complete ? I don't know... If you're looking for an idiomatic solution, the right person that can provide it is Steve Sanderson. It is too early to speak of idiomatic solution and good practices in Blazor. I did it because I felt so, nothing else.

I'm using the ValidationMessage components so that you can see when the validation comes into effect.

  • Related