Validate a Telerik component as child component and apply invalid border
Environment
Product |
AutoComplete for Blazor, ComboBox for Blazor, DatePicker for Blazor, DateTimePicker for Blazor, DropDownList for Blazor, MultiColumnComboBox for Blazor, MultiSelect for Blazor, TimePicker for Blazor |
Description
I am wrapping a Telerik component inside a custom component in my Form. When I try to validate it, the red invalid border does not appear.
Solution
Internally, the Telerik input components use the cascading EditContext
parameter that the EditForm
and TelerikForm
provide. The EditContext
API allow the components to determine if validation has passed or failed. If the validation fails, the components show a red border.
When you wrap an input component in another component, you must define a ValueExpression
parameter in the custom component. This will allow the custom component to receive the correct expression from the parent component, which holds the Form. The Blazor framework generates the expression automatically when using @bind-Value
, but not when there is another component in the component hierarchy tree.
The example below shows how to wrap a Telerik TextBox and DropDownList in different .razor
files and get the invalid red border when the validation does not pass.
Validate a TextBox and a DropDownList in custom components with ValueExpression parameters
@using System.ComponentModel.DataAnnotations
<TelerikForm Model="@CustomerToEdit"
OnValidSubmit="@OnFormValidSubmit"
Width="300px">
<FormValidation>
<DataAnnotationsValidator></DataAnnotationsValidator>
<TelerikValidationSummary />
</FormValidation>
<FormItems>
<FormItem Field="@nameof(Customer.Id)" Enabled="false" LabelText="ID`" />
<FormItem Field="@nameof(Customer.Name)">
<Template>
<label for="customer-name" class="k-label k-form-label">Name</label>
<div class="k-form-field-wrap">
<TextBox @bind-Value="@CustomerToEdit.Name"
Id="customer-name" />
</div>
</Template>
</FormItem>
<FormItem Field="@nameof(Customer.CountryId)">
<Template>
<label for="customer-countryid" class="k-label k-form-label">Country</label>
<div class="k-form-field-wrap">
<DropDownList Data="@Countries"
@bind-Value="@CustomerToEdit.CountryId"
TextField="@nameof(Country.Name)"
ValueField="@nameof(Country.Id)"
Id="customer-countryid" />
</div>
</Template>
</FormItem>
</FormItems>
</TelerikForm>
<p style="color:var(--kendo-color-success)"><strong>@FormSubmitResult</strong></p>
@code {
private Customer CustomerToEdit { get; set; } = new();
private List<Country> Countries { get; set; } = new();
private string FormSubmitResult { get; set; } = string.Empty;
private void OnFormValidSubmit()
{
FormSubmitResult = $"Form Submit Success at {DateTime.Now.ToString("HH:mm:ss")}";
}
protected override void OnInitialized()
{
Countries = new()
{
new() { Id = 1, Name = "Australia" },
new() { Id = 2, Name = "Bulgaria" },
new() { Id = 3, Name = "Germany" },
new() { Id = 4, Name = "India" },
new() { Id = 5, Name = "UK" },
new() { Id = 6, Name = "USA" }
};
}
}