A minimal yet powerful form validation library written in modern JavaScript. Zero dependencies!
Usage no npm install needed!
<script type="module">
import validatory from 'https://cdn.skypack.dev/validatory';
</script>
README
Validatory
A minimal yet powerful form validation library written in modern JavaScript. Zero dependencies!
Installation
The recommended and the most suitable way to install it is using Yarn:
$ yarn add validatory
or alternatively with NPM:
$ npm install --save validatory
How does it work?
The library will validate your form-elements using by default a RegExp pattern based validation, setting the
corresponding data-validation-state attribute both to the form-element and the associated form after each
form-element's input and change events.
The form-elements will be the ones that are queried with the initialization's formElementSelector parameter, and the
data-validation-state will be added by default to the form-element's root node.
The form-element will have the following states:
data-validation-state="not-validated" - This is the initial validation state.
data-validation-state="not-filled" - If the element is marked as required but hasn't any value yet.
data-validation-state="valid" - The element's value is valid.
data-validation-state="not-valid" - If the element value hasn't passed the validation process. (Generic state)
data-validation-state="not-valid-custom-state" - If the element value hasn't passed the validation process and the custom-state has been defined.
The form will have the following states:
data-validation-state="not-validated" - This is the initial validation state.
data-validation-state="not-valid" - If any of it's form-elements state is not valid.
data-validation-state="valid" - If all of it's form-elements state is valid.
For example, after the validation has been triggered, a non-valid form element will have the following state:
If you want to validate a <form>, you must include the data-validate attribute. It's validation state will
depend on it's elements' validation states.
<form action="/" data-validate></form>
form-element
If you want to validate an <input>, <textarea>, <select>, ... , you must as well include the
data-validate attribute. It's validation will be triggered after each input and change events.
<input type="text" data-validate/>
form-element - required
By setting the required attribute, the form element's value will be required, and it's state won't be valid until
it's filled..
<input type="text" data-validate required/>
form-element - built-in validators
As the validation process is by default based on RegExp patterns, the library will provide you the most common
value-type-associated patterns. For the time being, it will automatically add the corresponding data-validate-pattern
attribute to the elements with the following data-validate-type attributes.
Built-in validators won't work if the form element has not included the data-validate attribute.
data-validate-phone
It will validate 9 digit phone numbers. It will add the corresponding data-validate-pattern attribute to the
elements with the data-validate-phone attribute on runtime.
Both 123-123-123 and 123123123 phones will be valid.
data-validate-email
It will validate the element's value as an email, adding the correponding data-validate-pattern attribute to the
elements with the data-validate-email attribute.
Apart from the built-in validators, you may want to validate a form element using a custom RegExp pattern. By adding a
data-validate-pattern="(-your RegExp pattern-)" attribute to an element with the data-validate attribute, the
library will automatically use the provided pattern for validating the associated value. For example:
Any value but aValue
This pattern will test as valid any value but the provided one.
If you want the associated data-validation-state attribute to be set o node different from the selector matching one,
you will want to use the data-validation-state-reference-selector attribute. The library will look up for the first
selector-matching parent. For example:
<label class="form-checkbox" tabindex="0">
<input type="checkbox" class="form-checkbox__check" id="terms" name="terms"
required data-validate data-validate-any data-validation-state-reference-selector=".form-checkbox">
<span class="form-checkbox__content">I have read an accept the terms and conditions</span>
</label>
Initialization - basic
In order to properly initialize the library, we will call the library's init method, passing at least the following
parameters.
In order to extend the library's validators, we will add a new Validator instance to the ValidatorRegistry,
passing the required constructor parameters.
Your custom validation implementation must return/resolve with an object shaped as follows:
import {validatorRegistry, Validator} from 'validatory';
const yourAsyncValidationPromise = new Promise(resolve => setTimeout(() => resolve(true), 3000));
const customValidator = new Validator({
supports: node => node.classList.contains('form-textarea'),
isEmpty: node => node.value === '',
isValid: node => new Promise(resolve => yourAsyncValidationPromise.then(result => {
const valid = result === 'valid'; // Your custom validation
return resolve(valid ? {valid} : {valid, errorCode: 'your-custom-error-code'});
})),
});
validatorRegistry.add(customValidator);
Extending the library's Validators - Async validation helper
The library provides a helper method asyncValidation that will wrap your async logic and reduce the boilerplate needed to write a custom async validator.
Extending the library's Validators - Full example with Styles & custom data-states
If your are writting a custom validator that needs to display a custom error message based on the validation logic,
you will need to implement the validator and add these styles to your app.
In this example, we are using the es6-promise-debounce for debouncing the validation process.