Forms in Blazor
View and edit data in forms.
Blazor Forms
Many web applications allow the user to enter new data or display data for the user to modify, and they do these with forms. In HTML, the elements between the <form>
tag are automatically sent to a server with HTTP Requests.
We can tap into the HTML form by using Blazor’s <EditForm>
with Blazor controls and HTML elements. The <EditForm>
renders an HTML <form>
on the client. The Model
property of <EditForm>
provides data binding and validation through data attributes.
Using <EditForm>
enables you manage forms with familiar Model.Property
syntax.
Form Controls
Just as with HTML forms, you must put form fields between the <EditForm>
tags, and you need to denote some action for the form to take when the user submits it.
<EditForm Model="@todo" OnSubmit="@HandleValidSubmit">
<!-- form fields -->
</EditForm>
Blazor controls are identified by their Input
prefix. For example, <InputText>
, <InputCheckbox>
, and <InputDate>
all render corresponding HTML form controls (textbox, checkbox, and date inputs, respectively). Both HTML and Blazor controls are bindable.
Buttons can be <button>
elements, <input>
elements with a type=button
or type=submit
, an a
tag, or a custom component. Other form controls can also be custom-built. To use the control, just call the Blazor control by its name using HTML tag style syntax. See Blazor components for more on components.
<EditForm Model="@todo" OnSubmit="@HandleValidSubmit">
<div class="form-group m-3">
<label for="todo-item">To do: </label>
<InputText id="todo-item" @bind-Value="@todo.Title"></InputText>
</div>
<div class="form-group m-3">
<label for="todo-item">Due date:</label>
<InputDate id="todo-date" @bind-Value="@todo.Due"></InputDate>
</div>
<div class="form-group m-3">
<label for="todo-important">Important:</label>
<InputCheckbox id="todo-important" @bind-Value="@todo.Important"></InputCheckbox>
</div>
<div class="form-group m-3">
<label for="todo-complete">Complete:</label>
<InputCheckbox id="todo-complete" @bind-Value="@todo.Complete"></InputCheckbox>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary" @onclick="@HandleValidSubmit">Submit</button>
</div>
</EditForm>
The controls render the following form in a web page. Note that any styling is because the Blazor project template uses Bootstrap.
Validation
Having the data stored properly is important to any software. And validation is the first step in proper data storage. Validation starts in the project containing the data model. To set up validation at the model level, use Data Annotations from the System.ComponentModel.DataAnnotations
namespace and mark up the properties in the class with the validations you want. For example, a Meal
class in a meal planning app would contain validations for required fields, constraints on the length of string fields, and date constraints, as shown in the following sample:
While Entity Framework will still recognize the primary key because of the naming convention, some feel the code is more clear with the Key
attribute.
The data annotations applied to the model are used by Blazor validators. To enable validation for a form, add a DataAnnotationsValidator
component. This will run validation against form elements and supply a default message for any form field that doesn’t pass validation. You will likely want to add a ValidationSummary
or ValidationMessage
components, or both. The ValidationSummary
component displays a list of error messages for all form fields that do not pass validation. The Validationsummary
displays the list where it is placed in the page.
If you prefer to display error messages for a specific input on the form, then use the ValidationMessage
component.
<DataAnnotationsValidator />
<ValidationSummary />
The ValidationSummary
and ValidationMessage
components can be used together. If form fields do not pass validation, then the DataAnnotationsValidator
calls HandleInvalidSubmit
where you can perform logic related to validation.
<ValidationMessage For="() => todo.Title"/>
private void HandleInvalidSubmit()
{
statusClass = "alert-danger";
message = "Show a meaningful error message.";
}
Updating Data
The HandleValidSubmit
is the method that is called when an HTTP request has been submitted. From there, you can call a service layer that calls the API, and the API can update the data. A HandleValidSubmit
method looks something like the following sample. Notice you may have to determine whether a user is inserting or updating data. Additionally, you may need to do a bit of processing to send the data to the service and API in the shape it expects.
Conclusion
Blazor forms are a server side way to work with the same HTML forms and HTTP requests that web developers are already familiar with. Blazor contains several controls to help, but plain HTML elements work just as well. Additionally, Blazor helps with validation and some common actions that normally happen in a web app.