Skip to content

Commit 92bfa7e

Browse files
ntachevadimodi
andauthored
docs(input-validation):document validation mode options (#610)
* docs(input-validation):document validation mode options * docs(inputs): Validation mode docs * docs(input validation):updated kb and examples * Update common-features/input-validation.md Co-authored-by: Dimo Dimov <[email protected]> * Update common-features/input-validation.md Co-authored-by: Dimo Dimov <[email protected]> * Update common-features/input-validation.md Co-authored-by: Dimo Dimov <[email protected]> * Update knowledge-base/textbox-validate-on-change.md Co-authored-by: Dimo Dimov <[email protected]> * docs(validation-modes):update * Update components/dateinput/overview.md Co-authored-by: Dimo Dimov <[email protected]> * docs(input-validation):last update Co-authored-by: Dimo Dimov <[email protected]>
1 parent 4e7f06a commit 92bfa7e

File tree

10 files changed

+183
-15
lines changed

10 files changed

+183
-15
lines changed

common-features/input-validation.md

Lines changed: 164 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ position: 2
1111

1212
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.
1313

14+
In this article:
15+
16+
* [Validation Basics](#validation-basics)
17+
* [Validation Modes for Simple Inputs](#validation-modes-for-simple-inputs)
18+
19+
## Validation Basics
20+
1421
To validate the Blazor inputs, you need to:
1522

1623
1. Define a model that has the desired [Data Annotation attributes](https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation).
@@ -34,7 +41,7 @@ This article provides examples of validating the Telerik Blazor components. The
3441

3542
>tip Telerik offers the [Form Component]({%slug form-overview%}) that lets you generate and manage forms with predefined layouts and less code.
3643
37-
## Simple Inputs
44+
### Simple Inputs
3845

3946
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.
4047

@@ -139,7 +146,7 @@ Simple textbox-like inputs do not have any special behavior. You need to bind th
139146
public DateTime? DailyScrum { get; set; }
140147
141148
[Required(ErrorMessage = "Enter a starting time")]
142-
[Range(typeof(DateTime), "29/11/2018 10:00:00", "22/12/2025 17:00:00",
149+
[Range(typeof(DateTime), "11/29/2018 10:00:00", "12/22/2025 17:00:00",
143150
ErrorMessage = "Value for {0} must be between {1:dd MMM yyyy HH:mm} and {2:dd MMM yyyy HH:mm}")]
144151
public DateTime StartTime { get; set; }
145152
@@ -151,8 +158,8 @@ Simple textbox-like inputs do not have any special behavior. You need to bind th
151158
[Range(typeof(bool), "true", "true", ErrorMessage = "Must subscribe to the newsletter")]
152159
public bool SubscribeToNewsletter { get; set; }
153160
154-
[Required(ErrorMessage="You should add a note.")]
155-
[MaxLength(300, ErrorMessage ="Your notes are too long.")]
161+
[Required(ErrorMessage = "You should add a note.")]
162+
[MaxLength(300, ErrorMessage = "Your notes are too long.")]
156163
public string PersonalNotes { get; set; }
157164
}
158165
@@ -173,7 +180,7 @@ Simple textbox-like inputs do not have any special behavior. You need to bind th
173180
}
174181
````
175182

176-
## DropDownList
183+
### DropDownList
177184

178185
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`).
179186

@@ -234,7 +241,7 @@ This means that for required field validation to work, the current item must hav
234241
}
235242
````
236243

237-
## RadioGroup
244+
### RadioGroup
238245

239246
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 annottation attributes on the validated class. Note that required field validation needs nullable fields.
240247

@@ -292,7 +299,7 @@ The radio group acts in a way similar to a dropdownlist - there is a collection
292299
````
293300

294301

295-
## ComboBox
302+
### ComboBox
296303

297304
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.
298305

@@ -397,7 +404,7 @@ The ComboBox works with the `Value` of the selected item (through its `ValueFiel
397404

398405

399406

400-
## MultiSelect
407+
### MultiSelect
401408

402409
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).
403410

@@ -445,7 +452,7 @@ The MultiSelect has a value that is a `List` and the validation attributes must
445452
}
446453
````
447454

448-
## DateRangePicker
455+
### DateRangePicker
449456

450457
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.
451458

@@ -527,7 +534,7 @@ There is no built-in provision in the framework for validating a field value bas
527534
````
528535

529536

530-
## Editor
537+
### Editor
531538

532539
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.
533540

@@ -568,7 +575,7 @@ Unlike other components, the editor does not trigger form validation on every ke
568575
````
569576

570577

571-
## MaskedTextbox
578+
### MaskedTextbox
572579

573580
The Masked Textbox prompts the user for their input and restricts it according to its [Mask]({%slug maskedtextbox-mask-prompt%}).
574581

@@ -644,7 +651,7 @@ You may want to set the [`IncludeLiterals`]({%slug maskedtextbox-mask-prompt%}#i
644651
````
645652

646653

647-
## Sliders
654+
### Sliders
648655

649656
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.
650657

@@ -713,7 +720,7 @@ The sliders are, effectively, numeric inputs in terms of behavior and what data
713720
````
714721

715722

716-
## Color Palette
723+
### Color Palette
717724

718725
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.
719726

@@ -748,6 +755,150 @@ The Color Palette component, while not an input, can work with validation so you
748755
}
749756
````
750757

758+
## Validation Modes for Simple Inputs
759+
760+
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:
761+
762+
* `Input` - (default) - triggers validation on each key press (`oninput`)
763+
* `Change` - triggers validation on confirmed value change (`OnChange`)
764+
765+
The feature is supported by the following components treated as simple textbox-like inputs:
766+
767+
* DateInput
768+
* DatePicker
769+
* DateTimePicker
770+
* MaskedTextBox
771+
* NumericTextBox
772+
* TextArea
773+
* TextBox
774+
* TimePicker
775+
776+
>caption Configure the event triggering the input validation
777+
778+
````CSHTML
779+
@using System.ComponentModel.DataAnnotations
780+
@* This Using is for the model class attributes only *@
781+
@* The Id parameters are not mandatory for validation, they just show better forms integration *@
782+
783+
<EditForm Model="@person" OnValidSubmit="@HandleValidSubmit">
784+
<DataAnnotationsValidator />
785+
<ValidationSummary />
786+
787+
---------- Validate OnInput -----------
788+
<br />
789+
790+
<p class="name">
791+
<label for="nameTextbox">Name:</label>
792+
<TelerikTextBox @bind-Value="@person.Name" ValidateOn="@ValidationEvent.Input"
793+
Id="nameTextbox"></TelerikTextBox>
794+
<ValidationMessage For="@(() => person.Name)"></ValidationMessage>
795+
</p>
796+
<p class="personal-notes">
797+
<label for="personalNotes">Personal Notes:</label>
798+
<TelerikTextArea @bind-Value="@person.PersonalNotes" ValidateOn="@ValidationEvent.Input"
799+
Id="personalNotes"></TelerikTextArea>
800+
<ValidationMessage For="@(() => person.PersonalNotes)"></ValidationMessage>
801+
</p>
802+
<p class="phone-number">
803+
<label for="phoneNumber">Phone Number:</label>
804+
<TelerikMaskedTextBox @bind-Value="@person.PhoneNumber" ValidateOn="@ValidationEvent.Input"
805+
Id="phoneNumber" Mask="+1-000-000-0000" PromptPlaceholder="null"></TelerikMaskedTextBox>
806+
<ValidationMessage For="@(() => person.PhoneNumber)"></ValidationMessage>
807+
</p>
808+
809+
<br />
810+
---------- Validate OnChange -----------
811+
<br />
812+
813+
<p class="height">
814+
<label for="heightNumeric">Height (cm):</label>
815+
<TelerikNumericTextBox @bind-Value="@person.Height" ValidateOn="@ValidationEvent.Change"
816+
Id="heightNumeric" />
817+
<ValidationMessage For="@(() => person.Height)"></ValidationMessage>
818+
</p>
819+
<p class="birthday">
820+
<label for="birthdayDateInput">Birthday:</label>
821+
<TelerikDateInput @bind-Value="@person.Birthday" ValidateOn="@ValidationEvent.Change"
822+
Format="dd MMMM yyyy" Id="birthdayDateInput"></TelerikDateInput>
823+
<ValidationMessage For="@(() => person.Birthday)"></ValidationMessage>
824+
</p>
825+
<p class="favorite-day">
826+
<label for="favDayDatePicker">Favorite date:</label>
827+
<TelerikDatePicker @bind-Value="@person.FavoriteDay" ValidateOn="@ValidationEvent.Change"
828+
Format="dd MMMM yyyy" Id="favDayDatePicker"></TelerikDatePicker>
829+
<ValidationMessage For="@(() => person.FavoriteDay)"></ValidationMessage>
830+
</p>
831+
<p class="start-time">
832+
<label for="dayStartDateTimePicker">Start time:</label>
833+
<TelerikDateTimePicker @bind-Value="@person.StartTime" ValidateOn="@ValidationEvent.Change"
834+
Width="250px" Id="dayStartDateTimePicker" Format="G"></TelerikDateTimePicker>
835+
<ValidationMessage For="@(() => person.StartTime)"></ValidationMessage>
836+
</p>
837+
<p class="daily-scrum">
838+
<label for="scrumTimePicker">Daily scrum:</label>
839+
<TelerikTimePicker @bind-Value="@person.DailyScrum" ValidateOn="@ValidationEvent.Change"
840+
Id="scrumTimePicker"></TelerikTimePicker>
841+
<ValidationMessage For="@(() => person.DailyScrum)"></ValidationMessage>
842+
</p>
843+
844+
<TelerikButton ButtonType="@ButtonType.Submit">Submit</TelerikButton>
845+
</EditForm>
846+
847+
@code {
848+
// Usually this class would be in a different file
849+
public class Person
850+
{
851+
[Required(ErrorMessage = "Enter a name")]
852+
[MinLength(3, ErrorMessage = "That name is too short")]
853+
[StringLength(10, ErrorMessage = "That name is too long")]
854+
public string Name { get; set; }
855+
856+
[Required(ErrorMessage = "You should add a note.")]
857+
[MaxLength(300, ErrorMessage = "Your notes are too long.")]
858+
public string PersonalNotes { get; set; }
859+
860+
[MinLength(10, ErrorMessage = "Enter a valid phone number")]
861+
public string PhoneNumber { get; set; }
862+
863+
[Required(ErrorMessage = "Provide your height in centimeters")]
864+
[Range(70, 300, ErrorMessage = "Enter a value between 70 and 300")]
865+
public int? Height { get; set; }
866+
867+
[Required]
868+
[Range(typeof(DateTime), "1/1/1900", "1/12/2000",
869+
ErrorMessage = "Value for {0} must be between {1:dd MMM yyyy} and {2:dd MMM yyyy}")]
870+
public DateTime Birthday { get; set; }
871+
872+
[Required]
873+
[Range(typeof(DateTime), "1/1/1999", "1/12/2019",
874+
ErrorMessage = "Value for {0} must be between {1:dd MMM yyyy} and {2:dd MMM yyyy}")]
875+
[Display(Name = "Your Favourite Day")]
876+
public DateTime FavoriteDay { get; set; }
877+
878+
[Required(ErrorMessage = "Enter a starting time")]
879+
[Range(typeof(DateTime), "11/29/2018 10:00:00", "12/22/2025 17:00:00",
880+
ErrorMessage = "Value for {0} must be between {1:dd MMM yyyy HH:mm} and {2:dd MMM yyyy HH:mm}")]
881+
public DateTime StartTime { get; set; }
882+
883+
[Required(ErrorMessage = "The daily standup is required")]
884+
[Range(typeof(DateTime), "1/1/1900 08:00:00", "1/1/1900 17:00:00",
885+
ErrorMessage = "Time should be in business hours, between 8AM and 5 PM.")]
886+
public DateTime? DailyScrum { get; set; }
887+
}
888+
889+
Person person = new Person()
890+
{
891+
// for time pickers, the initial date value must match the date portion of the range validation rule
892+
DailyScrum = new DateTime(1900, 1, 1, 1, 1, 1),
893+
};
894+
895+
void HandleValidSubmit()
896+
{
897+
Console.WriteLine("OnValidSubmit");
898+
}
899+
}
900+
````
901+
751902

752903
## See Also
753904

components/dateinput/overview.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ The date input provides the following features:
6060

6161
* Validation - see the [Input Validation]({%slug common-features/input-validation%}) article.
6262

63+
* `ValidateOn` - configures the event that will trigger validation (if validation is enabled). Read more at [Validation Modes for Simple Inputs]({%slug common-features/input-validation%}#validation-modes-for-simple-inputs).
64+
6365
@[template](/_contentTemplates/date-inputs/format-placeholders.md#format-placeholder)
6466

6567
## DateTime and Nullable DateTime

components/datepicker/overview.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ The Blazor Date Picker component exposes the following features:
7171

7272
* Validation - see the [Input Validation]({%slug common-features/input-validation%}) article.
7373

74+
* `ValidateOn` - configures the event that will trigger validation (if validation is enabled). Read more at [Validation Modes for Simple Inputs]({%slug common-features/input-validation%}#validation-modes-for-simple-inputs).
75+
7476
The date picker is, essentially, a [date input]({%slug components/dateinput/overview%}) and a [calendar]({%slug components/calendar/overview%}) and the properties it exposes are mapped to the corresponding properties of these two components. You can read more about their behavior in the respective components' documentation.
7577

7678
@[template](/_contentTemplates/date-inputs/format-placeholders.md#format-placeholder)

components/datetimepicker/overview.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ The DateTimePicker component exposes the following features:
7474

7575
* Validation - see the [Input Validation]({%slug common-features/input-validation%}) article.
7676

77+
* `ValidateOn` - configures the event that will trigger validation (if validation is enabled). Read more at [Validation Modes for Simple Inputs]({%slug common-features/input-validation%}#validation-modes-for-simple-inputs).
78+
7779
When using the dropdown to edit dates, you must click the "Set" button to commit the date. It is located in the Time portion of the dropdown (you will be navigated to it automatically upon selecting a date). Clicking "Cancel", or outside of the dropdown without clicking "Set", will revert the time to the original value. You can also commit a date by clicking the "NOW" button which will choose the current time.
7880

7981
The time format specifiers in the `Format` control the tumblers available in the dropdown. For example, the `HH` specifier will result in a hour selector in a 24 hour format. If you also add the `tt` specifier, you will also get the AM/PM tumbler, but the 24 hour format will still be used. This means that you can also add several tumblers for the same time portion if the format string repeats them.

components/maskedtextbox/overview.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ To use a Telerik MaskedTextbox for Blazor:
8181

8282
* Validation - see the [Input Validation]({%slug common-features/input-validation%}) article.
8383

84+
* `ValidateOn` - configures the event that will trigger validation (if validation is enabled). Read more at [Validation Modes for Simple Inputs]({%slug common-features/input-validation%}#validation-modes-for-simple-inputs).
85+
8486

8587
## Some Sample Masks
8688

components/numerictextbox/overview.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ The numeric textbox provides the following features:
6868

6969
* Validation - see the [Input Validation]({%slug common-features/input-validation%}) article.
7070

71+
* `ValidateOn` - configures the event that will trigger validation (if validation is enabled). Read more at [Validation Modes for Simple Inputs]({%slug common-features/input-validation%}#validation-modes-for-simple-inputs).
72+
7173
>caption Example of using a custom format strings
7274
7375
````CSHTML

components/textarea/overview.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ To use the Telerik TextArea in your Blazor application:
8080

8181
* Validation - see the [Input Validation]({%slug common-features/input-validation%}) article.
8282

83+
* `ValidateOn` - configures the event that will trigger validation (if validation is enabled). Read more at [Validation Modes for Simple Inputs]({%slug common-features/input-validation%}#validation-modes-for-simple-inputs).
84+
8385
>caption TextArea with its most common features and symbols counter
8486
8587
````CSHTML

components/textbox/overview.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ for example: https://demos.telerik.com/blazor-ui/textbox/password
9999

100100
* Validation - see the [Input Validation]({%slug common-features/input-validation%}) article.
101101

102+
* `ValidateOn` - configures the event that will trigger validation (if validation is enabled). Read more at [Validation Modes for Simple Inputs]({%slug common-features/input-validation%}#validation-modes-for-simple-inputs).
102103

103104
## See Also
104105

components/timepicker/overview.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,13 @@ The Time Picker component exposes the following features:
7070
* `Width` - Defines the width of the TimePicker.
7171

7272
* `TabIndex` - maps to the `tabindex` attribute of the HTML element. You can use it to customize the order in which the inputs in your form focus with the `Tab` key.
73-
*
74-
* `Placeholder` - `string` - maps to the `placeholder` attribute of the HTML element. The `Placeholder` will appear if the component is bound to **nullable** DateTime object - `DateTime?`, but will not be rendered if the component is bound to the default value of a non-nullable DateTime object.
73+
74+
* `Placeholder` - `string` - maps to the `placeholder` attribute of the HTML element. The `Placeholder` will appear if the component is bound to **nullable** DateTime object - `DateTime?`, but will not be rendered if the component is bound to the default value of a non-nullable DateTime object.
7575

7676
* Validation - see the [Input Validation]({%slug common-features/input-validation%}) article.
7777

78+
* `ValidateOn` - configures the event that will trigger validation (if validation is enabled). Read more at [Validation Modes for Simple Inputs]({%slug common-features/input-validation%}#validation-modes-for-simple-inputs).
79+
7880
The `Min` and `Max` properties require a `DateTime` object, but will only use the time portion from it. Thus, the date itself is not important. The hours, minutes, seconds and AM/PM portions control the range of the tumblers in the time picker dropdown. They do not impose validation/limitations on the input editing.
7981

8082
When using the dropdown to edit dates, you must click the "Set" button to commit the date. Clicking "Cancel", or outside of the dropdown without clicking "Set", will revert the time to the original value. You can also commit a date by clicking the "NOW" button which will choose the current time.

knowledge-base/textbox-validate-on-change.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ Is there a way to disable this behaviour?
3131

3232
We believe that firing the validation immediately makes the user experience more fluid and lets the user know about form issues quickly, which reduces frustration. Thus, we fire validation with the `ValueChanged` event.
3333

34+
>tip Telerik UI for Blazor 2.30 adds a `ValidateOn` parameter to input components. It defines the event that triggers validation (`OnChange` or `OnInput`). Read more at [Validation Modes for Simple Inputs]({%slug common-features/input-validation%}#validation-modes-for-simple-inputs).
35+
3436
### Differences with standard inputs
3537

3638
The standard inputs (such as `InputText` and `InputNumber`) use the `onchange` DOM event to change the `Value` of the model. We have chosen to use `oninput` to provide immediate feedback.

0 commit comments

Comments
 (0)