How to handle the ValueChanged event and use forms and validation

Environment

Product The inputs from UI for Blazor

How to handle the ValueChanged event and use forms and validation

Problem

Handling the ValueChanged event exposed from inputs interferes with two-way binding through @bind-Value and thus, with validation.

You cannot use both @bind-Value and ValueChanged, you will get a compilation error similar to

The component parameter 'ValueChanged' is used two or more times for this component. Parameters must be unique (case-insensitive). The component parameter 'ValueChanged' is generated by the '@bind-Value' directive attribute.

Solution

You can use the ValueExpression and Value properties to provide, respectively, the model field and the value of the input, and you can update the model with the new value in the ValueChanged event handler.

Example of invoking validation messages when handling the ValueChanged event

@using System.ComponentModel.DataAnnotations // used for the model annotations only

<EditForm Model="person">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <TelerikTextBox ValueChanged="@( (string s) => MyValueChangeHandler(s) )" 
        Value="@person.theTbValue"
        ValueExpression="@( () => person.theTbValue )">
    </TelerikTextBox>

    <button type="submit">Submit</button>

</EditForm>

from the handler: @result
<br />
from model: @person.theTbValue

@code {
    string result;
    Person person = new Person();

    public class Person
    {
        [Required(ErrorMessage = "Enter a name")]
        [StringLength(10, ErrorMessage = "That name is too long")]
        public string theTbValue { get; set; } = "lorem ipsum";
    }

    private void MyValueChangeHandler(string theUserInput)
    {
        result = string.Format("The user entered: {0}", theUserInput);

        //you have to update the model manually because handling the ValueChanged event does not let you use @bind-Value
        //For the validation to work you must now also define the ValueExpression because @bind-Value did it for you
        person.theTbValue = theUserInput;
    }
}

The lambda expression in the handler is required by the framework: https://github.com/aspnet/AspNetCore/issues/12226.

Telerik inputs also offer an OnChange event that does not interfere with two-way binding. It fires on blur or on Enter.

In this article
Not finding the help you need? Improve this article