Angular Common - Data Validation
This guide provides the detailed information on validation capabilities of DevExtreme editors. It describes how to validate a single editor or a group of editors, display the validation summary, perform remote validation, use a custom validation engine, etc.
Validate an Editor Value
Associate a DevExtreme editor with the Validator UI component and specify validationRules to validate the editor. The full list of predefined validation rules is available in the Validation Rules Reference section.
- <dx-text-box [(value)]="login" placeholder="Login">
- <dx-validator>
- <dxi-validation-rule
- type="required">
- </dxi-validation-rule>
- <dxi-validation-rule
- type="pattern"
- pattern="^[a-zA-Z]+$"
- message="Do not use digits.">
- </dxi-validation-rule>
- </dx-validator>
- </dx-text-box>
- import { Component } from '@angular/core';
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
- })
- export class AppComponent {
- login: string;
- }
- import { BrowserModule } from '@angular/platform-browser';
- import { NgModule } from '@angular/core';
- import { AppComponent } from './app.component';
- import { DxTextBoxModule, DxValidatorModule } from 'devextreme-angular';
- @NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule,
- DxTextBoxModule,
- DxValidatorModule
- ],
- providers: [ ],
- bootstrap: [AppComponent]
- })
- export class AppModule { }
Group the Editors
Editors belonging to a single Validation Group can be validated together. All editors on a page are automatically collected in a Default Validation Group, which is suitable when you do not need to validate collections of editors separately. In other cases, define Validation Groups as shown in the following code:
- <dx-validation-group name="loginGroup">
- <dx-text-box [(value)]="login" placeholder="Login">
- <dx-validator>
- <!-- Login validation rules are configured here -->
- </dx-validator>
- </dx-text-box>
- <dx-text-box [(value)]="password" placeholder="Password">
- <dx-validator>
- <!-- Password validation rules are configured here -->
- </dx-validator>
- </dx-text-box>
- </dx-validation-group>
- import { Component } from '@angular/core';
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
- })
- export class AppComponent {
- login: string;
- password: string;
- }
- import { BrowserModule } from '@angular/platform-browser';
- import { NgModule } from '@angular/core';
- import { AppComponent } from './app.component';
- import { DxTextBoxModule, DxValidatorModule, DxValidationGroupModule } from 'devextreme-angular';
- @NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule,
- DxTextBoxModule,
- DxValidatorModule,
- DxValidationGroupModule
- ],
- providers: [ ],
- bootstrap: [AppComponent]
- })
- export class AppModule { }
Validate the Group
Call a group's validate() method in a Button's onClick event handler to validate the group. You can access the Validation Group via the handler's argument. The Button always validates the group to which it belongs. If the membership is not specified, the Button validates the Default Validation Group.
- <!-- <dx-validation-group> -->
- <dx-text-box [(value)]="login">
- <dx-validator>
- <!-- Login validation rules are configured here -->
- </dx-validator>
- </dx-text-box>
- <dx-text-box [(value)]="password">
- <dx-validator>
- <!-- Password validation rules are configured here -->
- </dx-validator>
- </dx-text-box>
- <dx-button text="Sign in" (onClick)="signIn($event)"></dx-button>
- <!-- </dx-validation-group> -->
- import { Component } from '@angular/core';
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
- })
- export class AppComponent {
- login: string;
- password: string;
- signIn(e) {
- let result = e.validationGroup.validate();
- if (result.isValid) {
- // Submit values to the server
- }
- }
- }
- import { BrowserModule } from '@angular/platform-browser';
- import { NgModule } from '@angular/core';
- import { AppComponent } from './app.component';
- import {
- DxTextBoxModule,
- DxValidatorModule,
- // DxValidationGroupModule,
- DxButtonModule
- } from 'devextreme-angular';
- @NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule,
- DxTextBoxModule,
- DxValidatorModule,
- // DxValidationGroupModule,
- DxButtonModule
- ],
- providers: [ ],
- bootstrap: [AppComponent]
- })
- export class AppModule { }
Alternatively, you can get a group's instance and call its validate method to validate this group:
- <dx-validation-group #targetGroup>
- <dx-text-box>
- <dx-validator>
- <dxi-validation-rule type="required">
- </dxi-validation-rule>
- </dx-validator>
- </dx-text-box>
- <dx-text-box>
- <dx-validator>
- <dxi-validation-rule type="required">
- </dxi-validation-rule>
- </dx-validator>
- </dx-text-box>
- </dx-validation-group>
- <dx-button
- text="Sign in"
- (onClick)="validateGroup($event)">
- </dx-button>
- import { Component } from '@angular/core';
- import { DxValidationGroupComponent } from 'devextreme-angular/ui/validation-group';
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
- })
- export class AppComponent {
- @ViewChild('targetGroup', {static: false}) validationGroup: DxValidationGroupComponent
- validateGroup() {
- this.validationGroup.instance.validate();
- }
- }
- import { BrowserModule } from '@angular/platform-browser';
- import { NgModule } from '@angular/core';
- import { AppComponent } from './app.component';
- import {
- DxTextBoxModule,
- DxButtonModule,
- DxValidatorModule,
- DxValidationGroupModule
- } from "devextreme-angular";
- @NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule,
- DxButtonModule,
- DxTextBoxModule,
- DxValidatorModule,
- DxValidationGroupModule
- ],
- providers: [],
- bootstrap: [AppComponent]
- })
- export class AppModule { }
Display Validation Errors
All group validation errors can be displayed in the ValidationSummary UI component. The following code shows how to add this UI component to a page. The commented-out codelines associate the Validation Summary with a named Validation Group.
- <!-- <dx-validation-group name="loginGroup"> -->
- ...
- <dx-validation-summary></dx-validation-summary>
- <!-- </dx-validation-group> -->
- import { BrowserModule } from '@angular/platform-browser';
- import { NgModule } from '@angular/core';
- import { AppComponent } from './app.component';
- import {
- // ...
- // DxValidationGroupModule,
- DxValidationSummaryModule
- } from 'devextreme-angular';
- @NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- // ...
- // DxValidationGroupModule,
- DxValidationSummaryModule
- ],
- providers: [ ],
- bootstrap: [AppComponent]
- })
- export class AppModule { }
Disable Validation Dynamically
All the rules, except the CustomRule and AsyncRule, are always applied and cannot be disabled at runtime.
If you need to disable validation dynamically, implement a CustomRule or AsyncRule in which you should simulate the validation logic of a target rule but apply it only under certain conditions.
The following example illustrates this case. A page contains two TextBoxes and a CheckBox. The first TextBox has proper RequiredRule; the second TextBox has a CustomRule that simulates the RequiredRule logic but applies it only when the CheckBox is selected. The reevaluate property is enabled to re-check the TextBox value after the CheckBox value was changed.
- <dx-text-box>
- <dx-validator>
- <dxi-validation-rule type="required">
- </dxi-validation-rule>
- </dx-validator>
- </dx-text-box>
- <dx-text-box>
- <dx-validator>
- <dxi-validation-rule
- type="custom"
- message="Required"
- [validationCallback]="customCallback"
- [reevaluate]="true">
- </dxi-validation-rule>
- </dx-validator>
- </dx-text-box>
- <dx-button
- text="Validate group"
- (onClick)="validateGroup($event)">
- </dx-button>
- <dx-check-box
- [(value)]="checkBoxValue">
- </dx-check-box>
- import { Component } from '@angular/core';
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
- })
- export class AppComponent {
- constructor() {
- this.customCallback = this.customCallback.bind(this);
- }
- checkBoxValue = false;
- customCallback(e) {
- if (this.checkBoxValue) {
- return !!e.value;
- }
- return true;
- }
- validateGroup(params) {
- params.validationGroup.validate();
- }
- }
- import { BrowserModule } from '@angular/platform-browser';
- import { NgModule } from '@angular/core';
- import { AppComponent } from './app.component';
- import {
- DxTextBoxModule,
- DxButtonModule,
- DxCheckBoxModule,
- DxValidatorModule
- } from "devextreme-angular";
- @NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule,
- DxCheckBoxModule,
- DxButtonModule,
- DxTextBoxModule,
- DxValidatorModule
- ],
- providers: [],
- bootstrap: [AppComponent]
- })
- export class AppModule { }
Custom Validation
To implement custom validation, use the CustomRule. Refer to the validationCallback function's description for an example.
Server-Side Validation
To implement server-side validation, use the AsyncRule. Refer to the validationCallback function's description for an example.
Validate a Custom Value
You can use the DevExtreme validation engine to validate a custom value, for example, a non-DevExtreme editor value or a concatenation of several editor values, by configuring the Validator's adapter property. The following example creates two text boxes and a button. A button click checks that at least one of these text boxes is filled. Their values are provided by the getValue function.
- <div id="contacts" [style.border]="borderStyle">
- <dx-text-box
- [(value)]="phone"
- placeholder="Phone"
- (onValueChanged)="revalidate()">
- </dx-text-box>
- <dx-text-box
- [(value)]="email"
- type="email"
- placeholder="Email"
- (onValueChanged)="revalidate()">
- </dx-text-box>
- </div>
- <dx-validator
- [adapter]="adapterConfig">
- <dxi-validation-rule
- type="required"
- message="Specify your phone or email.">
- </dxi-validation-rule>
- </dx-validator>
- <dx-validation-summary></dx-validation-summary>
- <dx-button
- text="Contact me"
- (onClick)="submit($event)">
- </dx-button>
- import { Component } from '@angular/core';
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
- })
- export class AppComponent {
- callbacks = [];
- phone: string;
- email: string;
- borderStyle: string = "none";
- adapterConfig = {
- getValue: () => {
- return this.phone || this.email;
- },
- applyValidationResults: (e) => {
- this.borderStyle = e.isValid ? "none" : "1px solid red";
- },
- validationRequestsCallbacks: this.callbacks
- };
- revalidate() {
- this.callbacks.forEach(func => {
- func();
- });
- };
- submit(e) {
- const { isValid } = e.validationGroup.validate();
- if (isValid) {
- // Submit values to the server
- }
- }
- }
- import { BrowserModule } from '@angular/platform-browser';
- import { NgModule } from '@angular/core';
- import { AppComponent } from './app.component';
- import {
- DxTextBoxModule,
- DxValidatorModule,
- DxValidationSummaryModule,
- DxButtonModule
- } from 'devextreme-angular';
- @NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule,
- DxTextBoxModule,
- DxValidatorModule,
- DxValidationSummaryModule,
- DxButtonModule
- ],
- providers: [ ],
- bootstrap: [AppComponent]
- })
- export class AppModule { }
If you have technical questions, please create a support ticket in the DevExpress Support Center.