Telerik blogs

 

Blazor provides fantastic helper components to make creating HTML forms simple so your web app can accept user data.

Modern web applications aren’t one-way streets. Users interact with our applications by navigating the website or web application or, most importantly, entering data.

In this part of the Blazor Basics series, we will learn how to create HTML forms to capture user data.

As a short teaser, Blazor offers a set of fantastic helper components to deal with form creation and form handling.

You can access the code used in this example on GitHub.

Creating HTML Forms Using Blazor

In this post, we will create a simple login form accepting the user’s username and password. We also want to use a masked password field. This example will demonstrate how you can build simple forms using Blazor.

A Blazor application showing a login page with a Login heading followed by an HTML form with a username and a password field.

First of all, we need a form. Blazor provides components wrapping the HTML form element to make creating forms more developer-friendly.

<EditForm Model="@UserData" OnSubmit="@Submit">
</EditForm>

The built-in EditForm component wraps the HTML form element.

It provides an OnSubmit property where we can provide a method that is called when the form is submitted.

There are two main approaches to implementing forms when using the EditForm component. We can provide a Model property as shown above, or we can create and provide an EditContext. The EditContext allows for more granular control.

However, we do not need that for our basic example. Instead, we prefer providing a Model property. It will create an EditContext behind the scenes.

Next, we add a submit button to the component template inside the EditForm component instance.

<EditForm Model="@UserData" OnSubmit="@Submit">
    <button class="btn btn-primary" type="submit">Log in</button>
</EditForm>

We use a default HTML button element and provide a few Bootstrap classes to style it. We also set the type to submit.

Adding Form Fields Using Wrapper Components

Blazor comes with built-in input components. Those components follow a naming convention and always start with “Input”. The following components are available:

  • InputCheckbox
  • InputDate
  • InputFile
  • InputNumber
  • InputRadio
  • InputRadioGroup
  • InputSelect
  • InputText
  • InputTextArea

All input components wrap the native HTML input control and provide helpful properties and events.

Besides the provided events and properties, we can add regular HTML attributes when input controls are used.

For example, we can use the InputText control and set the HTML type attribute to password to mask the user input.

The built-in input controls use the EditContext provided by the EditForm component to access the model properties. More specifically, it uses cascading parameters behind the scenes.

For our example, we add two InputText components to define an input field for the username and for the password.

<InputText @bind-Value="UserData.Username" />
<InputText type="password" @bind-Value="UserData.Password" />

As stated above, the built-in input types access the model provided to the EditForm component using the EditContext. It allows us to bind the Value property of the InputText component to a property of the UserData variable.

It’s important that we use the name of the variable provided to the Model property of the EditForm component. Otherwise, you will get a compiler error stating that the variable is not known in this context.

Notice that we set the HTML type attribute to the second InputText instance. The form field will mask the input when the user enters their password. It’s a regular HTML attribute.

The whole component, including a few divs to make it more appealing, looks like this:

<h1>Login</h1>

<EditForm Model="@UserData" OnSubmit="@Submit">
    <div style="margin-bottom: 10px;">
        <div>Username</div>
        <InputText @bind-Value="UserData.Username" />
    </div>
    <div style="margin-bottom: 10px;">
        <div>Password</div>
        <InputText type="password" @bind-Value="UserData.Password" />
    </div>
    <button class="btn btn-primary" type="submit">Log in</button>
</EditForm>

With only about 15 lines of code, we create a form with two input fields, a submit button and labels. We also provide a UserData object as the Model property and add a click handler to the OnSubmit property of the EditForm component.

Handling Form Submit

We already provided the Submit method as the OnSubmit event handler for the EditForm component. Now, let’s implement the Submit method within the @code section of our form component.

@code {
    public User UserData { get; set; }
    public string FormCompletedText { get; set; } = "";

    protected override void OnInitialized()
    {
        UserData = new User();
    }

    public void Submit()
    {
        FormCompletedText = $"User {UserData.Username} logged in.";
    }

    public class User
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }
}

We create two string properties. The UserData property holds the form data provided by the user. The FormCompletedText will be populated with a text we want to show when the user has logged in.

The Submit method is executed when a user submits the form by pressing the submit button. Within the method, we access the UserData property that contains the values the user has put into each input field.

We access the Username property and write a short message for the user to confirm the login was successful.

We add the following template snippet to the template section of the component to display the message to the user.

<p style="margin-top: 20px;">@FormCompletedText</p>

It will show the text set in the Submit method to the user whenever they press the login button.

Resetting Form Input Fields

Similar to regular HTML forms, we can use a button of type “reset” to reset the values in input fields.

We add the following line below the existing submit button within the EditForm component instance.

<button class="btn btn-secondary" type="reset">Reset</button>

When the user presses the button, the form fields are cleared.

Note: Keep in mind that this only clears the input fields visible on the screen. If we also want to reset the values within the UserData object, we need to add a Reset method and add it as an event handler to the onReset property of the EditForm component.

However, resetting form fields using a reset button isn’t as common as it once was. More commonly, you want to reset the fields when a form has been submitted.

The implementation is simple. We add the following line to the Submit method.

public void Submit()
{
    FormCompletedText = $"User {UserData.Username} logged in.";
    UserData = new User();
}

The second line of the Submit method creates a new instance of the User class and assigns it to the UserData property.

Form fields use a two-way binding, meaning that values changed in the code will also be reflected on the screen. As a result, all form fields are empty after submitting the form.

Dealing with Nullable Reference Types Warnings

The code above doesn’t account for nullable reference types (NRTs).

If you coded along, you definitely saw at least three compiler warnings caused by nullable reference types.

The error list in Visual Studio showing three compiler warnings regarding nullable reference types.

Let’s fix those warnings.

First, we add a default non-null value to the properties of the User class.

public class User
{
    public string Username { get; set; } = "";
    public string Password { get; set; } = "";
}

In this case, we set an empty string to both properties.

Next, instead of assigning an instance of the User class to the UserData property in the OnInitialized lifecycle method, we initialize the value when declaring the property.

@code {
    public User UserData { get; set; } = new User();
    public string FormCompletedText { get; set; } = "";

    public void Submit()
    {
        FormCompletedText = $"User {UserData.Username} logged in.";
        UserData = new User();
    }

    public class User
    {
        public string Username { get; set; } = "";
        public string Password { get; set; } = "";
    }
}

This version is not only shorter, doesn’t need an explicit OnInitialized override, but also fixes all nullable reference type-specific compiler warnings.

Conclusion

Blazor allows us to implement HTML forms using wrapper components. Those components provide a great API for event handling. We can add methods to handle form submits or form resets conveniently.

The built-in input wrapper components, such as the InputText component, allow us to add standard HTML attributes, such as type. And we can use the powerful two-way binding mechanism provided by the Blazor component model.

With less than 40 lines of code, we have a fully working HTML form, including a type-safe data class and form handling code. Of course, you would probably add more logic to the Submit method in a real-world application, such as calling a backend to verify the user data.

In the next article, we learn about different form validation options. Read it here: Blazor Basics: Advanced Blazor Form Validation.

You can access the code used in this example on GitHub.

If you want to learn more about Blazor development, you can watch my free Blazor Crash Course on YouTube. And stay tuned to the Telerik blog for more Blazor Basics.

Looking for something even easier? Among 110+ native Blazor components, Progress Telerik UI for Blazor offers a versatile Form component, complete with built-in validation. Try the whole library free for 30 days.

 


About the Author

Claudio Bernasconi

Claudio Bernasconi is a passionate software engineer and content creator writing articles and running a .NET developer YouTube channel. He has more than 10 years of experience as a .NET developer and loves sharing his knowledge about Blazor and other .NET topics with the community.

Related Posts

Comments

Comments are disabled in preview mode.