indicative
Indicative is a beautiful Laravel inspired validation library for Nodejs with powerful promises. A took out a
day to write this library as i was not able to find a simple and easy to use library which is also extendable.
After using Laravel and ROR it was very frustating by not getting any powerful and promises based validation module for nodejs.
Index
Philosphy
Time and water does not wait for anyone , nor does javascript. Javascript asynchronous nature is great in many ways but at times makes it harder to work with loops specially when you are doing heavy operations.
This is where promises comes into picture, unlike time and water when you make a promise with someone in real life, they will wait for you until you fulfill or break your promise. That what promises are in javascript.
Indicative returns and accept promises only, every time you validate or extend indicative validator it accepts and returns a promise and to do it makes use of https://www.npmjs.org/package/q .
Basic Usage
It is very simple to use indicative
var validator = require('indicative');
validator.initialize();
var rules = {
'name' : 'required|alpha'
};
var values = {
'name': 'johny123'
};
validator.validate(rules,values).then(function(success){
console.log(success);
}).catch(function(err){
console.log(err);
}).done();
Expected output
{ name: [ { rule: 'alpha', message: 'name should be alpha only' } ] }
What you just did is
- Require the indicative module.
- Initialized it , it is very important to initialize as it register and extend methods.
- We called a method validate and passed rules and values to run validations on.
Custom Error Messages
Above error message doesn't seems to be good , and can be more descriptive. Let's make it so.
var validator = require('indicative');
validator.initialize();
var rules = {
'name' : 'required|alpha'
};
var values = {
'name': 'johny123'
};
var messages = {
'alpha': 'Name should only contain letters , numbers and special characters are not allowed'
};
validator.validate(rules,values,messages).then(function(success){
console.log(success);
}).catch(function(err){
console.log(err);
}).done();
Expected output
{ name: [ { rule: 'alpha', message: 'Name should only contain letters , numbers and special characters are not allowed' } ] }
Now you can see your custom message getting printed instead of a system generated one. But there is one problem , above error is not personalized enough as it contains a word called Name , which makes it non usable for other fields like username , lastname and so on.
Templating
Indicative also allows templating which means you can also access field name, values , rules and arguments inside your custom message , here is an example.
var messages = {
'alpha': '%field% should only contain letters , numbers and special characters are not allowed'
};
You can access following
- %field% :- Field name
- %value% :- Value
- %arg0% :- Validation rule argument 0 ( if exists ). Example after:2014-10-20 , writing %arg0% will return 2014-10-20.
Fields spefic messages
You can also define messages for different fields.
var validator = require('indicative');
validator.initialize();
var rules = {
'name' : 'required|alpha',
'lastname': 'required|alpha'
};
var values = {
'name': 'johny123',
'lastname': 'english80'
};
var messages = {
'name':{
'alpha': '%field% should only contain letters , numbers and special characters are not allowed'
},
'lastname':{
'alpha': 'Hope your lastname is simple and does not have weird special characters or numbers'
}
};
validator.validate(rules,values,messages).then(function(success){
console.log(success);
}).catch(function(err){
console.log(err);
}).done();
Expected output
{ name:
[ { rule: 'alpha',
message: 'name should only contain letters , numbers and special characters are not allowed' } ],
lastname:
[ { rule: 'alpha',
message: 'Hope your lastname is simple and does not have weird special characters or numbers' } ] }
Cool so far right ? let's make it even better.
Available Valiation Rules
I have covered plenty of usual validation rules.
required
The field under validation must be present and should contain some value
email
The field under validation must be formatted as an email-address.
after:date
The field under validation must be after a given date. Example after:2014-10-20
alpha
The field under validation must be letters only.
alpha_num
The field under validation can contain letters, numbers for combination of both.
array
The field under validation must be a valid array.
before:date
The field under validation must be before a given date. Example after:2014-10-20
boolean
The field under validation must be a valid boolean, true
, false
, 0
and 1
is treated as valid
array.
required_if:field,value
The field under validation must be present and should not be emptfy if field
field is equal to value
.
required_with:foo,bar,...
The field under validation must be present and should not be empty if any of the other fields are present.
required_with_all:foo,bar,...
The field under validation must be present and should not be empty if all of the other fields are present.
required_without:foo,bar,...
The field under validation must be present and should not be empty if any of the other fields are not present.
required_without_all:foo,bar,...
The field under validation must be present and should not be empty if all of the other fields are not present.
same:field
The field under validation must watch the given field
in:foo,bar,...
The field must be in one of the given list of values.
not_in:foo,bar,...
The field must not be in one of the given list of values.
date
The field under validation must be a valid date, MM/DD/YYYY, MM-DD-YYYY, YYYY-MM-DD,YYYY/MM/DD date
formats are supported by default.
date_format:format
The field under validation must be a valid date and should match specified date format.
different:field
The field under validation should be different from the given field
equals:value
The field under validation should be equal to given value
url:field
The field under validation must be a valid url. http
, https
and ftp
is supported.
ip
The field under validation must be a valid ip address.
range:18,24
The field under validation must be under defined range. Range must be integer or float.
integer
The field under validation must be a valid integer.
min:length
The field under validation must be greater or equals to defined length
max:length
The field under validation must be less or equals to defined length
Extending Indicative
It is really easy to extend and add your own validation to indicative. Make sure your custom methods
should return promises , otherwise a new error will be thrown.
var phone_no = function(value,args,message){
var deferred = Q.defer();
var phoneRe =/^(()?\d{3}())?(-|\s)?\d{3}(-|\s)?\d{4}$/;
if(phoneRe.test(value)){
deferred.resolve();
}else{
deferred.reject(message);
}
return deferred.promise;
}
validator.extend('phone_no','Enter valid phone no',phone_no);
Let's discuss what happened this time
- First we wrote a method
phone_no
which takes value, args and error message as parameters. - Next we wrote our own logic to validate a phone number and returned a promise depending upon validation passed or failed.
- Next we used indicative method extend to register our phone_no method on rule named
phone_no
and passed our custom message.
Here is the full example
var validator = require('../indicative');
var Q = require('q');
validator.initialize();
var rules = {
'username': 'required|alpha|min:4',
'email': 'required|email',
'contact_no': 'phone_no',
'gender': 'in:Male,Female,Other',
'age':'range:18,70',
'password':'required|min:4'
};
var values = {
'username': 'nu',
'contact_no': '1201abs',
'email': 'nu@example.com',
'gender': 'M',
'age': 22
};
var phone_no = function(value,args,message){
var deferred = Q.defer();
var phoneRe =/^(()?\d{3}())?(-|\s)?\d{3}(-|\s)?\d{4}$/;
if(phoneRe.test(value)){
deferred.resolve();
}else{
deferred.reject(message);
}
return deferred.promise;
}
validator.extend('phone_no','Enter valid phone no',phone_no);
validator.validate(rules,values).then(function(success){
console.log(success);
}).catch(function(err){
console.log(err);
}).done();
Examples
You can access examples inside examples folder of this repo.
Contributing
Contribution is always welcomed, fork this repo to get started.