Blazor Form Validation


Creating an input forms is needed for just about every application.  Creating a form in Blazor is fairly strength forward using the Blazor components and the ASP.Net Core Data Annotations on your model.  The cool part is that the data annotations on your model is the same both in the client and on the server.  Another benefit of Blazor.

For this post we will be modifying the standard Weather forecast sample that ships as one of the pages in the project templates.  We will be changing it cities with their temperatures.  I will be using this project for the next couple of blog post, I will just be adding new features to it.

Getting Started




To get started building input forms, we will create a model and add our data annotations to it.   We have several simple fields and data annotations that deal with required and max length.  These should be common. 

    public class CityWeatherInfo
    {
        public int Id { get; set; }

        [Required]
        [MaxLength(100)]
        public string City { get; set; }

        [Required]
        [MaxLength(2)]
        public string State { get; set; }

        [Range(20, 120)]
        public int Temperature { get; set; }

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



Service


We will create a standard service that will provide static data and the normal GetAll() method that returns a collection of CityWeatherInfo.  We will have to register the services in our startup class.

We will have the normal list page that shows all the cities we have weather data on, just like the standard weather forecast page.

HTML



    <table class="table">
        <thead>
            <tr>
                <th>City</th>
                <th>State</th>
                <th>Temp. (F)</th>
                <th>Feels Like</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var city in cityInfo)
            {
                <tr>
                    <td>@city.City</td>

                    <td>@city.State</td>
                    <td>@city.Temperature</td>
                    <td>@city.FeelsLike</td>
                </tr>
            }
        </tbody>
    </table>


We add a button to our list page to display the form we need to fill out to add a new city’s weather to our list.


    <button class="btn btn-primary" @onclick="AddCity">Add New City</button>


Navigation


In the AddCity method we add a navigation call to go to our add page.  You will need to inject the NavigationManager service for the page to be able to use this service.  As you can see, navigation to a new page in code is also very simple.


    NavigationManager.NavigateTo("AddCity");


Form

Now comes the fun part.  We need to add a form that we can use to add a new city with its data to our city info collection.  There are several components built into Blazor that will help us out.  The main one is <EditForm>.   You set your model and the event handler for handling the submit.


    <EditForm Model="@city" OnValidSubmit="@HandleValidSubmit">


You should have noticed the event we are handling is the OnValidSubmit not just the submit.  We are using the OnValidSubmit because our model has the validation of the data annotations.  When the user clicks submit, Blazor will validate the model based on the data annotations.  If it is successful, the event handler will be called.  If it fails, you can display the validation errors the standard ASP.Net way using either   <DataAnnotationsValidator /> with <ValidationSummary /> or <ValidationMessage For="@(() => city.FeelsLike)" />.  This will make the code much simpler and cleaner.

We have component to each type of input we are going to use.  In our sample we will be using <InputText>, <InputNumber> and <InputSelect>.  You can find the complete list with descriptions here .



So, this is what our form looks like, using the summary validation component:

<EditForm Model="@city" OnValidSubmit="@HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <p>
        <label for="city">City: </label>
        <InputText id="city" @bind-Value="city.City" />

    </p>


    <p>
        <label for="state">State (Abbr): </label>
        <InputText id="description" @bind-Value="city.State" />
    </p>
    <p>
        <label for="temp">Temperature: </label>
        <InputNumber id="accommodation" @bind-Value="city.Temperature" />
    </p>
    <p>
        <label for="classification">Feels Like: </label>
        <InputSelect id="classification" @bind-Value="city.FeelsLike">
            <option value="">Select Feels Like ...</option>
            <option value="Beaching">Beaching</option>
            <option value="Nice">Nice</option>
            <option value="Nicer">Nicer</option>
            <option value="Hot">Hot</option>
            <option value="Windy">Windy</option>
            <option value="Bad">Bad</option>

        </InputSelect>
    </p>

    <button type="submit">Submit</button>
    <button class="btn btn-primary" @onclick="CancelAction">Cancel</button>


</EditForm>



On the HandleValidSubmit method we will need to add an “Add” method to our service to handle adding the new city to the collection.  You can see that method in the source code since it is simply added an object to our city info collection.

Once we successfully added the new city object, we need to go back to the list page so the user can see the new city added to the list collection.  To do this, we will simple use the Navigation service and put the list as the page to go to.

What is cool about doing it this way is that when we navigate back to the list page the OnInitializedAsync method will automatically get called and that will reload the city infos into the collection and the DOM will be updated with the change.

Since we are using the Server Model of Blazor, this is fine.  If you were using an API to handle the data persistence, you would return the new City from the Add call, add it to the display collection yourself.  You would have to manually call StateChanged() to update the DOM.  Or you could use the State management pattern.


Now we have the ability to add new Cities to our list.  With Blazor it because very simple because “There is a component for that”.

Source Code

Comments

Popular posts from this blog

Yes, Blazor Server can scale!

Blazor new and improved Search Box

Blazor Wizard Step Component