AsyncRule

A custom validation rule that is checked asynchronously. Use async rules for server-side validation.

Type:

Object

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.

View Demo

See Also

ignoreEmptyValue

If set to true, empty values are valid.

Type:

Boolean

Default Value: false

message

Specifies the message that is shown if the rule is broken.

Type:

String

Default Value: 'Value is invalid'

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.html
    app.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>
        <dx-text-box>
            <dx-validator>
                <dx-async-rule
                    message="My custom message"
                />
            </dx-validator>
        </dx-text-box>
    </template>
    
    <script>
    import 'devextreme/dist/css/dx.common.css';
    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.js
    import React from 'react';
    
    import 'devextreme/dist/css/dx.common.css';
    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.html
    app.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>
        <dx-text-box>
            <dx-validator>
                <dx-async-rule
                    message=""
                />
            </dx-validator>
        </dx-text-box>
    </template>
    
    <script>
    import 'devextreme/dist/css/dx.common.css';
    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.js
    import React from 'react';
    
    import 'devextreme/dist/css/dx.common.css';
    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.html
    app.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>
        <dx-text-box>
            <!-- The error message will be "Password is invalid" -->
            <dx-validator name="Password">
                <dx-async-rule />
            </dx-validator>
        </dx-text-box>
    </template>
    
    <script>
    import 'devextreme/dist/css/dx.common.css';
    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.js
    import React from 'react';
    
    import 'devextreme/dist/css/dx.common.css';
    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:

Boolean

Default Value: true

type

Specifies the rule type. Set it to "async" to use the AsyncRule.

Type:

String

Accepted Values: 'required' | 'numeric' | 'range' | 'stringLength' | 'custom' | 'compare' | 'pattern' | 'email' | 'async'

validationCallback

A function that validates the target value.

Type:

Function

Function parameters:
options:

Object

An object that defines validation parameters.

Object structure:
Name Type Description
column

Object

The column to which the cell being validated belongs. Exists only when you validate a built-in editor in the DataGrid or TreeList.

data

Object

The current row's data. Exists only when you validate a DataGrid or TreeList cell's value.

formItem

Object

The form item being validated. Exists only when you validate a built-in editor in the Form widget.

rule

Object

The rule being checked.

validator

Object

The Validator object that initiated the validation.

value

String

|

Number

The validated value.

Return Value:

Promise<any> (jQuery or native)

A Promise that should be resolved or rejected as shown in the example below.

The following code shows a generic validationCallback implementation. The function sends the value that should be validated to the server. The response contains a flag that indicates if the value is valid and optionally an error message:

jQuery
index.js
$(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({ isValid: false, message: res.message });

                        // ===== or if "res" is { isValid: Boolean, message: String } =====
                        d.resolve(res);
                    }).fail(function(error) {
                        // error.message contains request error message
                        d.reject({ isValid: false, message: error.message });
                    })
                    return d.promise();
                }
            }]
        });
});
Angular
app.component.html
app.component.ts
app.module.ts
<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(httpClient: HttpClient) {}

    validateAsync(params) {
        return new Promise((resolve, reject) => {
            this.httpClient.post("https://mydomain.com/MyDataService", { data: params.value })
                .toPromise()
                .then(res => {
                    // res.message contains validation error message
                    res.isValid ? resolve() : reject({ isValid: false, message: res.message });

                    // ===== or if "res" is { isValid: Boolean, message: String } =====
                    resolve(res);
                })
                .catch(error => {
                    // error.message contains request error message
                    reject({ isValid: false, message: error.message });
                });
        })
    }
}
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
App.vue
<template>
    <dx-text-box>
        <dx-validator>
            <dx-async-rule
                :validation-callback="validateAsync"
            />
        </dx-validator>
    </dx-text-box>
</template>

<script>
import 'devextreme/dist/css/dx.common.css';
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
    },
    methods: {
        validateAsync(params) {
            return new Promise((resolve, reject) => {
                fetch("https://mydomain.com/MyDataService", {
                    method: 'POST',
                    body: JSON.stringify({ data: params.value })
                }).then(res => {
                    // res.message contains validation error message
                    res.isValid ? resolve() : reject({ isValid: false, message: res.message });

                    // ===== or if "res" is { isValid: Boolean, message: String } =====
                    resolve(res);
                })
                .catch(error => {
                    // error.message contains request error message
                    reject({ isValid: false, message: error.message });
                });
            });
        }
    }
}
</script>
React
App.js
import React from 'react';

import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.css';

import { TextBox } from 'devextreme-react/text-box';
import {
    Validator,
    AsyncRule
} from 'devextreme-react/validator';

const validateAsync = function(params) {
    return new Promise((resolve, reject) => {
        fetch("https://mydomain.com/MyDataService", {
            method: 'POST',
            body: JSON.stringify({ data: params.value })
        })                   
        .then(res => {
            // res.message contains validation error message
            res.isValid ? resolve() : reject({ isValid: false, message: res.message });

            // ===== or if "res" is { isValid: Boolean, message: String } =====
            resolve(res);
        })
        .catch(error => {
            // error.message contains request error message
            reject({ isValid: false, message: error.message });
        });
    });
};

class App extends React.Component {
    render() {
        return (
            <TextBox>
                <Validator>
                    <AsyncRule
                        validationCallback={validateAsync} />
                </Validator>
            </TextBox>
        );
    }
}
export default App;