Validate.js
Fork me

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, a Coveralls project used to code coverage as well as the annotated source.

Validate.js is an open source component of Wrapp and is licensed under the MIT license.

Downloads

Development version (0.7.1)
29KB, uncompressed and plenty of comments
Production version (0.7.1)
3.8KB, minified and gzipped
(Source map)
Bleeding edge
Might not be 100% stable
Build Status Coverage Status

Installing

Browser/CDN
<script src="//cdnjs.cloudflare.com/ajax/libs/validate.js/0.7.1/validate.min.js"></script>
Require.js/AMD
require(["validate.js"], function(validate) {
  // ...
});
npm/node.js
$ npm install --save validate.js
var validate = require("validate.js");
Bower
$ bower install --save validate
Component
$ component install ansman/validate.js

Dependencies

There are no required external dependencies but the default parser and formatter for the datetime and date validator requires XDate or moment.js.
Validate.js will pick them up if they are in the global scope, otherwise you can set validate.moment and validate.XDate manually, for example like this if using a require based system:

var validate = require("validate.js");
validate.moment = require("moment");

If you want to use async validation you need to use a runtime that supports Promises.
You can tell validate.js to use any A+ compatible promise implemention like this:

// Simply set validate.Promise to be the promise constructor
// RSVP works
validate.Promise = RSVP.Promise;
// and Q.js too
validate.Promise = Q.Promise;

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.

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+, Chrome).

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

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 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 include %{value} in the error message it will be replaced with the actual value. The value is transformed using validate.stringifyValue (which per default just calls validate.prettify) but it can be overidden to customize the formatting.

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 format option which accepts the following values:

  • "grouped" (default) - Returns error messages grouped by attribute.
  • "flat" - Returns a flat list of error messages.
  • "detailed" - Returns a list of error objects containing more info on the error (see example). Each object will only contain a single message.
var constraints = {
  username: {
    presence: true,
    exclusion: {
      within: ["nicklas"],
      message: "'%{value}' is not allowed"
    }
  },
  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: "nick", password: "better"}, constraints);
// => undefined

validate({username: "nicklas", password: "better"}, constraints);
// => {"username": ["Username 'nicklas' is not allowed"]}

validate({password: "better"}, constraints, {fullMessages: false})
// => {"username": ["can't be blank"]}

validate({}, constraints, {format: "flat"})
// => ["Username can't be blank", "Password can't be blank"]

validate({username: "nicklas", password: "bad"}, constraints, {format: "detailed"})
// => [{
//   attribute: "password",
//   error: "Password must be at least 6 characters",
//   options: {
//     minimum: 6,
//     message: "must be at least 6 characters"
//   },
//   validator: "length",
//   value: "bad"
// }]

validate({}, {username: {presence: {message: "^You must pick a username"}}});
// => {"username": ["You must pick a username"]}

Async validation

validate.async 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.

If an Error is thrown from an async validator the argument passed to the rejection handler will be that error. This allows you to differentiate from 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, just override validate.Promise with the constructor of the new Promise implementation.

Validate.js will try to use the global Promise function if it exists otherwise it will throw an exception when using validate.async

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) {
      if (errors instanceof Error) {
        // This means an exception was thrown from a validator
        console.err(errors);
      } else {
        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 (RSVP in this case)
validate.Promise = RSVP.Promise;

Single value validation

validate.single validate.single(value, constraints, [options])

Sometimes you only want to validate a single value against some constraints and using the normal validate function is quite verbose so there is a shorthand for this.

It does little more than proxying the call do the main validation function but with the value wrapped in an object and the options fullMessages and format set to "flat". This is because there is no name which means it can't produce full messages.

You can use the provided format, capitalize and prettify utility functions to append your own name.

validate.single(null, {presence: true, email: true});
// => ["can't be blank"]

validate.single("foo", {presence: true, email: true});
// => ["is not a valid email"]

validate.single("foo@bar.com", {presence: true, email: true});
// => undefined

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 = {format: "flat"};
validate.async.options = {format: "flat"};
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({format: "grouped"}, {});
// => 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:

  1. value - The value exactly how it looks in the attribute object.
  2. options - The options for the validator. Guaranteed to not be null or undefined.
  3. key - The attribute name.
  4. 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

presence

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"]}
length

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"]
// }
numericality

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"
//   ]
// }
datetime

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).

Validate.js looks for moment and XDate in the global scope, if it isn't found you can set validate.moment and validate.XDate manually.

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({}, {departure: {datetime: true}});
// => undefined

validate({departure: "foobar"}, {departure: {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.

date

The date validator is just a shorthand for the datetime validator with the dateOnly option set to true.

format

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
inclusion

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
exclusion

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
email

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
equality

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

capitalize validate.capitalize(string)

Simply makes the first character in the string upper case.

validate.capitalize("foobar");
// => "Foobar"
collectFormValues 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" checked>
  <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: false}
</script>
contains validate.contains(collection, value)

Check if the given value exists in the given collection. Both arrays and objects are supported.

validate.contains({}, "foo");
// => false

validate.contains({foo: "bar"}, "foo");
// => true

validate.contains([1, 2, 3], 4);
// => false

validate.contains([1, 2, 3], 3);
// => true
extend validate.extend(object, otherObjects...)

A clone from underscore's extend. It will copy all attributes from the given objects to the first argument and return the first argument.

This can be used to do a shallow copy of objects by calling it with {} as the first argument.

var o1 = {foo: "bar"}
  , o2 = {baz: "quux"};

validate.extend(o1, o2) === o1;
// => true

o1;
// => {foo: "bar", baz: "quux"};

o2;
// => {bar: "quux"};

// Makes a copy of o1, doesn't modify o1
validate.extend({}, o1);
// => {foo: "bar", baz: "quux"};

// o1 is not touched
validate.extend({}, o1) === o1;
// => false
format validate.format(formatString, values)

This function allows you do perform basic string substitution.
It simply finds all %{...} and replaces them with the value in the values object.

The values are converted to strings using the string constructor.

If you want to have the %{...} literal simply prefix it with a single %.

validate.format("Hi, my name is %{name}", {name: "Nicklas"});
// => "Hi, my name is Nicklas"

validate.format("%%{this} will not be replaced", {this: "that"});
// => "%{this} will not be replaced"
getDeepObjectValue validate.getDeepObjectValue(object, keypath)

A function that returns attributes from object. If the key contains a period (.) it looks for the attribute in a nested object. Attributes containing a period can be accessed by escaping the period with a \.

validate.getDeepObjectValue({foo: "bar"}, "foo");
// => "bar"

validate.getDeepObjectValue({foo: {bar: {baz: "quux"}}}, "foo.bar.baz");
// => "quux"

validate.getDeepObjectValue({"foo.bar": "baz"}, "foo\\.bar");
// => "baz"
isArray validate.isArray(value)

Check if the given value is an array.

validate.isArray({});
// => false

validate.isArray([]);
// => true
isDate validate.isDate(value)

Check if the given value is a Date instance.

validate.isDate(new Date());
// => true

validate.isDate(null);
// => false

validate.isDate({});
// => false
isDefined validate.isDefined(value)

Check if the given value is not null or undefined.

validate.isDefined("foobar");
// => true

validate.isDefined(null);
// => false

validate.isDefined(undefined);
// => false
isDomElement validate.isDomElement(value)

Check if the given value is a DOM element. This function does slightly more than to just check if it's a DOM element. It also checks that the object supports querySelector and querySelectorAll which is used in the project.

validate.isDomElement({});
// => false

validate.isDomElement(document.createElement("div"));
// => true
isEmpty validate.isEmpty(value)

Check if the given value is non empty. The following value are considered empty:

  • null
  • undefined
  • Empty strings
  • Whitespace only strings
  • Empty arrays
  • Empty objects
validate.isEmpty({});
// => true

validate.isEmpty(null);
// => true

validate.isEmpty("");
// => true

validate.isEmpty("   ");
// => true

validate.isEmpty("foo");
// => false

validate.isEmpty({foo: "bar"});
// => false
isFunction validate.isFunction(value)

Check if the given value is a function. If this returns true the value will be callable.

validate.isFunction("foobar");
// => false

validate.isFunction(function() {});
// => true
isInteger validate.isInteger(value)

Check if the given value is an integer. If this returns true isNumber will also return true.

validate.isInteger("foobar");
// => false

validate.isInteger(3.14);
// => false

validate.isInteger(3);
// => true
isNumber validate.isNumber(value)

Check if the given value is a number. Unlike most isNumber checks this function does not consider NaN to be a number.

validate.isNumber("foobar");
// => false

validate.isNumber(3.14);
// => true
isObject validate.isObject(value)

Check if the given value is an object. This function considers arrays objects so be careful if this matters to you.

validate.isObject("foobar");
// => false

validate.isObject({});
// => true

validate.isObject([]);
// => true
isPromise validate.isPromise(value)

Check if the given value is a promise. This used the same semantics as the ECMAScript spec which means that any non empty object that has a .then function is a promise.

validate.isPromise({});
// => false

validate.isPromise(new Promise(function() {}));
// => true

validate.isPromise({then: function() {}});
// => true
isString validate.isString(value)

Check if the given value is a string.

validate.isString("");
// => true

validate.isString({});
// => false
prettify validate.prettify(string)

Provides a way to clean up strings so that they become human readable.

It is meant to prettify things like attribute names and other programming related entities. It will do the following things:

  • Split words divided by .
  • Remove backslashes
  • Replace _ and - with spaces
  • Split cameled cased words
  • Make the whole string lower case
  • Converts number to strings with no more than 2 decimals
  • Calls toString on objects
  • Joins arrays with , and calls prettify on all items

Important! It does not removing leading or trailing period since these are not considered separators.

validate.prettify("This.is_a-weirdString\\.");
// => "this is a weird string."
result validate.result(value, [arguments...])

Calls the value with the specified arguments and returns the result if it's a function otherwise it simply returns the value.

This is used in validate.js in places where for example options can be either an object or a function returning the options.

Important! Since the function is detached it is not called with a specific context, therefor this only works when the value is a pure function.

// Not a function, returns the first argument
validate.result("foobar", 1, 2);
// => "foobar"

// Returns the result of Math.max(1, 2)
validate.result(Math.max, 1, 2);
// => 2

// Doesn't work since String#toUpperCase is not a pure function
validate.result("foo".toUpperCase);
// => Uncaught TypeError: String.prototype.toUpperCase called on null or undefined

Changelog

0.7.1 - Apr 16, 2015 - Docs - Diff

  • Fixed an issue where dates would not be accepted by the presence validator due to an issue in validate.isEmpty. Thanks Yun Jia for reporting this.

0.7.0 - Mar 30, 2015 - Docs - Diff

  • Added validate.version as a way of gettings the version of the library.
  • Added a component.json file for installation via componentjs.
  • Breaking: Don't supply a name when calling define. Thanks Norman Xu for reporting this.
  • Breaking: If an async validator throws an error (or rejects the promise with an Error) the validation promise is rejected with the same error. Thanks Sebastian Seilund, Dmitry Kirilyuk and Dave Kushner for helping out with the details of this.
  • Breaking: The flatten option has been replaced with a new format option. Simply replace flatten: true with format: "flat" to migrate.
  • Implement a way to get detailed errors that contains the validator, message, value etc. Thanks mattruby for suggesting this.
  • %{value} in messages is now replaced with the actual value. Thanks nyrsimon for suggesting this.

0.6.1 - Mar 30, 2015 - Docs - Diff

  • Fixed validate.collectFormValues for IE9 and IE10.
    Thanks Kevin Burke for reporting and fixing this.

0.6.0 - Mar 15, 2015 - Docs - Diff

  • Async validation errors are no longer wrapped in the validate.ValidationErrors object.
  • Document the utility functions used by this library.
  • Add support for validating a single value. Thanks Aristides Lourenco for suggesting and implementing this.
  • All calls to Promise is now made with the new operator.
  • Breaking: require is no longer used for dependency management. Validate.js will still look for moment, XDate and Promise in the global scope but not using require any more. They can be added by settings validate.moment, validate.XDate and validate.Promise respectively. The idea behind this is to stop using the require function improperly.

0.5.0 - Mar 7, 2015 - Docs - Diff

  • Breaking: All validators besides presence now allow values that are rejected by the presence validator. Mostly this means that empty and whitespace only strings are now allowed by all validators except presence. 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 in validate.async. Thanks sebastianseilund for fixing this!
  • Fixed an issue where values without the length attribute passed the length 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.1 - Sep 22, 2014 - Docs - Diff

  • Fix an issue with the date validator that made it unusable. Thanks mrdanimal for reporting this.

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.2.0 - Jan 22, 2014 - Docs - Diff

  • Fix a bug where functions were considered blank. Thanks MarFarMa for discovering and fixing this.
  • Added support for AMD (require.js, commonjs etc). Thanks to zubulonj for this.
  • Breaking: Dropped support for IE8
  • Support for async validations

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