```json
//[doc-params]
{
"BlazorUI": ["Blazorise", "MudBlazor"]
}
```
```json
//[doc-seo]
{
"Description": "Learn how to implement form validation in ABP Blazor UI using Blazorise or MudBlazor with practical examples."
}
```
# Blazor UI: Forms & Validation
{{if BlazorUI == "Blazorise"}}
ABP Blazor UI is based on the [Blazorise](https://blazorise.com/docs) and does not have a built-in form validation infrastructure. However, you can use the [Blazorise validation infrastructure](https://blazorise.com/docs/components/validation) to validate your forms.
## Sample
_The example is provided by official Blazorise documentation._
```html
Please enter the name.
Name is good.
Enter valid name!
Please enter the email.
Email is good.
Enter valid email!
@code{
void ValidateEmail( ValidatorEventArgs e )
{
var email = Convert.ToString( e.Value );
e.Status = string.IsNullOrEmpty( email ) ? ValidationStatus.None :
email.Contains( "@" ) ? ValidationStatus.Success : ValidationStatus.Error;
}
}
```
> Check the [Blazorise documentation](https://blazorise.com/docs/components/validation) for more information and examples.
{{end}}
{{if BlazorUI == "MudBlazor"}}
ABP Blazor UI built on top of [MudBlazor](https://mudblazor.com) uses MudBlazor's built-in form components and validation infrastructure. MudBlazor accepts a `ValidationAttribute` (e.g. `[Required]`, `[EmailAddress]` from ASP.NET Core's `DataAnnotations`) on the input's `Validation` parameter, plus custom `Func` / `Func>` delegates. FluentValidation can be plugged in the same way.
## Sample
The most common pattern is wrapping inputs in a `` and binding the form's validation state through `IsValid`:
> Standard MudBlazor and ABP usings (`@using MudBlazor`, `@using Volo.Abp.MudBlazorUI`, etc.) come from the project's `_Imports.razor`. The example below only adds the additional usings needed for validation.
```razor
@using System.ComponentModel.DataAnnotations
Submit
@code {
private MudForm _form;
private bool _isValid;
private SampleModel _model = new();
private async Task SubmitAsync()
{
await _form.Validate();
if (_isValid)
{
// ...
}
}
public class SampleModel
{
[Required]
public string Name { get; set; }
[Required, EmailAddress]
public string Email { get; set; }
}
}
```
### Inputs Used in CRUD Pages
ABP's MudBlazor CRUD pages (see `AbpMudCrudPageBase`) use a `` containing a `` and standard MudBlazor inputs:
* `` / `` for text and multi-line text
* `` / `` for dropdowns
* `` for booleans
* `` / `` for date and time
* `` for numbers
`AbpMudCrudPageBase.CreateEntityAsync` and `UpdateEntityAsync` validate the form for you (`CreateFormRef.Validate()` / `EditFormRef.Validate()`) and only call the corresponding hook when the form is valid. To inject custom logic before the application service call, override `OnCreatingEntityAsync` / `OnUpdatingEntityAsync` (do **not** re-validate inside the override):
```csharp
protected override Task OnCreatingEntityAsync()
{
// mutate NewEntity here if needed
return base.OnCreatingEntityAsync();
}
```
> Check the [MudBlazor documentation](https://mudblazor.com/components/form) for the full list of validation modes and the [MudBlazor inputs reference](https://mudblazor.com/components/textfield).
### Modal Focus Behavior
By default a `MudFocusTrap` inside `` focuses the first tabbable child element after the dialog opens. When the dialog contains a `` as the first child, that "first tabbable element" is the tab button — not the first input on the active tab — so the user has to click into the field manually.
For dialogs that contain a ``, use this three-part setup to focus the intended input automatically:
```razor
...
...
```
- `DefaultFocus="DefaultFocus.None"` on the `` disables the focus trap's automatic focus so it doesn't grab the tab button.
- `KeepPanelsAlive="true"` on the `` mounts every tab panel up front, so the first input's `firstRender` happens at dialog-open time (otherwise inactive panels are mounted later, and `AutoFocus` runs after the dialog is already visible).
- `AutoFocus="true"` on the first input asks MudBlazor to focus that field on its first render.
`DialogOptions.DefaultFocus` is ignored for inline dialogs (` + ShowAsync()`), so always set `DefaultFocus` directly on the `` element.
For a dialog without `` (first child is the input), `DefaultFocus="DefaultFocus.FirstChild"` (the MudBlazor default) is enough and you don't need `AutoFocus`.
{{end}}