RadDataForm Validation Overview
If you followed the getting started section, you now know how to edit an object's properties with RadDataForm
for NativeScript. Sometimes you may need to validate if the user's input follows some requirements - for example, not leave an empty field in a registration form or provide a valid email. This article will present you the validation feature in RadDataForm
and show you how you can use the existing validators and create custom ones.
Figure 1: How validated field looks on Android (left) and iOS (right)
JSON Metadata
You can declare the validators in the JSON Metadata through the validators
key. The value of the validators should be an array of validators, where each validator is an object that has a name
and optionally params
. The params
, if present, is another object containing key value pairs, where the keys are the properties of the validator. Here's an example:
Example: How to add validators with JSON for a property
import { RegisteringUser } from '../data';
const description = 'Validation';
export default {
name: 'Validation',
description: description,
template: `
<Page>
<ActionBar :title="title">
<NavigationButton text="Back" android.systemIcon="ic_menu_back" @tap="onNavigationButtonTap"></NavigationButton>
</ActionBar>
<StackLayout>
<RadDataForm
ref="dataform"
:source="person"
:metadata="personMetadata">
</RadDataForm>
<Label :text="text"
textWrap="true"
margin="12"
android:color="#C73339"
ios:color="red"
horizontalAlignment="center"></Label>
<Button
text="Login"
margin="12"
horizontalAlignment="stretch"
@tap="onTap()"></Button>
</StackLayout>
</Page>
`,
data () {
return {
title: description,
person: new RegisteringUser(),
text: null,
personMetadata: {
'isReadOnly': false,
'commitMode': 'Immediate',
'validationMode': 'OnLostFocus',
'propertyAnnotations':
[
{
'name': 'username',
'displayName': 'Nick',
'index': 0,
'validators': [
{ 'name': 'NonEmpty' },
{ 'name': 'MaximumLength', 'params': { 'length': 10 } }
]
},
{
'name': 'email',
'displayName': 'E-Mail',
'index': 1,
'editor': 'Email',
'validators': [{
'name': 'RegEx',
'params': {
'regEx': '^[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}\\@telerik.com
## Validators List
Here's the list with supported validators:
* **TKNonEmptyValidator**
* **TKRangeValidator**
* **TKMinimumLengthValidator**
* **TKMaximumLengthValidator**
* **TKEmailValidator**
* **TKPhoneValidator**
* **TKIsTrueValidator**
* **TKRegExValidator**
## Validation Modes
You can choose when the validation of the changes happens by changing the data form's <a href="/ns-ui-api-reference//classes/raddataform.html#validationmode">`validationMode`</a> property. It accepts values from the <a href="/ns-ui-api-reference//enums/dataformvalidationmode.html">`DataFormValidationMode`</a> enumeration.
import { DataFormValidationMode } from 'nativescript-ui-dataform';
export default {
template:
<Page>
<ActionBar>
<ActionItem text="Immediate" android.position="popup" @tap="onImmediateTap"></ActionItem>
<ActionItem text="OnLostFocus" android.position="popup" @tap="onOnLostFocusTap"></ActionItem>
<ActionItem text="Manual" android.position="popup" @tap="onManualTap"></ActionItem>
</ActionBar>
<StackLayout>
<RadDataForm
ref="dataform"
:source="person"
:metadata="personMetadata"
:validationMode="validationMode"
commitMode="Manual">
</RadDataForm>
<Button
text="Validate manually"
horizontalAlignment="stretch"
@tap="onValidateTap()"></Button>
</StackLayout>
</Page>
,
data () {
return {
text: '',
validationMode: DataFormValidationMode.Immediate,
person: {
username: '',
password: '',
},
personMetadata: {
'isReadOnly': false,
'propertyAnnotations':
[
{
'name': 'username',
'displayName': 'Nick',
'index': 0,
'validators': [
{ 'name': 'NonEmpty' },
{ 'name': 'MaximumLength', 'params': { 'length': 10 } }
]
},
{
'name': 'password',
'displayName': 'Password',
'index': 2,
'validators': [
{
'name': 'NonEmpty',
}
]
},
]
}
};
},
methods: {
onImmediateTap() {
this.validationMode = DataFormValidationMode.Immediate;
},
onOnLostFocusTap() {
this.validationMode = DataFormValidationMode.OnLostFocus;
},
onManualTap() {
this.validationMode = DataFormValidationMode.Manual;
},
onValidateTap() {
this.$refs.dataform.validateAll()
.then(result => {
console.log(Validation result: ${result}
);
});
},
}
};
You should have in mind that the <a href="/ns-ui-api-reference//classes/raddataform.html#validationmode">`validationMode`</a> property is dependent on the value of the <a href="/ns-ui-api-reference//classes/raddataform.html#commitmode">`commitMode`</a> property, meaning that <a href="/ns-ui-api-reference//classes/raddataform.html">`RadDataForm`</a> will not let you commit property changes before you validate them. In other words:
* If `commitMode` is <a href="/ns-ui-api-reference//enums/dataformcommitmode.html#immediate">`Immediate`</a>, validation is also immediate disregarding the value of the `validationMode` property
* If `commitMode` is <a href="/ns-ui-api-reference//enums/dataformcommitmode.html#onlostfocus">`OnLostFocus`</a>, validation is immediate, if `validationMode` is <a href="/ns-ui-api-reference//enums/dataformvalidationmode.html#immediate">`Immediate`</a>, or <a href="/ns-ui-api-reference//enums/dataformvalidationmode.html#onlostfocus">`OnLostFocus`</a> otherwise
* If `commitMode` is <a href="/ns-ui-api-reference//enums/dataformcommitmode.html#manual">`Manual`</a>, validation will follow the value of `validationMode`.
## Validation Events
You can use the validation events to get notified when <a href="/ns-ui-api-reference//classes/raddataform.html">`RadDataForm`</a> validates its fields. You can also use these events for manual and/or asynchronous validation.
<snippet id='dataform-validation-event-vue'/>
There are two validation events that you can use to get notified when a property in <a href="/ns-ui-api-reference//classes/raddataform.html">`RadDataForm`</a> gets validated:
* **propertyValidate**: This event is fired while the value is validating and allows you to interfere and change the validation result.
* **propertyValidated**: This event is fired after the validation has finished and you can use it to check the final result from the validation.
## References
Related articles you might find useful:
* [**Editors List**](/ns-ui/DataForm/dataform-editors-list)
* [**Value Providers**](/ns-ui/DataForm/dataform-editors-providers)
,
'errorMessage': 'Please provide your @telerik.com email.'
}
}]
},
{
'name': 'password',
'displayName': 'Password',
'editor': 'Password',
'index': 2,
'validators': [
{
'name': 'NonEmpty',
},
{
'name': 'MinimumLength',
'params': {
'length': 6
}
},
]
},
{
'name': 'password2',
'displayName': 'Repeat Password',
'editor': 'Password',
'index': 3,
'validators': [
{
'name': 'NonEmpty',
},
{
'name': 'MinimumLength',
'params': {
'length': 6
}
},
]
},
{
'name': 'age',
'displayName': 'Age',
'index': 4,
'validators': [
{
'name': 'RangeValidator',
'params': {
'minimum': 1,
'maximum': 100,
'errorMessage': 'Age must be between 1-100.',
}
},
],
},
{
'name': 'agreeTerms',
'displayName': 'Agree Terms',
'index': 5,
'validators': [
{
'name': 'IsTrueValidator',
},
],
}
]
}
};
},
methods: {
onNavigationButtonTap() {
Frame.topmost().goBack();
},
onTap() {
let isValid = true;
const pName = this.$refs.dataform.getPropertyByName('username');
const pPwd = this.$refs.dataform.getPropertyByName('password');
const pPwd2 = this.$refs.dataform.getPropertyByName('password2');
if (pName.valueCandidate.toLowerCase() !== 'admin1') {
pName.errorMessage = 'Use admin1 as username.';
this.$refs.dataform.notifyValidated('username', false);
isValid = false;
} else {
this.$refs.dataform.notifyValidated('username', true);
}
if (!pPwd.valueCandidate) {
pPwd.errorMessage = 'Password is empty.';
this.$refs.dataform.notifyValidated('password', false);
isValid = false;
}
if (pPwd2.valueCandidate !== pPwd.valueCandidate) {
pPwd2.errorMessage = 'Password is not the same as above.';
this.$refs.dataform.notifyValidated('password2', false);
isValid = false;
} else {
this.$refs.dataform.notifyValidated('password2', true);
}
if (!isValid) {
this.text = 'Username or Password is not valid.';
} else {
this.text = '';
this.$refs.dataform.commitAll();
alert({
title: 'Successful Login',
message: `Welcome, ${this.person.username}`,
okButtonText: 'OK',
});
}
}
}
};
Validators List
Here's the list with supported validators:
- TKNonEmptyValidator
- TKRangeValidator
- TKMinimumLengthValidator
- TKMaximumLengthValidator
- TKEmailValidator
- TKPhoneValidator
- TKIsTrueValidator
- TKRegExValidator
Validation Modes
You can choose when the validation of the changes happens by changing the data form's validationMode
property. It accepts values from the DataFormValidationMode
enumeration.
import { DataFormValidationMode } from 'nativescript-ui-dataform';
export default {
template: `
<Page>
<ActionBar>
<ActionItem text="Immediate" android.position="popup" @tap="onImmediateTap"></ActionItem>
<ActionItem text="OnLostFocus" android.position="popup" @tap="onOnLostFocusTap"></ActionItem>
<ActionItem text="Manual" android.position="popup" @tap="onManualTap"></ActionItem>
</ActionBar>
<StackLayout>
<RadDataForm
ref="dataform"
:source="person"
:metadata="personMetadata"
:validationMode="validationMode"
commitMode="Manual">
</RadDataForm>
<Button
text="Validate manually"
horizontalAlignment="stretch"
@tap="onValidateTap()"></Button>
</StackLayout>
</Page>
`,
data () {
return {
text: '',
validationMode: DataFormValidationMode.Immediate,
person: {
username: '',
password: '',
},
personMetadata: {
'isReadOnly': false,
'propertyAnnotations':
[
{
'name': 'username',
'displayName': 'Nick',
'index': 0,
'validators': [
{ 'name': 'NonEmpty' },
{ 'name': 'MaximumLength', 'params': { 'length': 10 } }
]
},
{
'name': 'password',
'displayName': 'Password',
'index': 2,
'validators': [
{
'name': 'NonEmpty',
}
]
},
]
}
};
},
methods: {
onImmediateTap() {
this.validationMode = DataFormValidationMode.Immediate;
},
onOnLostFocusTap() {
this.validationMode = DataFormValidationMode.OnLostFocus;
},
onManualTap() {
this.validationMode = DataFormValidationMode.Manual;
},
onValidateTap() {
this.$refs.dataform.validateAll()
.then(result => {
console.log(`Validation result: ${result}`);
});
},
}
};
You should have in mind that the validationMode
property is dependent on the value of the commitMode
property, meaning that RadDataForm
will not let you commit property changes before you validate them. In other words:
- If
commitMode
isImmediate
, validation is also immediate disregarding the value of thevalidationMode
property - If
commitMode
isOnLostFocus
, validation is immediate, ifvalidationMode
isImmediate
, orOnLostFocus
otherwise - If
commitMode
isManual
, validation will follow the value ofvalidationMode
.
Validation Events
You can use the validation events to get notified when RadDataForm
validates its fields. You can also use these events for manual and/or asynchronous validation.
There are two validation events that you can use to get notified when a property in RadDataForm
gets validated:
- propertyValidate: This event is fired while the value is validating and allows you to interfere and change the validation result.
- propertyValidated: This event is fired after the validation has finished and you can use it to check the final result from the validation.
References
Related articles you might find useful: