UIKernel provides a handy tool to validate data, so that the user can be notified of invalid input before submitting a form or changes in an editable grid.
const validator = UIKernel.createValidator(serverValidationUrl, xhr);
Returns a builder that allows to define validation rules.
Parameters:
Type | Name | Description |
---|---|---|
String | serverValidationUrl | Optional. URI to send requests when validatorInstance.isValidRecord() is called. If this parameter is specified, validation will be performed remotely. If this parameter is omitted or requests cause Error 413, validation will be performed locally by means of validators specified below. |
Function | xhr | Optional. function sending requests to the server when validatorInstance.isValidRecord() is called. By default is used built-in xhr function, but you can override it here. |
validator.field(fieldName, rule, rule2, ..., ruleN);
Add synchronous field validation.
Parameters:
Type | Name | Description |
---|---|---|
String | fieldName | Required. Field name to add validation for. |
Function | rule | Required. Function to validate the field. If the field is invalid, the function should return a string value with error text. Else(if the field is valid) the function should return nothing. rule may be your own function, or one of the predefined in the UIKernel validation functions |
Function | rule2 | Optional |
Function | ruleN | Optional |
rule
s arguments:
Type | Name | Description |
---|---|---|
Any | value | The value of the field to validate |
validator.fields(fieldNames, rule);
Specify a rule for synchronous validation of a group of fields.
Parameters:
Type | Name | Description |
---|---|---|
String [ ] | fieldNames | Required. Field names(Array of string values) to add validation for. |
Function | rule | Required. Function to validate the fields. If any of the fields is invalid, the rule function should add the corresponding error to the errors object(second argument passed to the rule function). |
rule
s arguments:
Type | Name | Description |
---|---|---|
Object | record | Object with values of all fields. The object has the following structure: {field1: field1Value, field2: field2Value, …} |
ValidationErrors | errors | Object with errors of all fields. If any of the fields is invalid, the rule function should add the corresponding error to this errors object. |
validator.asyncDependence(fieldNames);
Specify server validation dependencies in a client validator.
Parameters:
Type | Name | Description |
---|---|---|
String [ ] | fieldNames | Required. Field names(Array of string values) which need to be validated on a remote server. |
Example:
/validation/client.js
//here we are specifying server validation URI as a parameter of createValidator
const clientValidator = UIKernel.createValidator(`/api/keywords/validation`)
//...here might be some other fields
.asyncDependence(['recordId', 'keywords']);
/validation/server.js
//serverValidator should be called in server model in response to a client request
// there is an example of how to do it is in the server side tutorial
const serverValidator = UIKernel.createValidator()
//...here might be some other fields
.asyncFields(
//dependent fields received from the client validator,
// they are sending to serverValidator automatically when
// clientValidator.isValidRecord(`serverValidationUrl`) is called.
['recordId', 'keywords'],
async function keywordValidation(record, errors) {
let queryString = `SELECT keyword FROM my_keywords_table WHERE record_id = ${record.recordId}`,
queryResult = await mysql.query(queryString),
existingKeywords = queryResult.map(row => row.keyword);
const uniqCount = 0;
for(let recKeyword of record.keywords)
if(existingKeywords.includes(recKeyword))
return errors.add('keywords', 'All the keywords must be new and unique!');
}
);
validator.asyncField(fieldName, rule);
Add an asynchronous validation rule to a field.
Parameters:
Type | Name | Description |
---|---|---|
String | fieldName | Required. |
async Function | rule | Required. Async function to validate the field. If the field is invalid, the function should resolve with a string value of the error text. Else(if the field is valid) the function should resolve with an empty value(null or undefined). |
validator.asyncFields(fieldNames, rule)
Specify a rule for asynchronous validation of a group of fields.
Parameters:
Type | Name | Description |
---|---|---|
String [ ] | fieldNames | Required. Field names(Array of string values) to add validation for. |
async Function | rule* | Required. Async function to validate the field. If any of the fields is invalid, the rule function should add the corresponding error to the errors object(second argument passed to the rule function) and resolve eventually. |
rule
s arguments:
Type | Name | Description |
---|---|---|
Object | record | Object with values of all fields. The object has the following structure: {field1: field1Value, field2: field2Value, …} |
ValidationErrors | errors | Object with errors of all fields. If any of the fields is invalid, the rule function should add the corresponding error to this errors object. |
let dependentFields = validator.getValidationDependency(fields);
Get all dependent fields required for validation of passed fields
.
Dependent fields come up when you use group validation methods: fields()
, asyncDependence()
, asyncFields()
.
Parameters:
Type | Name | Description |
---|---|---|
String [ ] | fields | Required. Fields names which you want to get dependent fields of |
Returns: String [ ]
Example:
let validator = UIKernel.createValidator()
.fields(['password', 'passwordConfirm'], (data, errors) => {
if (data.password !== data.passwordConfirm)
errors.add('passwordConfirm', 'Passwords don\'t match');
});
let dependentFields = validator.getValidationDependency(['passwordConfirm']);
console.log(dependentFields); //[['password']
const validationResult = await validator.isValidRecord(record);
Checks validity of the given record
. Returns ValidationErrors instance.
Parameters:
Type | Name | Description |
---|---|---|
Object | record | Required. Record to validate. The object has the following structure: {field1: field1Value, field2: field2Value, …} |
Returns: Promise which resolves with ValidationErrors instance.
There is a set of basic validation rules is provided out of the box:
// Check if value is not empty string, null and undefined
UIKernel.Validators.notNull(string errorMessage)
// Check if value is not an empty string, array or object and not null, undefined, 0
UIKernel.Validators.notEmpty(string errorMessage)
// Check if value is boolean
UIKernel.Validators.boolean(string errorMessage)
UIKernel.Validators.boolean.notNull(string errorMessage)
// Check if date matches min-to-max range
UIKernel.Validators.date(Date min, Date max, string errorMessage)
UIKernel.Validators.date.notNull(Date min, Date max, string errorMessage)
// Check if variants contain the value
UIKernel.Validators.enum(Array variants, string errorMessage)
UIKernel.Validators.enum.notNull(Array variants, string errorMessage)
// Check if value is float
UIKernel.Validators.float(number min, number max, string errorMessage)
UIKernel.Validators.float.notNull(number min, number max, string errorMessage)
// Check if value is integer
UIKernel.Validators.number(number min, number max, string errorMessage)
UIKernel.Validators.number.notNull(number min, number max, string errorMessage)
// Check if value matches regular expression
UIKernel.Validators.regExp(RegExp regExp, string errorMessage)
UIKernel.Validators.regExp.notNull(RegExp regExp, string errorMessage)
// Check if value belongs to set
UIKernel.Validators.set(Array set, string errorMessage)
UIKernel.Validators.set.notNull(Array set, string errorMessage)
You can also define your own validation rules. For example:
function oddNumbers(value) {
if (value % 2 === 0) {
return 'The value must be odd.';
}
}
const validator = UIKernel.createValidator()
.field('oddField', oddNumbers);
Usage of the validator is built-in in Grid and Form models, here is an example
But you can also use it independently wherever you want, e.g.:
const validator = UIKernel.createValidator()
// Check if email is valid using regular expression
.field('email', UIKernel.Validators.regExp.notNull(/^.*@.*$/, 'Your email is invalid'))
//validation of several dependent fields
.fields(['password', 'passwordConfirm'], (record, errors) => {
if (record.password !== record.passwordConfirm)
errors.add('passwordConfirm', 'Passwords don\'t match');
})
// Check if country isn't empty
.field('country', UIKernel.Validators.notNull('This field must not be empty.'))
// Check if data isn't less than '2014-10-01'
.field('timestamp', UIKernel.Validators.date.notNull(
'2014-10-01', null,
'Timestamp must exceed 2014-10-01'
))
// Check if age matches 15-90 range
.field('age', UIKernel.Validators.number.notNull(15, 90,
'You do not have the right age'
))
// Check if credit isn't less than 30.5
.field('credit', UIKernel.Validators.float(30.5, null,
'You can not take the credit which is less than 30.5'
))
// Check if interests belong to set
.field('interests',
UIKernel.Validators.set.notNull(['ART', 'SPORT', 'ANIMALS', 'GAMES'], 'An incorrect interest')
)
// Check if user agrees with terms of use
.field( 'agree', UIKernel.Validators.boolean.notNull(true, 'Select that you agree with the rules'))
// Check by means of the **custom validator** if a number is odd
.field('oddField', (value) => {
if (value % 2 === 0)
return 'oddField should be odd';
})
//async validation:
.asyncField('login', async function (val) {
let response = await fetch('https://yesno.wtf/api');
if(!response.ok)
throw new Error('Unable to reach validation API :(');
let respData = await response.json();
if (respData.answer !== 'yes')
return 'user with such login already exists!';
//or if it's the server side validation you can make DB request here
});
const testRecord = {
email: "z.freid1856@gmail.com",
password: "12345678",
passwordConfirm: "smth else",
country: "Austria",
timestamp: 1495032689647,
age: 161,
credit: 777,
interests: ["PSYCHOLOGY"],
agree: false,
oddField: 13,
login: "z.freid1856"
};
try {
const validationResult = await validator.isValidRecord(testRecord);
if (validationResult.isEmpty())
console.log('All right, there is no any errors! Validation result:', validationResult);
else
console.error('Passed record is invalid! Validation errors:', validationResult);
} catch (err) {
console.error('There is appeared an unexpected error in validation process:', err);
}