├── .gitignore ├── History.md ├── Makefile ├── Readme.md ├── component.json ├── lib ├── adapter.js ├── field.js ├── index.js └── validators.js └── test ├── adapter.js ├── field.js ├── index.html ├── index.js ├── mocha.css ├── mocha.js └── validators.js /.gitignore: -------------------------------------------------------------------------------- 1 | components 2 | build -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | 2 | 0.9.2 - October 1, 2014 3 | ----------------------- 4 | * add support for `domain` validation 5 | 6 | 0.9.1 - March 17, 2013 7 | ---------------------- 8 | * add `equal` validator 9 | 10 | 0.9.0 - March 14, 2013 11 | ---------------------- 12 | * change `#validator` to be chainable 13 | * change `required` validator to handle non-strings 14 | * add `novalidate` attribute to forms upon bind 15 | * call validators with `Field` as context 16 | 17 | 0.8.2 - December 10, 2013 18 | ------------------------- 19 | * upgrade `segmentio/validator` to `0.0.9` 20 | 21 | 0.8.1 - December 9, 2013 22 | ------------------------ 23 | * fix submit validator to be async 24 | 25 | 0.8.0 - December 9, 2013 26 | ------------------------ 27 | * upgrade `component/classes` to `1.1.4` 28 | * upgrade `component/event` to `0.1.2` 29 | * upgrade `segmentio/validator` to `0.0.6` 30 | 31 | 0.7.0 - November 14, 2013 32 | ------------------------- 33 | * fix to not validate inputs on blur if they're empty 34 | 35 | 0.6.0 - November 12, 2013 36 | ------------------------- 37 | * update `segmentio/validator` to `0.0.5` 38 | * fix to make validate callbacks optional 39 | 40 | 0.5.4 - October 20, 2013 41 | ------------------------ 42 | * fix bug in optional fields 43 | 44 | 0.5.3 - October 18, 2013 45 | ------------------------ 46 | * use `stopImmediatePropagation`, sorry IE 47 | 48 | 0.5.2 - October 18, 2013 49 | ------------------------ 50 | * add `clear` adapter 51 | * add `el` adapter 52 | * cleanup existing adapters 53 | 54 | 0.5.1 - October 18, 2013 55 | ------------------------ 56 | * add `valid` class to default adapter 57 | 58 | 0.5.0 - October 17, 2013 59 | ------------------------ 60 | * don't submit until async validators come back 61 | 62 | 0.4.0 - October 17, 2013 63 | ------------------------ 64 | * change name to `validate-form` 65 | * add `segmentio/validator` dependency 66 | 67 | 0.3.1 - September 27, 2013 68 | -------------------------- 69 | * add support for RGB and HSL colors 70 | 71 | 0.3.0 - September 13, 2013 72 | -------------------------- 73 | * make fields optional by default 74 | 75 | 0.2.3 - August 15, 2013 76 | ----------------------- 77 | * add `number` validator 78 | 79 | 0.2.2 - August 13, 2013 80 | ----------------------- 81 | * change `invalid` and `valid` to accept view methods 82 | 83 | 0.2.1 - August 13, 2013 84 | ----------------------- 85 | * add `name` to adapter 86 | 87 | 0.2.0 - July 30, 2013 88 | --------------------- 89 | * change api to take `form` 90 | 91 | 0.1.0 - July 29, 2013 92 | --------------------- 93 | * rewrite 94 | 95 | 0.0.1 - February 23, 2013 96 | ------------------------- 97 | :sparkles: 98 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | build: components $(shell find lib) 3 | @component build --dev 4 | 5 | components: component.json 6 | @component install --dev 7 | 8 | clean: 9 | @rm -fr build components 10 | 11 | test: build 12 | @open test/index.html 13 | 14 | .PHONY: clean test 15 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # validate-form 3 | 4 | Easily validate a form element against a set of rules. The rules can be sync or async, and the form submission will wait. 5 | 6 | ## Installation 7 | 8 | $ component install segmentio/validate-form 9 | 10 | ## Example 11 | 12 | ```js 13 | var validate = require('validate-form'); 14 | var form = document.getElementById('#form'); 15 | 16 | validate(form) 17 | .on('blur') 18 | .field('email') 19 | .is('required', 'Please enter your email.') 20 | .is('email') 21 | .field('password') 22 | .is('required') 23 | .is('minimum', 8, 'Minimum 8 characters.') 24 | .is(function (value) { 25 | return value != 'password'); 26 | }, 'Come on now...'); 27 | ``` 28 | 29 | ## API 30 | 31 | ### validate(el) 32 | 33 | Create a new validator for a given form `el`. 34 | 35 | ### #field(name) 36 | 37 | Add a field to the validator by its `name` attribute. You can also just pass the input `el` directly. 38 | 39 | ### #is(fn, [message]) 40 | 41 | Add a validation `fn` with an optional error `message`. 42 | 43 | ### #is(string, [message]) 44 | 45 | Add a validation function by its shorthand `string` with an optional error `message`. 46 | 47 | ### #is(regexp, [message]) 48 | 49 | Add a validation `regexp` with an optional error `message`. 50 | 51 | ### #is(string, settings..., [message]) 52 | 53 | Add a validation function that takes optional `settings...` and returns a regular validation function. This would be for things like minimum length, which require a `length` number. 54 | 55 | ### #on(event) 56 | 57 | Trigger the validation on an `event` in addition to `submit`. For example `'blur'`. 58 | 59 | ### #validate(callback) 60 | 61 | Validate the form manually and `callback(err, valid, msg)`. 62 | 63 | ### #value(fn) 64 | 65 | Set the value adapter `fn`, for retrieving the value of the element being validated. By default it will use `component/value`. 66 | 67 | ### #invalid(fn) 68 | 69 | Set the invalid adapter `fn`, for marking the element as invalid. By default this will add an `invalid` class to the element and append a message `label` element. 70 | 71 | ### #valid(fn) 72 | 73 | Set the valid adapter `fn`, for marking the element as valid. By default, this will remove an `invalid` class and any message elements. 74 | 75 | ## Shorthands 76 | 77 | * `RegExp` - validates against a `RegExp`. 78 | * `'required'` - requires a non-empty value. 79 | * `'email'` - requires an email address. 80 | * `'url'` - requires a URL. 81 | * `'domain'` - requires a domain name. 82 | * `'color'` - requires a hex, RGB or HSL color string. 83 | * `'hex'` - requires a hex color string. 84 | * `'rgb'` - requires an RGB color string. 85 | * `'hsl'` - requires an HSL color string. 86 | * `'minimum', length` - requires a minimum `length` of characters. (also `min`) 87 | * `'maximum', length` - requires a maximum `length` of characters. (also `max`) 88 | * `'equal', other` - requires that this field has the same value as `other` field 89 | 90 | ## License 91 | 92 | MIT 93 | -------------------------------------------------------------------------------- /component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "validate-form", 3 | "repo": "segmentio/validate-form", 4 | "description": "Easily validate a form element against a set of rules.", 5 | "version": "0.9.2", 6 | "license": "MIT", 7 | "keywords": [ 8 | "validate", 9 | "validator", 10 | "form", 11 | "input", 12 | "required", 13 | "regexp", 14 | "email", 15 | "url" 16 | ], 17 | "dependencies": { 18 | "component/classes": "1.1.4", 19 | "component/clone": "*", 20 | "component/domify": "1.1.1", 21 | "component/each": "0.1.0", 22 | "component/event": "0.1.2", 23 | "component/trim": "0.0.1", 24 | "component/type": "1.0.0", 25 | "component/value": "1.1.0", 26 | "ianstormtaylor/bind": "0.0.2", 27 | "ianstormtaylor/next-sibling": "0.0.1", 28 | "segmentio/is-email": "0.1.1", 29 | "segmentio/is-hex-color": "0.0.1", 30 | "segmentio/is-hsl-color": "0.0.1", 31 | "segmentio/is-rgb-color": "0.0.1", 32 | "segmentio/is-url": "0.1.0", 33 | "segmentio/is-domain": "0.0.1", 34 | "segmentio/submit-form": "0.0.1", 35 | "segmentio/validator": "0.0.9", 36 | "yields/prevent": "0.0.2", 37 | "yields/stop": "0.0.2" 38 | }, 39 | "development": { 40 | "component/assert": "*", 41 | "timoxley/next-tick": "*" 42 | }, 43 | "scripts": [ 44 | "lib/adapter.js", 45 | "lib/field.js", 46 | "lib/index.js", 47 | "lib/validators.js" 48 | ], 49 | "main": "lib/index.js" 50 | } -------------------------------------------------------------------------------- /lib/adapter.js: -------------------------------------------------------------------------------- 1 | 2 | var classes = require('classes'); 3 | var domify = require('domify'); 4 | var next = require('next-sibling'); 5 | var type = require('type'); 6 | var value = require('value'); 7 | 8 | 9 | /** 10 | * Default element accessor. 11 | * 12 | * @param {Element|Object} view 13 | */ 14 | 15 | exports.el = function (view) { 16 | if (view.el) return view.el; // handle views 17 | return view; 18 | }; 19 | 20 | 21 | /** 22 | * Default value method. 23 | * 24 | * @param {Element|Object} view 25 | */ 26 | 27 | exports.value = function (view) { 28 | var el = this.el(view); 29 | if ('function' == typeof view.value) return view.value(); 30 | if ('element' != type(el)) return; 31 | return value(el); 32 | }; 33 | 34 | 35 | /** 36 | * Default valid method. 37 | * 38 | * @param {Element|Object} view 39 | */ 40 | 41 | exports.valid = function (view) { 42 | this.clear(view); 43 | var el = this.el(view); 44 | if ('function' == typeof view.valid) return view.valid(); 45 | if ('element' != type(el)) return; 46 | 47 | classes(el).add('valid'); 48 | }; 49 | 50 | 51 | /** 52 | * Default invalid method. 53 | * 54 | * @param {Element|Object} view 55 | * @param {String} msg 56 | */ 57 | 58 | exports.invalid = function (view, msg) { 59 | this.clear(view); 60 | var el = this.el(view); 61 | if ('function' == typeof view.invalid) return view.invalid(msg); 62 | if ('element' != type(el)) return; 63 | 64 | classes(el).add('invalid'); 65 | if (msg && el.parentNode) { 66 | var message = domify('