Input Validation
The UI for Blazor suite supports and integrates seamlessly into Blazor's Forms and Validation infrastructure. All Telerik UI for Blazor Input components work out of the box when placed inside an EditForm
, respond to EditContext
changes and provide default invalid styles.
In this article:
Validation Basics
To validate the Blazor inputs, you need to:
- Define a model that has the desired Data Annotation attributes.
- Place the inputs corresponding to its fields in an
EditForm
. - Add a
DataAnnotationsValidator
inside the editable form. - Provide the values to the inputs through the
bind-Value
binding syntax.
This article provides examples of validating the Telerik Blazor components. The examples are separated by input types for brevity:
- Simple Inputs
- Color Palette
- ComboBox
- DateRangePicker
- DropDownList
- Editor
- MaskedTextbox
- MultiSelect
- RadioGroup
- Sliders
Telerik offers the Form Component that lets you generate and manage forms with predefined layouts and less code.
Simple Inputs
Simple textbox-like inputs do not have any special behavior. You need to bind them to a model field that has the desired data annotation attributes set. Such inputs are the textbox, numeric textbox and date input.
@using System.ComponentModel.DataAnnotations
@* This Using is for the model class attributes only *@
@* The Id parameters are not mandatory for validation, they just show better forms integration *@
<EditForm Model="@person" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p class="name">
<label for="nameTextbox">Name:</label>
<TelerikTextBox @bind-Value="@person.Name" Id="nameTextbox"></TelerikTextBox>
<ValidationMessage For="@(() => person.Name)"></ValidationMessage>
</p>
<p class="role">
<label for="roleAutoComplete">Role:</label>
<TelerikAutoComplete Data="@RoleSuggestions" @bind-Value="@person.Role" Id="roleAutoComplete"
Placeholder="Enter your role (can be free text)" ShowClearButton="true" />
<ValidationMessage For="@(() => person.Role)"></ValidationMessage>
</p>
<p class="height">
<label for="heightNumeric">Height (cm):</label>
<TelerikNumericTextBox @bind-Value="@person.Height" Id="heightNumeric" />
<ValidationMessage For="@(() => person.Height)"></ValidationMessage>
</p>
<p class="birthday">
<label for="birthdayDateInput">Birthday:</label>
<TelerikDateInput @bind-Value="@person.Birthday" Format="dd MMMM yyyy" Id="birthdayDateInput"></TelerikDateInput>
<ValidationMessage For="@(() => person.Birthday)"></ValidationMessage>
</p>
<p class="favorite-day">
<label for="favDayDatePicker">Favorite date:</label>
<TelerikDatePicker @bind-Value="@person.FavoriteDay" Format="dd MMMM yyyy" Id="favDayDatePicker"></TelerikDatePicker>
<ValidationMessage For="@(() => person.FavoriteDay)"></ValidationMessage>
</p>
<p class="daily-scrum">
<label for="scrumTimePicker">Daily scrum:</label>
<TelerikTimePicker @bind-Value="@person.DailyScrum" Id="scrumTimePicker"></TelerikTimePicker>
<ValidationMessage For="@(() => person.DailyScrum)"></ValidationMessage>
</p>
<p class="start-time">
<label for="dayStartDateTimePicker">Start time:</label>
<TelerikDateTimePicker Format="G" @bind-Value="@person.StartTime" Width="250px" Id="dayStartDateTimePicker"></TelerikDateTimePicker>
<ValidationMessage For="@(() => person.StartTime)"></ValidationMessage>
</p>
<p class="personal-notes">
<label for="personalNotes">Personal Notes:</label>
<TelerikTextArea @bind-Value="@person.PersonalNotes" Id="personalNotes"></TelerikTextArea>
<ValidationMessage For="@(() => person.PersonalNotes)"></ValidationMessage>
</p>
<p class="accepts-terms">
<label class="k-checkbox-label" for="acceptTermsCheckbox">Accepts terms</label>
<TelerikCheckBox @bind-Value="@person.AcceptsTerms" Id="acceptTermsCheckbox"></TelerikCheckBox>
<ValidationMessage For="@(() => person.AcceptsTerms)"></ValidationMessage>
</p>
<p class="subscribe-mail">
<label>
Newsletter subscription
<TelerikSwitch @bind-Value="@person.SubscribeToNewsletter"></TelerikSwitch>
</label>
<ValidationMessage For="@(() => person.SubscribeToNewsletter)"></ValidationMessage>
</p>
<p class="signature">
<label>
Signature
<TelerikSignature @bind-Value="@person.PersonalSignature" Width="100px" Height="100px"></TelerikSignature>
</label>
<ValidationMessage For="@(() => person.PersonalSignature)"></ValidationMessage>
</p>
<TelerikButton ButtonType="@ButtonType.Submit">Submit</TelerikButton>
</EditForm>
@code {
private Person person = new Person()
{
// for time pickers, the initial date value must match the date portion of the range validation rule
DailyScrum = new DateTime(1900, 1, 1, 1, 1, 1),
};
private void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
private List<string> RoleSuggestions { get; set; } = new List<string>() {
"Manager", "Developer", "QA", "Technical Writer", "Support Engineer", "Sales Agent", "Architect", "Designer"
};
// Usually this class would be in a different file
public class Person
{
[Required(ErrorMessage = "Enter a name")]
[StringLength(10, ErrorMessage = "That name is too long")]
public string Name { get; set; }
[Required]
[StringLength(15, ErrorMessage = "That role name is too long, use abbreviations")]
public string Role { get; set; }
[Required(ErrorMessage = "Provide your height in centimeters")]
[Range(1, 300, ErrorMessage = "Nobody is that tall")]
public int? Height { get; set; }
[Required]
[Range(typeof(DateTime), "1/1/1900", "1/12/2000",
ErrorMessage = "Value for {0} must be between {1:dd MMM yyyy} and {2:dd MMM yyyy}")]
public DateTime Birthday { get; set; }
[Required]
[Range(typeof(DateTime), "1/1/1999", "1/12/2019",
ErrorMessage = "Value for {0} must be between {1:dd MMM yyyy} and {2:dd MMM yyyy}")]
[Display(Name = "Your Favourite Day")]
public DateTime FavoriteDay { get; set; }
[Required(ErrorMessage = "The daily standup is required")]
[Range(typeof(DateTime), "1/1/1900 08:00:00", "1/1/1900 17:00:00",
ErrorMessage = "Time should be in business hours, between 8AM and 5 PM.")]
public DateTime? DailyScrum { get; set; }
[Required(ErrorMessage = "Enter a starting time")]
[Range(typeof(DateTime), "11/29/2018 10:00:00", "12/22/2025 17:00:00",
ErrorMessage = "Value for {0} must be between {1:dd MMM yyyy HH:mm} and {2:dd MMM yyyy HH:mm}")]
public DateTime StartTime { get; set; }
[Required]
[Range(typeof(bool), "true", "true", ErrorMessage = "Must accept terms")]
public bool AcceptsTerms { get; set; }
[Required]
[Range(typeof(bool), "true", "true", ErrorMessage = "Must subscribe to the newsletter")]
public bool SubscribeToNewsletter { get; set; }
[Required(ErrorMessage = "You should add a note.")]
[MaxLength(300, ErrorMessage = "Your notes are too long.")]
public string PersonalNotes { get; set; }
[Required(ErrorMessage = "You must sign the Form")]
public string PersonalSignature { get; set; }
}
}
Color Palette
The Color Palette component, while not an input, can work with validation so you can, for example, require that the user picks a color. Since it is not an input, it does not have an invalid state, but you can add validation messages around it.
@using System.ComponentModel.DataAnnotations @* This Using is for the model class attributes only *@
<EditForm Model="@validationModel" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<TelerikColorPalette @bind-Value="@validationModel.FavoriteColor" />
<ValidationMessage For="@(() => validationModel.FavoriteColor)" />
<TelerikButton ButtonType="@ButtonType.Submit">Submit</TelerikButton>
</EditForm>
@code {
ColorValidationModel validationModel { get; set; } = new ColorValidationModel();
class ColorValidationModel
{
[Required]
public string FavoriteColor { get; set; }
}
async void HandleValidSubmit()
{
Console.WriteLine("valid submit");
}
}
ComboBox
The ComboBox works with the Value
of the selected item (through its ValueField
). This means that for required field validation to work, the current item must have a null
value, or AllowCustom
must be true
and the input empty.
@using System.ComponentModel.DataAnnotations
@* This Using is for the model class attributes only *@
@* The Id parameter is not mandatory for validation, ut just shows better forms integration *@
<EditForm Model="@person" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p class="team">
<label for="teamCombobox">Team:</label>
<TelerikComboBox @bind-Value="person.Team" Placeholder="Select team" ShowClearButton="true" Id="teamCombobox"
Data="@teams" TextField="MyTextField" ValueField="MyValueField">
</TelerikComboBox>
<ValidationMessage For="@(() => person.Team)"></ValidationMessage>
</p>
<TelerikButton ButtonType="@ButtonType.Submit">Submit</TelerikButton>
</EditForm>
@code {
// Usually the model classes would be in different files
public class Person
{
[Required(ErrorMessage = "Team is mandatory.")]//the value field in the combobox model must be null for this to have effect
[Range(1, 3, ErrorMessage = "Please select an actual team.")] //limits the fourth option just to showcase this is honored
public int? Team { get; set; }
}
public class MyDdlModel
{
//nullable so the default item can allow required field validation
//alternatively, use a range validator and put a value out of that range for the default item
public int? MyValueField { get; set; }
public string MyTextField { get; set; }
}
Person person = new Person();
IEnumerable<MyDdlModel> teams = new List<MyDdlModel>
{
new MyDdlModel {MyTextField = "Team 1", MyValueField = 1},
new MyDdlModel {MyTextField = "Team 2", MyValueField = 2},
new MyDdlModel {MyTextField = "Team 3", MyValueField = 3},
new MyDdlModel {MyTextField = "CEO", MyValueField = 4}
};
void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
}
@using System.ComponentModel.DataAnnotations
@* This Using is for the model class attributes only *@
@* The Id parameter is not mandatory for validation, ut just shows better forms integration *@
@*You can still use a full model. Strings are used for brevity here*@
<EditForm Model="@person" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p class="team">
<label for="teamComboBox">Team:</label>
<TelerikComboBox Data="@ExistingTeams" @bind-Value="person.Team" AllowCustom="true" ShowClearButton="true" Id="teamComboBox"></TelerikComboBox>
<ValidationMessage For="@(() => person.Team)"></ValidationMessage>
</p>
<TelerikButton ButtonType="@ButtonType.Submit">Submit</TelerikButton>
</EditForm>
@code {
// Usually the model classes would be in different files
public class Person
{
[Required(ErrorMessage = "Team is mandatory.")]//the combo must be empty for this to take effect
[RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$",
ErrorMessage = "Characters are not allowed.")] // Allow up to 40 uppercase and lowercase symbols, no special characters
// Applies to custom values as well as values from the data source.
public string Team { get; set; }
}
Person person = new Person();
protected List<string> ExistingTeams = new List<string>() { "first", "second", "third" };
void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
}
DateRangePicker
The Date Range Picker component consists of two inputs that the user can change independently. They can choose to alter one or both, and the application cannot know their intent - they can change one to an invalid value (for example, a start date that is after the end date), but then intend to change the second input as well.
There is no built-in provision in the framework for validating a field value based on another field value and so you need to implement a custom data annotation attribute to ensure the start date is before the end date.
@* These using statements are for the custom data annotation validation attribute. Check its implementation at the end of this code snippet *@
@using System.Reflection
@using System.ComponentModel.DataAnnotations
<EditForm Model="@dateRange" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>Try typing a date in the End input that is earlier than the Start date, and press Submit.
Or, use the Up and Down arrows to change the value of either input.</p>
<TelerikDateRangePicker @bind-StartValue="@dateRange.StartDate"
@bind-EndValue="@dateRange.EndDate" />
<TelerikButton Class="mt-4" ButtonType="@ButtonType.Submit">Submit</TelerikButton>
</EditForm>
@code {
private DateRangeModel dateRange { get; set; } = new DateRangeModel()
{
StartDate = DateTime.Today,
EndDate = DateTime.Today.AddDays(5)
};
async void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
// A custom validation attribute is used to show an error message to the user
// if they type an end date that is before the start date in the input
public class CompareDateAttribute : ValidationAttribute
{
public string compareToDateTimeProperty;
public CompareDateAttribute(string compareToPropertyName)
{
this.compareToDateTimeProperty = compareToPropertyName;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var validationObject = validationContext.ObjectInstance;
PropertyInfo propertyInfo = validationObject.GetType().GetProperty(compareToDateTimeProperty);
var currentValue = (DateTime?)value;
var compareToValue = (DateTime?)propertyInfo?.GetValue(validationObject);
return currentValue < compareToValue ? ValidationResult.Success : new ValidationResult(ErrorMessage, new[] { validationContext.MemberName });
}
}
public class DateRangeModel
{
[Required]
[Range(typeof(DateTime), "1/1/2019", "1/12/2025",
ErrorMessage = "Value for {0} must be between {1:dd MMM yyyy} and {2:dd MMM yyyy}")]
// custom validation attribute to ensure start date is before the end date
[CompareDate(nameof(EndDate), ErrorMessage = "The Start date must be before the End date.")]
public DateTime? StartDate { get; set; }
[Required]
[Range(typeof(DateTime), "1/1/2019", "1/12/2025",
ErrorMessage = "Value for {0} must be between {1:dd MMM yyyy} and {2:dd MMM yyyy}")]
public DateTime? EndDate { get; set; }
public DateRangeModel()
{
}
}
}
DropDownList
The DropDownList always has an item selected - the first item from its data source, the item corresponding to the Value
, or the item created from the DefaultText
the developer provides (which has the default value for the type of the Value field - for example, 0
for an int
and null
for an int?
or string
).
This means that for required field validation to work, the current item must have a null
value. Alternatively, if you cannot alter the dropdownlist item model you already have, you can use range validation and set a value for the default item that is outside of the range of actual values.
@using System.ComponentModel.DataAnnotations
@* This Using is for the model class attributes only *@
@* The Id parameter is not mandatory for validation, ut just shows better forms integration *@
<EditForm Model="@person" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p class="gender">
<label for="genderDropdownlist">Gender:</label>
<TelerikDropDownList @bind-Value="person.Gender" DefaultText="Select gender" Id="genderDropdownlist"
Data="@genders" TextField="MyTextField" ValueField="MyValueField">
</TelerikDropDownList>
<ValidationMessage For="@(() => person.Gender)"></ValidationMessage>
</p>
<TelerikButton ButtonType="@ButtonType.Submit">Submit</TelerikButton>
</EditForm>
@code {
// Usually the model classes would be in different files
public class Person
{
[Required(ErrorMessage = "Gender is mandatory.")]//the value field in the dropdown model must be null in the default item
[Range(1, 3, ErrorMessage = "Please select your gender.")] //limits the fourth option just to showcase this is honored
public int? Gender { get; set; }
}
public class MyDdlModel
{
//nullable so the default item can allow required field validation
//alternatively, use a range validator and put a value out of that range for the default item
public int? MyValueField { get; set; }
public string MyTextField { get; set; }
}
Person person = new Person();
IEnumerable<MyDdlModel> genders = new List<MyDdlModel>
{
new MyDdlModel {MyTextField = "female", MyValueField = 1},
new MyDdlModel {MyTextField = "male", MyValueField = 2},
new MyDdlModel {MyTextField = "other", MyValueField = 3},
new MyDdlModel {MyTextField = "I'd rather not say", MyValueField = 4}
};
void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
}
Editor
The Editor produces an HTML string in the field you bind its Value
to. Thus, while the user may see a certain amount of content, the actual content may have more symbols, because the HTML tags count towards the total string length, but the user does not see them.
Unlike other components, the editor does not trigger form validation on every keystroke, because it is expected to require a lot of content and that would be bad for performance. Validation is still triggered upon the ValueChanged
event, but that fires with a delay - the DebounceDelay
parameter which defaults to 100ms.
@using System.ComponentModel.DataAnnotations
@* This Using is for the model class attributes only *@
<EditForm Model="@theProduct" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<TelerikEditor @bind-Value="@theProduct.Description">
</TelerikEditor>
<TelerikButton ButtonType="@ButtonType.Submit">Submit</TelerikButton>
</EditForm>
@code {
public class Product
{
[Required(ErrorMessage = "Description is required")]
[MaxLength(100, ErrorMessage = "The max allowed length of the content is 100 symbols")]
[MinLength(20, ErrorMessage = "The min allowed length of the content is 20 symbols")]
public string Description { get; set; }
}
Product theProduct = new Product();
void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
}
MaskedTextbox
The Masked Textbox prompts the user for their input and restricts it according to its Mask.
The Blazor validation is, however, controlled by data annotation attributes on the model and so the application must have the appropriate rules set that match the desired input and masks. The RegularExpression annotation is commonly used to require a specific input format and values, or you can implement custom data annotation attributes too.
You may want to set the IncludeLiterals
parameter to true
and/or set the PromptPlaceholder
parameter accordingly to keep the prompt characters in the Value
so you can validate the content more easily.
@using System.ComponentModel.DataAnnotations
@* This Using is for the model class attributes only *@
<EditForm Model="@Payment" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
<TelerikFloatingLabel Text="Credit Card:">
<TelerikMaskedTextBox MaskOnFocus="true"
Mask="0000-0000-0000-0000"
IncludeLiterals="true"
@bind-Value="@Payment.CreditCard">
</TelerikMaskedTextBox>
</TelerikFloatingLabel>
<ValidationMessage For="@(() => Payment.CreditCard)" />
</p>
<p>
<TelerikFloatingLabel Text="Phone:">
<TelerikMaskedTextBox MaskOnFocus="true"
Mask="+1-000-000-0000"
@bind-Value="@Payment.PhoneNumber"
PromptPlaceholder="null">
</TelerikMaskedTextBox>
</TelerikFloatingLabel>
<ValidationMessage For="@(() => Payment.PhoneNumber)" />
</p>
<p>
<TelerikFloatingLabel Text="ZIP:">
<TelerikMaskedTextBox MaskOnFocus="true"
Mask="00000-9999"
@bind-Value="@Payment.Zip"
PromptPlaceholder="null">
</TelerikMaskedTextBox>
</TelerikFloatingLabel>
<ValidationMessage For="@(() => Payment.Zip)" />
</p>
<TelerikButton ButtonType="@ButtonType.Submit" ThemeColor="primary">Submit</TelerikButton>
</EditForm>
@code{
PaymentDetails Payment { get; set; } = new PaymentDetails();
public class PaymentDetails
{
//NOTE: These are sample rules, make sure to use ones that are correct and suitable for your application needs
[Required]
[RegularExpression("^[1-9][0-9]{3}-[1-3]{4}-[0-9]{4}-[0-9]{4}$", ErrorMessage = "Please enter a valid credit card number")]
public string CreditCard { get; set; }
[MinLength(10)]
public string PhoneNumber { get; set; }
[Required]
[RegularExpression(@"^\d{5}(?:[-\s]\d{4})?$", ErrorMessage = "Please Enter valid ZIP code")]
public string Zip { get; set; }
}
void HandleValidSubmit()
{
Console.WriteLine("VALID SUBMIT");
}
}
MultiSelect
The MultiSelect has a value that is a List
and the validation attributes must take that into account (for example, a regular expression attribute cannot work).
@using System.ComponentModel.DataAnnotations
@* This Using is for the model class attributes only *@
@* The Id parameter is not mandatory for validation, ut just shows better forms integration *@
<EditForm Model="@person" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p class="languages">
<label for="languagesMultiSelect">Languages:</label>
<TelerikMultiSelect @bind-Value="@person.DevLanguages"
Placeholder="Programming languages you know"
Data="@DevSkills"
Id="languagesMultiSelect"/>
<ValidationMessage For="@(() => person.DevLanguages)"></ValidationMessage>
</p>
<TelerikButton ButtonType="@ButtonType.Submit">Submit</TelerikButton>
</EditForm>
@code {
public class Person
{
[Required(ErrorMessage = "You must list the dev skills you have")]
[MinLength(3, ErrorMessage = "At least three languages are required so this application is considered")]
public List<string> DevLanguages { get; set; }
}
Person person = new Person();
List<string> DevSkills = new List<string>
{
"Blazor", "C#", "Python", "C", "C++", "Assembler", "Ruby", "Java", "JavaScript", "HTML", "CSS", "SQL", "PHP"
};
void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
}
RadioGroup
The radio group acts in a way similar to a dropdownlist - there is a collection of items that have values, and those values are used to populate a field in the model that is being validated. This lets you define the necessary data annotation attributes on the validated class. Note that required field validation needs nullable fields.
@using System.ComponentModel.DataAnnotations
@* This Using is for the model class attributes only *@
<EditForm Model="@form" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
Choose 2FA method:<br />
<TelerikRadioGroup Data="@TFAMethods"
@bind-Value="@form.TwoFaMethod"
ValueField="@nameof(TwoFactorAuthMethod.MethodId)"
TextField="@nameof(TwoFactorAuthMethod.MethodName)">
</TelerikRadioGroup>
<ValidationMessage For="@( () => form.TwoFaMethod )" />
<br />
<TelerikButton ButtonType="@ButtonType.Submit" ThemeColor="primary">SUBMIT</TelerikButton>
</EditForm>
@code{
RegistrationFormModel form { get; set; } = new RegistrationFormModel();
List<TwoFactorAuthMethod> TFAMethods { get; set; } = new List<TwoFactorAuthMethod>
{
new TwoFactorAuthMethod { MethodId = 1, MethodName = "None"},
new TwoFactorAuthMethod { MethodId = 2, MethodName = "SMS"},
new TwoFactorAuthMethod { MethodId = 3, MethodName = "Mobile App"},
new TwoFactorAuthMethod { MethodId = 4, MethodName = "Phone"},
};
public class RegistrationFormModel
{
[Required(ErrorMessage = "You must select a two-factor authentication method.")]
[Range(2, 3, ErrorMessage = "Phone authentication is not available at this time, and you must have an authentication method.")]
public int? TwoFaMethod { get; set; }
}
public class TwoFactorAuthMethod
{
public int? MethodId { get; set; }
public string MethodName { get; set; }
}
void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
}
Sliders
The sliders are, effectively, numeric inputs in terms of behavior and what data they provide. Thus, you can apply the standard validation rules to them.
@using System.ComponentModel.DataAnnotations
@* This Using is for the model class attributes only *@
<EditForm Model="@TheModel" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p class="temperature">
Enter your temperature:
<TelerikSlider @bind-Value="@TheModel.BodyTemperature"
Min="32.0"
Max="45.0"
Decimals="1"
SmallStep="0.1"
LargeStep="1.0"
Width="100%">
</TelerikSlider>
<ValidationMessage For="@(() => TheModel.BodyTemperature)"></ValidationMessage>
</p>
<p class="price-range">
Enter your preferred price range:
<TelerikRangeSlider @bind-StartValue="@TheModel.StartPrice"
@bind-EndValue="@TheModel.EndPrice"
Min="5.0"
Max="25.0"
Decimals="1"
SmallStep="0.5"
LargeStep="1.0"
Width="100%">
</TelerikRangeSlider>
<ValidationMessage For="@(() => TheModel.EndPrice)"></ValidationMessage>
</p>
<TelerikButton ButtonType="@ButtonType.Submit">Submit</TelerikButton>
</EditForm>
<style>
.validation-message {
margin-top: 1em;
}
</style>
@code{
MyModel TheModel { get; set; } = new MyModel();
void HandleValidSubmit()
{
Console.WriteLine("Valid Submit");
}
public class MyModel
{
[Required(ErrorMessage = "Enter body temperature")]
[Range(35.0, 42.0, ErrorMessage = "Body temperature should be between 35 and 42. Please verify.")]
public double? BodyTemperature { get; set; }
[Required(ErrorMessage = "Enter price range start")]
[Range(10.0, 16.0, ErrorMessage = "Start Price Range should be between 10.0 and 16.0")]
public double? StartPrice { get; set; }
[Required(ErrorMessage = "Enter price range end")]
[Range(12.0, 20.0, ErrorMessage = "End Price Range should be between 12.0 and 20.0")]
public double? EndPrice { get; set; }
}
}
Validation Modes for Simple Inputs
The simple textbox-like inputs (listed below) can trigger validation at different events. You can customize that through the ValidateOn
parameter. It takes a member of the ValidationEvent
enum and provides the following options:
-
Input
- (default) - triggers validation on each key press (oninput
) -
Change
- triggers validation on confirmed value change (OnChange
)
The feature is supported by the following components treated as simple textbox-like inputs:
- DateInput
- DatePicker
- DateTimePicker
- MaskedTextBox
- NumericTextBox
- TextArea
- TextBox
- TimePicker
@using System.ComponentModel.DataAnnotations
@* This Using is for the model class attributes only *@
@* The Id parameters are not mandatory for validation, they just show better forms integration *@
<EditForm Model="@person" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
---------- Validate OnInput -----------
<br />
<p class="name">
<label for="nameTextbox">Name:</label>
<TelerikTextBox @bind-Value="@person.Name" ValidateOn="@ValidationEvent.Input"
Id="nameTextbox"></TelerikTextBox>
<ValidationMessage For="@(() => person.Name)"></ValidationMessage>
</p>
<p class="personal-notes">
<label for="personalNotes">Personal Notes:</label>
<TelerikTextArea @bind-Value="@person.PersonalNotes" ValidateOn="@ValidationEvent.Input"
Id="personalNotes"></TelerikTextArea>
<ValidationMessage For="@(() => person.PersonalNotes)"></ValidationMessage>
</p>
<p class="phone-number">
<label for="phoneNumber">Phone Number:</label>
<TelerikMaskedTextBox @bind-Value="@person.PhoneNumber" ValidateOn="@ValidationEvent.Input"
Id="phoneNumber" Mask="+1-000-000-0000" PromptPlaceholder="null"></TelerikMaskedTextBox>
<ValidationMessage For="@(() => person.PhoneNumber)"></ValidationMessage>
</p>
<br />
---------- Validate OnChange -----------
<br />
<p class="height">
<label for="heightNumeric">Height (cm):</label>
<TelerikNumericTextBox @bind-Value="@person.Height" ValidateOn="@ValidationEvent.Change"
Id="heightNumeric" />
<ValidationMessage For="@(() => person.Height)"></ValidationMessage>
</p>
<p class="birthday">
<label for="birthdayDateInput">Birthday:</label>
<TelerikDateInput @bind-Value="@person.Birthday" ValidateOn="@ValidationEvent.Change"
Format="dd MMMM yyyy" Id="birthdayDateInput"></TelerikDateInput>
<ValidationMessage For="@(() => person.Birthday)"></ValidationMessage>
</p>
<p class="favorite-day">
<label for="favDayDatePicker">Favorite date:</label>
<TelerikDatePicker @bind-Value="@person.FavoriteDay" ValidateOn="@ValidationEvent.Change"
Format="dd MMMM yyyy" Id="favDayDatePicker"></TelerikDatePicker>
<ValidationMessage For="@(() => person.FavoriteDay)"></ValidationMessage>
</p>
<p class="start-time">
<label for="dayStartDateTimePicker">Start time:</label>
<TelerikDateTimePicker @bind-Value="@person.StartTime" ValidateOn="@ValidationEvent.Change"
Width="250px" Id="dayStartDateTimePicker" Format="G"></TelerikDateTimePicker>
<ValidationMessage For="@(() => person.StartTime)"></ValidationMessage>
</p>
<p class="daily-scrum">
<label for="scrumTimePicker">Daily scrum:</label>
<TelerikTimePicker @bind-Value="@person.DailyScrum" ValidateOn="@ValidationEvent.Change"
Id="scrumTimePicker"></TelerikTimePicker>
<ValidationMessage For="@(() => person.DailyScrum)"></ValidationMessage>
</p>
<TelerikButton ButtonType="@ButtonType.Submit">Submit</TelerikButton>
</EditForm>
@code {
// Usually this class would be in a different file
public class Person
{
[Required(ErrorMessage = "Enter a name")]
[MinLength(3, ErrorMessage = "That name is too short")]
[StringLength(10, ErrorMessage = "That name is too long")]
public string Name { get; set; }
[Required(ErrorMessage = "You should add a note.")]
[MaxLength(300, ErrorMessage = "Your notes are too long.")]
public string PersonalNotes { get; set; }
[MinLength(10, ErrorMessage = "Enter a valid phone number")]
public string PhoneNumber { get; set; }
[Required(ErrorMessage = "Provide your height in centimeters")]
[Range(70, 300, ErrorMessage = "Enter a value between 70 and 300")]
public int? Height { get; set; }
[Required]
[Range(typeof(DateTime), "1/1/1900", "1/12/2000",
ErrorMessage = "Value for {0} must be between {1:dd MMM yyyy} and {2:dd MMM yyyy}")]
public DateTime Birthday { get; set; }
[Required]
[Range(typeof(DateTime), "1/1/1999", "1/12/2019",
ErrorMessage = "Value for {0} must be between {1:dd MMM yyyy} and {2:dd MMM yyyy}")]
[Display(Name = "Your Favourite Day")]
public DateTime FavoriteDay { get; set; }
[Required(ErrorMessage = "Enter a starting time")]
[Range(typeof(DateTime), "11/29/2018 10:00:00", "12/22/2025 17:00:00",
ErrorMessage = "Value for {0} must be between {1:dd MMM yyyy HH:mm} and {2:dd MMM yyyy HH:mm}")]
public DateTime StartTime { get; set; }
[Required(ErrorMessage = "The daily standup is required")]
[Range(typeof(DateTime), "1/1/1900 08:00:00", "1/1/1900 17:00:00",
ErrorMessage = "Time should be in business hours, between 8AM and 5 PM.")]
public DateTime? DailyScrum { get; set; }
}
Person person = new Person()
{
// for time pickers, the initial date value must match the date portion of the range validation rule
DailyScrum = new DateTime(1900, 1, 1, 1, 1, 1),
};
void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
}