Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Bumped version to v0.7.0, updated readme and dist files

  • Loading branch information...
commit 5a8805822ff7db91e1c5ea744d1b02bc65ff1763 1 parent 7c08a01
@thedersen authored
View
14 README.md
@@ -1,4 +1,4 @@
-# Backbone.Validation v0.6.4
+# Backbone.Validation v0.7.0
A validation plugin for [Backbone.js](http://documentcloud.github.com/backbone) that validates both your model as well as form input.
@@ -18,13 +18,13 @@ You can download the raw source from [GitHub](http://github.com/thedersen/backbo
#### Standard builds
-* Development: [backbone-validation.js](https://raw.github.com/thedersen/backbone.validation/master/dist/backbone-validation.js) *21.5kb*
-* Production: [backbone-validation-min.js](https://raw.github.com/thedersen/backbone.validation/master/dist/backbone-validation-min.js) *2.5kb gzipped*
+* Development: [backbone-validation.js](https://raw.github.com/thedersen/backbone.validation/master/dist/backbone-validation.js) *22.7kb*
+* Production: [backbone-validation-min.js](https://raw.github.com/thedersen/backbone.validation/master/dist/backbone-validation-min.js) *2.7kb gzipped*
#### AMD builds
-* Development: [backbone-validation-amd.js](https://raw.github.com/thedersen/backbone.validation/master/dist/backbone-validation-amd.js) *21.8kb*
-* Production: [backbone-validation-amd-min.js](https://raw.github.com/thedersen/backbone.validation/master/dist/backbone-validation-amd-min.js) *2.6kb gzipped*
+* Development: [backbone-validation-amd.js](https://raw.github.com/thedersen/backbone.validation/master/dist/backbone-validation-amd.js) *23.1kb*
+* Production: [backbone-validation-amd-min.js](https://raw.github.com/thedersen/backbone.validation/master/dist/backbone-validation-amd-min.js) *2.8kb gzipped*
#### Node.js builds
@@ -776,6 +776,10 @@ Basic behaviour:
## Release notes
+#### v0.7.0
+
+* Nested validation is back! See [Configure validation rules](#configure-validation-rules-on-the-model)
+
#### v0.6.4
* `format(...)` and `formatLabel(...)` are made available for custom validators on `this` (Thanks to [rafanoronha](https://github.com/rafanoronha))
View
4 dist/backbone-validation-amd-min.js
@@ -1,8 +1,8 @@
-// Backbone.Validation v0.6.4
+// Backbone.Validation v0.7.0
//
// Copyright (c) 2011-2012 Thomas Pedersen
// Distributed under MIT License
//
// Documentation and full license available at:
// http://thedersen.com/projects/backbone-validation
-(function(e){typeof exports=="object"?module.exports=e(require("backbone"),require("underscore")):typeof define=="function"&&define.amd&&define(["backbone","underscore"],e)})(function(e,t){return e.Validation=function(e){"use strict";var t={forceUpdate:!1,selector:"name",labelFormatter:"sentenceCase",valid:Function.prototype,invalid:Function.prototype},n={formatLabel:function(e,n){return u[t.labelFormatter](e,n)},format:function(){var e=Array.prototype.slice.call(arguments),t=e.shift();return t.replace(/\{(\d+)\}/g,function(t,n){return typeof e[n]!="undefined"?e[n]:t})}},r=function(){var r=function(t){return e.reduce(e.keys(t.validation||{}),function(e,t){return e[t]=void 0,e},{})},s=function(t,n){var r=t.validation?t.validation[n]||{}:{};if(e.isFunction(r)||e.isString(r))r={fn:r};return e.isArray(r)||(r=[r]),e.reduce(r,function(t,n){return e.each(e.without(e.keys(n),"msg"),function(e){t.push({fn:a[e],val:n[e],msg:n.msg})}),t},[])},o=function(t,r,i,o){return e.reduce(s(t,r),function(s,u){var f=e.extend({},n,a),l=u.fn.call(f,i,r,u.val,t,o);return l===!1||s===!1?!1:l&&!s?u.msg||l:s},"")},u=function(t,n){var r,i,s={},u=!0,a=e.clone(n);for(i in n)r=o(t,i,n[i],a),r&&(s[i]=r,u=!1);return{invalidAttrs:s,isValid:u}},f=function(t,n){return{preValidate:function(t,n){return o(this,t,n,e.extend({},this.attributes))},isValid:function(t){if(e.isString(t))return!o(this,t,this.get(t),e.extend({},this.attributes));if(e.isArray(t)){for(var n=0;n<t.length;n++)if(o(this,t[n],this.get(t[n]),e.extend({},this.attributes)))return!1;return!0}return t===!0&&this.validate(),this.validation?this._isValid:!0},validate:function(i,s){var o=this,a=!i,f=e.extend({},n,s),l=r(o),c=e.extend({},l,o.attributes,i),h=i||c,p=u(o,c);o._isValid=p.isValid,e.each(e.keys(l),function(e){var n=p.invalidAttrs.hasOwnProperty(e);n||f.valid(t,e,f.selector)}),e.each(e.keys(l),function(e){var n=p.invalidAttrs.hasOwnProperty(e),r=h.hasOwnProperty(e);n&&(r||a)&&f.invalid(t,e,p.invalidAttrs[e],f.selector)}),e.defer(function(){o.trigger("validated",o._isValid,o,p.invalidAttrs),o.trigger("validated:"+(o._isValid?"valid":"invalid"),o,p.invalidAttrs)});if(!f.forceUpdate&&e.intersection(e.keys(p.invalidAttrs),e.keys(h)).length>0)return p.invalidAttrs}}},l=function(t,n,r){e.extend(n,f(t,r))},c=function(e){delete e.validate,delete e.preValidate,delete e.isValid},h=function(e){l(this.view,e,this.options)},p=function(e){c(e)};return{version:"0.6.4",configure:function(n){e.extend(t,n)},bind:function(n,r){var s=n.model,o=n.collection;r=e.extend({},t,i,r);if(typeof s=="undefined"&&typeof o=="undefined")throw"Before you execute the binding your view must have a model or a collection.\nSee http://thedersen.com/projects/backbone-validation/#using-form-model-validation for more information.";s&&l(n,s,r),o&&(o.each(function(e){l(n,e,r)}),o.bind("add",h,{view:n,options:r}),o.bind("remove",p))},unbind:function(e){var t=e.model,n=e.collection;t&&c(e.model),n&&(n.each(function(e){c(e)}),n.unbind("add",h),n.unbind("remove",p))},mixin:f(null,t)}}(),i=r.callbacks={valid:function(e,t,n){e.$("["+n+"~="+t+"]").removeClass("invalid").removeAttr("data-error")},invalid:function(e,t,n,r){e.$("["+r+"~="+t+"]").addClass("invalid").attr("data-error",n)}},s=r.patterns={digits:/^\d+$/,number:/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/,email:/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,url:/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i},o=r.messages={required:"{0} is required",acceptance:"{0} must be accepted",min:"{0} must be greater than or equal to {1}",max:"{0} must be less than or equal to {1}",range:"{0} must be between {1} and {2}",length:"{0} must be {1} characters",minLength:"{0} must be at least {1} characters",maxLength:"{0} must be at most {1} characters",rangeLength:"{0} must be between {1} and {2} characters",oneOf:"{0} must be one of: {1}",equalTo:"{0} must be the same as {1}",pattern:"{0} must be a valid {1}"},u=r.labelFormatters={none:function(e){return e},sentenceCase:function(e){return e.replace(/(?:^\w|[A-Z]|\b\w)/g,function(e,t){return t===0?e.toUpperCase():" "+e.toLowerCase()}).replace("_"," ")},label:function(e,t){return t.labels&&t.labels[e]||u.sentenceCase(e,t)}},a=r.validators=function(){var t=String.prototype.trim?function(e){return e===null?"":String.prototype.trim.call(e)}:function(e){var t=/^\s+/,n=/\s+$/;return e===null?"":e.toString().replace(t,"").replace(n,"")},n=function(t){return e.isNumber(t)||e.isString(t)&&t.match(s.number)},r=function(n){return!(e.isNull(n)||e.isUndefined(n)||e.isString(n)&&t(n)==="")};return{fn:function(t,n,r,i,s){return e.isString(r)&&(r=i[r]),r.call(i,t,n,s)},required:function(t,n,i,s,u){var a=e.isFunction(i)?i.call(s,t,n,u):i;if(!a&&!r(t))return!1;if(a&&!r(t))return this.format(o.required,this.formatLabel(n,s))},acceptance:function(t,n,r,i){if(t!=="true"&&(!e.isBoolean(t)||t===!1))return this.format(o.acceptance,this.formatLabel(n,i))},min:function(e,t,r,i){if(!n(e)||e<r)return this.format(o.min,this.formatLabel(t,i),r)},max:function(e,t,r,i){if(!n(e)||e>r)return this.format(o.max,this.formatLabel(t,i),r)},range:function(e,t,r,i){if(!n(e)||e<r[0]||e>r[1])return this.format(o.range,this.formatLabel(t,i),r[0],r[1])},length:function(e,n,i,s){if(!r(e)||t(e).length!==i)return this.format(o.length,this.formatLabel(n,s),i)},minLength:function(e,n,i,s){if(!r(e)||t(e).length<i)return this.format(o.minLength,this.formatLabel(n,s),i)},maxLength:function(e,n,i,s){if(!r(e)||t(e).length>i)return this.format(o.maxLength,this.formatLabel(n,s),i)},rangeLength:function(e,n,i,s){if(!r(e)||t(e).length<i[0]||t(e).length>i[1])return this.format(o.rangeLength,this.formatLabel(n,s),i[0],i[1])},oneOf:function(t,n,r,i){if(!e.include(r,t))return this.format(o.oneOf,this.formatLabel(n,i),r.join(", "))},equalTo:function(e,t,n,r,i){if(e!==i[n])return this.format(o.equalTo,this.formatLabel(t,r),this.formatLabel(n,r))},pattern:function(e,t,n,i){if(!r(e)||!e.toString().match(s[n]||n))return this.format(o.pattern,this.formatLabel(t,i),n)}}}();return r}(t),e.Validation});
+(function(e){typeof exports=="object"?module.exports=e(require("backbone"),require("underscore")):typeof define=="function"&&define.amd&&define(["backbone","underscore"],e)})(function(e,t){return e.Validation=function(e){"use strict";var t={forceUpdate:!1,selector:"name",labelFormatter:"sentenceCase",valid:Function.prototype,invalid:Function.prototype},n={formatLabel:function(e,n){return a[t.labelFormatter](e,n)},format:function(){var e=Array.prototype.slice.call(arguments),t=e.shift();return t.replace(/\{(\d+)\}/g,function(t,n){return typeof e[n]!="undefined"?e[n]:t})}},r=function(t,n,i){return n=n||{},i=i||"",e.each(t,function(e,s){t.hasOwnProperty(s)&&(!e||typeof e!="object"||e instanceof Date||e instanceof RegExp?n[i+s]=e:r(e,n,i+s+"."))}),n},i=function(){var i=function(t){return e.reduce(e.keys(t.validation||{}),function(e,t){return e[t]=void 0,e},{})},o=function(t,n){var r=t.validation?t.validation[n]||{}:{};if(e.isFunction(r)||e.isString(r))r={fn:r};return e.isArray(r)||(r=[r]),e.reduce(r,function(t,n){return e.each(e.without(e.keys(n),"msg"),function(e){t.push({fn:f[e],val:n[e],msg:n.msg})}),t},[])},u=function(t,r,i,s){return e.reduce(o(t,r),function(o,u){var a=e.extend({},n,f),l=u.fn.call(a,i,r,u.val,t,s);return l===!1||o===!1?!1:l&&!o?u.msg||l:o},"")},a=function(t,n){var i,s={},o=!0,a=e.clone(n),f=r(n);return e.each(f,function(e,n){i=u(t,n,e,a),i&&(s[n]=i,o=!1)}),{invalidAttrs:s,isValid:o}},l=function(t,n){return{preValidate:function(t,n){return u(this,t,n,e.extend({},this.attributes))},isValid:function(t){var n=r(this.attributes);if(e.isString(t))return!u(this,t,n[t],e.extend({},this.attributes));if(e.isArray(t)){for(var i=0;i<t.length;i++)if(u(this,t[i],n[t[i]],e.extend({},this.attributes)))return!1;return!0}return t===!0&&this.validate(),this.validation?this._isValid:!0},validate:function(s,o){var u=this,f=!s,l=e.extend({},n,o),c=i(u),h=e.extend({},c,u.attributes,s),p=r(s||h),d=a(u,h);u._isValid=d.isValid,e.each(e.keys(c),function(e){var n=d.invalidAttrs.hasOwnProperty(e);n||l.valid(t,e,l.selector)}),e.each(e.keys(c),function(e){var n=d.invalidAttrs.hasOwnProperty(e),r=p.hasOwnProperty(e);n&&(r||f)&&l.invalid(t,e,d.invalidAttrs[e],l.selector)}),e.defer(function(){u.trigger("validated",u._isValid,u,d.invalidAttrs),u.trigger("validated:"+(u._isValid?"valid":"invalid"),u,d.invalidAttrs)});if(!l.forceUpdate&&e.intersection(e.keys(d.invalidAttrs),e.keys(p)).length>0)return d.invalidAttrs}}},c=function(t,n,r){e.extend(n,l(t,r))},h=function(e){delete e.validate,delete e.preValidate,delete e.isValid},p=function(e){c(this.view,e,this.options)},d=function(e){h(e)};return{version:"0.7.0",configure:function(n){e.extend(t,n)},bind:function(n,r){var i=n.model,o=n.collection;r=e.extend({},t,s,r);if(typeof i=="undefined"&&typeof o=="undefined")throw"Before you execute the binding your view must have a model or a collection.\nSee http://thedersen.com/projects/backbone-validation/#using-form-model-validation for more information.";i&&c(n,i,r),o&&(o.each(function(e){c(n,e,r)}),o.bind("add",p,{view:n,options:r}),o.bind("remove",d))},unbind:function(e){var t=e.model,n=e.collection;t&&h(e.model),n&&(n.each(function(e){h(e)}),n.unbind("add",p),n.unbind("remove",d))},mixin:l(null,t)}}(),s=i.callbacks={valid:function(e,t,n){e.$("["+n+"~="+t+"]").removeClass("invalid").removeAttr("data-error")},invalid:function(e,t,n,r){e.$("["+r+"~="+t+"]").addClass("invalid").attr("data-error",n)}},o=i.patterns={digits:/^\d+$/,number:/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/,email:/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,url:/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i},u=i.messages={required:"{0} is required",acceptance:"{0} must be accepted",min:"{0} must be greater than or equal to {1}",max:"{0} must be less than or equal to {1}",range:"{0} must be between {1} and {2}",length:"{0} must be {1} characters",minLength:"{0} must be at least {1} characters",maxLength:"{0} must be at most {1} characters",rangeLength:"{0} must be between {1} and {2} characters",oneOf:"{0} must be one of: {1}",equalTo:"{0} must be the same as {1}",pattern:"{0} must be a valid {1}"},a=i.labelFormatters={none:function(e){return e},sentenceCase:function(e){return e.replace(/(?:^\w|[A-Z]|\b\w)/g,function(e,t){return t===0?e.toUpperCase():" "+e.toLowerCase()}).replace("_"," ")},label:function(e,t){return t.labels&&t.labels[e]||a.sentenceCase(e,t)}},f=i.validators=function(){var t=String.prototype.trim?function(e){return e===null?"":String.prototype.trim.call(e)}:function(e){var t=/^\s+/,n=/\s+$/;return e===null?"":e.toString().replace(t,"").replace(n,"")},n=function(t){return e.isNumber(t)||e.isString(t)&&t.match(o.number)},r=function(n){return!(e.isNull(n)||e.isUndefined(n)||e.isString(n)&&t(n)==="")};return{fn:function(t,n,r,i,s){return e.isString(r)&&(r=i[r]),r.call(i,t,n,s)},required:function(t,n,i,s,o){var a=e.isFunction(i)?i.call(s,t,n,o):i;if(!a&&!r(t))return!1;if(a&&!r(t))return this.format(u.required,this.formatLabel(n,s))},acceptance:function(t,n,r,i){if(t!=="true"&&(!e.isBoolean(t)||t===!1))return this.format(u.acceptance,this.formatLabel(n,i))},min:function(e,t,r,i){if(!n(e)||e<r)return this.format(u.min,this.formatLabel(t,i),r)},max:function(e,t,r,i){if(!n(e)||e>r)return this.format(u.max,this.formatLabel(t,i),r)},range:function(e,t,r,i){if(!n(e)||e<r[0]||e>r[1])return this.format(u.range,this.formatLabel(t,i),r[0],r[1])},length:function(e,n,i,s){if(!r(e)||t(e).length!==i)return this.format(u.length,this.formatLabel(n,s),i)},minLength:function(e,n,i,s){if(!r(e)||t(e).length<i)return this.format(u.minLength,this.formatLabel(n,s),i)},maxLength:function(e,n,i,s){if(!r(e)||t(e).length>i)return this.format(u.maxLength,this.formatLabel(n,s),i)},rangeLength:function(e,n,i,s){if(!r(e)||t(e).length<i[0]||t(e).length>i[1])return this.format(u.rangeLength,this.formatLabel(n,s),i[0],i[1])},oneOf:function(t,n,r,i){if(!e.include(r,t))return this.format(u.oneOf,this.formatLabel(n,i),r.join(", "))},equalTo:function(e,t,n,r,i){if(e!==i[n])return this.format(u.equalTo,this.formatLabel(t,r),this.formatLabel(n,r))},pattern:function(e,t,n,i){if(!r(e)||!e.toString().match(o[n]||n))return this.format(u.pattern,this.formatLabel(t,i),n)}}}();return i}(t),e.Validation});
View
62 dist/backbone-validation-amd.js
@@ -1,4 +1,4 @@
-// Backbone.Validation v0.6.4
+// Backbone.Validation v0.7.0
//
// Copyright (c) 2011-2012 Thomas Pedersen
// Distributed under MIT License
@@ -29,9 +29,10 @@ Backbone.Validation = (function(_){
};
- // Helper functions used when formatting error messages
- // ----------------------------------------------------
+ // Helper functions
+ // ----------------
+ // Formatting functions used for formatting error messages
var formatFunctions = {
// Uses the configured label formatter to format the attribute name
// to make it more readable for the user
@@ -50,6 +51,40 @@ Backbone.Validation = (function(_){
}
};
+ // Flattens an object
+ // eg:
+ //
+ // var o = {
+ // address: {
+ // street: 'Street',
+ // zip: 1234
+ // }
+ // };
+ //
+ // becomes:
+ //
+ // var o = {
+ // 'address.street': 'Street',
+ // 'address.zip': 1234
+ // };
+ var flatten = function (obj, into, prefix) {
+ into = into || {};
+ prefix = prefix || '';
+
+ _.each(obj, function(val, key) {
+ if(obj.hasOwnProperty(key)) {
+ if (val && typeof val === 'object' && !(val instanceof Date || val instanceof RegExp)) {
+ flatten(val, into, prefix + key + '.');
+ }
+ else {
+ into[prefix + key] = val;
+ }
+ }
+ });
+
+ return into;
+ };
+
// Validation
// ----------
@@ -126,18 +161,19 @@ Backbone.Validation = (function(_){
// Returns and object containing names of invalid attributes
// as well as error messages.
var validateModel = function(model, attrs) {
- var error, attr,
+ var error,
invalidAttrs = {},
isValid = true,
- computed = _.clone(attrs);
+ computed = _.clone(attrs),
+ flattened = flatten(attrs);
- for (attr in attrs) {
- error = validateAttr(model, attr, attrs[attr], computed);
+ _.each(flattened, function(val, attr) {
+ error = validateAttr(model, attr, val, computed);
if (error) {
invalidAttrs[attr] = error;
isValid = false;
}
- }
+ });
return {
invalidAttrs: invalidAttrs,
@@ -159,12 +195,14 @@ Backbone.Validation = (function(_){
// entire model is valid. Passing true will force a validation
// of the model.
isValid: function(option) {
+ var flattened = flatten(this.attributes);
+
if(_.isString(option)){
- return !validateAttr(this, option, this.get(option), _.extend({}, this.attributes));
+ return !validateAttr(this, option, flattened[option], _.extend({}, this.attributes));
}
if(_.isArray(option)){
for (var i = 0; i < option.length; i++) {
- if(validateAttr(this, option[i], this.get(option[i]), _.extend({}, this.attributes))){
+ if(validateAttr(this, option[i], flattened[option[i]], _.extend({}, this.attributes))){
return false;
}
}
@@ -185,7 +223,7 @@ Backbone.Validation = (function(_){
opt = _.extend({}, options, setOptions),
validatedAttrs = getValidatedAttrs(model),
allAttrs = _.extend({}, validatedAttrs, model.attributes, attrs),
- changedAttrs = attrs || allAttrs,
+ changedAttrs = flatten(attrs || allAttrs),
result = validateModel(model, allAttrs);
model._isValid = result.isValid;
@@ -256,7 +294,7 @@ Backbone.Validation = (function(_){
return {
// Current version of the library
- version: '0.6.4',
+ version: '0.7.0',
// Called to configure the default options
configure: function(options) {
View
4 dist/backbone-validation-min.js
@@ -1,8 +1,8 @@
-// Backbone.Validation v0.6.4
+// Backbone.Validation v0.7.0
//
// Copyright (c) 2011-2012 Thomas Pedersen
// Distributed under MIT License
//
// Documentation and full license available at:
// http://thedersen.com/projects/backbone-validation
-Backbone.Validation=function(e){"use strict";var t={forceUpdate:!1,selector:"name",labelFormatter:"sentenceCase",valid:Function.prototype,invalid:Function.prototype},n={formatLabel:function(e,n){return u[t.labelFormatter](e,n)},format:function(){var e=Array.prototype.slice.call(arguments),t=e.shift();return t.replace(/\{(\d+)\}/g,function(t,n){return typeof e[n]!="undefined"?e[n]:t})}},r=function(){var r=function(t){return e.reduce(e.keys(t.validation||{}),function(e,t){return e[t]=void 0,e},{})},s=function(t,n){var r=t.validation?t.validation[n]||{}:{};if(e.isFunction(r)||e.isString(r))r={fn:r};return e.isArray(r)||(r=[r]),e.reduce(r,function(t,n){return e.each(e.without(e.keys(n),"msg"),function(e){t.push({fn:a[e],val:n[e],msg:n.msg})}),t},[])},o=function(t,r,i,o){return e.reduce(s(t,r),function(s,u){var f=e.extend({},n,a),l=u.fn.call(f,i,r,u.val,t,o);return l===!1||s===!1?!1:l&&!s?u.msg||l:s},"")},u=function(t,n){var r,i,s={},u=!0,a=e.clone(n);for(i in n)r=o(t,i,n[i],a),r&&(s[i]=r,u=!1);return{invalidAttrs:s,isValid:u}},f=function(t,n){return{preValidate:function(t,n){return o(this,t,n,e.extend({},this.attributes))},isValid:function(t){if(e.isString(t))return!o(this,t,this.get(t),e.extend({},this.attributes));if(e.isArray(t)){for(var n=0;n<t.length;n++)if(o(this,t[n],this.get(t[n]),e.extend({},this.attributes)))return!1;return!0}return t===!0&&this.validate(),this.validation?this._isValid:!0},validate:function(i,s){var o=this,a=!i,f=e.extend({},n,s),l=r(o),c=e.extend({},l,o.attributes,i),h=i||c,p=u(o,c);o._isValid=p.isValid,e.each(e.keys(l),function(e){var n=p.invalidAttrs.hasOwnProperty(e);n||f.valid(t,e,f.selector)}),e.each(e.keys(l),function(e){var n=p.invalidAttrs.hasOwnProperty(e),r=h.hasOwnProperty(e);n&&(r||a)&&f.invalid(t,e,p.invalidAttrs[e],f.selector)}),e.defer(function(){o.trigger("validated",o._isValid,o,p.invalidAttrs),o.trigger("validated:"+(o._isValid?"valid":"invalid"),o,p.invalidAttrs)});if(!f.forceUpdate&&e.intersection(e.keys(p.invalidAttrs),e.keys(h)).length>0)return p.invalidAttrs}}},l=function(t,n,r){e.extend(n,f(t,r))},c=function(e){delete e.validate,delete e.preValidate,delete e.isValid},h=function(e){l(this.view,e,this.options)},p=function(e){c(e)};return{version:"0.6.4",configure:function(n){e.extend(t,n)},bind:function(n,r){var s=n.model,o=n.collection;r=e.extend({},t,i,r);if(typeof s=="undefined"&&typeof o=="undefined")throw"Before you execute the binding your view must have a model or a collection.\nSee http://thedersen.com/projects/backbone-validation/#using-form-model-validation for more information.";s&&l(n,s,r),o&&(o.each(function(e){l(n,e,r)}),o.bind("add",h,{view:n,options:r}),o.bind("remove",p))},unbind:function(e){var t=e.model,n=e.collection;t&&c(e.model),n&&(n.each(function(e){c(e)}),n.unbind("add",h),n.unbind("remove",p))},mixin:f(null,t)}}(),i=r.callbacks={valid:function(e,t,n){e.$("["+n+"~="+t+"]").removeClass("invalid").removeAttr("data-error")},invalid:function(e,t,n,r){e.$("["+r+"~="+t+"]").addClass("invalid").attr("data-error",n)}},s=r.patterns={digits:/^\d+$/,number:/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/,email:/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,url:/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i},o=r.messages={required:"{0} is required",acceptance:"{0} must be accepted",min:"{0} must be greater than or equal to {1}",max:"{0} must be less than or equal to {1}",range:"{0} must be between {1} and {2}",length:"{0} must be {1} characters",minLength:"{0} must be at least {1} characters",maxLength:"{0} must be at most {1} characters",rangeLength:"{0} must be between {1} and {2} characters",oneOf:"{0} must be one of: {1}",equalTo:"{0} must be the same as {1}",pattern:"{0} must be a valid {1}"},u=r.labelFormatters={none:function(e){return e},sentenceCase:function(e){return e.replace(/(?:^\w|[A-Z]|\b\w)/g,function(e,t){return t===0?e.toUpperCase():" "+e.toLowerCase()}).replace("_"," ")},label:function(e,t){return t.labels&&t.labels[e]||u.sentenceCase(e,t)}},a=r.validators=function(){var t=String.prototype.trim?function(e){return e===null?"":String.prototype.trim.call(e)}:function(e){var t=/^\s+/,n=/\s+$/;return e===null?"":e.toString().replace(t,"").replace(n,"")},n=function(t){return e.isNumber(t)||e.isString(t)&&t.match(s.number)},r=function(n){return!(e.isNull(n)||e.isUndefined(n)||e.isString(n)&&t(n)==="")};return{fn:function(t,n,r,i,s){return e.isString(r)&&(r=i[r]),r.call(i,t,n,s)},required:function(t,n,i,s,u){var a=e.isFunction(i)?i.call(s,t,n,u):i;if(!a&&!r(t))return!1;if(a&&!r(t))return this.format(o.required,this.formatLabel(n,s))},acceptance:function(t,n,r,i){if(t!=="true"&&(!e.isBoolean(t)||t===!1))return this.format(o.acceptance,this.formatLabel(n,i))},min:function(e,t,r,i){if(!n(e)||e<r)return this.format(o.min,this.formatLabel(t,i),r)},max:function(e,t,r,i){if(!n(e)||e>r)return this.format(o.max,this.formatLabel(t,i),r)},range:function(e,t,r,i){if(!n(e)||e<r[0]||e>r[1])return this.format(o.range,this.formatLabel(t,i),r[0],r[1])},length:function(e,n,i,s){if(!r(e)||t(e).length!==i)return this.format(o.length,this.formatLabel(n,s),i)},minLength:function(e,n,i,s){if(!r(e)||t(e).length<i)return this.format(o.minLength,this.formatLabel(n,s),i)},maxLength:function(e,n,i,s){if(!r(e)||t(e).length>i)return this.format(o.maxLength,this.formatLabel(n,s),i)},rangeLength:function(e,n,i,s){if(!r(e)||t(e).length<i[0]||t(e).length>i[1])return this.format(o.rangeLength,this.formatLabel(n,s),i[0],i[1])},oneOf:function(t,n,r,i){if(!e.include(r,t))return this.format(o.oneOf,this.formatLabel(n,i),r.join(", "))},equalTo:function(e,t,n,r,i){if(e!==i[n])return this.format(o.equalTo,this.formatLabel(t,r),this.formatLabel(n,r))},pattern:function(e,t,n,i){if(!r(e)||!e.toString().match(s[n]||n))return this.format(o.pattern,this.formatLabel(t,i),n)}}}();return r}(_);
+Backbone.Validation=function(e){"use strict";var t={forceUpdate:!1,selector:"name",labelFormatter:"sentenceCase",valid:Function.prototype,invalid:Function.prototype},n={formatLabel:function(e,n){return a[t.labelFormatter](e,n)},format:function(){var e=Array.prototype.slice.call(arguments),t=e.shift();return t.replace(/\{(\d+)\}/g,function(t,n){return typeof e[n]!="undefined"?e[n]:t})}},r=function(t,n,i){return n=n||{},i=i||"",e.each(t,function(e,s){t.hasOwnProperty(s)&&(!e||typeof e!="object"||e instanceof Date||e instanceof RegExp?n[i+s]=e:r(e,n,i+s+"."))}),n},i=function(){var i=function(t){return e.reduce(e.keys(t.validation||{}),function(e,t){return e[t]=void 0,e},{})},o=function(t,n){var r=t.validation?t.validation[n]||{}:{};if(e.isFunction(r)||e.isString(r))r={fn:r};return e.isArray(r)||(r=[r]),e.reduce(r,function(t,n){return e.each(e.without(e.keys(n),"msg"),function(e){t.push({fn:f[e],val:n[e],msg:n.msg})}),t},[])},u=function(t,r,i,s){return e.reduce(o(t,r),function(o,u){var a=e.extend({},n,f),l=u.fn.call(a,i,r,u.val,t,s);return l===!1||o===!1?!1:l&&!o?u.msg||l:o},"")},a=function(t,n){var i,s={},o=!0,a=e.clone(n),f=r(n);return e.each(f,function(e,n){i=u(t,n,e,a),i&&(s[n]=i,o=!1)}),{invalidAttrs:s,isValid:o}},l=function(t,n){return{preValidate:function(t,n){return u(this,t,n,e.extend({},this.attributes))},isValid:function(t){var n=r(this.attributes);if(e.isString(t))return!u(this,t,n[t],e.extend({},this.attributes));if(e.isArray(t)){for(var i=0;i<t.length;i++)if(u(this,t[i],n[t[i]],e.extend({},this.attributes)))return!1;return!0}return t===!0&&this.validate(),this.validation?this._isValid:!0},validate:function(s,o){var u=this,f=!s,l=e.extend({},n,o),c=i(u),h=e.extend({},c,u.attributes,s),p=r(s||h),d=a(u,h);u._isValid=d.isValid,e.each(e.keys(c),function(e){var n=d.invalidAttrs.hasOwnProperty(e);n||l.valid(t,e,l.selector)}),e.each(e.keys(c),function(e){var n=d.invalidAttrs.hasOwnProperty(e),r=p.hasOwnProperty(e);n&&(r||f)&&l.invalid(t,e,d.invalidAttrs[e],l.selector)}),e.defer(function(){u.trigger("validated",u._isValid,u,d.invalidAttrs),u.trigger("validated:"+(u._isValid?"valid":"invalid"),u,d.invalidAttrs)});if(!l.forceUpdate&&e.intersection(e.keys(d.invalidAttrs),e.keys(p)).length>0)return d.invalidAttrs}}},c=function(t,n,r){e.extend(n,l(t,r))},h=function(e){delete e.validate,delete e.preValidate,delete e.isValid},p=function(e){c(this.view,e,this.options)},d=function(e){h(e)};return{version:"0.7.0",configure:function(n){e.extend(t,n)},bind:function(n,r){var i=n.model,o=n.collection;r=e.extend({},t,s,r);if(typeof i=="undefined"&&typeof o=="undefined")throw"Before you execute the binding your view must have a model or a collection.\nSee http://thedersen.com/projects/backbone-validation/#using-form-model-validation for more information.";i&&c(n,i,r),o&&(o.each(function(e){c(n,e,r)}),o.bind("add",p,{view:n,options:r}),o.bind("remove",d))},unbind:function(e){var t=e.model,n=e.collection;t&&h(e.model),n&&(n.each(function(e){h(e)}),n.unbind("add",p),n.unbind("remove",d))},mixin:l(null,t)}}(),s=i.callbacks={valid:function(e,t,n){e.$("["+n+"~="+t+"]").removeClass("invalid").removeAttr("data-error")},invalid:function(e,t,n,r){e.$("["+r+"~="+t+"]").addClass("invalid").attr("data-error",n)}},o=i.patterns={digits:/^\d+$/,number:/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/,email:/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,url:/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i},u=i.messages={required:"{0} is required",acceptance:"{0} must be accepted",min:"{0} must be greater than or equal to {1}",max:"{0} must be less than or equal to {1}",range:"{0} must be between {1} and {2}",length:"{0} must be {1} characters",minLength:"{0} must be at least {1} characters",maxLength:"{0} must be at most {1} characters",rangeLength:"{0} must be between {1} and {2} characters",oneOf:"{0} must be one of: {1}",equalTo:"{0} must be the same as {1}",pattern:"{0} must be a valid {1}"},a=i.labelFormatters={none:function(e){return e},sentenceCase:function(e){return e.replace(/(?:^\w|[A-Z]|\b\w)/g,function(e,t){return t===0?e.toUpperCase():" "+e.toLowerCase()}).replace("_"," ")},label:function(e,t){return t.labels&&t.labels[e]||a.sentenceCase(e,t)}},f=i.validators=function(){var t=String.prototype.trim?function(e){return e===null?"":String.prototype.trim.call(e)}:function(e){var t=/^\s+/,n=/\s+$/;return e===null?"":e.toString().replace(t,"").replace(n,"")},n=function(t){return e.isNumber(t)||e.isString(t)&&t.match(o.number)},r=function(n){return!(e.isNull(n)||e.isUndefined(n)||e.isString(n)&&t(n)==="")};return{fn:function(t,n,r,i,s){return e.isString(r)&&(r=i[r]),r.call(i,t,n,s)},required:function(t,n,i,s,o){var a=e.isFunction(i)?i.call(s,t,n,o):i;if(!a&&!r(t))return!1;if(a&&!r(t))return this.format(u.required,this.formatLabel(n,s))},acceptance:function(t,n,r,i){if(t!=="true"&&(!e.isBoolean(t)||t===!1))return this.format(u.acceptance,this.formatLabel(n,i))},min:function(e,t,r,i){if(!n(e)||e<r)return this.format(u.min,this.formatLabel(t,i),r)},max:function(e,t,r,i){if(!n(e)||e>r)return this.format(u.max,this.formatLabel(t,i),r)},range:function(e,t,r,i){if(!n(e)||e<r[0]||e>r[1])return this.format(u.range,this.formatLabel(t,i),r[0],r[1])},length:function(e,n,i,s){if(!r(e)||t(e).length!==i)return this.format(u.length,this.formatLabel(n,s),i)},minLength:function(e,n,i,s){if(!r(e)||t(e).length<i)return this.format(u.minLength,this.formatLabel(n,s),i)},maxLength:function(e,n,i,s){if(!r(e)||t(e).length>i)return this.format(u.maxLength,this.formatLabel(n,s),i)},rangeLength:function(e,n,i,s){if(!r(e)||t(e).length<i[0]||t(e).length>i[1])return this.format(u.rangeLength,this.formatLabel(n,s),i[0],i[1])},oneOf:function(t,n,r,i){if(!e.include(r,t))return this.format(u.oneOf,this.formatLabel(n,i),r.join(", "))},equalTo:function(e,t,n,r,i){if(e!==i[n])return this.format(u.equalTo,this.formatLabel(t,r),this.formatLabel(n,r))},pattern:function(e,t,n,i){if(!r(e)||!e.toString().match(o[n]||n))return this.format(u.pattern,this.formatLabel(t,i),n)}}}();return i}(_);
View
62 dist/backbone-validation.js
@@ -1,4 +1,4 @@
-// Backbone.Validation v0.6.4
+// Backbone.Validation v0.7.0
//
// Copyright (c) 2011-2012 Thomas Pedersen
// Distributed under MIT License
@@ -21,9 +21,10 @@ Backbone.Validation = (function(_){
};
- // Helper functions used when formatting error messages
- // ----------------------------------------------------
+ // Helper functions
+ // ----------------
+ // Formatting functions used for formatting error messages
var formatFunctions = {
// Uses the configured label formatter to format the attribute name
// to make it more readable for the user
@@ -42,6 +43,40 @@ Backbone.Validation = (function(_){
}
};
+ // Flattens an object
+ // eg:
+ //
+ // var o = {
+ // address: {
+ // street: 'Street',
+ // zip: 1234
+ // }
+ // };
+ //
+ // becomes:
+ //
+ // var o = {
+ // 'address.street': 'Street',
+ // 'address.zip': 1234
+ // };
+ var flatten = function (obj, into, prefix) {
+ into = into || {};
+ prefix = prefix || '';
+
+ _.each(obj, function(val, key) {
+ if(obj.hasOwnProperty(key)) {
+ if (val && typeof val === 'object' && !(val instanceof Date || val instanceof RegExp)) {
+ flatten(val, into, prefix + key + '.');
+ }
+ else {
+ into[prefix + key] = val;
+ }
+ }
+ });
+
+ return into;
+ };
+
// Validation
// ----------
@@ -118,18 +153,19 @@ Backbone.Validation = (function(_){
// Returns and object containing names of invalid attributes
// as well as error messages.
var validateModel = function(model, attrs) {
- var error, attr,
+ var error,
invalidAttrs = {},
isValid = true,
- computed = _.clone(attrs);
+ computed = _.clone(attrs),
+ flattened = flatten(attrs);
- for (attr in attrs) {
- error = validateAttr(model, attr, attrs[attr], computed);
+ _.each(flattened, function(val, attr) {
+ error = validateAttr(model, attr, val, computed);
if (error) {
invalidAttrs[attr] = error;
isValid = false;
}
- }
+ });
return {
invalidAttrs: invalidAttrs,
@@ -151,12 +187,14 @@ Backbone.Validation = (function(_){
// entire model is valid. Passing true will force a validation
// of the model.
isValid: function(option) {
+ var flattened = flatten(this.attributes);
+
if(_.isString(option)){
- return !validateAttr(this, option, this.get(option), _.extend({}, this.attributes));
+ return !validateAttr(this, option, flattened[option], _.extend({}, this.attributes));
}
if(_.isArray(option)){
for (var i = 0; i < option.length; i++) {
- if(validateAttr(this, option[i], this.get(option[i]), _.extend({}, this.attributes))){
+ if(validateAttr(this, option[i], flattened[option[i]], _.extend({}, this.attributes))){
return false;
}
}
@@ -177,7 +215,7 @@ Backbone.Validation = (function(_){
opt = _.extend({}, options, setOptions),
validatedAttrs = getValidatedAttrs(model),
allAttrs = _.extend({}, validatedAttrs, model.attributes, attrs),
- changedAttrs = attrs || allAttrs,
+ changedAttrs = flatten(attrs || allAttrs),
result = validateModel(model, allAttrs);
model._isValid = result.isValid;
@@ -248,7 +286,7 @@ Backbone.Validation = (function(_){
return {
// Current version of the library
- version: '0.6.4',
+ version: '0.7.0',
// Called to configure the default options
configure: function(options) {
View
2  package.json
@@ -1,7 +1,7 @@
{
"name": "backbone-validation",
"title": "Backbone.Validation",
- "version": "0.6.4",
+ "version": "0.7.0",
"author": {
"name": "Thomas Pedersen",
"url": "http://thedersen.com/"
View
2  src/backbone-validation.js
@@ -278,7 +278,7 @@ Backbone.Validation = (function(_){
return {
// Current version of the library
- version: '0.6.4',
+ version: '0.7.0',
// Called to configure the default options
configure: function(options) {

0 comments on commit 5a88058

Please sign in to comment.
Something went wrong with that request. Please try again.