
Validate.js
Validate.js provides a declarative way of validating javascript objects.
The project can be found on GitHub where you can also find our issue tracker. There is also a Travis project used for testing and the annotated source.
Validate.js is an open source component of Wrapp and is licensed under the MIT license.
Downloads & Dependencies
There are no required external dependencies but the default parser and formatter for the datetime and date validator requires XDate or moment.js
Overview
There are already many validation libraries out there today but most of them are very tightly coupled to a language or framework.
The goal of validate.js is to provide a cross framework and cross language way of validating data. The validation constraints can be declared in JSON and shared between clients and the server. Python validation is planned so is Clojure.
Important!
One thing that is a bit unorthodox is that most validators will consider
empty values (null
, undefined
, whitespace
only strings etc) valid values. So for example adding a constraint of
at least 6 characters will be like saying If the attribute is given
it must be at least 6 characters.
This differs from example Ruby on Rails where validators instead have
the allow_nil
option. I find it quite common that you
want to have constraints on an optional attribute.
Supported runtimes
Validate.js works with any ECMAScript 5.1 runtime which means it works in both the browser and in node.js
All modern browsers are supported (IE9+, Firefox 3+, Opera 10.5+, Safari 4+).
IE8 support can likely be achived by polyfilling the following functions:
Array.prototype.indexOf
String.prototype.trim
Examples
You can find some basic examples included in the project.
They are meant to give a feeling for how to use the library and should not be considered production ready code.
The native HTML form validate has been disabled in a demo purpose so that you may see how validate.js works in action.
Acknowledgements
- The design of these docs pages have been heavily inspired by backbonejs.org.
- All the validators have been inspired by Rails' validators.
Constraints
The constraints have the following format
{
<attribute>: {
<validator name>: <validator options>
}
}
Unless otherwise specified you can always specify the message option to customize the message returned if the validator doesn't pass. Just remember to not include the attribute name since it's automatically prepended to the error message.
Sometimes it's nice to be able validate field differently depending on the input itself. validate.js allows the validators object and validator options to be a function that should return the constraints/options:
var constraints = {
creditCardNumber: {
presence: true,
format: {
pattern: /^(34|37|4|5[1-5]).*$/,
message: "must be a valid Amex, Visa or Mastercard number"
},
length: function(value, attributes, attributeName, options, constraints) {
if (value) {
// Amex
if ((/^(34|37).*$/).test(value)) return {is: 15};
// Visa, Mastercard
if ((/^(4|5[1-5]).*$/).test(value)) return {is: 16};
}
// Unknown card, don't validate length
return false;
}
},
creditCardZip: function(value, attributes, attributeName, options, constraints) {
if (!(/^(34|37).*$/).test(attributes.creditCardNumber)) return null;
return {
presence: true,
length: {is: 5}
};
}
};
validate({creditCardNumber: "4"}, constraints);
// => {"creditCardNumber": ["Credit card number is the wrong length (should be 16 characters)"]}
validate({creditCardNumber: "4242424242424242"}, constraints);
// => undefined
validate({creditCardNumber: "340000000000000"}, constraints);
// => {"creditCardZip": ["Credit card zip can't be blank"]}
If you don't want to give any options to a validator you may pass
true
instead of an empty object. The validator will not
be run if the options are falsy.
Important! Most validators consider empty values (null
, undefined
, whitespace
only strings etc) valid values so make sure you use the
presence
validator on attributes that are required.
Validate function
validate(attributes, constraints, [options])
Validates the attributes object against the constraints.
The attributes must be a plain object or a form element,
things like backbone models etc are not supported.
For the format of the constraints see the constraints section.
If the attributes objects is an HTML/DOM element
collectFormValues
is called before validating.
If there are no errors nothing is returned. Otherwise an object in this
format is returned: {<attribute>: [<error>, <error>, ...]}
Since validators don't include the argument name in the error message
the validate function prepends it for them. This behaviour can be
disabled by setting the fullMessages option to false
.
If you need an error not to be prefixed by the attribute add a leading
^
to the error and it won't be prepended. If you need to
have a leading ^
but want the prefixing just write \^
.
If you want to customize how the attribute names are prettified you
can just override the validate.prettify
to your liking.
There is also a flatten option which, if true
, returns a flat
array instead of an object.
var constraints = {
username: {presence: true},
password: {
presence: true,
length: {
minimum: 6,
message: "must be at least 6 characters"
}
}
};
validate({password: "bad"}, constraints);
// => {
// "username": ["Username can't be blank"],
// "password": ["Password must be at least 6 characters"]
// }
validate({username: "nicklas", password: "better"}, constraints);
// => undefined
validate({password: "better"}, constraints, {fullMessages: false})
// => {"username": ["can't be blank"]}
validate({}, constraints, {flatten: true})
// => ["Username can't be blank", "Password can't be blank"]
validate({}, {username: {presence: {message: "^You must pick a username"}}});
// => {"username": ["You must pick a username"]}
Async validation
validate.async(attributes, constraints, [options])
Even though none of the built in validators are async it is sometimes useful to have async validations. One example would be to check if a username is already used by asking the server.
Validate.js supports async validations through the validate.async
function. It has the same signature as the regular validation function
and accepts the same options.
validate.async
returns a Promise
that is resolved if the validation passes and is rejected if the
validation failed, passing the errors as the first argument.
The errors has the same format as the errors from the regular validation function.
The errors object will be an instance of validate.ValidationErrors to be able to differentiate between coding errors and validation errors.
You can use the async validate function even if no validations are async, it still returns a promise. You can not, however, use the regular function with async validations.
Any A+ type promise can be used, the following are supported out of the box (in order of precedence):
- ES6 promises (or the polyfill version)
- RSVP.js
- when
- Q
Validate.js looks for the promises in the global scope first and
if it can't find it, it tries to import them using the require
function if it exists. This means that AMD is supported but you will
need to make sure that the implementation you want to use is loaded
before you use the async function.
You can easily use any other A+ compatible
Promise by simply setting validate.Promise
to a function
that accepts the promise callback and returns the created promise.
Please note that jQuery's promise implementation is not A+ compatible and will not work.
Example:
var success = function() {
alert("The validations passed");
}
, error = function(errors) {
alert(JSON.stringify(errors, null, 2));
}
, constraints = {name: {presence: true}};
// Will call the success function
validate.async({name: "Nicklas"}, constraints).then(success, error);
// Will call the error function
validate.async({}, constraints).then(success, error);
// Supporting another promise implementation, in this case we'll always use
// the ES6 promise
validate.Promise = function(callback) {
return new Promise(callback);
};
Nested validation
Validate.js also has limited support for nested objects (objects within objects) using the dot notation.
The implementation is fairly basic and doesn't do anything clever with the messages. It doesn't support things like only validating a sub key if the parent key is present so for more advanced validations multiple validation schemas are recommended.
var constraints = {
"addresses.shipping": {
presence: true
},
"addresses.shipping.street": {
format: {
// Must be numbers followed by a name
pattern: "^[0-9]+ .+$",
message: "^The street for the shipping address must be a valid street name"
}
}
};
validate({}, constraints);
// => {"addresses.shipping": ["Addresses shipping can't be blank"]}
validate({addresses: {shipping: {street: "Foobar"}}}, constraints);
// => {"addresses.shipping.street": ["The street for the shipping address must be a valid street name"]}
validate({"foo.bar": 3}, {"foo\\.bar": {numericality: {even: true}}});
// => {"foo\.bar": ["Foo bar must be even"]}
Default options
Both the validate
, validate.async
as well
as all validators support specifying default options by setting
the options
property on the respective function or
validator.
Most validators allow you to specify default messages in addition to default options, refer to the documentation for the individual validators for information on how to do this.
var constraints = {
name: {
presence: true
}
};
validate.options = {flatten: true};
validate.async.options = {flatten: true};
validate.validators.presence.options = {message: "can't be empty"};
// The default options will be used for both the
// validator and the validate function
validate({}, constraints);
// => ["Name can't be empty"]
// The default options are not used if the constraints options are falsy
validate({flatten: false}, {});
// => undefined
Writing your own validator
Writing your own validator is super simple! Just add it to the
validate.validators
object and it will be automatically
picked up.
The validator receives the following arguments:
- value - The value exactly how it looks in the attribute object.
-
options - The options for the validator. Guaranteed to not
be
null
orundefined
. - key - The attribute name.
- attributes - The entire attributes object.
If the validator passes simply return null
or undefined
.
Otherwise return a string or an array of strings containing the
error message(s).
Make sure not to append the key name, this will be done automatically.
validate.validators.custom = function(value, options, key, attributes) {
console.log(value);
console.log(options);
console.log(key);
console.log(attributes);
return "is totally wrong";
};
// Will log:
// - "some value"
// - "some options"
// - "foo"
// - {"foo": "some value"}
validate({foo: "some value"}, {foo: {custom: "some options"}});
// => {foo: ["Foo is totally wrong"]}
Writing an async validator
Async validators are equal to a regular one in every way except
in what they return. An async validator should return a promise
(usually a validate.Promise
instance).
The promise should be resolved if the validation passed and rejected if it fails giving the message as the first argument:
validate.validators.myAsyncValidator = function(value) {
return validate.Promise(function(resolve, reject) {
setTimeout(function() {
if (value === "foo") resolve();
else reject("is not foo");
}, 100);
});
};
var constraints = {name: {myAsyncValidator: true}}
, success = alert.bind(this, "The validations passed")
, error = function(errors) {
alert(JSON.stringify(errors, null, 2));
};
// Will call the success callback
validate.async({name: "foo"}, constraints).then(success, error);
// Will call the error callback with {name: ["Name is not foo"]} as the first argument
validate.async({name: "bar"}, constraints).then(success, error);
Validators
The presence validator validates that the value isn't empty.
This validator will probably the most used one, it corresponds to
HTML5's required attribute.
You can use the message option to customize the message. The
default message is can't be blank and can be changed by
setting validate.validators.presence.message
.
These are the values that are considered empty:
null
undefined
[]
(empty objects){}
(empty arrays)""
(empty string)" "
(whitespace only string)
Important! All other values are considered valid (including functions)!
validate({}, {username: {presence: true}})
// => {"username": ["Username can't be blank"]}
validate({username: "ansman"}, {username: {presence: true}})
// => undefined
validate({}, {username: {presence: {message: "is required"}}})
// => {"username": ["Username is required"]}
validate.validators.presence.message = "is required";
validate({}, {username: {presence: true}});
// => {"username": ["Username is required"]}
The length validator will check the length of a string.
Any object with the length
property can be validated
but all the default error messages refers to strings so make sure
you override them if you plan on validating arrays using this.
You may specify the following length constraints:
- is
- The value has to have exactly this length. The default error is is the wrong length (should be %{count} characters)
- minimum
- The value cannot be shorter than this value. The default error is is too short (minimum is %{count} characters)
- maximum
- The value cannot be longer than this value. The default error is is too long (maximum is %{count} characters)
You can specify the error message using the wrongLength,
tooShort and tooLong options. The default values are
is the wrong length (should be %{count} characters),
is too short (minimum is %{count} characters) and
is too long (maximum is %{count} characters) respectively.
As you may have noticed you can use %{count}
as a placeholder
for the actual constraint and it will be replaced for you.
The default messages can also be changed by setting the following
attributes on validate.validators.length
:
notValid
tooLong
tooShort
wrongLength
You can also use the message as the message for all errors (this overrides any other custom errors).
Per default the number of characters are counted (using the length
property), if you want to count something else you can specify the
tokenizer option which should be a function that takes a single
argument (the value) and the returns a value that should be used when
counting.
The tokenizer will never be called with nil
or undefined
as an argument.
Once important thing to note is that the value needs to have a numeric
value for the length
property or the message has an incorrect length
is returned.
An error is also logged to the console since this is considered a
coding error.
var constraints = {
key1: {length: {is: 3}},
key2: {length: {minimum: 20}},
key3: {length: {maximum: 3}},
key4: {
length: {
minimum: 3,
tooShort: "needs to have %{count} words or more",
tokenizer: function(value) {
return value.split(/\s+/g);
}
}
}
};
validate({}, constraints);
// => undefined
// This is because nil and undefined are valid values.
// Use the presence validator if you don't want to allow empty values.
var values = {
key1: "wrong length",
key2: "too short",
key3: "too long",
key4: "too short"
};
validate(values, constraints);
// => {
// "key1": ["Key1 is the wrong length (should be 3 characters)"],
// "key2": ["Key2 is too short (minimum is 20 characters)"],
// "key3": ["Key3 is too long (maximum is 3 characters)"],
// "key4": ["Key4 needs to have 3 words or more"]
// }
The numericality validator will only allow numbers.
Per default strings are coerced to numbers using the +
operator. If this is not desirable you can set the noStrings
option to false
to disable this behaviour.
The following constraints can be applied:
- onlyInteger
- Real numbers won't be allowed. The error message is must be an integer
- greaterThan
- The input has to be greater than this value. The error message is must be greater than %{count}
- greaterThanOrEqualTo
- The input has to be at least this value. The error message is must be greater than or equal to %{count}
- equalTo
- The input has to be exactly this value. The error message is must be equal to %{count}
- lessThanOrEqualTo
- The input can be this value at the most. The error message is must be less than or equal to %{count}
- lessThan
- The input has to be less than this value. The error message is must be less than %{count}
- odd
- The input has to be odd. The error message is must be odd
- even
- The input has to be even. The error message is must be even
If you want a custom error message you may specify it using the
message option or by settings one of the following default
messages on the validate.validators.numericality
object:
notValid
notInteger
notGreaterThan
notGreaterThanOrEqualTo
notEqualTo
notLessThan
notLessThanOrEqualTo
notOdd
notEven
// null and undefined are valid values regardless of the options
validate({}, {duration: {numericality: true}});
//= > undefined
validate({duration: "foobar"}, {duration: {numericality: true}});
// => {"duration": ["Duration is not a number"]}
validate({duration: "3"}, {duration: {numericality: true}});
// => undefined
validate({duration: "3"}, {duration: {numericality: {noStrings: true}}});
// => {"duration": ["Duration is not a number"]}
var constraints = {
duration: {
numericality: {
onlyInteger: true,
greaterThan: 0,
lessThanOrEqualTo: 30,
even: true
}
}
};
validate({duration: 3.14}, constraints);
// => {"duration": ["Duration must be an integer"]}
validate({duration: 4711}, constraints);
// => {
// "duration": [
// "Duration must be less than or equal to 30",
// "Duration must be even"
// ]
// }
This datetime validator can be used to validate dates and times. The default implementation supports XDate and moment.js but it's easy to use any date library (see example below).
You can specify the follow constraints:
- earliest
-
The date cannot be before this time. This argument will be parsed
using the
parse
function, just like the value. The default error must be no earlier than %{date} - latest
-
The date cannot be after this time. This argument will be parsed
using the
parse
function, just like the value. The default error must be no later than %{date} - dateOnly
- If true, only dates (not datetimes) will be allowed. The default error is must be a valid date
- dateFormat
- The format for dates. The values for this will be different depending on which date library is used. Check the XDate or moment.js documentation for more information.
You can change the default message by setting any of these settings
on the validate.validators.datetime
object:
notValid
tooEarly
tooLate
If you want to use some other library you can override the
parse
and format
functions:
validate({}, {depature: {datetime: true}});
// => undefined
validate({departure: "foobar"}, {depature: {datetime: true}});
// => {"departure": ["Departure must be a valid date"]}
validate({departure: "2013-12-11 10:09:08", {departure: {datetime: true}}});
// => undefined
var constraints = {
birthday: {
datetime: {
dateOnly: true,
latest: XDate.today().addYears(-18),
message: "^You need to be atleast 18 years old"
}
}
};
validate({birthday: "3013-11-14 22:34:52"}, constraints);
// => {"birthday": ["Birthday must be a valid date"]}
validate({birthday: "3013-11-14"}, constraints);
// => {"birthday": ["You need to be atleast 18 years old"]}
// If you want to use another library override the two methods below:
// Value will be the input (guaranteed not to be null or undefined) and options
// are options given to the validator.
// This function should return the number of milliseconds since the UTC epoch
// or NaN if it's not a valid date.
validate.validators.datetime.parse = function(value, options) {
return new XDate(value, true).getTime();
};
// This function is only used when formatting dates for error messages.
// Value is the number of milliseconds since the UTC epoch.
// You should return a formatted strings of the given date.
// Make sure to check options.dateOnly and options.dateFormat when formatting.
validate.validators.datetime.format = function(value, options) {
var format = options.dateFormat || (options.dateOnly ? "yyyy-MM-dd" : "u");
return new XDate(date, true).toString(format);
};
You may also want to override the format
function in order to
customize the formatting of dates which are formatted as
ISO8601 per default.
If you want to change the parsing but keep using XDate you can
create a custom XDate parser.
The date validator is just a shorthand for the
datetime validator
with the dateOnly
option set to true
.
The format validator will validate a value against a regular expression
of your chosing.
The default message if the value doesn't match is is invalid
so you'll likely want to customize it by settings message
to something in the options or by setting a new global default
message using validate.validators.format.message
The pattern option can either be a javascript regexp or string that will be passed to the RegExp constructor. If the pattern is a string and you want to specify flags you may use the flags option.
Please note that the whole string must match the regexp, not just a part of the value.
var pattern = /\d{5}(-\d{4})?/;
validate({}, {zipCode: {format: pattern}});
// => undefined
validate({zipCode: "foobar"}, {zipCode: {format: pattern}});
// => {"zipCode": ["Zip code is invalid"]};
validate({zipCode: "12345"}, {zipCode: {format: pattern}});
// => undefined
var constraints = {
username: {
format: {
pattern: "[a-z0-9]+",
flags: "i",
message: "can only contain a-z and 0-9"
}
}
};
validate({username: "Nicklas!"}, constraints);
// => {"username": ["Username can only contain a-z and 0-9"]}
validate({username: "Nicklas"}, constraints);
// => undefined
The inclusion validator is useful for validating input from a dropdown
for example.
It checks that the given value exists in the list given by the within option.
You can specify within as a list or as an object (in which
case the keys of the object are used).
The default message is ^%{value} is not included in the list
and can be changed by setting
validate.validators.inclusion.message
var sizes = ["small", "medium", "large"];
validate({}, {size: {inclusion: sizes}});
// => undefined
validate({size: "xlarge"}, {size: {inclusion: sizes}});
// => {"size": ["xlarge is not included in the list"]}
var constraints = {
size: {
inclusion: {
within: {"Small": "s", "Medium": "m", "Large": "l"},
message: "^We're currently out of %{value}"
}
}
};
validate({size: "Extra large"}, constraints);
// => {"size": ["We're currently out of Extra large"]}
validate({size: "Medium"}, constraints);
// => undefined
The exclusion validator is useful for restriction certain values.
It checks that the given value is not in the list given by the
within option.
You can specify within as a list or as an object (in which
case the keys of the object are used).
The default message is ^%{value} is restricted
and can be changed by setting
validate.validators.exclusion.message
var restrictedDomains = ["jp", "ch"];
validate({}, {subdomain: {exclusion: restrictedDomains}});
// => undefined
validate({subdomain: "jp"}, {subdomain: {exclusion: restrictedDomains}});
// => {"size": ["jp is restricted"]}
var constraints = {
subdomain: {
exclusion: {
within: {jp: "Japan", "ch": "China"},
message: "^We don't support %{value} right now, sorry"
}
}
};
validate({subdomain: "jp"}, constraints);
// => {"subdomain": ["We don't support jp right now, sorry"]}
validate({subdomain: "com"}, constraints);
// => undefined
The email validator attempts to make sure the input is a valid email.
Validating emails is tricky business due to the complex rules of
email address formatting.
For example john.doe@gmail
is a perfectly valid email
but it's most likely just the case that John has forgotten to write
.com
at the end.
Validate.js tries to be pragmatic and allows most valid emails but
tries to catch common typos such as forgetting the TLD.
If you want to know more about email validation the
Wikipedia article
and the email page on regular-expressions.info
are good places to start.
You can customize the regexp used by setting validate.validators.email.PATTERN
to a regexp of your chosing, just remember that javascript regexp
does substring matching.
The default message is is not a valid email and as usual you
can override it using the message option or by setting
validate.validators.email.message
Important! Besides null
and undefined
being valid empty strings and whitespace only strings are also valid.
var constraints = {
from: {
email: true
}
};
validate({from: null}, constraints);
// => undefined
validate({from: " "}, constraints);
// => undefined
validate({from: "nicklas@ansman"}, constraints);
// => {"email": ["From is not a valid email"]}
// Any TLD is allowed
validate({from: "nicklas@foo.faketld"}, constraints);
// => undefined
// Upper cased emails are allowed
validate({from: "NICKLAS@ANSMAN.SE"}, constraints);
// => undefined
constraints = {
from: {
email: {
message: "doesn't look like a valid email"
}
}
};
validate({from: "foobar"}, constraints);
// => {"email": ["From doesn't look like a valid email"]}
// It allows unicode
validate({from: "first.läst@example.com"}, constraints);
// => undefined
The equality validator can be used to verify that one attribute
is always equal to another.
This is useful when having a "confirm password" input for
example.
You specify which attribute by simply using the name of it as the options for the validator or by giving the option attribute.
By default ===
is used to check the quality, it you
need to validate more complex objects you can give a function
using the comparator option which should be a function
that accepts two arguments and returns true
if they
objects are equal and false
if they are not.
The default message is is not equal to %{attribute}
validate.validators.equality.message
var constraints = {
confirmPassword: {
equality: "password"
}
};
validate({password: "foo", confirmPassword: "foo"}, constraints);
// => undefined
validate({password: "foo", confirmPassword: "bar"}, constraints);
// => {confirmPassword: ["Confirm password is not equal to password"]}
constraints = {
complexAttribute: {
equality: {
attribute: "otherComplexAttribute",
message: "is not complex enough",
comparator: function(v1, v2) {
return JSON.stringify(v1) === JSON.stringify(v2);
}
}
}
};
validate({complexAttribute: [1,2,3], otherComplexAttribute: [1,2,3]}, constraints);
// => undefined
validate({complexAttribute: [1,2,3], otherComplexAttribute: [3,2,1]}, constraints);
// => {complexAttribute: ["Complex attribute is not complex enough"]}
Utilities
validate.collectFormValues(rootElement, [options])
One of the most common tasks is collecting the values and it was only recently this was possible in a native way (FormData) so as a convenience a function for doing this has been added to validate.js
This function will find all named inputs (inputs that specify the name attribute) and collect their values.
The following options exists:
- nullify
- Converts empty strings to
null
(default is true) - trim
- Trims whitespace from the start and end of the value
You can ignore inputs by adding the data-ignored
attribute.
<form id="login">
<input type="text" name="username" value="ansman">
<input type="password" name="password" value="correcthorsebatterystaple">
<input type="checkbox" name="remember-me">
<input type="hidden" name="some-hidden-value" data-ignored>
</form>
<script>
var form = document.querySelector("form#login");
validate.collectFormValues(form);
// => {username: "ansman", password: "correcthorsebatterystaple", remember-me: true}
</script>
Installing
node.js
Install it like every other npm package:
$ npm install validate.js
You can also add it to the dependencies
section of your
package.json
like so:
{
"dependencies": {
"validate.js": "~0.5.0"
}
}
Then in your code you can do something like this:
var validate = require("validate.js");
validate({}, {username: {presence: true}});
// => {"username": ["Username can't be blank"]};
Browser
Simply add this to your HTML:
<script src="path/to/validate.min.js"></script>
If you want to use Source Maps just place the validate.min.map file in the same directory as the javascript file.
If you're using a commonjs compatible AMD such as require.js you can use this code to include validate.js
require(["validate"], function(validate) {
// Your code
});
Bower
To install using Bower just run:
$ bower install validate
or add it to your bower.json
file:
{
"dependencies": {
"validate": "0.5.0"
}
}
Changelog
0.5.0 - Mar 7, 2015 - Docs - Diff
-
Breaking: All validators besides
presence
now allow values that are rejected by thepresence
validator. Mostly this means that empty and whitespace only strings are now allowed by all validators exceptpresence
. Thanks droganov for reporting this! - Examples have now been added and can be found here. Thanks Alexander Sergéev for suggesting this.
- Added a function to collect form values from a HTML form.
- Added an equality validator. Thanks Gutsulyak Dmitry for suggesting this.
- Added support for validating HTML forms element by simply passing them instead of an attributes object.
0.4.0 - Feb 6, 2015 - Docs - Diff
- Breaking: Empty and whitespace only strings are now valid emails.
-
Fixed a bug where
fullMessages
didn't work invalidate.async
. Thanks sebastianseilund for fixing this! -
Fixed an issue where values without the
length
attribute passed thelength
validator. Thanks Cellule for fixing this! -
Make async errors an instance of
validate.ValidationErrors
. Thanks sebastianseilund, Jokero and dkushner for helping with the details. - Fix an error when nested objects are null. Thanks javve for reporting this.
-
Support fetching moment from the global scope and not just using
require
. Thanks alvipeo for suggesting this. - Support for default options and messages. Thanks tamtakoe for suggesting this.
- Fix a bug in the date validator. Thanks Jokero for fixing this.
0.3.2 - Oct 5, 2014 - Docs - Diff
- Pass the attributes as argument when resolving an async validation. Thanks pstoica for suggesting this.
- Move the repository from wrapp to ansman
0.3.0 - Sep 5, 2014 - Docs - Diff
- Allow upper case letters in email addresses
- Breaking: Nested validation - periods can now be used for validated nested objects. Thanks colinskow for implementing this.
- Support moment.js for datetime parsing and formatting
0.1.3 - Nov 26, 2013 - Docs - Diff
- Fix a bug where only upper cased 2 letter TLDs were allowed in the email validator
- More lax validation of the TLDs in the email validator
0.1.2 - Nov 25, 2013 - Docs - Diff
- Add bower.json
- Add an easy way of validating emails using the email validator
0.1.1 - Nov 16, 2013 - Docs - Diff
- Fix a bug when fullMessages was false and errors were prefixed by ^
0.1.0 - Nov 15, 2013 - Docs
- Initial release