Angular Validator - AsyncRule
A custom validation rule that is checked asynchronously. Use async rules for server-side validation.
To specify the async rule, set the type to "async" and declare the validationCallback function.
You can also set a custom message, specify whether empty values are valid, and whether the rule should be re-evaluated, even if the target value is the same.
Validation rules are checked in the following order: All the synchronous rules are checked in the same order as in the validationRules array. Then, all the async rules are checked simultaneously.
See Also
ignoreEmptyValue
If true, the validationCallback is not executed for null, undefined, false, and empty strings.
message
An error message can be specified as follows:
Hard-code the message
jQuery
index.js$(function() { $("#textBox").dxTextBox({ ... }) .dxValidator({ type: "async", message: "My custom message" }); });
Angular
app.component.htmlapp.module.ts<dx-text-box> <dx-validator> <dxi-validation-rule type="async" message="My custom message"> </dxi-validation-rule> </dx-validator> </dx-text-box>
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { DxValidatorModule, DxTextBoxModule } from 'devextreme-angular'; @NgModule({ declarations: [ AppComponent ], imports: [ DxTextBoxModule, BrowserModule, DxValidatorModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Vue
App.vue<template> <DxTextBox> <DxValidator> <DxAsyncRule message="My custom message" /> </DxValidator> </DxTextBox> </template> <script> import 'devextreme/dist/css/dx.light.css'; import { DxTextBox } from 'devextreme-vue/text-box'; import { DxValidator, DxAsyncRule } from 'devextreme-vue/validator'; export default { components: { DxTextBox, DxValidator, DxAsyncRule } } </script>
React
App.jsimport React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { TextBox } from 'devextreme-react/text-box'; import { Validator, AsyncRule } from 'devextreme-react/validator'; class App extends React.Component { render() { return ( <TextBox> <Validator> <AsyncRule message="My custom message" /> </Validator> </TextBox> ); } } export default App;
Hide the message
jQuery
index.js$(function() { $("#textBox").dxTextBox({ ... }) .dxValidator({ type: "async", message: "" }); });
Angular
app.component.htmlapp.module.ts<dx-text-box> <dx-validator> <dxi-validation-rule type="async" message=""> </dxi-validation-rule> </dx-validator> </dx-text-box>
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { DxValidatorModule, DxTextBoxModule } from 'devextreme-angular'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, DxValidatorModule, DxTextBoxModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Vue
App.vue<template> <DxTextBox> <DxValidator> <DxAsyncRule message="" /> </DxValidator> </DxTextBox> </template> <script> import 'devextreme/dist/css/dx.light.css'; import { DxTextBox } from 'devextreme-vue/text-box'; import { DxValidator, DxAsyncRule } from 'devextreme-vue/validator'; export default { components: { DxTextBox, DxValidator, DxAsyncRule } } </script>
React
App.jsimport React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { TextBox } from 'devextreme-react/text-box'; import { Validator, AsyncRule } from 'devextreme-react/validator'; class App extends React.Component { render() { return ( <TextBox> <Validator> <AsyncRule message="" /> </Validator> </TextBox> ); } } export default App;
Display the editor's name in the message
jQuery
index.js$(function() { $("#textBox").dxTextBox({ ... }) .dxValidator({ name: "Password", // The error message will be "Password is invalid" validationRules: [{ type: "async" }] }); });
Angular
app.component.htmlapp.module.ts<dx-text-box> <!-- The error message will be "Password is invalid" --> <dx-validator name="Password"> <dxi-validation-rule type="async"> </dxi-validation-rule> </dx-validator> </dx-text-box>
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { DxValidatorModule, DxTextBoxModule } from 'devextreme-angular'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, DxValidatorModule, DxTextBoxModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Vue
App.vue<template> <DxTextBox> <!-- The error message will be "Password is invalid" --> <DxValidator name="Password"> <DxAsyncRule /> </DxValidator> </DxTextBox> </template> <script> import 'devextreme/dist/css/dx.light.css'; import { DxTextBox } from 'devextreme-vue/text-box'; import { DxValidator, DxAsyncRule } from 'devextreme-vue/validator'; export default { components: { DxValidator, DxAsyncRule } } </script>
React
App.jsimport React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { TextBox } from 'devextreme-react/text-box'; import { Validator, AsyncRule } from 'devextreme-react/validator'; class App extends React.Component { render() { return ( <TextBox> {/* The error message will be "Password is invalid" */} <Validator name="Password"> <AsyncRule} /> </Validator> </TextBox> ); } } export default App;
Get the message from the server
See the example in the validationCallback description.
reevaluate
Indicates whether the rule should always be checked for the target value or only when the value changes.
type
validationCallback
Name | Type | Description |
---|---|---|
column |
The column to which the cell being validated belongs. Exists only when you validate a built-in editor in the DataGrid or TreeList. |
|
data |
The current row's data. Exists only when you validate a DataGrid or TreeList cell's value. |
|
formItem |
The form item being validated. Exists only when you validate a built-in editor in the Form UI component. |
|
rule |
The rule being checked. |
|
validator |
The Validator object that initiated the validation. |
|
value | | |
The validated value. |
The following code shows a generic validationCallback implementation for a server that returns a JSON response. The function sends the value that should be validated to the server. The response includes a flag that indicates validity, and optionally an error message that is used if validation fails.
jQuery
$(function() { $("#textBox").dxTextBox({ ... }) .dxValidator({ validationRules: [{ type: "async", validationCallback: function(params) { const d = $.Deferred(); $.ajax( ... ).done(function(res) { // res.message contains validation error message res.isValid ? d.resolve() : d.reject(res.message); // ===== or if "res" is { isValid: Boolean, message: String } ===== d.resolve(res); }).fail(function(error) { console.error("Server-side validation error", error); d.reject("Cannot contact validation server"); }) return d.promise(); } }] }); });
Angular
<dx-text-box> <dx-validator> <dxi-validation-rule type="async" [validationCallback]="validateAsync"> </dxi-validation-rule> </dx-validator> </dx-text-box>
import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { constructor(private httpClient: HttpClient) { this.validateAsync = this.validateAsync.bind(this); } validateAsync(params) { return new Promise((resolve, reject) => { this.httpClient.post("https://mydomain.com/MyDataService", { data: params.value }) .toPromise() .then((res: any) => { // res.message contains validation error message res.isValid ? resolve() : reject(res.message); // ===== or if "res" is { isValid: Boolean, message: String } ===== resolve(res); }) .catch(error => { console.error("Server-side validation error", error); reject("Cannot contact validation server"); }); }) } }
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { HttpClientModule } from '@angular/common/http'; import { DxValidatorModule, DxTextBoxModule } from 'devextreme-angular'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpClientModule, DxTextBoxModule, DxValidatorModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Vue
<template> <DxTextBox> <DxValidator> <DxAsyncRule :validation-callback="validateAsync" /> </DxValidator> </DxTextBox> </template> <script> import 'devextreme/dist/css/dx.light.css'; import { DxTextBox } from 'devextreme-vue/text-box'; import { DxValidator, DxAsyncRule } from 'devextreme-vue/validator'; import 'whatwg-fetch'; export default { components: { DxTextBox, DxValidator, DxAsyncRule }, methods: { validateAsync(params) { return new Promise((resolve, reject) => { fetch("https://mydomain.com/MyDataService", { method: 'POST', body: JSON.stringify({ data: params.value }) }) .then(response => { if (!response.ok) { throw new Error(`HTTP error: ${res.status} ${res.statusText}`); } return response.json(); }) .then(res => { // res.message contains validation error message res.isValid ? resolve() : reject(res.message); // ===== or if "res" is { isValid: Boolean, message: String } ===== resolve(res); }) .catch(error => { console.error("Server-side validation error", error); reject("Cannot contact validation server"); }); }); } } } </script>
React
import React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { TextBox } from 'devextreme-react/text-box'; import { Validator, AsyncRule } from 'devextreme-react/validator'; import 'whatwg-fetch'; const validateAsync = function(params) { return new Promise((resolve, reject) => { fetch("https://mydomain.com/MyDataService", { method: 'POST', body: JSON.stringify({ data: params.value }) }) .then(response => { if (!response.ok) { throw new Error(`HTTP error: ${res.status} ${res.statusText}`); } return response.json(); }) .then(res => { // res.message contains validation error message res.isValid ? resolve() : reject(res.message); // ===== or if "res" is { isValid: Boolean, message: String } ===== resolve(res); }) .catch(error => { console.error("Server-side validation error", error); reject("Cannot contact validation server"); }); }); }; class App extends React.Component { render() { return ( <TextBox> <Validator> <AsyncRule validationCallback={validateAsync} /> </Validator> </TextBox> ); } } export default App;
If you have technical questions, please create a support ticket in the DevExpress Support Center.