Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

parsleyjs

Package Overview
Dependencies
Maintainers
1
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

parsleyjs - npm Package Compare versions

Comparing version 2.0.0-rc2 to 2.0.0

dist/parsley.remote.js

12

bower.json
{
"name": "parsleyjs",
"version": "2.0.0-rc2",
"version": "2.0.0",
"ignore": [

@@ -19,6 +19,7 @@ "**/.*",

"jquery": "~1.10.0",
"validator.js": "~0.5.5",
"validator.js": "~0.5.8",
"requirejs": "~2.1.0",
"bootstrap": "~3.0.3",
"sinonjs": "~1.7.3"
"sinonjs": "~1.7.3",
"uwidget": "~0.0.1"
},

@@ -35,3 +36,6 @@ "keywords": [

},
"license": "MIT"
"license": "MIT",
"main": [
"./dist/parsley.js"
]
}

@@ -1,8 +0,74 @@

#Changelog
# Parsley 2.x changelog
**master**
## 2.0.0
- fixed remote re-entering already validated value (#576)
- added `stopImmediatePropagation()` un `onSubmit()` method to avoid conflicts
with other libraries (#561)
- fixed parsleyFieldMultiple behavior that tried to bind non radio or checkbox
fields as a multiple field (#589)
- `input[type=hidden]` are now excluded by default (#589)
- fixed constraints unicity on fields belonging to same multiple group
- added `data-parsley-remote-validator` feature (#587)
- now support custom messages placeholders (#602)
- fix exception when ParsleyField or ParsleyFieldMultiple value is null or
undefined (#598)
- fixed `destroy()` method + added test (#555)
- added requirejs AMD support for `dist/parsley.js` and `dist/parsley.min.js`
versions (#606)
- fixed custom namespace -multiple that didn't re-evaluated correctly (#595)
- added `ParsleyUI.getErrorsMessages()` (Closes #607)
## 2.0.0-rc5
- totally reworked multiple fields (#542):
- created a new Class: `ParsleyFieldMultiple`
- multiple fields returns now same `ParsleyFieldMultiple` instance
- `dist/parsley+remote.js` and `dist/parsley+remote.min.js` have been renamed
to `dist/parsley.remote.js` and `dist/parsley.remote.min.js`
- changed the way `asyncValidate` handle events
- fix warning if parsley called on a page without elements to validate (#562)
- fixed `ParsleyUtils.attr()` attribute checking (#564)
- updated `ParsleyUtils.get()` method. Do not support anymore placeholder
feature since `ParsleyUtils.get() || placeholder` writing is more readable
- select and select multiple elements both handle the `parsley-success` and
`parsley-error` classes directly and not their parent.
- added pattern flags support (#566, #550)
- fixed ParsleyFieldMultiple optional fields if not explicitely required
- fixed ParsleyFieldMultiple trigger
- fixed select UI auto-bind change on error (#537)
- fixed `asyncIsValid()` and `asyncValidate()` API to support `force` option
## 2.0.0-rc4
- fixed js error if wrong data-parsley-errors-container is given
- fixed js error if `name=""` or `id=""` for parlsey multiple fields (#533)
- fixed dynamically added fields form inheritance (#532)
- fixed parsley-remote.js remote validator registration that overrided
other extra validators.
- added multiple xhr queries aborting in parsley.remote to avoid unneeded
server overload with keyup trigger
- fixed excluded fields option and added some doc for it (#546)
- fixed `range` validator with `0` value (#543)
- added `data-parsley-trim-value` option
- updated validator.js
- added `this.submitEvent.preventDefault()` support for parsley.remote
call twice form / field tests with parsley.remote for better support (#552)
- fixed global leaks shown by test suite
- new $ Parsley API behavior:
- returns `undefined` if called on non existing DOM element
+ console warn (#548)
- returns an array of instances if called on selector with multiple
elements (#547)
- fixed `min`, `max`, `range` validators (#556)
## 2.0.0-rc3
- fixed $ conflict (#525)
- added `force` validation for `isValid()` and `validate()`
- added doc events example
- added doc Help section
- added `data-parsley-errors-messages-disabled` option
**2.0.0-rc2**
## 2.0.0-rc2

@@ -13,1 +79,5 @@ - added `data-parsley-validate-if-empty` field option (#489)

or an `id` to be binded (instead of just a name)
## 2.0.0-rc1
- initial 2.x public release
/*!
* Parsleyjs
* Guillaume Potier - <guillaume@wisembly.com>
* Version 2.0.0-rc2 - built Sun Mar 02 2014 16:29:28
* Version 2.0.0 - built Sat Apr 19 2014 17:29:18
* MIT Licensed
*
*/
!function(a){var b={attr:function(a,b,c){var d,e={},f=new RegExp("^"+b,"i");if("undefined"==typeof a||"undefined"==typeof a[0])return{};for(var g in a[0].attributes)if(d=a[0].attributes[g],"undefined"!=typeof d&&null!==d&&d.specified&&f.test(d.name)){if("undefined"!=typeof c&&new RegExp(c,"i").test(d.name))return!0;e[this.camelize(d.name.replace(b,""))]=this.deserializeValue(d.value)}return"undefined"==typeof c?e:!1},setAttr:function(a,b,c,d){a[0].setAttribute(this.dasherize(b+c),String(d))},get:function(a,b,c){for(var d=0,e=(b||"").split(".");this.isObject(a)||this.isArray(a);)if(a=a[e[d++]],d===e.length)return a||c;return c},hash:function(a){return String(Math.random()).substring(2,a?a+2:9)},isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)},isObject:function(a){return a===Object(a)},deserializeValue:function(b){var c;try{return b?"true"==b||("false"==b?!1:"null"==b?null:isNaN(c=Number(b))?/^[\[\{]/.test(b)?a.parseJSON(b):b:c):b}catch(d){return b}},camelize:function(a){return a.replace(/-+(.)?/g,function(a,b){return b?b.toUpperCase():""})},dasherize:function(a){return a.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}},c={namespace:"data-parsley-",inputs:"input, textarea, select",excluded:"input[type=button], input[type=submit], input[type=reset]",priorityEnabled:!0,uiEnabled:!0,validationThreshold:3,focus:"first",trigger:!1,errorClass:"parsley-error",successClass:"parsley-success",classHandler:function(){},errorsContainer:function(){},errorsWrapper:'<ul class="parsley-errors-list"></ul>',errorTemplate:"<li></li>"},d=function(){};d.prototype={actualizeOptions:function(){return this.options=this.parsleyInstance.OptionsFactory.get(this),this},validateThroughValidator:function(){return window.ParsleyValidator.validate.apply(window.ParsleyValidator,arguments)},subscribe:function(b,c){return a.listenTo(this,b.toLowerCase(),c),this},unsubscribe:function(b){return a.unsubscribeTo(this,b.toLowerCase()),this},reset:function(){if("ParsleyField"===this.__class__)return a.emit("parsley:field:reset",this);for(var b=0;b<this.fields.length;b++)a.emit("parsley:field:reset",this.fields[b]);a.emit("parsley:form:reset",this)},destroy:function(){if("ParsleyField"===this.__class__)return a.emit("parsley:field:destroy",this),void this.$element.removeData("Parsley");for(var b=0;b<this.fields.length;b++)this.fields[b].destroy();a.emit("parsley:form:destroy",this),this.$element.removeData("Parsley")}},function(a){var b=function(a){return this.__class__="Validator",this.__version__="0.5.5",this.options=a||{},this.bindingKey=this.options.bindingKey||"_validatorjsConstraint",this};b.prototype={constructor:b,validate:function(a,b,c){if("string"!=typeof a&&"object"!=typeof a)throw new Error("You must validate an object or a string");return"string"==typeof a||g(a)?this._validateString(a,b,c):this.isBinded(a)?this._validateBindedObject(a,b):this._validateObject(a,b,c)},bind:function(a,b){if("object"!=typeof a)throw new Error("Must bind a Constraint to an object");return a[this.bindingKey]=new c(b),this},unbind:function(a){return"undefined"==typeof a._validatorjsConstraint?this:(delete a[this.bindingKey],this)},isBinded:function(a){return"undefined"!=typeof a[this.bindingKey]},getBinded:function(a){return this.isBinded(a)?a[this.bindingKey]:null},_validateString:function(a,b,c){var f,h=[];g(b)||(b=[b]);for(var i=0;i<b.length;i++){if(!(b[i]instanceof e))throw new Error("You must give an Assert or an Asserts array to validate a string");f=b[i].check(a,c),f instanceof d&&h.push(f)}return h.length?h:!0},_validateObject:function(a,b,d){if("object"!=typeof b)throw new Error("You must give a constraint to validate an object");return b instanceof c?b.check(a,d):new c(b).check(a,d)},_validateBindedObject:function(a,b){return a[this.bindingKey].check(a,b)}},b.errorCode={must_be_a_string:"must_be_a_string",must_be_an_array:"must_be_an_array",must_be_a_number:"must_be_a_number",must_be_a_string_or_array:"must_be_a_string_or_array"};var c=function(a,b){if(this.__class__="Constraint",this.options=b||{},this.nodes={},a)try{this._bootstrap(a)}catch(c){throw new Error("Should give a valid mapping object to Constraint",c,a)}return this};c.prototype={constructor:c,check:function(a,b){var c,d={};for(var h in this.options.strict?this.nodes:a)if(this.options.strict?this.has(h,a):this.has(h))c=this._check(h,a[h],b),(g(c)&&c.length>0||!g(c)&&!f(c))&&(d[h]=c);else if(this.options.strict)try{(new e).HaveProperty(h).validate(a)}catch(i){d[h]=i}return f(d)?!0:d},add:function(a,b){if(b instanceof e||g(b)&&b[0]instanceof e)return this.nodes[a]=b,this;if("object"==typeof b&&!g(b))return this.nodes[a]=b instanceof c?b:new c(b),this;throw new Error("Should give an Assert, an Asserts array, a Constraint",b)},has:function(a,b){var b="undefined"!=typeof b?b:this.nodes;return"undefined"!=typeof b[a]},get:function(a,b){return this.has(a)?this.nodes[a]:b||null},remove:function(a){var b=[];for(var c in this.nodes)c!==a&&(b[c]=this.nodes[c]);return this.nodes=b,this},_bootstrap:function(a){if(a instanceof c)return this.nodes=a.nodes;for(var b in a)this.add(b,a[b])},_check:function(a,b,d){if(this.nodes[a]instanceof e)return this._checkAsserts(b,[this.nodes[a]],d);if(g(this.nodes[a]))return this._checkAsserts(b,this.nodes[a],d);if(this.nodes[a]instanceof c)return this.nodes[a].check(b,d);throw new Error("Invalid node",this.nodes[a])},_checkAsserts:function(a,b,c){for(var d,e=[],f=0;f<b.length;f++)d=b[f].check(a,c),"undefined"!=typeof d&&!0!==d&&e.push(d);return e}};var d=function(a,b,c){if(this.__class__="Violation",!(a instanceof e))throw new Error("Should give an assertion implementing the Assert interface");this.assert=a,this.value=b,"undefined"!=typeof c&&(this.violation=c)};d.prototype={show:function(){var a={assert:this.assert.__class__,value:this.value};return this.violation&&(a.violation=this.violation),a},__toString:function(){if("undefined"!=typeof this.violation)var a='", '+this.getViolation().constraint+" expected was "+this.getViolation().expected;return this.assert.__class__+' assert failed for "'+this.value+a||""},getViolation:function(){var a,b;for(a in this.violation)b=this.violation[a];return{constraint:a,expected:b}}};var e=function(a){return this.__class__="Assert",this.__parentClass__=this.__class__,this.groups=[],"undefined"!=typeof a&&this.addGroup(a),this};e.prototype={construct:e,check:function(a,b){if(!(b&&!this.hasGroup(b)||!b&&this.hasGroups()))try{return this.validate(a,b)}catch(c){return c}},hasGroup:function(a){return g(a)?this.hasOneOf(a):"Any"===a?!0:this.hasGroups()?-1!==this.groups.indexOf(a):"Default"===a},hasOneOf:function(a){for(var b=0;b<a.length;b++)if(this.hasGroup(a[b]))return!0;return!1},hasGroups:function(){return this.groups.length>0},addGroup:function(a){return g(a)?this.addGroups(a):(this.hasGroup(a)||this.groups.push(a),this)},removeGroup:function(a){for(var b=[],c=0;c<this.groups.length;c++)a!==this.groups[c]&&b.push(this.groups[c]);return this.groups=b,this},addGroups:function(a){for(var b=0;b<a.length;b++)this.addGroup(a[b]);return this},HaveProperty:function(a){return this.__class__="HaveProperty",this.node=a,this.validate=function(a){if("undefined"==typeof a[this.node])throw new d(this,a,{value:this.node});return!0},this},Blank:function(){return this.__class__="Blank",this.validate=function(a){if("string"!=typeof a)throw new d(this,a,{value:b.errorCode.must_be_a_string});if(""!==a.replace(/^\s+/g,"").replace(/\s+$/g,""))throw new d(this,a);return!0},this},Callback:function(a){if(this.__class__="Callback",this.arguments=Array.prototype.slice.call(arguments),1===this.arguments.length?this.arguments=[]:this.arguments.splice(0,1),"function"!=typeof a)throw new Error("Callback must be instanciated with a function");return this.fn=a,this.validate=function(a){var b=[a].concat(this.arguments),c=this.fn.apply(this,b);if(!0!==c)throw new d(this,a,{result:c});return!0},this},Choice:function(a){if(this.__class__="Choice",!g(a)&&"function"!=typeof a)throw new Error("Choice must be instanciated with an array or a function");return this.list=a,this.validate=function(a){for(var b="function"==typeof this.list?this.list():this.list,c=0;c<b.length;c++)if(a===b[c])return!0;throw new d(this,a,{choices:b})},this},Collection:function(a){return this.__class__="Collection",this.constraint="undefined"!=typeof a?new c(a):!1,this.validate=function(a,c){var e,h=new b,i=0,j={},k=this.groups.length?this.groups:c;if(!g(a))throw new d(this,array,{value:b.errorCode.must_be_an_array});for(var l=0;l<a.length;l++)e=this.constraint?h.validate(a[l],this.constraint,k):h.validate(a[l],k),f(e)||(j[i]=e),i++;return f(j)?!0:j},this},Count:function(a){return this.__class__="Count",this.count=a,this.validate=function(a){if(!g(a))throw new d(this,a,{value:b.errorCode.must_be_an_array});var c="function"==typeof this.count?this.count(a):this.count;if(isNaN(Number(c)))throw new Error("Count must be a valid interger",c);if(c!==a.length)throw new d(this,a,{count:c});return!0},this},Email:function(){return this.__class__="Email",this.validate=function(a){var c=/^((([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;if("string"!=typeof a)throw new d(this,a,{value:b.errorCode.must_be_a_string});if(!c.test(a))throw new d(this,a);return!0},this},Eql:function(a){if(this.__class__="Eql","undefined"==typeof a)throw new Error("Equal must be instanciated with an Array or an Object");return this.eql=a,this.validate=function(a){var b="function"==typeof this.eql?this.eql(a):this.eql;if(!h.eql(b,a))throw new d(this,a,{eql:b});return!0},this},EqualTo:function(a){if(this.__class__="EqualTo","undefined"==typeof a)throw new Error("EqualTo must be instanciated with a value or a function");return this.reference=a,this.validate=function(a){var b="function"==typeof this.reference?this.reference(a):this.reference;if(b!==a)throw new d(this,a,{value:b});return!0},this},GreaterThan:function(a){if(this.__class__="GreaterThan","undefined"==typeof a)throw new Error("Should give a threshold value");return this.threshold=a,this.validate=function(a){if(""===a||isNaN(Number(a)))throw new d(this,a,{value:b.errorCode.must_be_a_number});if(this.threshold>=a)throw new d(this,a,{threshold:this.threshold});return!0},this},GreaterThanOrEqual:function(a){if(this.__class__="GreaterThanOrEqual","undefined"==typeof a)throw new Error("Should give a threshold value");return this.threshold=a,this.validate=function(a){if(""===a||isNaN(Number(a)))throw new d(this,a,{value:b.errorCode.must_be_a_number});if(this.threshold>a)throw new d(this,a,{threshold:this.threshold});return!0},this},InstanceOf:function(a){if(this.__class__="InstanceOf","undefined"==typeof a)throw new Error("InstanceOf must be instanciated with a value");return this.classRef=a,this.validate=function(a){if(!0!=a instanceof this.classRef)throw new d(this,a,{classRef:this.classRef});return!0},this},IPv4:function(){return this.__class__="IPv4",this.validate=function(a){var c=/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;if("string"!=typeof a)throw new d(this,a,{value:b.errorCode.must_be_a_string});if(!c.test(a))throw new d(this,a);return!0},this},Length:function(a){if(this.__class__="Length",!a.min&&!a.max)throw new Error("Lenth assert must be instanciated with a { min: x, max: y } object");return this.min=a.min,this.max=a.max,this.validate=function(a){if("string"!=typeof a&&!g(a))throw new d(this,a,{value:b.errorCode.must_be_a_string_or_array});if("undefined"!=typeof this.min&&this.min===this.max&&a.length!==this.min)throw new d(this,a,{min:this.min,max:this.max});if("undefined"!=typeof this.max&&a.length>this.max)throw new d(this,a,{max:this.max});if("undefined"!=typeof this.min&&a.length<this.min)throw new d(this,a,{min:this.min});return!0},this},LessThan:function(a){if(this.__class__="LessThan","undefined"==typeof a)throw new Error("Should give a threshold value");return this.threshold=a,this.validate=function(a){if(""===a||isNaN(Number(a)))throw new d(this,a,{value:b.errorCode.must_be_a_number});if(this.threshold<=a)throw new d(this,a,{threshold:this.threshold});return!0},this},LessThanOrEqual:function(a){if(this.__class__="LessThanOrEqual","undefined"==typeof a)throw new Error("Should give a threshold value");return this.threshold=a,this.validate=function(a){if(""===a||isNaN(Number(a)))throw new d(this,a,{value:b.errorCode.must_be_a_number});if(this.threshold<a)throw new d(this,a,{threshold:this.threshold});return!0},this},Mac:function(){return this.__class__="Mac",this.validate=function(a){var c=/^(?:[0-9A-F]{2}:){5}[0-9A-F]{2}$/i;if("string"!=typeof a)throw new d(this,a,{value:b.errorCode.must_be_a_string});if(!c.test(a))throw new d(this,a);return!0},this},NotNull:function(){return this.__class__="NotNull",this.validate=function(a){if(null===a||"undefined"==typeof a)throw new d(this,a);return!0},this},NotBlank:function(){return this.__class__="NotBlank",this.validate=function(a){if("string"!=typeof a)throw new d(this,a,{value:b.errorCode.must_be_a_string});if(""===a.replace(/^\s+/g,"").replace(/\s+$/g,""))throw new d(this,a);return!0},this},Null:function(){return this.__class__="Null",this.validate=function(a){if(null!==a)throw new d(this,a);return!0},this},Range:function(a,b){if(this.__class__="Range",!a||!b)throw new Error("Range assert expects min and max values");return this.min=a,this.max=b,this.validate=function(a){try{return"string"==typeof a&&isNaN(Number(a))||g(a)?(new e).Length({min:this.min,max:this.max}).validate(a):(new e).GreaterThanOrEqual(this.min).validate(a)&&(new e).LessThanOrEqual(this.max).validate(a),!0}catch(b){throw new d(this,a,b.violation)}return!0},this},Regexp:function(a,c){if(this.__class__="Regexp","undefined"==typeof a)throw new Error("You must give a regexp");return this.regexp=a,this.flag=c||"",this.validate=function(a){if("string"!=typeof a)throw new d(this,a,{value:b.errorCode.must_be_a_string});if(!new RegExp(this.regexp).test(a,this.flag))throw new d(this,a,{regexp:this.regexp,flag:this.flag});return!0},this},Required:function(){return this.__class__="Required",this.validate=function(a){if("undefined"==typeof a)throw new d(this,a);if("string"==typeof a)try{(new e).NotNull().validate(a)&&(new e).NotBlank().validate(a)}catch(b){throw new d(this,a)}return!0},this},Unique:function(a){return this.__class__="Unique","object"==typeof a&&(this.key=a.key),this.validate=function(a){var c,e=[];if(!g(a))throw new d(this,a,{value:b.errorCode.must_be_an_array});for(var f=0;f<a.length;f++)if(c="object"==typeof a[f]?a[f][this.key]:a[f],"undefined"!=typeof c){if(-1!==e.indexOf(c))throw new d(this,a,{value:c});e.push(c)}return!0},this}},a.Assert=e,a.Validator=b,a.Violation=d,a.Constraint=c,Array.prototype.indexOf||(Array.prototype.indexOf=function(a){if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if(0===c)return-1;var d=0;if(arguments.length>1&&(d=Number(arguments[1]),d!=d?d=0:0!=d&&1/0!=d&&d!=-1/0&&(d=(d>0||-1)*Math.floor(Math.abs(d)))),d>=c)return-1;for(var e=d>=0?d:Math.max(c-Math.abs(d),0);c>e;e++)if(e in b&&b[e]===a)return e;return-1});var f=function(a){for(var b in a)return!1;return!0},g=function(a){return"[object Array]"===Object.prototype.toString.call(a)},h={eql:function(a,b){if(a===b)return!0;if("undefined"!=typeof Buffer&&Buffer.isBuffer(a)&&Buffer.isBuffer(b)){if(a.length!==b.length)return!1;for(var c=0;c<a.length;c++)if(a[c]!==b[c])return!1;return!0}return a instanceof Date&&b instanceof Date?a.getTime()===b.getTime():"object"!=typeof a&&"object"!=typeof b?a==b:this.objEquiv(a,b)},isUndefinedOrNull:function(a){return null===a||"undefined"==typeof a},isArguments:function(a){return"[object Arguments]"==Object.prototype.toString.call(a)},keys:function(a){if(Object.keys)return Object.keys(a);var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b},objEquiv:function(a,b){if(this.isUndefinedOrNull(a)||this.isUndefinedOrNull(b))return!1;if(a.prototype!==b.prototype)return!1;if(this.isArguments(a))return this.isArguments(b)?eql(pSlice.call(a),pSlice.call(b)):!1;try{var c,d,e=this.keys(a),f=this.keys(b)}catch(g){return!1}if(e.length!==f.length)return!1;for(e.sort(),f.sort(),d=e.length-1;d>=0;d--)if(e[d]!=f[d])return!1;for(d=e.length-1;d>=0;d--)if(c=e[d],!this.eql(a[c],b[c]))return!1;return!0}};"function"==typeof define&&define.amd&&define("validator",[],function(){return a})}("undefined"==typeof exports?this["undefined"!=typeof validatorjs_ns?validatorjs_ns:"Validator"]={}:exports);var e=function(a,b){this.__class__="ParsleyValidator",this.Validator=Validator,this.locale="en",this.init(a||{},b||{})};e.prototype={init:function(b,c){this.catalog=c;for(var d in b)this.addValidator(d,b[d].fn,b[d].priority);a.emit("parsley:validator:init")},setLocale:function(a){if("undefined"==typeof this.catalog[a])throw new Error(a+" is not available in the catalog");return this.locale=a,this},addCatalog:function(a,b,c){return"object"==typeof b&&(this.catalog[a]=b),!0===c?this.setLocale(a):this},addMessage:function(a,b,c){void 0===typeof this.catalog[a]&&(this.catalog[a]={}),this.catalog[a][b]=c},validate:function(){return(new this.Validator.Validator).validate.apply(new Validator.Validator,arguments)},addValidator:function(b,c,d){return this.validators[b]=function(b){return a.extend((new Validator.Assert).Callback(c,b),{priority:d})},this},updateValidator:function(a,b,c){return addValidator(a,b,c)},removeValidator:function(a){return delete this.validators[a],this},getErrorMessage:function(a){var b;return b="type"===a.name?window.ParsleyConfig.i18n[this.locale][a.name][a.requirements]:this.formatMesssage(window.ParsleyConfig.i18n[this.locale][a.name],a.requirements),""!==b?b:window.ParsleyConfig.i18n[this.locale].defaultMessage},formatMesssage:function(a,b){if("object"==typeof b){for(var c in b)a=this.formatMesssage(a,b[c]);return a}return"string"==typeof a?a.replace(new RegExp("%s","i"),b):""},validators:{notblank:function(){return a.extend((new Validator.Assert).NotBlank(),{priority:2})},required:function(){return a.extend((new Validator.Assert).Required(),{priority:512})},type:function(b){var c;switch(b){case"email":c=(new Validator.Assert).Email();break;case"number":c=(new Validator.Assert).Regexp("^-?(?:\\d+|\\d{1,3}(?:,\\d{3})+)?(?:\\.\\d+)?$");break;case"integer":c=(new Validator.Assert).Regexp("^-?\\d+$");break;case"digits":c=(new Validator.Assert).Regexp("^\\d+$");break;case"alphanum":c=(new Validator.Assert).Regexp("^\\w+$","i");break;case"url":c=(new Validator.Assert).Regexp("(https?:\\/\\/)?(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,4}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)","i");break;default:throw new Error("validator type `"+b+"` is not supported")}return a.extend(c,{priority:256})},pattern:function(b){return a.extend((new Validator.Assert).Regexp(b),{priority:64})},minlength:function(b){return a.extend((new Validator.Assert).Length({min:b}),{priority:30})},maxlength:function(b){return a.extend((new Validator.Assert).Length({max:b}),{priority:30})},length:function(b){return a.extend((new Validator.Assert).Length({min:b[0],max:b[1]}),{priority:32})},mincheck:function(a){return this.minlength(a)},maxcheck:function(a){return this.maxlength(a)},check:function(a){return this.length(a)},min:function(b){return a.extend((new Validator.Assert).GreaterThanOrEqual(b),{priority:30})},max:function(b){return a.extend((new Validator.Assert).LessThanOrEqual(b),{priority:30})},range:function(b){return a.extend((new Validator.Assert).Range(b[0],b[1]),{priority:32})},equalto:function(b){return a.extend((new Validator.Assert).Callback(function(b,c){return b===a(c).val()},b),{priority:256})}}};var f=function(){this.__class__="ParsleyUI"};f.prototype={listen:function(){return a.listen("parsley:form:init",this,this.setupForm),a.listen("parsley:field:init",this,this.setupField),a.listen("parsley:field:validated",this,this.reflow),a.listen("parsley:form:validated",this,this.focus),a.listen("parsley:field:reset",this,this.reset),a.listen("parsley:form:destroy",this,this.destroy),a.listen("parsley:field:destroy",this,this.destroy),this},reflow:function(a){if("undefined"!=typeof a._ui&&!1!==a._ui.active){var b=this._diff(a.validationResult,a._ui.lastValidationResult);a._ui.lastValidationResult=a.validationResult,a._ui.validatedOnce=!0,this.manageStatusClass(a),this.manageErrorsMessages(a,b),this.actualizeTriggers(a),(b.kept.length||b.added.length)&&"undefined"==typeof a._ui.failedOnce&&this.manageFailingFieldTrigger(a)}},manageStatusClass:function(a){!0===a.validationResult?this._successClass(a):a.validationResult.length>0?this._errorClass(a):this._resetClass(a)},manageErrorsMessages:function(b,c){if("undefined"!=typeof b.options.errorMessage)return void(c.added.length||c.kept.length?(0===b._ui.$errorsWrapper.find(".parsley-custom-error-message").length&&b._ui.$errorsWrapper.append(a(b.options.errorTemplate).addClass("parsley-custom-error-message")),b._ui.$errorsWrapper.addClass("filled").find(".parsley-custom-error-message").html(b.options.errorMessage)):b._ui.$errorsWrapper.removeClass("filled").find(".parsley-custom-error-message").remove());for(var d=0;d<c.removed.length;d++)this.removeError(b,c.removed[d].assert.name,!0);for(d=0;d<c.added.length;d++)this.addError(b,c.added[d].assert.name,void 0,c.added[d].assert,!0);for(d=0;d<c.kept.length;d++)this.updateError(b,c.kept[d].assert.name,void 0,c.kept[d].assert,!0)},addError:function(b,c,d,e,f){b._ui.$errorsWrapper.addClass("filled").append(a(b.options.errorTemplate).addClass("parsley-"+c).html(d||this._getErrorMessage(b,e))),!0!==f&&this._errorClass(b)},updateError:function(a,b,c,d,e){a._ui.$errorsWrapper.addClass("filled").find(".parsley-"+b).html(c||this._getErrorMessage(a,d)),!0!==e&&this._errorClass(a)},removeError:function(a,b,c){a._ui.$errorsWrapper.removeClass("filled").find(".parsley-"+b).remove(),!0!==c&&this.manageStatusClass(a)},focus:function(a){if(!0===a.validationResult||"none"===a.options.focus)return a._focusedField=null;a._focusedField=null;for(var b=0;b<a.fields.length;b++)if(!0!==a.fields[b].validationResult&&a.fields[b].validationResult.length>0&&"undefined"==typeof a.fields[b].options.noFocus){if("first"===a.options.focus)return a._focusedField=a.fields[b].$element,a._focusedField.focus();a._focusedField=a.fields[b].$element}return null===a._focusedField?null:a._focusedField.focus()},_getErrorMessage:function(a,b){var c=b.name+"Message";return"undefined"!=typeof a.options[c]?a.options[c]:window.ParsleyValidator.getErrorMessage(b)},_diff:function(a,b,c){for(var d=[],e=[],f=0;f<a.length;f++){for(var g=!1,h=0;h<b.length;h++)if(a[f].assert.name===b[h].assert.name){g=!0;break}g?e.push(a[f]):d.push(a[f])}return{kept:e,added:d,removed:c?[]:this._diff(b,a,!0).added}},setupForm:function(b){b.$element.on("submit.Parsley",!1,a.proxy(b.onSubmitValidate,b)),!1!==b.options.uiEnabled&&b.$element.attr("novalidate","")},setupField:function(b){var c={active:!1};!1!==b.options.uiEnabled&&(c.active=!0,b.$element.attr(b.options.namespace+"id",b.__id__),c.$errorClassHandler=this._manageClassHandler(b),c.errorsWrapperId="parsley-id-"+("undefined"!=typeof b.options.multiple?"multiple-"+b.options.multiple:b.__id__),c.$errorsWrapper=a(b.options.errorsWrapper).attr("id",c.errorsWrapperId),c.lastValidationResult=[],c.validatedOnce=!1,c.validationInformationVisible=!1,b._ui=c,this._insertErrorWrapper(b),this.actualizeTriggers(b))},_manageClassHandler:function(b){if("string"==typeof b.options.classHandler&&a(b.options.classHandler).length)return a(b.options.classHandler);var c=b.options.classHandler(b);return"undefined"!=typeof c&&c.length?c:"undefined"==typeof b.options.multiple?b.$element:b.$element.parent()},_insertErrorWrapper:function(b){if("string"==typeof b.options.errorsContainer&&a(b.options.errorsContainer).length)return a(b.options.errorsContainer).append(b._ui.$errorsWrapper);var c=b.options.errorsContainer(b);return"undefined"!=typeof c&&c.length?c.append(b._ui.$errorsWrapper):"undefined"==typeof b.options.multiple?b.$element.after(b._ui.$errorsWrapper):b.$element.parent().after(b._ui.$errorsWrapper)},actualizeTriggers:function(b){if(b.$element.off(".Parsley"),!1!==b.options.trigger){var c=b.options.trigger.replace(/^\s+/g,"").replace(/\s+$/g,"");""!==c&&b.$element.on(c.split(" ").join(".Parsley ")+".Parsley",!1,a.proxy("function"==typeof b.eventValidate?b.eventValidate:this.eventValidate,b))}},eventValidate:function(a){new RegExp("key").test(a.type)&&!this._ui.validationInformationVisible&&this.getValue().length<=this.options.validationThreshold||(this._ui.validatedOnce=!0,this.validate())},manageFailingFieldTrigger:function(b){return b._ui.failedOnce=!0,b.options.multiple&&a("["+b.options.namespace+'multiple="'+b.options.multiple+'"]').each(function(){return new RegExp("change","i").test(a(this).parsley().options.trigger||"")?void 0:a(this).parsley().$element.on("change.ParsleyFailedOnce",!1,a.proxy(b.validate,b))}),new RegExp("keyup","i").test(b.options.trigger||"")?void 0:b.$element.on("keyup.ParsleyFailedOnce",!1,a.proxy(b.validate,b))},reset:function(b){b.$element.off(".Parsley"),b.$element.off(".ParsleyFailedOnce"),"ParsleyForm"!==b.__class__&&(b._ui.$errorsWrapper.children().each(function(){a(this).remove()}),this._resetClass(b),b._ui.validatedOnce=!1,b._ui.lastValidationResult=[],b._ui.validationInformationVisible=!1)},destroy:function(a){this.reset(a),"ParsleyForm"!==a.__class__&&(a._ui.$errorsWrapper.remove(),delete a._ui)},_successClass:function(a){a._ui.validationInformationVisible=!0,a._ui.$errorClassHandler.removeClass(a.options.errorClass).addClass(a.options.successClass)},_errorClass:function(a){a._ui.validationInformationVisible=!0,a._ui.$errorClassHandler.removeClass(a.options.successClass).addClass(a.options.errorClass)},_resetClass:function(a){a._ui.$errorClassHandler.removeClass(a.options.successClass).removeClass(a.options.errorClass)}};var g=function(c,d,e,f){this.__class__="OptionsFactory",this.__id__=b.hash(4),this.formOptions=null,this.fieldOptions=null,this.staticOptions=a.extend(!0,{},c,d,e,{namespace:f})};g.prototype={get:function(a){if("undefined"==typeof a.__class__)throw new Error("Parsley Instance expected");switch(a.__class__){case"Parsley":return this.staticOptions;case"ParsleyForm":return this.getFormOptions(a);case"ParsleyField":return this.getFieldOptions(a);default:throw new Error("Instance "+a.__class__+" is not supported")}},getFormOptions:function(c){return this.formOptions=b.attr(c.$element,this.staticOptions.namespace),a.extend({},this.staticOptions,this.formOptions)},getFieldOptions:function(c){return this.fieldOptions=b.attr(c.$element,this.staticOptions.namespace),a.extend({},this.staticOptions,this.formOptions,this.fieldOptions)}};var h=function(c,d){if(this.__class__="ParsleyForm",this.__id__=b.hash(4),"Parsley"!==b.get(d,"__class__"))throw new Error("You must give a Parsley instance");return this.parsleyInstance=d,this.init(a(c))};h.prototype={init:function(a){return this.$element=a,this.validationResult=null,this.options=this.parsleyInstance.OptionsFactory.get(this),this._bindFields()},onSubmitValidate:function(b){return this.validate(void 0,b),!1===this.validationResult&&b instanceof a.Event&&b.preventDefault(),this},validate:function(b,c){this.submitEvent=c,this.validationResult=!0;var d=[];this._refreshFields(),a.emit("parsley:form:validate",this);for(var e=0;e<this.fields.length;e++)b&&b!==this.fields[e].options.group||(d=this.fields[e].validate(),!0!==d&&d.length>0&&this.validationResult&&(this.validationResult=!1));return a.emit("parsley:form:validated",this),this.validationResult},isValid:function(a){this._refreshFields();for(var b=0;b<this.fields.length;b++)if((!a||a===this.fields[b].options.group)&&!1===this.fields[b].isValid())return!1;return!0},_refreshFields:function(){return this.actualizeOptions()._bindFields()},_bindFields:function(){var a=this;return this.fields=[],this.$element.find(this.options.inputs).each(function(){var b=new window.Parsley(this,{},a.parsleyInstance);"ParsleyField"===b.__class__&&a.fields.push(b)}),this}};var i=function(c,d,e,f,g){if("ParsleyField"!==b.get(c,"__class__"))throw new Error("ParsleyField instance expected");if("function"!=typeof window.ParsleyValidator.validators[d]&&"Assert"!==window.ParsleyValidator.validators[d](e).__parentClass__)throw new Error("Valid validator expected");var h=function(a,c){return"undefined"!=typeof a.options[c+"Priority"]?a.options[c+"Priority"]:b.get(window.ParsleyValidator.validators[c](e),"priority",2)};return f=f||h(c,d),a.extend(window.ParsleyValidator.validators[d](e),{name:d,requirements:e,priority:f,groups:[f],isDomConstraint:g||b.attr(c.$element,c.options.namespace,d)})},j=function(c,d){if(this.__class__="ParsleyField",this.__id__=b.hash(4),"Parsley"!==b.get(d,"__class__"))throw new Error("You must give a Parsley instance");return this.parsleyInstance=d,this.init(a(c),d.options)};j.prototype={init:function(a){if(this.constraints=[],this.$element=a,this.validationResult=[],this.options=this.parsleyInstance.OptionsFactory.get(this),this.$element.is("input[type=radio], input[type=checkbox]")&&"undefined"==typeof this.options.multiple||this.$element.is("select")&&"undefined"!=typeof this.$element.attr("multiple")){if("undefined"==typeof this.$element.attr("name")&&"undefined"==typeof this.$element.attr("id"))return window.console&&window.console.warn&&window.console.warn("To be binded by Parsley, a radio, a checkbox and a multiple select input must have either a name, and id or a multiple option.",this.$element),this.parsleyInstance;this.options.multiple=(this.$element.attr("name")||this.$element.attr("id")).replace(/(:|\.|\[|\]|\$)/g,""),b.setAttr(this.$element,this.options.namespace,"multiple",this.options.multiple)}return this.bindConstraints()},validate:function(){return this.value=this.getValue(),a.emit("parsley:field:validate",this),a.emit("parsley:field:"+(this.isValid(this.value)?"success":"error"),this),a.emit("parsley:field:validated",this),this.validationResult},getConstraintsSortedPriorities:function(){for(var a=[],b=0;b<this.constraints.length;b++)-1===a.indexOf(this.constraints[b].priority)&&a.push(this.constraints[b].priority);return a.sort(function(a,b){return b-a}),a},isValid:function(a){var b=this.getConstraintsSortedPriorities();if(a=a||this.getValue(),this.refreshConstraints(),""===a&&!this.isRequired()&&"undefined"==typeof this.options.validateIfEmpty&&"undefined"==typeof this.options.multiple)return this.validationResult=[];if(!1===this.options.priorityEnabled)return!0===(this.validationResult=this.validateThroughValidator(a,this.constraints,"Any"));for(var c=0;c<b.length;c++)if(!0!==(this.validationResult=this.validateThroughValidator(a,this.constraints,b[c])))return!1;return!0},isRequired:function(){var a=this._constraintIndex("required");return!(-1===a||-1!==a&&!1===this.constraints[a].requirements)},getValue:function(){if("undefined"!=typeof this.options.value)return this.options.value;if("undefined"==typeof this.options.multiple)return this.$element.val();if(this.$element.is("input[type=radio]"))return a("["+this.options.namespace+'multiple="'+this.options.multiple+'"]:checked').val()||"";
if(this.$element.is("input[type=checkbox]")){var b=[];return a("["+this.options.namespace+'multiple="'+this.options.multiple+'"]:checked').each(function(){b.push(a(this).val())}),b.length?b:""}return this.$element.is("select")?null===this.$element.val()?"":this.$element.val():void 0},refreshConstraints:function(){return this.actualizeOptions().bindConstraints()},bindConstraints:function(){for(var a=[],b=0;b<this.constraints.length;b++)!1===this.constraints[b].isDomConstraint&&a.push(this.constraints[b]);this.constraints=a;for(var c in this.options)this.addConstraint(c,this.options[c]);return this.bindHtml5Constraints()},bindHtml5Constraints:function(){(this.$element.hasClass("required")||this.$element.attr("required"))&&this.addConstraint("required",!0,void 0,!0),"string"==typeof this.$element.attr("pattern")&&this.addConstraint("pattern",this.$element.attr("pattern"),void 0,!0),"undefined"!=typeof this.$element.attr("min")&&"undefined"!=typeof this.$element.attr("max")?this.addConstraint("range",[this.$element.attr("min"),this.$element.attr("max")],void 0,!0):"undefined"!=typeof this.$element.attr("min")?this.addConstraint("min",this.$element.attr("min"),void 0,!0):"undefined"!=typeof this.$element.attr("max")&&this.addConstraint("max",this.$element.attr("max"),void 0,!0);var a=this.$element.attr("type");return"undefined"==typeof a?this:"number"===a?this.addConstraint("type","integer",void 0,!0):new RegExp(a,"i").test("email url range")?this.addConstraint("type",a,void 0,!0):void 0},addConstraint:function(a,b,c,d){return a=a.toLowerCase(),"function"==typeof window.ParsleyValidator.validators[a]&&(constraint=new i(this,a,b,c,d),-1!==this._constraintIndex(constraint.name)&&this.removeConstraint(constraint.name),this.constraints.push(constraint)),this},removeConstraint:function(a){for(var b=0;b<this.constraints.length;b++)if(a===this.constraints[b].name){this.constraints.splice(b,1);break}return this},updateConstraint:function(a,b,c){return this.removeConstraint(a).addConstraint(a,b,c)},_constraintIndex:function(a){for(var b=0;b<this.constraints.length;b++)if(a===this.constraints[b].name)return b;return-1}};var k=a({}),l={};a.listen=function(a){if("undefined"==typeof l[a]&&(l[a]=[]),"function"==typeof arguments[1])return l[a].push({fn:arguments[1]});if("object"==typeof arguments[1]&&"function"==typeof arguments[2])return l[a].push({fn:arguments[2],ctxt:arguments[1]});throw new Error("Wrong parameters")},a.listenTo=function(a,b,c){if("undefined"==typeof l[b]&&(l[b]=[]),!(a instanceof j||a instanceof h))throw new Error("Must give Parsley instance");if("string"!=typeof b||"function"!=typeof c)throw new Error("Wrong parameters");l[b].push({instance:a,fn:c})},a.unsubscribe=function(a,b){if("undefined"!=typeof l[a]){if("string"!=typeof a||"function"!=typeof b)throw new Error("Wrong arguments");for(var c=0;c<l[a].length;c++)if(l[a][c].fn===b)return l[a].splice(c,1)}},a.unsubscribeTo=function(a,b){if("undefined"!=typeof l[b]){if(!(a instanceof j||a instanceof h))throw new Error("Must give Parsley instance");for(var c=0;c<l[b].length;c++)if("undefined"!=typeof l[b][c].instance&&l[b][c].instance.__id__===a.__id__)return l[b].splice(c,1)}},a.unsubscribeAll=function(a){"undefined"!=typeof l[a]&&delete l[a]},a.emit=function(a,b){if("undefined"!=typeof l[a])for(var c=0;c<l[a].length;c++)if("undefined"!=typeof l[a][c].instance){if(b instanceof j||b instanceof h)if(l[a][c].instance.__id__!==b.__id__){if(l[a][c].instance instanceof h&&b instanceof j)for(var d=0;d<l[a][c].instance.fields.length;d++)if(l[a][c].instance.fields[d].__id__===b.__id__){l[a][c].fn.apply(k,Array.prototype.slice.call(arguments,1));continue}}else l[a][c].fn.apply(k,Array.prototype.slice.call(arguments,1))}else l[a][c].fn.apply("undefined"!=typeof l[a][c].ctxt?l[a][c].ctxt:k,Array.prototype.slice.call(arguments,1))},a.subscribed=function(){return l},window.ParsleyConfig=window.ParsleyConfig||{},window.ParsleyConfig.i18n=window.ParsleyConfig.i18n||{},window.ParsleyConfig.i18n.en=a.extend(window.ParsleyConfig.i18n.en||{},{defaultMessage:"This value seems to be invalid.",type:{email:"This value should be a valid email.",url:"This value should be a valid url.",number:"This value should be a valid number.",integer:"This value should be a valid integer.",digits:"This value should be digits.",alphanum:"This value should be alphanumeric."},notblank:"This value should not be blank.",required:"This value is required.",pattern:"This value seems to be invalid.",min:"This value should be greater than or equal to %s.",max:"This value should be lower than or equal to %s.",range:"This value should be between %s and %s.",minlength:"This value is too short. It should have %s characters or more.",maxlength:"This value is too long. It should have %s characters or less.",length:"This value length is invalid. It should be between %s and %s characters long.",mincheck:"You must select at least %s choices.",maxcheck:"You must select %s choices or less.",check:"You must select between %s and %s choices.",equalto:"This value should be the same."}),"undefined"!=typeof window.ParsleyValidator&&window.ParsleyValidator.addCatalog("en",window.ParsleyConfig.i18n.en,!0);var m=function(c,d,e){if(this.__class__="Parsley",this.__version__="2.0.0-rc2",this.__id__=b.hash(4),"undefined"==typeof c)throw new Error("You must give an element");return this.init(a(c),d,e)};m.prototype={init:function(a,d,e){if(!a.length)throw new Error("You must bind Parsley on an existing element.");return this.$element=a,this.$element.data("Parsley")?this.$element.data("Parsley"):(this.OptionsFactory=new g(c,b.get(window,"ParsleyConfig",{}),d,this.getNamespace(d)),d=this.OptionsFactory.staticOptions,this.$element.is("form")||b.attr(this.$element,d.namespace,"validate")&&!this.$element.is(d.inputs)?this.bind("parsleyForm",e):this.$element.is(d.inputs)&&!this.$element.is(d.excluded)?this.bind("parsleyField",e):this)},getNamespace:function(a){return"undefined"!=typeof this.$element.data("parsleyNamespace")?this.$element.data("parsleyNamespace"):"undefined"!=typeof b.get(a,"namespace")?a.namespace:"undefined"!=typeof b.get(window,"ParsleyConfig.namespace")?window.ParsleyConfig.namespace:c.namespace},bind:function(b,c){switch(b){case"parsleyForm":parsleyInstance=a.extend(new h(this.$element,c||this),new d,window.ParsleyExtend);break;case"parsleyField":parsleyInstance=a.extend(new j(this.$element,c||this),new d,window.ParsleyExtend);break;default:throw new Error(b+"is not a supported Parsley type")}return("ParsleyForm"===parsleyInstance.__class__||"ParsleyField"===parsleyInstance.__class__)&&(this.$element.data("Parsley",parsleyInstance),a.emit("parsley:"+("parsleyForm"===b?"form":"field")+":init",parsleyInstance)),parsleyInstance}},a.fn.parsley=a.fn.psly=function(a){return new m(this,a)},window.ParsleyUI="function"==typeof b.get(window.ParsleyConfig,"ParsleyUI")?(new window.ParsleyConfig.ParsleyUI).listen():(new f).listen(),"undefined"==typeof window.ParsleyExtend&&(window.ParsleyExtend={}),"undefined"==typeof window.ParsleyConfig&&(window.ParsleyConfig={}),window.Parsley=window.psly=m,window.ParsleyUtils=b,window.ParsleyValidator=new e(window.ParsleyConfig.validators,window.ParsleyConfig.i18n),!1!==b.get(window,"ParsleyConfig.autoBind")&&a(document).ready(function(){a("[data-parsley-validate]").each(function(){new m(this)})})}(window.jQuery);
!function(a){var b={attr:function(a,b,c){var d,e={},f=new RegExp("^"+b,"i");if("undefined"==typeof a||"undefined"==typeof a[0])return{};for(var g in a[0].attributes)if(d=a[0].attributes[g],"undefined"!=typeof d&&null!==d&&d.specified&&f.test(d.name)){if("undefined"!=typeof c&&new RegExp(c+"$","i").test(d.name))return!0;e[this.camelize(d.name.replace(b,""))]=this.deserializeValue(d.value)}return"undefined"==typeof c?e:!1},setAttr:function(a,b,c,d){a[0].setAttribute(this.dasherize(b+c),String(d))},get:function(a,b){for(var c=0,d=(b||"").split(".");this.isObject(a)||this.isArray(a);)if(a=a[d[c++]],c===d.length)return a;return void 0},hash:function(a){return String(Math.random()).substring(2,a?a+2:9)},isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)},isObject:function(a){return a===Object(a)},deserializeValue:function(b){var c;try{return b?"true"==b||("false"==b?!1:"null"==b?null:isNaN(c=Number(b))?/^[\[\{]/.test(b)?a.parseJSON(b):b:c):b}catch(d){return b}},camelize:function(a){return a.replace(/-+(.)?/g,function(a,b){return b?b.toUpperCase():""})},dasherize:function(a){return a.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}},c={namespace:"data-parsley-",inputs:"input, textarea, select",excluded:"input[type=button], input[type=submit], input[type=reset], input[type=hidden]",priorityEnabled:!0,uiEnabled:!0,validationThreshold:3,focus:"first",trigger:!1,errorClass:"parsley-error",successClass:"parsley-success",classHandler:function(){},errorsContainer:function(){},errorsWrapper:'<ul class="parsley-errors-list"></ul>',errorTemplate:"<li></li>"},d=function(){};d.prototype={asyncSupport:!1,actualizeOptions:function(){return this.options=this.OptionsFactory.get(this),this},validateThroughValidator:function(a,b,c){return window.ParsleyValidator.validate.apply(window.ParsleyValidator,[a,b,c])},subscribe:function(b,c){return a.listenTo(this,b.toLowerCase(),c),this},unsubscribe:function(b){return a.unsubscribeTo(this,b.toLowerCase()),this},reset:function(){if("ParsleyForm"!==this.__class__)return a.emit("parsley:field:reset",this);for(var b=0;b<this.fields.length;b++)a.emit("parsley:field:reset",this.fields[b]);a.emit("parsley:form:reset",this)},destroy:function(){if("ParsleyForm"!==this.__class__)return this.$element.removeData("Parsley"),this.$element.removeData("ParsleyFieldMultiple"),void a.emit("parsley:field:destroy",this);for(var b=0;b<this.fields.length;b++)this.fields[b].destroy();this.$element.removeData("Parsley"),a.emit("parsley:form:destroy",this)}},function(a){var b=function(a){return this.__class__="Validator",this.__version__="0.5.8",this.options=a||{},this.bindingKey=this.options.bindingKey||"_validatorjsConstraint",this};b.prototype={constructor:b,validate:function(a,b,c){if("string"!=typeof a&&"object"!=typeof a)throw new Error("You must validate an object or a string");return"string"==typeof a||g(a)?this._validateString(a,b,c):this.isBinded(a)?this._validateBindedObject(a,b):this._validateObject(a,b,c)},bind:function(a,b){if("object"!=typeof a)throw new Error("Must bind a Constraint to an object");return a[this.bindingKey]=new c(b),this},unbind:function(a){return"undefined"==typeof a._validatorjsConstraint?this:(delete a[this.bindingKey],this)},isBinded:function(a){return"undefined"!=typeof a[this.bindingKey]},getBinded:function(a){return this.isBinded(a)?a[this.bindingKey]:null},_validateString:function(a,b,c){var f,h=[];g(b)||(b=[b]);for(var i=0;i<b.length;i++){if(!(b[i]instanceof e))throw new Error("You must give an Assert or an Asserts array to validate a string");f=b[i].check(a,c),f instanceof d&&h.push(f)}return h.length?h:!0},_validateObject:function(a,b,d){if("object"!=typeof b)throw new Error("You must give a constraint to validate an object");return b instanceof c?b.check(a,d):new c(b).check(a,d)},_validateBindedObject:function(a,b){return a[this.bindingKey].check(a,b)}},b.errorCode={must_be_a_string:"must_be_a_string",must_be_an_array:"must_be_an_array",must_be_a_number:"must_be_a_number",must_be_a_string_or_array:"must_be_a_string_or_array"};var c=function(a,b){if(this.__class__="Constraint",this.options=b||{},this.nodes={},a)try{this._bootstrap(a)}catch(c){throw new Error("Should give a valid mapping object to Constraint",c,a)}return this};c.prototype={constructor:c,check:function(a,b){var c,d={};for(var h in this.options.strict?this.nodes:a)if(this.options.strict?this.has(h,a):this.has(h))c=this._check(h,a[h],b),(g(c)&&c.length>0||!g(c)&&!f(c))&&(d[h]=c);else if(this.options.strict)try{(new e).HaveProperty(h).validate(a)}catch(i){d[h]=i}return f(d)?!0:d},add:function(a,b){if(b instanceof e||g(b)&&b[0]instanceof e)return this.nodes[a]=b,this;if("object"==typeof b&&!g(b))return this.nodes[a]=b instanceof c?b:new c(b),this;throw new Error("Should give an Assert, an Asserts array, a Constraint",b)},has:function(a,b){return b="undefined"!=typeof b?b:this.nodes,"undefined"!=typeof b[a]},get:function(a,b){return this.has(a)?this.nodes[a]:b||null},remove:function(a){var b=[];for(var c in this.nodes)c!==a&&(b[c]=this.nodes[c]);return this.nodes=b,this},_bootstrap:function(a){if(a instanceof c)return this.nodes=a.nodes;for(var b in a)this.add(b,a[b])},_check:function(a,b,d){if(this.nodes[a]instanceof e)return this._checkAsserts(b,[this.nodes[a]],d);if(g(this.nodes[a]))return this._checkAsserts(b,this.nodes[a],d);if(this.nodes[a]instanceof c)return this.nodes[a].check(b,d);throw new Error("Invalid node",this.nodes[a])},_checkAsserts:function(a,b,c){for(var d,e=[],f=0;f<b.length;f++)d=b[f].check(a,c),"undefined"!=typeof d&&!0!==d&&e.push(d);return e}};var d=function(a,b,c){if(this.__class__="Violation",!(a instanceof e))throw new Error("Should give an assertion implementing the Assert interface");this.assert=a,this.value=b,"undefined"!=typeof c&&(this.violation=c)};d.prototype={show:function(){var a={assert:this.assert.__class__,value:this.value};return this.violation&&(a.violation=this.violation),a},__toString:function(){return"undefined"!=typeof this.violation&&(this.violation='", '+this.getViolation().constraint+" expected was "+this.getViolation().expected),this.assert.__class__+' assert failed for "'+this.value+this.violation||""},getViolation:function(){var a,b;for(a in this.violation)b=this.violation[a];return{constraint:a,expected:b}}};var e=function(a){return this.__class__="Assert",this.__parentClass__=this.__class__,this.groups=[],"undefined"!=typeof a&&this.addGroup(a),this};e.prototype={construct:e,check:function(a,b){if(!(b&&!this.hasGroup(b)||!b&&this.hasGroups()))try{return this.validate(a,b)}catch(c){return c}},hasGroup:function(a){return g(a)?this.hasOneOf(a):"Any"===a?!0:this.hasGroups()?-1!==this.groups.indexOf(a):"Default"===a},hasOneOf:function(a){for(var b=0;b<a.length;b++)if(this.hasGroup(a[b]))return!0;return!1},hasGroups:function(){return this.groups.length>0},addGroup:function(a){return g(a)?this.addGroups(a):(this.hasGroup(a)||this.groups.push(a),this)},removeGroup:function(a){for(var b=[],c=0;c<this.groups.length;c++)a!==this.groups[c]&&b.push(this.groups[c]);return this.groups=b,this},addGroups:function(a){for(var b=0;b<a.length;b++)this.addGroup(a[b]);return this},HaveProperty:function(a){return this.__class__="HaveProperty",this.node=a,this.validate=function(a){if("undefined"==typeof a[this.node])throw new d(this,a,{value:this.node});return!0},this},Blank:function(){return this.__class__="Blank",this.validate=function(a){if("string"!=typeof a)throw new d(this,a,{value:b.errorCode.must_be_a_string});if(""!==a.replace(/^\s+/g,"").replace(/\s+$/g,""))throw new d(this,a);return!0},this},Callback:function(a){if(this.__class__="Callback",this.arguments=Array.prototype.slice.call(arguments),1===this.arguments.length?this.arguments=[]:this.arguments.splice(0,1),"function"!=typeof a)throw new Error("Callback must be instanciated with a function");return this.fn=a,this.validate=function(a){var b=this.fn.apply(this,[a].concat(this.arguments));if(!0!==b)throw new d(this,a,{result:b});return!0},this},Choice:function(a){if(this.__class__="Choice",!g(a)&&"function"!=typeof a)throw new Error("Choice must be instanciated with an array or a function");return this.list=a,this.validate=function(a){for(var b="function"==typeof this.list?this.list():this.list,c=0;c<b.length;c++)if(a===b[c])return!0;throw new d(this,a,{choices:b})},this},Collection:function(a){return this.__class__="Collection",this.constraint="undefined"!=typeof a?new c(a):!1,this.validate=function(a,c){var e,h=new b,i=0,j={},k=this.groups.length?this.groups:c;if(!g(a))throw new d(this,array,{value:b.errorCode.must_be_an_array});for(var l=0;l<a.length;l++)e=this.constraint?h.validate(a[l],this.constraint,k):h.validate(a[l],k),f(e)||(j[i]=e),i++;return f(j)?!0:j},this},Count:function(a){return this.__class__="Count",this.count=a,this.validate=function(a){if(!g(a))throw new d(this,a,{value:b.errorCode.must_be_an_array});var c="function"==typeof this.count?this.count(a):this.count;if(isNaN(Number(c)))throw new Error("Count must be a valid interger",c);if(c!==a.length)throw new d(this,a,{count:c});return!0},this},Email:function(){return this.__class__="Email",this.validate=function(a){var c=/^((([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;if("string"!=typeof a)throw new d(this,a,{value:b.errorCode.must_be_a_string});if(!c.test(a))throw new d(this,a);return!0},this},Eql:function(a){if(this.__class__="Eql","undefined"==typeof a)throw new Error("Equal must be instanciated with an Array or an Object");return this.eql=a,this.validate=function(a){var b="function"==typeof this.eql?this.eql(a):this.eql;if(!h.eql(b,a))throw new d(this,a,{eql:b});return!0},this},EqualTo:function(a){if(this.__class__="EqualTo","undefined"==typeof a)throw new Error("EqualTo must be instanciated with a value or a function");return this.reference=a,this.validate=function(a){var b="function"==typeof this.reference?this.reference(a):this.reference;if(b!==a)throw new d(this,a,{value:b});return!0},this},GreaterThan:function(a){if(this.__class__="GreaterThan","undefined"==typeof a)throw new Error("Should give a threshold value");return this.threshold=a,this.validate=function(a){if(""===a||isNaN(Number(a)))throw new d(this,a,{value:b.errorCode.must_be_a_number});if(this.threshold>=a)throw new d(this,a,{threshold:this.threshold});return!0},this},GreaterThanOrEqual:function(a){if(this.__class__="GreaterThanOrEqual","undefined"==typeof a)throw new Error("Should give a threshold value");return this.threshold=a,this.validate=function(a){if(""===a||isNaN(Number(a)))throw new d(this,a,{value:b.errorCode.must_be_a_number});if(this.threshold>a)throw new d(this,a,{threshold:this.threshold});return!0},this},InstanceOf:function(a){if(this.__class__="InstanceOf","undefined"==typeof a)throw new Error("InstanceOf must be instanciated with a value");return this.classRef=a,this.validate=function(a){if(!0!=a instanceof this.classRef)throw new d(this,a,{classRef:this.classRef});return!0},this},IPv4:function(){return this.__class__="IPv4",this.validate=function(a){var c=/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;if("string"!=typeof a)throw new d(this,a,{value:b.errorCode.must_be_a_string});if(!c.test(a))throw new d(this,a);return!0},this},Length:function(a){if(this.__class__="Length",!a.min&&!a.max)throw new Error("Lenth assert must be instanciated with a { min: x, max: y } object");return this.min=a.min,this.max=a.max,this.validate=function(a){if("string"!=typeof a&&!g(a))throw new d(this,a,{value:b.errorCode.must_be_a_string_or_array});if("undefined"!=typeof this.min&&this.min===this.max&&a.length!==this.min)throw new d(this,a,{min:this.min,max:this.max});if("undefined"!=typeof this.max&&a.length>this.max)throw new d(this,a,{max:this.max});if("undefined"!=typeof this.min&&a.length<this.min)throw new d(this,a,{min:this.min});return!0},this},LessThan:function(a){if(this.__class__="LessThan","undefined"==typeof a)throw new Error("Should give a threshold value");return this.threshold=a,this.validate=function(a){if(""===a||isNaN(Number(a)))throw new d(this,a,{value:b.errorCode.must_be_a_number});if(this.threshold<=a)throw new d(this,a,{threshold:this.threshold});return!0},this},LessThanOrEqual:function(a){if(this.__class__="LessThanOrEqual","undefined"==typeof a)throw new Error("Should give a threshold value");return this.threshold=a,this.validate=function(a){if(""===a||isNaN(Number(a)))throw new d(this,a,{value:b.errorCode.must_be_a_number});if(this.threshold<a)throw new d(this,a,{threshold:this.threshold});return!0},this},Mac:function(){return this.__class__="Mac",this.validate=function(a){var c=/^(?:[0-9A-F]{2}:){5}[0-9A-F]{2}$/i;if("string"!=typeof a)throw new d(this,a,{value:b.errorCode.must_be_a_string});if(!c.test(a))throw new d(this,a);return!0},this},NotNull:function(){return this.__class__="NotNull",this.validate=function(a){if(null===a||"undefined"==typeof a)throw new d(this,a);return!0},this},NotBlank:function(){return this.__class__="NotBlank",this.validate=function(a){if("string"!=typeof a)throw new d(this,a,{value:b.errorCode.must_be_a_string});if(""===a.replace(/^\s+/g,"").replace(/\s+$/g,""))throw new d(this,a);return!0},this},Null:function(){return this.__class__="Null",this.validate=function(a){if(null!==a)throw new d(this,a);return!0},this},Range:function(a,b){if(this.__class__="Range","undefined"==typeof a||"undefined"==typeof b)throw new Error("Range assert expects min and max values");return this.min=a,this.max=b,this.validate=function(a){try{return"string"==typeof a&&isNaN(Number(a))||g(a)?(new e).Length({min:this.min,max:this.max}).validate(a):(new e).GreaterThanOrEqual(this.min).validate(a)&&(new e).LessThanOrEqual(this.max).validate(a),!0}catch(b){throw new d(this,a,b.violation)}return!0},this},Regexp:function(a,c){if(this.__class__="Regexp","undefined"==typeof a)throw new Error("You must give a regexp");return this.regexp=a,this.flag=c||"",this.validate=function(a){if("string"!=typeof a)throw new d(this,a,{value:b.errorCode.must_be_a_string});if(!new RegExp(this.regexp,this.flag).test(a))throw new d(this,a,{regexp:this.regexp,flag:this.flag});return!0},this},Required:function(){return this.__class__="Required",this.validate=function(a){if("undefined"==typeof a)throw new d(this,a);try{"string"==typeof a?(new e).NotNull().validate(a)&&(new e).NotBlank().validate(a):!0===g(a)&&(new e).Length({min:1}).validate(a)}catch(b){throw new d(this,a)}return!0},this},Unique:function(a){return this.__class__="Unique","object"==typeof a&&(this.key=a.key),this.validate=function(a){var c,e=[];if(!g(a))throw new d(this,a,{value:b.errorCode.must_be_an_array});for(var f=0;f<a.length;f++)if(c="object"==typeof a[f]?a[f][this.key]:a[f],"undefined"!=typeof c){if(-1!==e.indexOf(c))throw new d(this,a,{value:c});e.push(c)}return!0},this}},a.Assert=e,a.Validator=b,a.Violation=d,a.Constraint=c,Array.prototype.indexOf||(Array.prototype.indexOf=function(a){if(null===this)throw new TypeError;var b=Object(this),c=b.length>>>0;if(0===c)return-1;var d=0;if(arguments.length>1&&(d=Number(arguments[1]),d!=d?d=0:0!==d&&1/0!=d&&d!=-1/0&&(d=(d>0||-1)*Math.floor(Math.abs(d)))),d>=c)return-1;for(var e=d>=0?d:Math.max(c-Math.abs(d),0);c>e;e++)if(e in b&&b[e]===a)return e;return-1});var f=function(a){for(var b in a)return!1;return!0},g=function(a){return"[object Array]"===Object.prototype.toString.call(a)},h={eql:function(a,b){if(a===b)return!0;if("undefined"!=typeof Buffer&&Buffer.isBuffer(a)&&Buffer.isBuffer(b)){if(a.length!==b.length)return!1;for(var c=0;c<a.length;c++)if(a[c]!==b[c])return!1;return!0}return a instanceof Date&&b instanceof Date?a.getTime()===b.getTime():"object"!=typeof a&&"object"!=typeof b?a==b:this.objEquiv(a,b)},isUndefinedOrNull:function(a){return null===a||"undefined"==typeof a},isArguments:function(a){return"[object Arguments]"==Object.prototype.toString.call(a)},keys:function(a){if(Object.keys)return Object.keys(a);var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b},objEquiv:function(a,b){if(this.isUndefinedOrNull(a)||this.isUndefinedOrNull(b))return!1;if(a.prototype!==b.prototype)return!1;if(this.isArguments(a))return this.isArguments(b)?eql(pSlice.call(a),pSlice.call(b)):!1;try{var c,d,e=this.keys(a),f=this.keys(b);if(e.length!==f.length)return!1;for(e.sort(),f.sort(),d=e.length-1;d>=0;d--)if(e[d]!=f[d])return!1;for(d=e.length-1;d>=0;d--)if(c=e[d],!this.eql(a[c],b[c]))return!1;return!0}catch(g){return!1}}};"function"==typeof define&&define.amd&&define("validator",[],function(){return a})}("undefined"==typeof exports?this["undefined"!=typeof validatorjs_ns?validatorjs_ns:"Validator"]={}:exports);var e=function(a,b){this.__class__="ParsleyValidator",this.Validator=Validator,this.locale="en",this.init(a||{},b||{})};e.prototype={init:function(b,c){this.catalog=c;for(var d in b)this.addValidator(d,b[d].fn,b[d].priority);a.emit("parsley:validator:init")},setLocale:function(a){if("undefined"==typeof this.catalog[a])throw new Error(a+" is not available in the catalog");return this.locale=a,this},addCatalog:function(a,b,c){return"object"==typeof b&&(this.catalog[a]=b),!0===c?this.setLocale(a):this},addMessage:function(a,b,c){return void 0===typeof this.catalog[a]&&(this.catalog[a]={}),this.catalog[a][b.toLowerCase()]=c,this},validate:function(){return(new this.Validator.Validator).validate.apply(new Validator.Validator,arguments)},addValidator:function(b,c,d){return this.validators[b.toLowerCase()]=function(b){return a.extend((new Validator.Assert).Callback(c,b),{priority:d})},this},updateValidator:function(a,b,c){return addValidator(a,b,c)},removeValidator:function(a){return delete this.validators[a],this},getErrorMessage:function(a){var b;return b="type"===a.name?this.catalog[this.locale][a.name][a.requirements]:this.formatMessage(this.catalog[this.locale][a.name],a.requirements),""!==b?b:this.catalog[this.locale].defaultMessage},formatMessage:function(a,b){if("object"==typeof b){for(var c in b)a=this.formatMessage(a,b[c]);return a}return"string"==typeof a?a.replace(new RegExp("%s","i"),b):""},validators:{notblank:function(){return a.extend((new Validator.Assert).NotBlank(),{priority:2})},required:function(){return a.extend((new Validator.Assert).Required(),{priority:512})},type:function(b){var c;switch(b){case"email":c=(new Validator.Assert).Email();break;case"number":c=(new Validator.Assert).Regexp("^-?(?:\\d+|\\d{1,3}(?:,\\d{3})+)?(?:\\.\\d+)?$");break;case"integer":c=(new Validator.Assert).Regexp("^-?\\d+$");break;case"digits":c=(new Validator.Assert).Regexp("^\\d+$");break;case"alphanum":c=(new Validator.Assert).Regexp("^\\w+$","i");break;case"url":c=(new Validator.Assert).Regexp("(https?:\\/\\/)?(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,4}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)","i");break;default:throw new Error("validator type `"+b+"` is not supported")}return a.extend(c,{priority:256})},pattern:function(b){var c="";return/^\/.*\/(?:[gimy]*)$/.test(b)&&(c=b.replace(/.*\/([gimy]*)$/,"$1"),b=b.replace(new RegExp("^/(.*?)/"+c+"$"),"$1")),a.extend((new Validator.Assert).Regexp(b,c),{priority:64})},minlength:function(b){return a.extend((new Validator.Assert).Length({min:b}),{priority:30,requirementsTransformer:function(){return"string"!=typeof b||isNaN(b)?b:parseInt(b,10)}})},maxlength:function(b){return a.extend((new Validator.Assert).Length({max:b}),{priority:30,requirementsTransformer:function(){return"string"!=typeof b||isNaN(b)?b:parseInt(b,10)}})},length:function(b){return a.extend((new Validator.Assert).Length({min:b[0],max:b[1]}),{priority:32})},mincheck:function(a){return this.minlength(a)},maxcheck:function(a){return this.maxlength(a)},check:function(a){return this.length(a)},min:function(b){return a.extend((new Validator.Assert).GreaterThanOrEqual(b),{priority:30,requirementsTransformer:function(){return"string"!=typeof b||isNaN(b)?b:parseInt(b,10)}})},max:function(b){return a.extend((new Validator.Assert).LessThanOrEqual(b),{priority:30,requirementsTransformer:function(){return"string"!=typeof b||isNaN(b)?b:parseInt(b,10)}})},range:function(b){return a.extend((new Validator.Assert).Range(b[0],b[1]),{priority:32,requirementsTransformer:function(){for(var a=0;a<b.length;a++)b[a]="string"!=typeof b[a]||isNaN(b[a])?b[a]:parseInt(b[a],10);return b}})},equalto:function(b){return a.extend((new Validator.Assert).EqualTo(b),{priority:256,requirementsTransformer:function(){return a(b).length?a(b).val():b}})}}};var f=function(){this.__class__="ParsleyUI"};f.prototype={listen:function(){return a.listen("parsley:form:init",this,this.setupForm),a.listen("parsley:field:init",this,this.setupField),a.listen("parsley:field:validated",this,this.reflow),a.listen("parsley:form:validated",this,this.focus),a.listen("parsley:field:reset",this,this.reset),a.listen("parsley:form:destroy",this,this.destroy),a.listen("parsley:field:destroy",this,this.destroy),this},reflow:function(a){if("undefined"!=typeof a._ui&&!1!==a._ui.active){var b=this._diff(a.validationResult,a._ui.lastValidationResult);a._ui.lastValidationResult=a.validationResult,a._ui.validatedOnce=!0,this.manageStatusClass(a),this.manageErrorsMessages(a,b),this.actualizeTriggers(a),(b.kept.length||b.added.length)&&"undefined"==typeof a._ui.failedOnce&&this.manageFailingFieldTrigger(a)}},getErrorsMessages:function(a){if(!0===a.validationResult)return[];for(var b=[],c=0;c<a.validationResult.length;c++)b.push(this._getErrorMessage(a,a.validationResult[c].assert));return b},manageStatusClass:function(a){!0===a.validationResult?this._successClass(a):a.validationResult.length>0?this._errorClass(a):this._resetClass(a)},manageErrorsMessages:function(b,c){if("undefined"==typeof b.options.errorsMessagesDisabled){if("undefined"!=typeof b.options.errorMessage)return c.added.length||c.kept.length?(0===b._ui.$errorsWrapper.find(".parsley-custom-error-message").length&&b._ui.$errorsWrapper.append(a(b.options.errorTemplate).addClass("parsley-custom-error-message")),b._ui.$errorsWrapper.addClass("filled").find(".parsley-custom-error-message").html(b.options.errorMessage)):b._ui.$errorsWrapper.removeClass("filled").find(".parsley-custom-error-message").remove();for(var d=0;d<c.removed.length;d++)this.removeError(b,c.removed[d].assert.name,!0);for(d=0;d<c.added.length;d++)this.addError(b,c.added[d].assert.name,void 0,c.added[d].assert,!0);for(d=0;d<c.kept.length;d++)this.updateError(b,c.kept[d].assert.name,void 0,c.kept[d].assert,!0)}},addError:function(b,c,d,e,f){b._ui.$errorsWrapper.addClass("filled").append(a(b.options.errorTemplate).addClass("parsley-"+c).html(d||this._getErrorMessage(b,e))),!0!==f&&this._errorClass(b)},updateError:function(a,b,c,d,e){a._ui.$errorsWrapper.addClass("filled").find(".parsley-"+b).html(c||this._getErrorMessage(a,d)),!0!==e&&this._errorClass(a)},removeError:function(a,b,c){a._ui.$errorsWrapper.removeClass("filled").find(".parsley-"+b).remove(),!0!==c&&this.manageStatusClass(a)},focus:function(a){if(!0===a.validationResult||"none"===a.options.focus)return a._focusedField=null;a._focusedField=null;for(var b=0;b<a.fields.length;b++)if(!0!==a.fields[b].validationResult&&a.fields[b].validationResult.length>0&&"undefined"==typeof a.fields[b].options.noFocus){if("first"===a.options.focus)return a._focusedField=a.fields[b].$element,a._focusedField.focus();a._focusedField=a.fields[b].$element}return null===a._focusedField?null:a._focusedField.focus()},_getErrorMessage:function(a,b){var c=b.name+"Message";return"undefined"!=typeof a.options[c]?window.ParsleyValidator.formatMessage(a.options[c],b.requirements):window.ParsleyValidator.getErrorMessage(b)},_diff:function(a,b,c){for(var d=[],e=[],f=0;f<a.length;f++){for(var g=!1,h=0;h<b.length;h++)if(a[f].assert.name===b[h].assert.name){g=!0;break}g?e.push(a[f]):d.push(a[f])}return{kept:e,added:d,removed:c?[]:this._diff(b,a,!0).added}},setupForm:function(b){b.$element.on("submit.Parsley",!1,a.proxy(b.onSubmitValidate,b)),!1!==b.options.uiEnabled&&b.$element.attr("novalidate","")},setupField:function(b){var c={active:!1};!1!==b.options.uiEnabled&&(c.active=!0,b.$element.attr(b.options.namespace+"id",b.__id__),c.$errorClassHandler=this._manageClassHandler(b),c.errorsWrapperId="parsley-id-"+("undefined"!=typeof b.options.multiple?"multiple-"+b.options.multiple:b.__id__),c.$errorsWrapper=a(b.options.errorsWrapper).attr("id",c.errorsWrapperId),c.lastValidationResult=[],c.validatedOnce=!1,c.validationInformationVisible=!1,b._ui=c,this._insertErrorWrapper(b),this.actualizeTriggers(b))},_manageClassHandler:function(b){if("string"==typeof b.options.classHandler&&a(b.options.classHandler).length)return a(b.options.classHandler);var c=b.options.classHandler(b);return"undefined"!=typeof c&&c.length?c:"undefined"==typeof b.options.multiple||b.$element.is("select")?b.$element:b.$element.parent()},_insertErrorWrapper:function(b){var c;if("string"==typeof b.options.errorsContainer){if(a(b.options.errorsContainer+"").length)return a(b.options.errorsContainer).append(b._ui.$errorsWrapper);window.console&&window.console.warn&&window.console.warn("The errors container `"+b.options.errorsContainer+"` does not exist in DOM")}return"function"==typeof b.options.errorsContainer&&(c=b.options.errorsContainer(b)),"undefined"!=typeof c&&c.length?c.append(b._ui.$errorsWrapper):"undefined"==typeof b.options.multiple?b.$element.after(b._ui.$errorsWrapper):b.$element.parent().after(b._ui.$errorsWrapper)},actualizeTriggers:function(b){var c=this;if(b.options.multiple?a("["+b.options.namespace+'multiple="'+b.options.multiple+'"]').each(function(){a(this).off(".Parsley")}):b.$element.off(".Parsley"),!1!==b.options.trigger){var d=b.options.trigger.replace(/^\s+/g,"").replace(/\s+$/g,"");""!==d&&(b.options.multiple?a("["+b.options.namespace+'multiple="'+b.options.multiple+'"]').each(function(){a(this).on(d.split(" ").join(".Parsley ")+".Parsley",!1,a.proxy("function"==typeof b.eventValidate?b.eventValidate:c.eventValidate,b))}):b.$element.on(d.split(" ").join(".Parsley ")+".Parsley",!1,a.proxy("function"==typeof b.eventValidate?b.eventValidate:this.eventValidate,b)))}},eventValidate:function(a){new RegExp("key").test(a.type)&&!this._ui.validationInformationVisible&&this.getValue().length<=this.options.validationThreshold||(this._ui.validatedOnce=!0,this.validate())},manageFailingFieldTrigger:function(b){return b._ui.failedOnce=!0,b.options.multiple&&a("["+b.options.namespace+'multiple="'+b.options.multiple+'"]').each(function(){return new RegExp("change","i").test(a(this).parsley().options.trigger||"")?void 0:a(this).on("change.ParsleyFailedOnce",!1,a.proxy(b.validate,b))}),b.$element.is("select")&&!new RegExp("change","i").test(b.options.trigger||"")?b.$element.on("change.ParsleyFailedOnce",!1,a.proxy(b.validate,b)):new RegExp("keyup","i").test(b.options.trigger||"")?void 0:b.$element.on("keyup.ParsleyFailedOnce",!1,a.proxy(b.validate,b))},reset:function(b){b.$element.off(".Parsley"),b.$element.off(".ParsleyFailedOnce"),"undefined"!=typeof b._ui&&"ParsleyForm"!==b.__class__&&(b._ui.$errorsWrapper.children().each(function(){a(this).remove()}),this._resetClass(b),b._ui.validatedOnce=!1,b._ui.lastValidationResult=[],b._ui.validationInformationVisible=!1)},destroy:function(a){this.reset(a),"ParsleyForm"!==a.__class__&&(a._ui.$errorsWrapper.remove(),delete a._ui)},_successClass:function(a){a._ui.validationInformationVisible=!0,a._ui.$errorClassHandler.removeClass(a.options.errorClass).addClass(a.options.successClass)},_errorClass:function(a){a._ui.validationInformationVisible=!0,a._ui.$errorClassHandler.removeClass(a.options.successClass).addClass(a.options.errorClass)},_resetClass:function(a){a._ui.$errorClassHandler.removeClass(a.options.successClass).removeClass(a.options.errorClass)}};var g=function(c,d,e,f){this.__class__="OptionsFactory",this.__id__=b.hash(4),this.formOptions=null,this.fieldOptions=null,this.staticOptions=a.extend(!0,{},c,d,e,{namespace:f})};g.prototype={get:function(a){if("undefined"==typeof a.__class__)throw new Error("Parsley Instance expected");switch(a.__class__){case"Parsley":return this.staticOptions;case"ParsleyForm":return this.getFormOptions(a);case"ParsleyField":case"ParsleyFieldMultiple":return this.getFieldOptions(a);default:throw new Error("Instance "+a.__class__+" is not supported")}},getFormOptions:function(c){return this.formOptions=b.attr(c.$element,this.staticOptions.namespace),a.extend({},this.staticOptions,this.formOptions)},getFieldOptions:function(c){return this.fieldOptions=b.attr(c.$element,this.staticOptions.namespace),null===this.formOptions&&"undefined"!=typeof c.parent&&(this.formOptions=this.getFormOptions(c.parent)),a.extend({},this.staticOptions,this.formOptions,this.fieldOptions)}};var h=function(c,d){if(this.__class__="ParsleyForm",this.__id__=b.hash(4),"OptionsFactory"!==b.get(d,"__class__"))throw new Error("You must give an OptionsFactory instance");this.OptionsFactory=d,this.$element=a(c),this.validationResult=null,this.options=this.OptionsFactory.get(this)};h.prototype={onSubmitValidate:function(b){return this.validate(void 0,void 0,b),!1===this.validationResult&&b instanceof a.Event&&(b.stopImmediatePropagation(),b.preventDefault()),this},validate:function(b,c,d){this.submitEvent=d,this.validationResult=!0;var e=[];this._refreshFields(),a.emit("parsley:form:validate",this);for(var f=0;f<this.fields.length;f++)b&&b!==this.fields[f].options.group||(e=this.fields[f].validate(c),!0!==e&&e.length>0&&this.validationResult&&(this.validationResult=!1));return a.emit("parsley:form:validated",this),this.validationResult},isValid:function(a,b){this._refreshFields();for(var c=0;c<this.fields.length;c++)if((!a||a===this.fields[c].options.group)&&!1===this.fields[c].isValid(b))return!1;return!0},_refreshFields:function(){return this.actualizeOptions()._bindFields()},_bindFields:function(){var a=this;return this.fields=[],this.fieldsMappedById={},this.$element.find(this.options.inputs).each(function(){var b=new window.Parsley(this,{},a);"ParsleyField"!==b.__class__&&"ParsleyFieldMultiple"!==b.__class__||b.$element.is(b.options.excluded)||"undefined"==typeof a.fieldsMappedById[b.__class__+"-"+b.__id__]&&(a.fieldsMappedById[b.__class__+"-"+b.__id__]=b,a.fields.push(b))}),this}};var i=function(c,d,e,f,g){if(!new RegExp("ParsleyField").test(b.get(c,"__class__")))throw new Error("ParsleyField or ParsleyFieldMultiple instance expected");if("function"!=typeof window.ParsleyValidator.validators[d]&&"Assert"!==window.ParsleyValidator.validators[d](e).__parentClass__)throw new Error("Valid validator expected");var h=function(a,c){return"undefined"!=typeof a.options[c+"Priority"]?a.options[c+"Priority"]:b.get(window.ParsleyValidator.validators[c](e),"priority")||2};return f=f||h(c,d),"function"==typeof window.ParsleyValidator.validators[d](e).requirementsTransformer&&(e=window.ParsleyValidator.validators[d](e).requirementsTransformer()),a.extend(window.ParsleyValidator.validators[d](e),{name:d,requirements:e,priority:f,groups:[f],isDomConstraint:g||b.attr(c.$element,c.options.namespace,d)})},j=function(c,d,e){this.__class__="ParsleyField",this.__id__=b.hash(4),this.$element=a(c),"undefined"!=typeof e?(this.parent=e,this.OptionsFactory=this.parent.OptionsFactory,this.options=this.OptionsFactory.get(this)):(this.OptionsFactory=d,this.options=this.OptionsFactory.get(this)),this.constraints=[],this.constraintsByName={},this.validationResult=[],this._bindConstraints()
};j.prototype={validate:function(b){return this.value=this.getValue(),a.emit("parsley:field:validate",this),a.emit("parsley:field:"+(this.isValid(b,this.value)?"success":"error"),this),a.emit("parsley:field:validated",this),this.validationResult},isValid:function(a,b){this.refreshConstraints();var c=this._getConstraintsSortedPriorities();if(b=b||this.getValue(),0===b.length&&!this._isRequired()&&"undefined"==typeof this.options.validateIfEmpty&&!0!==a)return this.validationResult=[];if(!1===this.options.priorityEnabled)return!0===(this.validationResult=this.validateThroughValidator(b,this.constraints,"Any"));for(var d=0;d<c.length;d++)if(!0!==(this.validationResult=this.validateThroughValidator(b,this.constraints,c[d])))return!1;return!0},getValue:function(){var a;return a="undefined"!=typeof this.options.value?this.options.value:this.$element.val(),"undefined"==typeof a||null===a?"":!0===this.options.trimValue?a.replace(/^\s+|\s+$/g,""):a},refreshConstraints:function(){return this.actualizeOptions()._bindConstraints()},addConstraint:function(a,b,c,d){if(a=a.toLowerCase(),"function"==typeof window.ParsleyValidator.validators[a]){var e=new i(this,a,b,c,d);"undefined"!==this.constraintsByName[e.name]&&this.removeConstraint(e.name),this.constraints.push(e),this.constraintsByName[e.name]=e}return this},removeConstraint:function(a){for(var b=0;b<this.constraints.length;b++)if(a===this.constraints[b].name){this.constraints.splice(b,1);break}return this},updateConstraint:function(a,b,c){return this.removeConstraint(a).addConstraint(a,b,c)},_bindConstraints:function(){for(var a=[],b=0;b<this.constraints.length;b++)!1===this.constraints[b].isDomConstraint&&a.push(this.constraints[b]);this.constraints=a;for(var c in this.options)this.addConstraint(c,this.options[c]);return this._bindHtml5Constraints()},_bindHtml5Constraints:function(){(this.$element.hasClass("required")||this.$element.attr("required"))&&this.addConstraint("required",!0,void 0,!0),"string"==typeof this.$element.attr("pattern")&&this.addConstraint("pattern",this.$element.attr("pattern"),void 0,!0),"undefined"!=typeof this.$element.attr("min")&&"undefined"!=typeof this.$element.attr("max")?this.addConstraint("range",[this.$element.attr("min"),this.$element.attr("max")],void 0,!0):"undefined"!=typeof this.$element.attr("min")?this.addConstraint("min",this.$element.attr("min"),void 0,!0):"undefined"!=typeof this.$element.attr("max")&&this.addConstraint("max",this.$element.attr("max"),void 0,!0);var a=this.$element.attr("type");return"undefined"==typeof a?this:"number"===a?this.addConstraint("type","integer",void 0,!0):new RegExp(a,"i").test("email url range")?this.addConstraint("type",a,void 0,!0):this},_isRequired:function(){return"undefined"==typeof this.constraintsByName.required?!1:!1!==this.constraintsByName.required.requirements},_getConstraintsSortedPriorities:function(){for(var a=[],b=0;b<this.constraints.length;b++)-1===a.indexOf(this.constraints[b].priority)&&a.push(this.constraints[b].priority);return a.sort(function(a,b){return b-a}),a}};var k=function(){this.__class__="ParsleyFieldMultiple"};k.prototype={addElement:function(a){return this.$elements.push(a),this},refreshConstraints:function(){var a;if(this.constraints=[],this.$element.is("select"))return this.actualizeOptions()._bindConstraints(),this;for(var b=0;b<this.$elements.length;b++){a=this.$elements[b].data("ParsleyFieldMultiple").refreshConstraints().constraints;for(var c=0;c<a.length;c++)this.addConstraint(a[c].name,a[c].requirements,a[c].priority,a[c].isDomConstraint)}return this},getValue:function(){if("undefined"!=typeof this.options.value)return this.options.value;if(this.$element.is("input[type=radio]"))return a("["+this.options.namespace+'multiple="'+this.options.multiple+'"]:checked').val()||"";if(this.$element.is("input[type=checkbox]")){var b=[];return a("["+this.options.namespace+'multiple="'+this.options.multiple+'"]:checked').each(function(){b.push(a(this).val())}),b.length?b:[]}return this.$element.is("select")&&null===this.$element.val()?[]:this.$element.val()},_init:function(a){return this.$elements=[this.$element],this.options.multiple=a,this}};var l=a({}),m={};a.listen=function(a){if("undefined"==typeof m[a]&&(m[a]=[]),"function"==typeof arguments[1])return m[a].push({fn:arguments[1]});if("object"==typeof arguments[1]&&"function"==typeof arguments[2])return m[a].push({fn:arguments[2],ctxt:arguments[1]});throw new Error("Wrong parameters")},a.listenTo=function(a,b,c){if("undefined"==typeof m[b]&&(m[b]=[]),!(a instanceof j||a instanceof h))throw new Error("Must give Parsley instance");if("string"!=typeof b||"function"!=typeof c)throw new Error("Wrong parameters");m[b].push({instance:a,fn:c})},a.unsubscribe=function(a,b){if("undefined"!=typeof m[a]){if("string"!=typeof a||"function"!=typeof b)throw new Error("Wrong arguments");for(var c=0;c<m[a].length;c++)if(m[a][c].fn===b)return m[a].splice(c,1)}},a.unsubscribeTo=function(a,b){if("undefined"!=typeof m[b]){if(!(a instanceof j||a instanceof h))throw new Error("Must give Parsley instance");for(var c=0;c<m[b].length;c++)if("undefined"!=typeof m[b][c].instance&&m[b][c].instance.__id__===a.__id__)return m[b].splice(c,1)}},a.unsubscribeAll=function(a){"undefined"!=typeof m[a]&&delete m[a]},a.emit=function(a,b){if("undefined"!=typeof m[a])for(var c=0;c<m[a].length;c++)if("undefined"!=typeof m[a][c].instance){if(b instanceof j||b instanceof h)if(m[a][c].instance.__id__!==b.__id__){if(m[a][c].instance instanceof h&&b instanceof j)for(var d=0;d<m[a][c].instance.fields.length;d++)if(m[a][c].instance.fields[d].__id__===b.__id__){m[a][c].fn.apply(l,Array.prototype.slice.call(arguments,1));continue}}else m[a][c].fn.apply(l,Array.prototype.slice.call(arguments,1))}else m[a][c].fn.apply("undefined"!=typeof m[a][c].ctxt?m[a][c].ctxt:l,Array.prototype.slice.call(arguments,1))},a.subscribed=function(){return m},window.ParsleyConfig=window.ParsleyConfig||{},window.ParsleyConfig.i18n=window.ParsleyConfig.i18n||{},window.ParsleyConfig.i18n.en=a.extend(window.ParsleyConfig.i18n.en||{},{defaultMessage:"This value seems to be invalid.",type:{email:"This value should be a valid email.",url:"This value should be a valid url.",number:"This value should be a valid number.",integer:"This value should be a valid integer.",digits:"This value should be digits.",alphanum:"This value should be alphanumeric."},notblank:"This value should not be blank.",required:"This value is required.",pattern:"This value seems to be invalid.",min:"This value should be greater than or equal to %s.",max:"This value should be lower than or equal to %s.",range:"This value should be between %s and %s.",minlength:"This value is too short. It should have %s characters or more.",maxlength:"This value is too long. It should have %s characters or less.",length:"This value length is invalid. It should be between %s and %s characters long.",mincheck:"You must select at least %s choices.",maxcheck:"You must select %s choices or less.",check:"You must select between %s and %s choices.",equalto:"This value should be the same."}),"undefined"!=typeof window.ParsleyValidator&&window.ParsleyValidator.addCatalog("en",window.ParsleyConfig.i18n.en,!0);var n=function(c,d,e){if(this.__class__="Parsley",this.__version__="2.0.0",this.__id__=b.hash(4),"undefined"==typeof c)throw new Error("You must give an element");if("undefined"!=typeof e&&"ParsleyForm"!==e.__class__)throw new Error("Parent instance must be a ParsleyForm instance");return this.init(a(c),d,e)};n.prototype={init:function(a,d,e){if(!a.length)throw new Error("You must bind Parsley on an existing element.");if(this.$element=a,this.$element.data("Parsley")){var f=this.$element.data("Parsley");return"undefined"!=typeof e&&(f.parent=e),f}return this.OptionsFactory=new g(c,b.get(window,"ParsleyConfig")||{},d,this.getNamespace(d)),this.options=this.OptionsFactory.get(this),this.$element.is("form")||b.attr(this.$element,this.options.namespace,"validate")&&!this.$element.is(this.options.inputs)?this.bind("parsleyForm"):this.$element.is(this.options.inputs)&&!this.$element.is(this.options.excluded)?this.isMultiple()?this.handleMultiple(e):this.bind("parsleyField",e):this},isMultiple:function(){return this.$element.is("input[type=radio], input[type=checkbox]")&&"undefined"==typeof this.options.multiple||this.$element.is("select")&&"undefined"!=typeof this.$element.attr("multiple")},handleMultiple:function(c){var d,e,f,g=this;if(this.options=a.extend(this.options,c?c.OptionsFactory.get(c):{},b.attr(this.$element,this.options.namespace)),this.options.multiple?e=this.options.multiple:"undefined"!=typeof this.$element.attr("name")&&this.$element.attr("name").length?e=d=this.$element.attr("name"):"undefined"!=typeof this.$element.attr("id")&&this.$element.attr("id").length&&(e=this.$element.attr("id")),this.$element.is("select")&&"undefined"!=typeof this.$element.attr("multiple"))return this.bind("parsleyFieldMultiple",c,e||this.__id__);if("undefined"==typeof e)return window.console&&window.console.warn&&window.console.warn("To be binded by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.",this.$element),this;if(e=e.replace(/(:|\.|\[|\]|\$)/g,""),"undefined"!=typeof d&&a('input[name="'+d+'"]').each(function(){a(this).is("input[type=radio], input[type=checkbox]")&&a(this).attr(g.options.namespace+"multiple",e)}),a("["+this.options.namespace+"multiple="+e+"]").length)for(var h=0;h<a("["+this.options.namespace+"multiple="+e+"]").length;h++)if("undefined"!=typeof a(a("["+this.options.namespace+"multiple="+e+"]").get(h)).data("Parsley")){f=a(a("["+this.options.namespace+"multiple="+e+"]").get(h)).data("Parsley"),this.$element.data("ParsleyFieldMultiple")||(f.addElement(this.$element),this.$element.attr(this.options.namespace+"id",f.__id__));break}return this.bind("parsleyField",c,e,!0),f||this.bind("parsleyFieldMultiple",c,e)},getNamespace:function(a){return"undefined"!=typeof this.$element.data("parsleyNamespace")?this.$element.data("parsleyNamespace"):"undefined"!=typeof b.get(a,"namespace")?a.namespace:"undefined"!=typeof b.get(window,"ParsleyConfig.namespace")?window.ParsleyConfig.namespace:c.namespace},bind:function(c,e,f,g){var i;switch(c){case"parsleyForm":i=a.extend(new h(this.$element,this.OptionsFactory),new d,window.ParsleyExtend)._bindFields();break;case"parsleyField":i=a.extend(new j(this.$element,this.OptionsFactory,e),new d,window.ParsleyExtend);break;case"parsleyFieldMultiple":i=a.extend(new j(this.$element,this.OptionsFactory,e),new d,new k,window.ParsleyExtend)._init(f);break;default:throw new Error(c+"is not a supported Parsley type")}return"undefined"!=typeof f&&b.setAttr(this.$element,this.options.namespace,"multiple",f),"undefined"!=typeof g?(this.$element.data("ParsleyFieldMultiple",i),i):(new RegExp("ParsleyF","i").test(i.__class__)&&(this.$element.data("Parsley",i),a.emit("parsley:"+("parsleyForm"===c?"form":"field")+":init",i)),i)}},a.fn.parsley=a.fn.psly=function(b){if(this.length>1){var c=[];return this.each(function(){c.push(a(this).parsley(b))}),c}return a(this).length?new n(this,b):void(window.console&&window.console.warn&&window.console.warn("You must bind Parsley on an existing element."))},window.ParsleyUI="function"==typeof b.get(window,"ParsleyConfig.ParsleyUI")?(new window.ParsleyConfig.ParsleyUI).listen():(new f).listen(),"undefined"==typeof window.ParsleyExtend&&(window.ParsleyExtend={}),"undefined"==typeof window.ParsleyConfig&&(window.ParsleyConfig={}),window.Parsley=window.psly=n,window.ParsleyUtils=b,window.ParsleyValidator=new e(window.ParsleyConfig.validators,window.ParsleyConfig.i18n),!1!==b.get(window,"ParsleyConfig.autoBind")&&a(document).ready(function(){a("[data-parsley-validate]").length&&a("[data-parsley-validate]").parsley()}),"function"==typeof define&&define.amd&&define("parsley",function(){return window.Parsley})}(window.jQuery);

@@ -35,3 +35,3 @@ module.exports = function (grunt) {

source: {
src: ['src/parsley.js', 'src/parsley/*.js', 'src/parsley.remote.js'],
src: ['src/parsley.js', 'src/parsley/*.js', 'src/extra/plugin/remote.js'],
options: {

@@ -162,3 +162,3 @@ output: 'doc/annotated-source/',

files: {
'dist/parsley+remote.min.js': 'dist/parsley+remote.js'
'dist/parsley.remote.min.js': 'dist/parsley.remote.js'
}

@@ -177,4 +177,4 @@ }

remote: {
src: ['src/parsley.remote.js', 'dist/parsley.js'],
dest: 'dist/parsley+remote.js'
src: ['src/extra/plugin/remote.js', 'dist/parsley.js'],
dest: 'dist/parsley.remote.js'
}

@@ -181,0 +181,0 @@ }

{
"name": "parsleyjs",
"version": "2.0.0-rc2",
"version": "2.0.0",
"license": "MIT",
"description": "Validate your forms, frontend, without writing a single line of javascript!",
"main": [
"./dist/parsley.js"
],
"keywords": [

@@ -7,0 +10,0 @@ "parsley",

@@ -9,3 +9,3 @@ # Parsley

2.0.0-rc2
2.0.0

@@ -24,2 +24,12 @@ ## Doc

##Integrations
Create integration with other framework as a separate Github repo and send a pull request for including here.
Some integrations are
* [CakePHP](https://github.com/Codaxis/parsley-helper)
* [Django](https://github.com/agiliq/django-parsley)
* [Rails](https://github.com/mekishizufu/parsley-rails)
* [OSSCDN by MaxCDN](http://osscdn.com/#/parsleyjs)
## Install dev environment

@@ -26,0 +36,0 @@

@@ -25,2 +25,5 @@ // ParsleyConfig definition if not already set

length: "La lunghezza di questo valore deve essere compresa fra %s e %s caratteri.",
mincheck: "Devi scegliere almeno %s opzioni.",
maxcheck: "Devi scegliere al più %s opzioni.",
check: "Devi scegliere tra %s e %s opzioni.",
equalto: "Questo valore deve essere identico."

@@ -27,0 +30,0 @@ });

@@ -26,2 +26,4 @@ // Parsley.js @@version

'parsley/field',
// `Multiple` Class. Extend `ParsleyField` to generate `ParsleyFieldMultiple`
'parsley/multiple',
// Tiny Parsley Pub / Sub mechanism, used for `ParsleyUI` and Listeners

@@ -31,5 +33,5 @@ 'parsley/pubsub',

'i18n/en'
], function (ParsleyUtils, ParsleyDefaults, ParsleyAbstract, ParsleyValidator, ParsleyUI, ParsleyOptionsFactory, ParsleyForm, ParsleyField) {
], function (ParsleyUtils, ParsleyDefaults, ParsleyAbstract, ParsleyValidator, ParsleyUI, ParsleyOptionsFactory, ParsleyForm, ParsleyField, ParsleyMultiple) {
// ### Parsley factory
var Parsley = function (element, options, parsleyInstance) {
var Parsley = function (element, options, parsleyFormInstance) {
this.__class__ = 'Parsley';

@@ -43,7 +45,10 @@ this.__version__ = '@@version';

return this.init($(element), options, parsleyInstance);
if ('undefined' !== typeof parsleyFormInstance && 'ParsleyForm' !== parsleyFormInstance.__class__)
throw new Error('Parent instance must be a ParsleyForm instance');
return this.init($(element), options, parsleyFormInstance);
};
Parsley.prototype = {
init: function ($element, options, parsleyInstance) {
init: function ($element, options, parsleyFormInstance) {
if (!$element.length)

@@ -54,17 +59,24 @@ throw new Error('You must bind Parsley on an existing element.');

// If element have already been binded, returns its Parsley instance
if (this.$element.data('Parsley'))
return this.$element.data('Parsley');
// If element have already been binded, returns its saved Parsley instance
if (this.$element.data('Parsley')) {
var savedparsleyFormInstance = this.$element.data('Parsley');
// If saved instance have been binded without a ParsleyForm parent and there is one given in this call, add it
if ('undefined' !== typeof parsleyFormInstance)
savedparsleyFormInstance.parent = parsleyFormInstance;
return savedparsleyFormInstance;
}
// Handle 'static' options
this.OptionsFactory = new ParsleyOptionsFactory(ParsleyDefaults, ParsleyUtils.get(window, 'ParsleyConfig', {}), options, this.getNamespace(options));
options = this.OptionsFactory.staticOptions;
this.OptionsFactory = new ParsleyOptionsFactory(ParsleyDefaults, ParsleyUtils.get(window, 'ParsleyConfig') || {}, options, this.getNamespace(options));
this.options = this.OptionsFactory.get(this);
// A ParsleyForm instance is obviously a `<form>` elem but also every node that is not an input and have `data-parsley-validate` attribute
if (this.$element.is('form') || (ParsleyUtils.attr(this.$element, options.namespace, 'validate') && !this.$element.is(options.inputs)))
return this.bind('parsleyForm', parsleyInstance);
if (this.$element.is('form') || (ParsleyUtils.attr(this.$element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)))
return this.bind('parsleyForm');
// Else every other element that is supported and not excluded is binded as a `ParsleyField`
else if (this.$element.is(options.inputs) && !this.$element.is(options.excluded))
return this.bind('parsleyField', parsleyInstance);
// Every other supported element and not excluded element is binded as a `ParsleyField` or `ParsleyFieldMultiple`
else if (this.$element.is(this.options.inputs) && !this.$element.is(this.options.excluded))
return this.isMultiple() ? this.handleMultiple(parsleyFormInstance) : this.bind('parsleyField', parsleyFormInstance);

@@ -74,2 +86,70 @@ return this;

isMultiple: function () {
return (this.$element.is('input[type=radio], input[type=checkbox]') && 'undefined' === typeof this.options.multiple) || (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple'));
},
// Multiples fields are a real nightmare :(
// Maybe some refacto would be appreciated here..
handleMultiple: function (parsleyFormInstance) {
var
that = this,
name,
multiple,
parsleyMultipleInstance;
// Get parsleyFormInstance options if exist, mixed with element attributes
this.options = $.extend(this.options, parsleyFormInstance ? parsleyFormInstance.OptionsFactory.get(parsleyFormInstance) : {}, ParsleyUtils.attr(this.$element, this.options.namespace));
// Handle multiple name
if (this.options.multiple) {
multiple = this.options.multiple;
} else if ('undefined' !== typeof this.$element.attr('name') && this.$element.attr('name').length) {
multiple = name = this.$element.attr('name');
} else if ('undefined' !== typeof this.$element.attr('id') && this.$element.attr('id').length) {
multiple = this.$element.attr('id');
}
// Special select multiple input
if (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple')) {
return this.bind('parsleyFieldMultiple', parsleyFormInstance, multiple || this.__id__);
// Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
} else if ('undefined' === typeof multiple) {
if (window.console && window.console.warn)
window.console.warn('To be binded by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
return this;
}
// Remove special chars
multiple = multiple.replace(/(:|\.|\[|\]|\$)/g, '');
// Add proper `data-parsley-multiple` to siblings if we had a name
if ('undefined' !== typeof name)
$('input[name="' + name + '"]').each(function () {
if ($(this).is('input[type=radio], input[type=checkbox]'))
$(this).attr(that.options.namespace + 'multiple', multiple);
});
// Check here if we don't already have a related multiple instance saved
if ($('[' + this.options.namespace + 'multiple=' + multiple +']').length)
for (var i = 0; i < $('[' + this.options.namespace + 'multiple=' + multiple +']').length; i++)
if ('undefined' !== typeof $($('[' + this.options.namespace + 'multiple=' + multiple +']').get(i)).data('Parsley')) {
parsleyMultipleInstance = $($('[' + this.options.namespace + 'multiple=' + multiple +']').get(i)).data('Parsley');
if (!this.$element.data('ParsleyFieldMultiple')) {
parsleyMultipleInstance.addElement(this.$element);
this.$element.attr(this.options.namespace + 'id', parsleyMultipleInstance.__id__);
}
break;
}
// Create a secret ParsleyField instance for every multiple field. It would be stored in `data('ParsleyFieldMultiple')`
// And would be useful later to access classic `ParsleyField` stuff while being in a `ParsleyFieldMultiple` instance
this.bind('parsleyField', parsleyFormInstance, multiple, true);
return parsleyMultipleInstance || this.bind('parsleyFieldMultiple', parsleyFormInstance, multiple);
},
// Retrieve namespace used for DOM-API

@@ -88,11 +168,29 @@ getNamespace: function (options) {

// Return proper `ParsleyForm` or `ParsleyField`
bind: function (type, parentParsleyInstance) {
// Return proper `ParsleyForm`, `ParsleyField` or `ParsleyFieldMultiple`
bind: function (type, parentParsleyFormInstance, multiple, doNotStore) {
var parsleyInstance;
switch (type) {
case 'parsleyForm':
parsleyInstance = $.extend(new ParsleyForm(this.$element, parentParsleyInstance || this), new ParsleyAbstract(), window.ParsleyExtend);
parsleyInstance = $.extend(
new ParsleyForm(this.$element, this.OptionsFactory),
new ParsleyAbstract(),
window.ParsleyExtend
)._bindFields();
break;
case 'parsleyField':
parsleyInstance = $.extend(new ParsleyField(this.$element, parentParsleyInstance || this), new ParsleyAbstract(), window.ParsleyExtend);
parsleyInstance = $.extend(
new ParsleyField(this.$element, this.OptionsFactory, parentParsleyFormInstance),
new ParsleyAbstract(),
window.ParsleyExtend
);
break;
case 'parsleyFieldMultiple':
parsleyInstance = $.extend(
new ParsleyField(this.$element, this.OptionsFactory, parentParsleyFormInstance),
new ParsleyAbstract(),
new ParsleyMultiple(),
window.ParsleyExtend
)._init(multiple);
break;
default:

@@ -102,3 +200,13 @@ throw new Error(type + 'is not a supported Parsley type');

if ('ParsleyForm' === parsleyInstance.__class__ || 'ParsleyField' === parsleyInstance.__class__) {
if ('undefined' !== typeof multiple)
ParsleyUtils.setAttr(this.$element, this.options.namespace, 'multiple', multiple);
if ('undefined' !== typeof doNotStore) {
this.$element.data('ParsleyFieldMultiple', parsleyInstance);
return parsleyInstance;
}
// Store instance if `ParsleyForm`, `ParsleyField` or `ParsleyFieldMultiple`
if (new RegExp('ParsleyF', 'i').test(parsleyInstance.__class__)) {
// Store for later access the freshly binded instance in DOM element itself using jQuery `data()`

@@ -118,2 +226,20 @@ this.$element.data('Parsley', parsleyInstance);

$.fn.parsley = $.fn.psly = function (options) {
if (this.length > 1) {
var instances = [];
this.each(function () {
instances.push($(this).parsley(options));
});
return instances;
}
// Return undefined if applied to non existing DOM element
if (!$(this).length) {
if (window.console && window.console.warn)
window.console.warn('You must bind Parsley on an existing element.');
return;
}
return new Parsley(this, options);

@@ -125,3 +251,3 @@ };

// Could be overriden by defining a `window.ParsleyConfig.ParsleyUI` appropriate class (with `listen()` method basically)
window.ParsleyUI = 'function' === typeof ParsleyUtils.get(window.ParsleyConfig, 'ParsleyUI') ?
window.ParsleyUI = 'function' === typeof ParsleyUtils.get(window, 'ParsleyConfig.ParsleyUI') ?
new window.ParsleyConfig.ParsleyUI().listen() : new ParsleyUI().listen();

@@ -148,6 +274,5 @@

$(document).ready(function () {
// Works only on `data-parsley-validate`. We dunno here user specific namespace
$('[data-parsley-validate]').each(function () {
new Parsley(this);
});
// Works only on `data-parsley-validate`.
if ($('[data-parsley-validate]').length)
$('[data-parsley-validate]').parsley();
});

@@ -154,0 +279,0 @@

@@ -1,7 +0,10 @@

define('parsley/abstract', function () {
var ParsleyAbstract = function(options) {};
define('parsley/abstract', [
], function () {
var ParsleyAbstract = function() {};
ParsleyAbstract.prototype = {
asyncSupport: false,
actualizeOptions: function () {
this.options = this.parsleyInstance.OptionsFactory.get(this);
this.options = this.OptionsFactory.get(this);

@@ -13,3 +16,3 @@ return this;

validateThroughValidator: function (value, constraints, priority) {
return window.ParsleyValidator.validate.apply(window.ParsleyValidator, arguments);
return window.ParsleyValidator.validate.apply(window.ParsleyValidator, [value, constraints, priority]);
},

@@ -36,3 +39,3 @@

// Field case: just emit a reset event for UI
if ('ParsleyField' === this.__class__)
if ('ParsleyForm' !== this.__class__)
return $.emit('parsley:field:reset', this);

@@ -50,5 +53,6 @@

// Field case: emit destroy event to clean UI and then destroy stored instance
if ('ParsleyField' === this.__class__) {
if ('ParsleyForm' !== this.__class__) {
this.$element.removeData('Parsley');
this.$element.removeData('ParsleyFieldMultiple');
$.emit('parsley:field:destroy', this);
this.$element.removeData('Parsley');

@@ -62,4 +66,4 @@ return;

this.$element.removeData('Parsley');
$.emit('parsley:form:destroy', this);
this.$element.removeData('Parsley');
}

@@ -66,0 +70,0 @@ };

@@ -17,3 +17,3 @@ // All these options could be overriden and specified directly in DOM using

// Excluded inputs by default
excluded: 'input[type=button], input[type=submit], input[type=reset]',
excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',

@@ -27,3 +27,3 @@ // Stop validating field on highest priority failing constraint

// key events threshold before validation
// Key events threshold before validation
validationThreshold: 3,

@@ -30,0 +30,0 @@

@@ -6,4 +6,4 @@ define('parsley/factory/constraint', [

if ('ParsleyField' !== ParsleyUtils.get(parsleyField, '__class__'))
throw new Error('ParsleyField instance expected');
if (!new RegExp('ParsleyField').test(ParsleyUtils.get(parsleyField, '__class__')))
throw new Error('ParsleyField or ParsleyFieldMultiple instance expected');

@@ -18,3 +18,3 @@ if ('function' !== typeof window.ParsleyValidator.validators[name] &&

return ParsleyUtils.get(window.ParsleyValidator.validators[name](requirements), 'priority', 2);
return ParsleyUtils.get(window.ParsleyValidator.validators[name](requirements), 'priority') || 2;
};

@@ -24,2 +24,6 @@

// If validator have a requirementsTransformer, execute it
if ('function' === typeof window.ParsleyValidator.validators[name](requirements).requirementsTransformer)
requirements = window.ParsleyValidator.validators[name](requirements).requirementsTransformer();
return $.extend(window.ParsleyValidator.validators[name](requirements), {

@@ -26,0 +30,0 @@ name: name,

@@ -25,2 +25,3 @@ define('parsley/factory/options', [

case 'ParsleyField':
case 'ParsleyFieldMultiple':
return this.getFieldOptions(parsleyInstance);

@@ -42,2 +43,5 @@ default:

if (null === this.formOptions && 'undefined' !== typeof fieldInstance.parent)
this.formOptions = this.getFormOptions(fieldInstance.parent);
// not deep extend, since formOptions and fieldOptions is a 1 level deep object

@@ -44,0 +48,0 @@ return $.extend({}, this.staticOptions, this.formOptions, this.fieldOptions);

@@ -6,41 +6,37 @@ define('parsley/field', [

], function (ConstraintFactory, ParsleyUI, ParsleyUtils) {
var ParsleyField = function(field, parsleyInstance) {
var ParsleyField = function (field, OptionsFactory, parsleyFormInstance) {
this.__class__ = 'ParsleyField';
this.__id__ = ParsleyUtils.hash(4);
if ('Parsley' !== ParsleyUtils.get(parsleyInstance, '__class__'))
throw new Error('You must give a Parsley instance');
this.$element = $(field);
this.parsleyInstance = parsleyInstance;
return this.init($(field), parsleyInstance.options);
};
// If we have a parent `ParsleyForm` instance given, use its `OptionsFactory`, and save parent
if ('undefined' !== typeof parsleyFormInstance) {
this.parent = parsleyFormInstance;
this.OptionsFactory = this.parent.OptionsFactory;
this.options = this.OptionsFactory.get(this);
ParsleyField.prototype = {
init: function ($element, options) {
this.constraints = [];
this.$element = $element;
this.validationResult = [];
this.options = this.parsleyInstance.OptionsFactory.get(this);
// Else, take the `Parsley` one
} else {
this.OptionsFactory = OptionsFactory;
this.options = this.OptionsFactory.get(this);
}
// Select / radio / checkbox multiple inputs hack
if ((this.$element.is('input[type=radio], input[type=checkbox]') && 'undefined' === typeof this.options.multiple) || (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple'))) {
if ('undefined' === typeof this.$element.attr('name') && 'undefined' === typeof this.$element.attr('id')) {
if (window.console && window.console.warn)
window.console.warn('To be binded by Parsley, a radio, a checkbox and a multiple select input must have either a name, and id or a multiple option.', this.$element);
// Initialize some properties
this.constraints = [];
this.constraintsByName = {};
this.validationResult = [];
return this.parsleyInstance;
}
// Bind constraints
this._bindConstraints();
};
this.options.multiple = (this.$element.attr('name') || this.$element.attr('id')).replace(/(:|\.|\[|\]|\$)/g, '');
ParsleyUtils.setAttr(this.$element, this.options.namespace, 'multiple', this.options.multiple);
}
return this.bindConstraints();
},
// Returns validationResult. For field, it could be:
// - `true` if all green
// - `[]` if non required field and empty
// - `[Violation, [Violation..]]` if errors
validate: function () {
ParsleyField.prototype = {
// # Public API
// Validate field and $.emit some events for mainly `ParsleyUI`
// @returns validationResult:
// - `true` if all constraint passes
// - `[]` if not required field and empty (not validated)
// - `[Violation, [Violation..]]` if there were validation errors
validate: function (force) {
this.value = this.getValue();

@@ -51,3 +47,3 @@

$.emit('parsley:field:' + (this.isValid(this.value) ? 'success' : 'error'), this);
$.emit('parsley:field:' + (this.isValid(force, this.value) ? 'success' : 'error'), this);

@@ -60,20 +56,10 @@ // Field validated event. `this.validationResult` could be altered for custom needs too

getConstraintsSortedPriorities: function () {
var priorities = [];
// Just validate field. Do not trigger any event
// Same @return as `validate()`
isValid: function (force, value) {
// Recompute options and rebind constraints to have latest changes
this.refreshConstraints();
// Create array unique of priorities
for (var i = 0; i < this.constraints.length; i++)
if (-1 === priorities.indexOf(this.constraints[i].priority))
priorities.push(this.constraints[i].priority);
// Sort them by priority DESC
priorities.sort(function (a, b) { return b - a; });
return priorities;
},
// Same @return as `validate()`
isValid: function (value) {
// Sort priorities to validate more important first
var priorities = this.getConstraintsSortedPriorities();
var priorities = this._getConstraintsSortedPriorities();

@@ -83,9 +69,5 @@ // Value could be passed as argument, needed to add more power to 'parsley:field:validate'

// Recompute options and rebind constraints to have latest changes
this.refreshConstraints();
// If a field is empty and not required, leave it alone, it's just fine
// Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
// And if multiple field
if ('' === value && !this.isRequired() && 'undefined' === typeof this.options.validateIfEmpty && 'undefined' === typeof this.options.multiple)
if (0 === value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty && true !== force)
return this.validationResult = [];

@@ -105,43 +87,77 @@

// Field is required if have required constraint without `false` value
isRequired: function () {
var constraintIndex = this._constraintIndex('required');
// @returns Parsley field computed value that could be overrided or configured in DOM
getValue: function () {
var value;
return !(-1 === constraintIndex || (-1 !== constraintIndex && false === this.constraints[constraintIndex].requirements));
},
getValue: function () {
// Value could be overriden in DOM
if ('undefined' !== typeof this.options.value)
return this.options.value;
value = this.options.value;
else
value = this.$element.val();
// Regular input, textarea and simple select
if ('undefined' === typeof this.options.multiple)
return this.$element.val();
// Handle wrong DOM or configurations
if ('undefined' === typeof value || null === value)
return '';
// Radio input case
if (this.$element.is('input[type=radio]'))
return $('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]:checked').val() || '';
// Use `data-parsley-trim-value="true"` to auto trim inputs entry
if (true === this.options.trimValue)
return value.replace(/^\s+|\s+$/g, '');
// checkbox input case
if (this.$element.is('input[type=checkbox]')) {
var values = [];
return value;
},
$('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]:checked').each(function () {
values.push($(this).val());
});
// Actualize options that could have change since previous validation
// Re-bind accordingly constraints (could be some new, removed or updated)
refreshConstraints: function () {
return this.actualizeOptions()._bindConstraints();
},
return values.length ? values : '';
/**
* Add a new constraint to a field
*
* @method addConstraint
* @param {String} name
* @param {Mixed} requirements optional
* @param {Number} priority optional
* @param {Boolean} isDomConstraint optional
*/
addConstraint: function (name, requirements, priority, isDomConstraint) {
name = name.toLowerCase();
if ('function' === typeof window.ParsleyValidator.validators[name]) {
var constraint = new ConstraintFactory(this, name, requirements, priority, isDomConstraint);
// if constraint already exist, delete it and push new version
if ('undefined' !== this.constraintsByName[constraint.name])
this.removeConstraint(constraint.name);
this.constraints.push(constraint);
this.constraintsByName[constraint.name] = constraint;
}
// Select multiple case
if (this.$element.is('select'))
return null === this.$element.val() ? '' : this.$element.val();
return this;
},
refreshConstraints: function () {
return this.actualizeOptions().bindConstraints();
// Remove a constraint
removeConstraint: function (name) {
for (var i = 0; i < this.constraints.length; i++)
if (name === this.constraints[i].name) {
this.constraints.splice(i, 1);
break;
}
return this;
},
bindConstraints: function () {
// Update a constraint (Remove + re-add)
updateConstraint: function (name, parameters, priority) {
return this.removeConstraint(name)
.addConstraint(name, parameters, priority);
},
// # Internals
// Internal only.
// Bind constraints from config + options + DOM
_bindConstraints: function () {
var constraints = [];

@@ -161,6 +177,8 @@

// finally, bind special HTML5 constraints
return this.bindHtml5Constraints();
return this._bindHtml5Constraints();
},
bindHtml5Constraints: function () {
// Internal only.
// Bind specific HTML5 constraints to be HTML5 compliant
_bindHtml5Constraints: function () {
// html5 required

@@ -199,50 +217,29 @@ if (this.$element.hasClass('required') || this.$element.attr('required'))

return this.addConstraint('type', type, undefined, true);
},
/**
* Add a new constraint to a field
*
* @method addConstraint
* @param {String} name
* @param {Mixed} requirements optional
* @param {Number} priority optional
* @param {Boolean} isDomConstraint optional
*/
addConstraint: function (name, requirements, priority, isDomConstraint) {
name = name.toLowerCase();
if ('function' === typeof window.ParsleyValidator.validators[name]) {
constraint = new ConstraintFactory(this, name, requirements, priority, isDomConstraint);
// if constraint already exist, delete it and push new version
if (-1 !== this._constraintIndex(constraint.name))
this.removeConstraint(constraint.name);
this.constraints.push(constraint);
}
return this;
},
removeConstraint: function (name) {
for (var i = 0; i < this.constraints.length; i++)
if (name === this.constraints[i].name) {
this.constraints.splice(i, 1);
break;
}
// Internal only.
// Field is required if have required constraint without `false` value
_isRequired: function () {
if ('undefined' === typeof this.constraintsByName.required)
return false;
return this;
return false !== this.constraintsByName.required.requirements;
},
updateConstraint: function (name, parameters, priority) {
return this.removeConstraint(name)
.addConstraint(name, parameters, priority);
},
// Internal only.
// Sort constraints by priority DESC
_getConstraintsSortedPriorities: function () {
var priorities = [];
_constraintIndex: function (name) {
// Create array unique of priorities
for (var i = 0; i < this.constraints.length; i++)
if (name === this.constraints[i].name)
return i;
if (-1 === priorities.indexOf(this.constraints[i].priority))
priorities.push(this.constraints[i].priority);
return -1;
// Sort them by priority DESC
priorities.sort(function (a, b) { return b - a; });
return priorities;
}

@@ -249,0 +246,0 @@ };

@@ -5,29 +5,25 @@ define('parsley/form', [

], function (ParsleyAbstract, ParsleyUtils) {
var ParsleyForm = function(element, parsleyInstance) {
var ParsleyForm = function (element, OptionsFactory) {
this.__class__ = 'ParsleyForm';
this.__id__ = ParsleyUtils.hash(4);
if ('Parsley' !== ParsleyUtils.get(parsleyInstance, '__class__'))
throw new Error('You must give a Parsley instance');
if ('OptionsFactory' !== ParsleyUtils.get(OptionsFactory, '__class__'))
throw new Error('You must give an OptionsFactory instance');
this.parsleyInstance = parsleyInstance;
return this.init($(element));
this.OptionsFactory = OptionsFactory;
this.$element = $(element);
this.validationResult = null;
this.options = this.OptionsFactory.get(this);
};
ParsleyForm.prototype = {
init: function ($element) {
this.$element = $element;
this.validationResult = null;
this.options = this.parsleyInstance.OptionsFactory.get(this);
return this._bindFields();
},
onSubmitValidate: function (event) {
this.validate(undefined, event);
this.validate(undefined, undefined, event);
// prevent form submission if validation fails
if (false === this.validationResult && event instanceof $.Event)
if (false === this.validationResult && event instanceof $.Event) {
event.stopImmediatePropagation();
event.preventDefault();
}

@@ -38,3 +34,3 @@ return this;

// @returns boolean
validate: function (group, event) {
validate: function (group, force, event) {
this.submitEvent = event;

@@ -57,3 +53,3 @@ this.validationResult = true;

fieldValidationResult = this.fields[i].validate();
fieldValidationResult = this.fields[i].validate(force);

@@ -70,3 +66,3 @@ if (true !== fieldValidationResult && fieldValidationResult.length > 0 && this.validationResult)

// Iterate over refreshed fields, and stop on first failure
isValid: function (group) {
isValid: function (group, force) {
this._refreshFields();

@@ -80,3 +76,3 @@

if (false === this.fields[i].isValid())
if (false === this.fields[i].isValid(force))
return false;

@@ -94,10 +90,15 @@ }

var self = this;
this.fields = [];
this.fieldsMappedById = {};
this.$element.find(this.options.inputs).each(function () {
var fieldInstance = new window.Parsley(this, {}, self.parsleyInstance);
var fieldInstance = new window.Parsley(this, {}, self);
// only add valid field children
if ('ParsleyField' === fieldInstance.__class__)
self.fields.push(fieldInstance);
// Only add valid and not excluded `ParsleyField` and `ParsleyFieldMultiple` children
if (('ParsleyField' === fieldInstance.__class__ || 'ParsleyFieldMultiple' === fieldInstance.__class__) && !fieldInstance.$element.is(fieldInstance.options.excluded))
if ('undefined' === typeof self.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__]) {
self.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__] = fieldInstance;
self.fields.push(fieldInstance);
}
});

@@ -104,0 +105,0 @@

@@ -5,3 +5,5 @@ define('parsley/pubsub', [

], function (ParsleyField, ParsleyForm) {
var o = $({}), subscribed = {};
var
o = $({}),
subscribed = {};

@@ -8,0 +10,0 @@ // $.listen(name, callback);

@@ -52,2 +52,16 @@ define('parsley/ui', [

// Returns an array of field's error message(s)
getErrorsMessages: function (fieldInstance) {
// No error message, field is valid
if (true === fieldInstance.validationResult)
return [];
var messages = [];
for (var i = 0; i < fieldInstance.validationResult.length; i++)
messages.push(this._getErrorMessage(fieldInstance, fieldInstance.validationResult[i].assert));
return messages;
},
manageStatusClass: function (fieldInstance) {

@@ -63,2 +77,5 @@ if (true === fieldInstance.validationResult)

manageErrorsMessages: function (fieldInstance, diff) {
if ('undefined' !== typeof fieldInstance.options.errorsMessagesDisabled)
return;
// Case where we have errorMessage option that configure an unique field error message, regardless failing validators

@@ -72,14 +89,12 @@ if ('undefined' !== typeof fieldInstance.options.errorMessage) {

fieldInstance._ui.$errorsWrapper
return fieldInstance._ui.$errorsWrapper
.addClass('filled')
.find('.parsley-custom-error-message')
.html(fieldInstance.options.errorMessage);
} else {
fieldInstance._ui.$errorsWrapper
.removeClass('filled')
.find('.parsley-custom-error-message')
.remove();
}
return;
return fieldInstance._ui.$errorsWrapper
.removeClass('filled')
.find('.parsley-custom-error-message')
.remove();
}

@@ -161,3 +176,3 @@

if ('undefined' !== typeof fieldInstance.options[customConstraintErrorMessage])
return fieldInstance.options[customConstraintErrorMessage];
return window.ParsleyValidator.formatMessage(fieldInstance.options[customConstraintErrorMessage], constraint.requirements);

@@ -168,3 +183,4 @@ return window.ParsleyValidator.getErrorMessage(constraint);

_diff: function (newResult, oldResult, deep) {
var added = [],
var
added = [],
kept = [];

@@ -239,20 +255,36 @@

// Determine which element will have `parsley-error` and `parsley-success` classes
_manageClassHandler: function (fieldInstance) {
// An element selector could be passed through DOM with `data-parsley-class-handler=#foo`
if ('string' === typeof fieldInstance.options.classHandler && $(fieldInstance.options.classHandler).length)
return $(fieldInstance.options.classHandler);
// Class handled could also be determined by function given in Parsley options
var $handler = fieldInstance.options.classHandler(fieldInstance);
// If this function returned a valid existing DOM element, go for it
if ('undefined' !== typeof $handler && $handler.length)
return $handler;
return 'undefined' === typeof fieldInstance.options.multiple ? fieldInstance.$element : fieldInstance.$element.parent();
// Otherwise, if simple element (input, texatrea, select..) it will perfectly host the classes
if ('undefined' === typeof fieldInstance.options.multiple || fieldInstance.$element.is('select'))
return fieldInstance.$element;
// But if multiple element (radio, checkbox), that would be their parent
return fieldInstance.$element.parent();
},
_insertErrorWrapper: function (fieldInstance) {
if ('string' === typeof fieldInstance.options.errorsContainer && $(fieldInstance.options.errorsContainer).length)
return $(fieldInstance.options.errorsContainer).append(fieldInstance._ui.$errorsWrapper);
var $errorsContainer;
var $errorsContainer = fieldInstance.options.errorsContainer(fieldInstance);
if ('string' === typeof fieldInstance.options.errorsContainer )
if ($(fieldInstance.options.errorsContainer + '').length)
return $(fieldInstance.options.errorsContainer).append(fieldInstance._ui.$errorsWrapper);
else if (window.console && window.console.warn)
window.console.warn('The errors container `' + fieldInstance.options.errorsContainer + '` does not exist in DOM');
if ('function' === typeof fieldInstance.options.errorsContainer)
$errorsContainer = fieldInstance.options.errorsContainer(fieldInstance);
if ('undefined' !== typeof $errorsContainer && $errorsContainer.length)

@@ -265,4 +297,11 @@ return $errorsContainer.append(fieldInstance._ui.$errorsWrapper);

actualizeTriggers: function (fieldInstance) {
var that = this;
// Remove Parsley events already binded on this field
fieldInstance.$element.off('.Parsley');
if (fieldInstance.options.multiple)
$('[' + fieldInstance.options.namespace + 'multiple="' + fieldInstance.options.multiple + '"]').each(function () {
$(this).off('.Parsley');
});
else
fieldInstance.$element.off('.Parsley');

@@ -279,7 +318,15 @@ // If no trigger is set, all good

// Bind fieldInstance.eventValidate if exists (for parsley.ajax for example), ParsleyUI.eventValidate otherwise
fieldInstance.$element
.on(
triggers.split(' ').join('.Parsley ') + '.Parsley',
false,
$.proxy('function' === typeof fieldInstance.eventValidate ? fieldInstance.eventValidate : this.eventValidate, fieldInstance));
if (fieldInstance.options.multiple)
$('[' + fieldInstance.options.namespace + 'multiple="' + fieldInstance.options.multiple + '"]').each(function () {
$(this).on(
triggers.split(' ').join('.Parsley ') + '.Parsley',
false,
$.proxy('function' === typeof fieldInstance.eventValidate ? fieldInstance.eventValidate : that.eventValidate, fieldInstance));
});
else
fieldInstance.$element
.on(
triggers.split(' ').join('.Parsley ') + '.Parsley',
false,
$.proxy('function' === typeof fieldInstance.eventValidate ? fieldInstance.eventValidate : this.eventValidate, fieldInstance));
},

@@ -303,9 +350,14 @@

// Radio and checkboxes fields
// Radio and checkboxes fields must bind every field multiple
if (fieldInstance.options.multiple)
$('[' + fieldInstance.options.namespace + 'multiple="' + fieldInstance.options.multiple + '"]').each(function () {
if (!new RegExp('change', 'i').test($(this).parsley().options.trigger || ''))
return $(this).parsley().$element.on('change.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
return $(this).on('change.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
});
// Select case
if (fieldInstance.$element.is('select'))
if (!new RegExp('change', 'i').test(fieldInstance.options.trigger || ''))
return fieldInstance.$element.on('change.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
// All other inputs fields

@@ -321,2 +373,6 @@ if (!new RegExp('keyup', 'i').test(fieldInstance.options.trigger || ''))

// Nothing to do if UI never initialized for this field
if ('undefined' === typeof parsleyInstance._ui)
return;
if ('ParsleyForm' === parsleyInstance.__class__)

@@ -323,0 +379,0 @@ return;

@@ -7,3 +7,4 @@ define('parsley/utils', function () {

attr: function ($element, namespace, checkAttr) {
var attribute,
var
attribute,
obj = {},

@@ -17,5 +18,6 @@ regex = new RegExp('^' + namespace, 'i');

attribute = $element[0].attributes[i];
if ('undefined' !== typeof attribute && null !== attribute && attribute.specified && regex.test(attribute.name)) {
if ('undefined' !== typeof checkAttr && new RegExp(checkAttr, 'i').test(attribute.name))
return true;
if ('undefined' !== typeof checkAttr && new RegExp(checkAttr + '$', 'i').test(attribute.name))
return true;

@@ -34,5 +36,6 @@ obj[this.camelize(attribute.name.replace(namespace, ''))] = this.deserializeValue(attribute.value);

// Recursive object / array getter
get: function (obj, path, placeholder) {
var i = 0,
paths = (path || '').split('.');
get: function (obj, path) {
var
i = 0,
paths = (path || '').split('.');

@@ -42,6 +45,6 @@ while (this.isObject(obj) || this.isArray(obj)) {

if (i === paths.length)
return obj || placeholder;
return obj;
}
return placeholder;
return undefined;
},

@@ -48,0 +51,0 @@

@@ -50,3 +50,5 @@ define('parsley/validator', [

this.catalog[locale][name] = message;
this.catalog[locale][name.toLowerCase()] = message;
return this;
},

@@ -60,3 +62,3 @@

addValidator: function (name, fn, priority) {
this.validators[name] = function (requirements) {
this.validators[name.toLowerCase()] = function (requirements) {
return $.extend(new Validator.Assert().Callback(fn, requirements), { priority: priority });

@@ -83,14 +85,14 @@ };

if ('type' === constraint.name)
message = window.ParsleyConfig.i18n[this.locale][constraint.name][constraint.requirements];
message = this.catalog[this.locale][constraint.name][constraint.requirements];
else
message = this.formatMesssage(window.ParsleyConfig.i18n[this.locale][constraint.name], constraint.requirements);
message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
return '' !== message ? message : window.ParsleyConfig.i18n[this.locale].defaultMessage;
return '' !== message ? message : this.catalog[this.locale].defaultMessage;
},
// Kind of light `sprintf()` implementation
formatMesssage: function (string, parameters) {
formatMessage: function (string, parameters) {
if ('object' === typeof parameters) {
for (var i in parameters)
string = this.formatMesssage(string, parameters[i]);
string = this.formatMessage(string, parameters[i]);

@@ -142,9 +144,31 @@ return string;

pattern: function (regexp) {
return $.extend(new Validator.Assert().Regexp(regexp), { priority: 64 });
var flags = '';
// Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
if (!!(/^\/.*\/(?:[gimy]*)$/.test(regexp))) {
// Replace the regexp literal string with the first match group: ([gimy]*)
// If no flag is present, this will be a blank string
flags = regexp.replace(/.*\/([gimy]*)$/, '$1');
// Again, replace the regexp literal string with the first match group:
// everything excluding the opening and closing slashes and the flags
regexp = regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
}
return $.extend(new Validator.Assert().Regexp(regexp, flags), { priority: 64 });
},
minlength: function (length) {
return $.extend(new Validator.Assert().Length({ min: length }), { priority: 30 });
minlength: function (value) {
return $.extend(new Validator.Assert().Length({ min: value }), {
priority: 30,
requirementsTransformer: function () {
return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
}
});
},
maxlength: function (length) {
return $.extend(new Validator.Assert().Length({ max: length }), { priority: 30 });
maxlength: function (value) {
return $.extend(new Validator.Assert().Length({ max: value }), {
priority: 30,
requirementsTransformer: function () {
return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
}
});
},

@@ -164,14 +188,35 @@ length: function (array) {

min: function (value) {
return $.extend(new Validator.Assert().GreaterThanOrEqual(value), { priority: 30 });
return $.extend(new Validator.Assert().GreaterThanOrEqual(value), {
priority: 30,
requirementsTransformer: function () {
return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
}
});
},
max: function (value) {
return $.extend(new Validator.Assert().LessThanOrEqual(value), { priority: 30 });
return $.extend(new Validator.Assert().LessThanOrEqual(value), {
priority: 30,
requirementsTransformer: function () {
return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
}
});
},
range: function (array) {
return $.extend(new Validator.Assert().Range(array[0], array[1]), { priority: 32 });
return $.extend(new Validator.Assert().Range(array[0], array[1]), {
priority: 32,
requirementsTransformer: function () {
for (var i = 0; i < array.length; i++)
array[i] = 'string' === typeof array[i] && !isNaN(array[i]) ? parseInt(array[i], 10) : array[i];
return array;
}
});
},
equalto: function (identifier) {
return $.extend(new Validator.Assert().Callback(function (value, identifier) {
return value === $(identifier).val();
}, identifier), { priority: 256 });
equalto: function (value) {
return $.extend(new Validator.Assert().EqualTo(value), {
priority: 256,
requirementsTransformer: function () {
return $(value).length ? $(value).val() : value;
}
});
}

@@ -178,0 +223,0 @@ }

@@ -0,1 +1,6 @@

// AMD Compliance
if ('function' === typeof define && define.amd)
define('parsley', function() { return window.Parsley; } );
})(window.jQuery);

@@ -29,3 +29,10 @@ define(function () {

});
it.skip('should use unsubscribe()');
it('should use unsubscribe()', function () {
$('body').append('<input type="email" id="element" />');
var parsleyInstance = $('#element').parsley();
parsleyInstance.subscribe('foo', function () { return 'bar'; });
expect($.subscribed().foo.length).to.be(1);
parsleyInstance.unsubscribe('foo');
expect($.subscribed().foo.length).to.be(0);
});
it('should use reset() on field', function () {

@@ -47,3 +54,3 @@ $('body').append('<input type="email" data-parsley-pattern="[A-F][0-9]{5}" data-parsley-required id="element" />');

'</form>');
parsleyForm = new Parsley($('#element'));
var parsleyForm = new Parsley($('#element'));
parsleyForm.validate();

@@ -81,3 +88,4 @@ expect($('#parsley-id-' + $('#field1').psly().__id__ + ' li').length).to.be(1);

'</form>');
parsleyForm = new Parsley($('#element'));
var parsleyForm = new Parsley($('#element'));
var fieldEventsCount = 0;

@@ -87,6 +95,27 @@ // Test that a subscribed field event on parent form would be triggered by fields too

parsleyForm.subscribe('parsley:field:destroy', function () {
if (1 === triggered)
fieldEventsCount++;
});
parsleyForm.subscribe('parsley:form:destroy', function () {
// we properly triggered before the 2 field:destroy events for this form
expect(fieldEventsCount).to.be(2);
// we should never enter here since parsley form instance is destroyed
$.listen('parsley:form:validate', function () {
expect(true).to.be(false);
});
// test that a submit event does not trigger parsley validation anymore
$('#element').on('submit', function (e) {
e.preventDefault();
expect($('#element').data('Parsley')).to.be(undefined);
expect($('#field1').data('Parsley')).to.be(undefined);
$.unsubscribeAll('parsley:form:validate');
done();
});
triggered++;
$('#element').submit();
});

@@ -100,5 +129,2 @@

parsleyForm.destroy();
expect($('#element').data('Parsley')).to.be(undefined);
expect($('#field1').data('Parsley')).to.be(undefined);
});

@@ -105,0 +131,0 @@ afterEach(function () {

define('features/extra', [
'extra/dateiso'
'extra/validator/dateiso'
], function () {
return function (ParsleyValidator) {
describe('ParsleyExtras', function () {
describe('ParsleyExtras validators', function () {
it('should have dateiso validator', function () {

@@ -17,4 +17,42 @@ expect(window.ParsleyConfig.validators).to.have.key('dateiso');

});
it('should have a bind.js plugin allowing to give pure json validation config to parsley constructor', function (done) {
require(['extra/plugin/bind'], function () {
$('body').append(
'<form id="element" >' +
'<input type="text" name="name" />' +
'<input type="text" name="email" id="email" />' +
'<input type="checkbox" name="sexe" id="sexe" value="male" />' +
'<input type="checkbox" name="sexe" value="female" />' +
'</form>');
var parsleyInstance = $('#element').parsley({
fields: {
'[name="name"]': {
required: true,
length: [4, 20]
},
'#email': {
type: 'email'
},
'#sexe': {
required: true
}
}
});
expect($('[name="name"]').parsley().constraints.length).to.be(2);
expect($('#email').parsley().constraints.length).to.be(1);
expect($('#sexe').parsley().constraints.length).to.be(1);
expect($('#sexe').parsley().constraints[0].name).to.be('required');
done();
});
});
afterEach(function () {
if ($('#element').length)
$('#element').remove();
if ($('.parsley-errors-list').length)
$('.parsley-errors-list').remove();
});
});
};
});

@@ -47,16 +47,2 @@ define(function () {

});
it('should support select multiple', function () {
$('body').append(
'<select multiple id="element" >' +
'<option value="1">1</option>' +
'<option value="2">2</option>' +
'<option value="3">3</option>' +
'</select>');
var parsleyField = new Parsley($('#element'));
expect(parsleyField.__class__).to.be('ParsleyField');
expect(parsleyField.options.multiple).to.be('element');
expect(parsleyField.getValue()).to.be('');
$('#element option[value="1"]').attr('selected', 'selected');
expect(parsleyField.getValue()).to.be.eql(['1']);
});
it('should have a proper updateConstraint() javascript method', function () {

@@ -139,2 +125,3 @@ $('body').append('<input type="text" id="element" />');

expect(parsleyField.isValid()).to.be(true);
ParsleyValidator.removeValidator('multiple');
});

@@ -146,7 +133,13 @@ it('should properly compute constraints on each validation', function () {

}, 2);
ParsleyValidator.addValidator('multiple', function (value, multiple) {
if (!isNaN(parseFloat(value)) && isFinite(value))
return !(Number(value) % multiple);
return false;
}, 512);
var parsleyField = new Parsley($('#element'))
.addConstraint('multiple', 4)
.addConstraint('foobazer', true);
parsleyField.bindConstraints();
parsleyField.refreshConstraints();
expect(parsleyField.constraints.length).to.be(4);

@@ -160,6 +153,8 @@ $('#element').removeAttr('data-parsley-required');

expect(parsleyField.constraints.length).to.be(2);
ParsleyValidator.removeValidator('foobazer');
ParsleyValidator.removeValidator('multiple');
});
it('should handle constraints priorities on validation', function () {
$('body').append('<input type="email" pattern="[A-F][0-9]{5}" required id="element" />');
parsleyField = new Parsley($('#element'));
var parsleyField = new Parsley($('#element'));
expect(parsleyField.isValid()).to.be(false);

@@ -179,3 +174,3 @@ expect(parsleyField.validationResult.length).to.be(1);

$('body').append('<input type="email" pattern="[A-F][0-9]{5}" required id="element" />');
parsleyField = new Parsley($('#element'), { priorityEnabled: false });
var parsleyField = new Parsley($('#element'), { priorityEnabled: false });
expect(parsleyField.isValid()).to.be(false);

@@ -234,2 +229,19 @@ expect(parsleyField.validationResult.length).to.be(3);

});
it('should have a force option for validate and isValid methods', function () {
$('body').append('<input type="email" id="element" />');
expect($('#element').parsley().isValid()).to.be.eql([]);
expect($('#element').parsley().validate()).to.be.eql([]);
expect($('#element').parsley().isValid(true)).to.be(false);
expect($('#element').parsley().validate(true).length).to.be(1);
});
it('should have a trim-value option', function () {
$('body').append('<input type="text" id="element" value=" foo " />');
expect($('#element').parsley().getValue()).to.be(' foo ');
$('#element').attr('data-parsley-trim-value', true).parsley().actualizeOptions();
expect($('#element').parsley().getValue()).to.be('foo');
});
it('should properly handle null or undefined values', function () {
$('body').append('<input type="text" id="element" required value/>');
expect($('#element').parsley().isValid()).to.be(false);
});
afterEach(function () {

@@ -236,0 +248,0 @@ window.ParsleyConfig = { i18n: window.ParsleyConfig.i18n, validators: window.ParsleyConfig.validators };

@@ -17,3 +17,3 @@ define(function () {

'</form>');
parsleyForm = new Parsley($('#element'));
var parsleyForm = new Parsley($('#element'));
expect(parsleyForm.fields.length).to.be(2);

@@ -28,5 +28,6 @@ });

'<div data-parsley-validate></div>' + // ParsleyForm, not a valid child
'<input id="field3" disabled />' + // Disabled, excluded buy custom options below
'<input type="submit"/>' + // Excluded field, not valid
'</form>');
parsleyForm = new Parsley($('#element'));
var parsleyForm = new Parsley($('#element'), { excluded: '[disabled], input[type=button], input[type=submit], input[type=reset]' });
expect(parsleyForm.fields.length).to.be(2);

@@ -41,3 +42,3 @@ });

'</form>');
parsleyForm = new Parsley($('#element'));
var parsleyForm = new Parsley($('#element'));
expect(parsleyForm.fields.length).to.be(2);

@@ -57,3 +58,3 @@ expect(new Parsley('#field1').options.trigger).to.be('change');

'</form>');
parsleyForm = new Parsley($('#element'));
var parsleyForm = new Parsley($('#element'));
parsleyForm.validate();

@@ -72,3 +73,3 @@ expect(parsleyForm.validationResult).to.be(false);

'</form>');
parsleyForm = new Parsley($('#element'));
var parsleyForm = new Parsley($('#element'));
expect(parsleyForm.isValid()).to.be(false);

@@ -87,4 +88,13 @@ $('#field1').val('value');

'</form>');
parsleyForm = new Parsley($('#element'));
var parsleyForm = new Parsley($('#element'));
// parsley.remote hack because if valid, parsley remote re-send form
parsleyForm.subscribe('parsley:form:validate', function (formInstance) {
if (formInstance.asyncSupport)
formInstance.submitEvent._originalPreventDefault();
});
var event = $.Event();
// parsley.remote hack
event._originalPreventDefault = event.preventDefault;
event.preventDefault = sinon.spy();

@@ -96,7 +106,50 @@ parsleyForm.onSubmitValidate(event);

$('#field3').val('foo');
event = $.Event();
// parsley.remote hack
event._originalPreventDefault = event.preventDefault;
event.preventDefault = sinon.spy();
parsleyForm.onSubmitValidate(event);
expect(event.preventDefault.called).to.be(false);
if (!parsleyForm.asyncSupport)
expect(event.preventDefault.called).to.be(false);
else
expect(event.preventDefault.called).to.be(true);
});
it('should have a force option for validate and isValid methods', function () {
$('body').append(
'<form id="element">' +
'<input id="field1" type="email" />' +
'<input id="field3" data-parsley-notblank="true" />' +
'</form>');
expect($('#element').parsley().isValid()).to.be(true);
expect($('#element').parsley().isValid(undefined, true)).to.be(false);
expect($('#element').parsley().validate()).to.be(true);
expect($('#element').parsley().validate(undefined, true)).to.be(false);
});
it('should properly bind dynamically added fields', function () {
$('body').append('<form id="element" data-parsley-trigger="change"></form>');
$('#element').append('<input type="email" id="email" required />');
var fieldInstance = $('#email').psly();
expect(fieldInstance.__class__).to.be('ParsleyField');
var formInstance = $('#element').psly();
// form corectly have its field, and field have finaly its parent form
expect(formInstance.fields[0].$element.attr('id')).to.be('email');
expect(fieldInstance.parent.__class__).to.be('ParsleyForm');
});
it('should stop event propagation on form submit', function (done) {
$('body').append('<form id="element"><input type="text" required/></form>');
var parsleyInstance = $('#element').parsley();
$('#element').on('submit', function () {
// It sould never pass here!
expect(true).to.be(false);
});
parsleyInstance.subscribe('parsley:form:validated', function () {
done();
});
$('#element').submit();
});
afterEach(function () {

@@ -103,0 +156,0 @@ if ($('#element').length)

@@ -33,3 +33,3 @@ define(function () {

});
it('should return Parsley if instantiated on an excluded field type', function () {
it('should return Parsley instance if instantiated on an excluded field type, and do not have an errors container', function () {
$('body').append('<input type="submit" id="element" />');

@@ -39,3 +39,15 @@ var parsleyInstance = new Parsley($('#element'));

expect(parsleyInstance.__class__).to.be('Parsley');
expect($('#parsley-id-' + parsleyInstance.__id__).length).to.be(0);
});
it('should have excluded fields by default', function () {
$('body').append(
'<form id="element" >' +
'<input type="submit" />' +
'<input type="reset" />' +
'<input type="hidden" />' +
'<input type="button" />' +
'</form>');
var parsleyInstance = $('#element').parsley();
expect(parsleyInstance.fields.length).to.be(0);
});
it('should return ParsleyForm if instantiated on an unsupported element with data-parsley-validate attribute', function () {

@@ -85,19 +97,14 @@ $('body').append('<div id="element" data-parsley-validate></div>');

});
it('should not bind radio or checkboxes withoud a name, an id or a multiple option', function () {
$('body').append('<input type="radio" value="foo" />');
it('should have a jquery API returning undefined if done on a non existing element', function () {
window.console.warn = sinon.spy();
parsleyInstance = $('input[type=radio]').psly();
expect(parsleyInstance.__class__).to.be('Parsley');
expect($('#foo').parsley()).to.be(undefined);
expect(window.console.warn.called).to.be(true);
$('input[type=radio]').attr('id', 'element');
parsleyInstance = $('#element').parsley();
expect(parsleyInstance.__class__).to.be('ParsleyField');
expect(parsleyInstance.options.multiple).to.be('element');
parsleyInstance.destroy();
$('input[type=radio]').attr('name', 'element');
parsleyInstance = $('input[name=element]').parsley();
expect(parsleyInstance.__class__).to.be('ParsleyField');
expect(parsleyInstance.options.multiple).to.be('element');
$('input[name=element]').remove();
});
it('should have a jquery API that binds multiple selectors', function () {
$('body').append('<div id="element">'+
'<input type="text" id="foo" required />' +
'<input type="text" id="bar" required />' +
'</div>');
expect($('input').parsley().length).to.be(2);
});
afterEach(function () {

@@ -104,0 +111,0 @@ window.ParsleyConfig = { i18n: window.ParsleyConfig.i18n, validators: window.ParsleyConfig.validators };

define('features/remote', [
'src/parsley.remote',
'extra/plugin/remote',
], function (ParsleyExtend) {

@@ -7,3 +7,5 @@

window._remoteParsleyExtend = window.ParsleyExtend;
window.ParsleyExtend = {};
window._remoteParsleyConfig = window.ParsleyConfig;
window.ParsleyExtend = window.ParsleyExtend || {};
window.ParsleyConfig = window.ParsleyConfig || {};

@@ -15,3 +17,4 @@ return function () {

window.ParsleyExtend = window._remoteParsleyExtend;
sinon.stub($, 'ajax');
window.ParsleyConfig = window._remoteParsleyConfig;
window.ParsleyValidator.init(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
});

@@ -45,3 +48,2 @@ it('should have window.ParsleyExtend defined', function () {

it('should trigger right events on asyncValidate for form and field', function (done) {
$.listen('parsley:form:validated', function () { done(); });
$('body').append(

@@ -53,9 +55,150 @@ '<form id="element" data-parsley-trigger="change">' +

'</form>');
$('#element').psly().asyncValidate();
$('#element').psly()
.subscribe('parsley:form:validated', function () { done(); })
.asyncValidate();
});
it.skip('should handle properly validation with remote validator', function () {});
it.skip('should save some calls for querries already done');
it.skip('should handle remote reverse option');
it.skip('should handle remote options');
it('should have a force option for asyncValidate and asyncIsValid methods', function (done) {
$('body').append('<input type="email" id="element" />');
var parsleyInstance = $('#element').parsley();
parsleyInstance.asyncIsValid()
.done(function () {
parsleyInstance.asyncValidate()
.done(function () {
parsleyInstance.asyncIsValid(true)
.fail(function () {
parsleyInstance.asyncValidate(true)
.fail(function () {
done();
});
});
});
});
});
it('should handle properly validation with remote validator', function (done) {
$('body').append('<input type="text" data-parsley-remote="http://foo.bar" id="element" required name="element" value="foo" />');
var parsleyInstance = $('#element').parsley();
sinon.stub($, 'ajax').returns($.Deferred().reject({ status: 400, state: function () { return 'rejected' } }, 'error', 'error'));
parsleyInstance.asyncIsValid()
.fail(function () {
$.ajax.restore();
sinon.stub($, 'ajax').returns($.Deferred().resolve({}, 'success', { status: 200, state: function () { return 'resolved' } }));
$('#element').val('bar');
parsleyInstance.asyncIsValid()
.done(function () {
$.ajax.restore();
done();
});
});
});
it('should handle remote reverse option', function (done) {
$('body').append('<input type="text" data-parsley-remote="http://foo.bar" id="element" data-parsley-remote-reverse="true" required name="element" value="baz" />');
var parsleyInstance = $('#element').parsley();
sinon.stub($, 'ajax').returns($.Deferred().resolve({}, 'success', { status: 200, state: function () { return 'resolved' } }));
parsleyInstance.asyncIsValid()
.fail(function () {
$.ajax.restore();
sinon.stub($, 'ajax').returns($.Deferred().reject({ status: 400, state: function () { return 'rejected' } }, 'error', 'error'));
$('#element').val('bux');
parsleyInstance.asyncIsValid()
.done(function () {
$.ajax.restore();
done();
});
});
});
it('should handle remote options', function (done) {
$('body').append('<input type="text" data-parsley-remote="http://foo.bar" id="element" data-parsley-remote-options=\'{ "type": "POST", "data": {"foo": "bar"} }\' required name="element" value="baz" />');
var parsleyInstance = $('#element').parsley();
sinon.stub($, 'ajax').returns($.Deferred().resolve({}, 'success', { status: 200, state: function () { return 'resolved' } }));
parsleyInstance.asyncIsValid()
.done(function () {
expect($.ajax.calledWithMatch({ type: "POST" })).to.be(true);
expect($.ajax.calledWithMatch({ url: "http://foo.bar" })).to.be(true);
expect($.ajax.calledWithMatch({ data: { "foo": "bar", "element": "baz" } })).to.be(true);
$.ajax.restore();
done();
});
});
it('should save some calls for querries already done', function (done) {
$('body').append('<input type="text" data-parsley-remote="http://foo.bar" id="element" required name="element" value="foo" />');
var parsleyInstance = $('#element').parsley();
sinon.stub($, 'ajax').returns($.Deferred().resolve({}, 'success', { status: 200, state: function () { return 'resolved' } }));
parsleyInstance.asyncIsValid()
.done(function () {
expect($.ajax.calledOnce).to.be(true);
expect($.ajax.calledWithMatch({ data: { "element": "foo" } })).to.be(true);
$.ajax.restore();
sinon.stub($, 'ajax').returns($.Deferred().reject({ status: 400, state: function () { return 'rejected' } }, 'error', 'error'));
$('#element').val('bar');
parsleyInstance.asyncIsValid()
.fail(function () {
expect($.ajax.calledOnce).to.be(true);
expect($.ajax.calledWithMatch({ data: { "element": "bar" } })).to.be(true);
$.ajax.restore();
sinon.stub($, 'ajax').returns($.Deferred().resolve({}, 'success', { status: 200, state: function () { return 'resolved' } }));
$('#element').val('foo');
parsleyInstance.asyncIsValid()
.done(function () {
expect($.ajax.callCount).to.be(0);
expect($.ajax.calledOnce).to.be(false);
$.ajax.restore();
done();
});
});
});
});
// custom validator needed for this test is registered in `tests.js` before running this suite
it('should handle remote validator option', function (done) {
$('body').append('<input type="text" data-parsley-remote="http://foo.bar" id="element" data-parsley-remote-validator="cUSTom" required name="element" value="foobar" />');
var parsleyInstance = $('#element').parsley();
sinon.stub($, 'ajax').returns($.Deferred().resolve({}, 'success', { status: 200, state: function () { return 'resolved' } }));
parsleyInstance.asyncIsValid()
.fail(function () {
$.ajax.restore();
sinon.stub($, 'ajax').returns($.Deferred().reject({ status: 400, state: function () { return 'rejected' } }, 'error', 'error'));
$('#element').val('foobaz');
parsleyInstance.asyncIsValid()
.fail(function () {
$.ajax.restore();
sinon.stub($, 'ajax').returns($.Deferred().reject({ status: 404, state: function () { return 'rejected' } }, 'error', 'not found'));
$('#element').val('fooquux');
parsleyInstance.asyncIsValid()
.done(function () {
$.ajax.restore();
done();
});
});
});
});
it('should handle remote validator option with custom url', function (done) {
$('body').append('<input type="text" data-parsley-remote id="element" data-parsley-remote-validator="mycustom" required name="element" value="foobar" />');
var parsleyInstance = $('#element').parsley();
parsleyInstance.addAsyncValidator('mycustom', function (xhr) {
return xhr.status === 404;
}, 'http://foobar.baz');
sinon.stub($, 'ajax').returns($.Deferred().resolve({}, 'success', { status: 200, state: function () { return 'resolved' } }));
parsleyInstance.asyncIsValid()
.fail(function () {
expect($.ajax.calledWithMatch({ url: "http://foobar.baz" })).to.be(true);
$.ajax.restore();
done();
});
});
it.skip('should abort successives querries and do not handle their return');
afterEach(function () {

@@ -68,8 +211,5 @@ if ($('#element').length)

});
});
after(function () {
$.ajax.restore();
});
});
};
});

@@ -34,3 +34,9 @@ define(function () {

});
it('should add proper parsley class on success or failure', function () {
it('should handle wrong errors-container option', function () {
$('body').append('<input type="text" id="element" data-parsley-errors-container="#donotexist" />');
window.console.warn = sinon.spy();
var parsleyInstance = $('#element').psly();
expect(window.console.warn.called).to.be(true);
});
it('should add proper parsley class on success or failure (type=text)', function () {
$('body').append('<input type="text" id="element" required />');

@@ -45,2 +51,33 @@ var parsleyField = $('#element').psly();

});
it('should add proper parsley class on success or failure (type=radio)', function () {
$('body').append('<input type="radio" id="element" required />');
var parsleyField = $('#element').psly();
parsleyField.validate();
expect($('#element').parent().hasClass('parsley-error')).to.be(true);
expect($('#element').parent().hasClass('parsley-success')).to.be(false);
$('#element').attr('checked', 'checked').psly().validate();
expect($('#element').parent().hasClass('parsley-success')).to.be(true);
expect($('#element').parent().hasClass('parsley-error')).to.be(false);
});
it('should add proper parsley class on success or failure (input=checkbox)', function () {
$('body').append('<input type="checkbox" id="element" required />');
var parsleyField = $('#element').psly();
parsleyField.validate();
expect($('#element').parent().hasClass('parsley-error')).to.be(true);
expect($('#element').parent().hasClass('parsley-success')).to.be(false);
$('#element').attr('checked', 'checked').psly().validate();
expect($('#element').parent().hasClass('parsley-success')).to.be(true);
expect($('#element').parent().hasClass('parsley-error')).to.be(false);
});
it('should add proper parsley class on success or failure (select multiple)', function () {
$('body').append('<select multiple id="element" required><option value="foo">foo</option></select>');
var parsleyField = $('#element').psly();
parsleyField.validate();
expect($('#element').hasClass('parsley-error')).to.be(true);
expect($('#element').hasClass('parsley-success')).to.be(false);
$('#element option[value="foo"]').attr('selected', 'selected');
parsleyField.validate();
expect($('#element').hasClass('parsley-success')).to.be(true);
expect($('#element').hasClass('parsley-error')).to.be(false);
});
it('should handle class-handler option', function () {

@@ -94,2 +131,8 @@ $('body').append(

});
it('should show custom error message with variabilized parameters', function () {
$('body').append('<input type="text" id="element" value="bar" data-parsley-minlength="7" data-parsley-minlength-message="foo %s bar"/>');
var parsleyField = $('#element').psly();
parsleyField.validate();
expect($('ul#parsley-id-' + parsleyField.__id__ + ' li').text()).to.be('foo 7 bar');
});
it('should show custom error message for whole field', function () {

@@ -105,2 +148,9 @@ $('body').append('<input type="email" id="element" required data-parsley-error-message="baz"/>');

});
it('should display no error message if diabled', function () {
$('body').append('<input type="email" id="element" required data-parsley-errors-messages-disabled />');
var parsleyField = $('#element').psly();
parsleyField.validate();
expect($('ul#parsley-id-' + parsleyField.__id__ + ' li').length).to.be(0);
expect($('#element').hasClass('parsley-error')).to.be(true);
});
it('should handle simple triggers (change, focus..)', function () {

@@ -113,7 +163,7 @@ $('body').append('<input type="email" id="element" required data-parsley-trigger="change" />');

});
it('should auto bind error triggers on field error', function () {
$('body').append('<input type="email" id="element" required data-parsley-trigger="change" />');
it('should auto bind error trigger on selet field error (input=text)', function () {
$('body').append('<input type="email" id="element" required />');
var parsleyField = $('#element').psly();
expect($('ul#parsley-id-' + parsleyField.__id__ + ' li').length).to.be(0);
$('#element').trigger($.Event('change'));
parsleyField.validate();
expect($('ul#parsley-id-' + parsleyField.__id__ + ' li').length).to.be(1);

@@ -124,2 +174,17 @@ expect($('ul#parsley-id-' + parsleyField.__id__ + ' li').hasClass('parsley-required')).to.be(true);

});
it('should auto bind error trigger on selet field error (select)', function () {
$('body').append('<select id="element" required>'+
'<option value="">Choose</option>' +
'<option value="foo">foo</option>' +
'<option value="bar">bar</option>' +
'</select>');
var parsleyField = $('#element').psly();
expect($('ul#parsley-id-' + parsleyField.__id__ + ' li').length).to.be(0);
parsleyField.validate();
expect($('ul#parsley-id-' + parsleyField.__id__ + ' li').length).to.be(1);
expect($('ul#parsley-id-' + parsleyField.__id__ + ' li').hasClass('parsley-required')).to.be(true);
$('#element [option="foo"]').attr('selected', 'selected');
$('#element').trigger($.Event('change'));
expect($('ul#parsley-id-' + parsleyField.__id__ + ' li').hasClass('parsley-type')).to.be(false);
});
it('should handle complex triggers (keyup, keypress..)', function () {

@@ -157,3 +222,3 @@ $('body').append('<input type="email" id="element" required data-parsley-trigger="keyup" />');

'</form>');
parsleyForm = new Parsley($('#element'));
var parsleyForm = new Parsley($('#element'));
expect($('#element').attr('novalidate')).not.to.be(undefined);

@@ -199,2 +264,14 @@ });

});
it('should have a getErrorsMessage() method', function () {
$('body').append('<input type="email" id="element" value="foo" data-parsley-minlength="5" />');
var parsleyInstance = $('#element').parsley();
parsleyInstance.validate();
expect(window.ParsleyUI.getErrorsMessages(parsleyInstance).length).to.be(1);
expect(window.ParsleyUI.getErrorsMessages(parsleyInstance)[0]).to.be('This value should be a valid email.');
$('#element').attr('data-parsley-priority-enabled', false);
parsleyInstance.validate();
expect(window.ParsleyUI.getErrorsMessages(parsleyInstance).length).to.be(2);
expect(window.ParsleyUI.getErrorsMessages(parsleyInstance)[0]).to.be('This value is too short. It should have 5 characters or more.');
});
afterEach(function () {

@@ -201,0 +278,0 @@ if ($('#element').length)

@@ -57,2 +57,21 @@ define(function () {

});
it('should have a checkAttr feature for attr() method', function () {
var element = [{
attributes: [
{
specified: true,
name: "data-parsley-required-message",
value: "foo"
},
{
specified: true,
name: "data-parsley-validate",
value: true
}
]
}];
expect(ParsleyUtils.attr(element, 'data-parsley-', 'required')).to.be(false);
expect(ParsleyUtils.attr(element, 'data-parsley-', 'required-message')).to.be(true);
expect(ParsleyUtils.attr(element, 'data-parsley-', 'validate')).to.be(true);
});
it('should have a proper get() function', function () {

@@ -66,3 +85,2 @@ var object = {

expect(ParsleyUtils.get(object, 'foo.baz')).to.be(undefined);
expect(ParsleyUtils.get(object, 'foobarbaz', 'foo')).to.be('foo');
});

@@ -69,0 +87,0 @@ });

@@ -45,2 +45,4 @@ define(function () {

expect(parsleyValidator.validate('10', parsleyValidator.validators.min(6))).to.be(true);
$('body').append('<input type="text" id="element" value="7" min="2" />');
expect($('#element').parsley().isValid()).to.be(true);
});

@@ -51,4 +53,7 @@ it('should have a max validator', function () {

expect(parsleyValidator.validate('1', parsleyValidator.validators.max(10))).to.be(true);
expect(parsleyValidator.validate('1', parsleyValidator.validators.max("10"))).to.be(true);
expect(parsleyValidator.validate('10', parsleyValidator.validators.max(10))).to.be(true);
expect(parsleyValidator.validate('17', parsleyValidator.validators.max(10))).not.to.be(true);
$('body').append('<input type="text" id="element" value="7" max="20" />');
expect($('#element').parsley().isValid()).to.be(true);
});

@@ -59,2 +64,4 @@ it('should have a range validator', function () {

expect(parsleyValidator.validate('17', parsleyValidator.validators.range([5, 10]))).not.to.be(true);
$('body').append('<input type="text" id="element" value="7" max="20" min="2" />');
expect($('#element').parsley().isValid()).to.be(true);
});

@@ -87,2 +94,4 @@ it('should have a type="number" validator', function () {

expect(parsleyValidator.validate('foo$', parsleyValidator.validators.type('alphanum'))).not.to.be(true);
$('body').append('<input type="alphanum" id="element" value="v4kRRyhYvo0P" />');
expect($('#element').parsley().isValid()).to.be(true);
});

@@ -102,2 +111,6 @@ it('should have a type="url" validator', function () {

expect(parsleyValidator.validate('A', parsleyValidator.validators.pattern('[a-z]+'))).not.to.be(true);
expect(parsleyValidator.validate('a', parsleyValidator.validators.pattern('/[a-z]+/'))).to.be(true);
expect(parsleyValidator.validate('A', parsleyValidator.validators.pattern('/[a-z]+/'))).not.to.be(true);
expect(parsleyValidator.validate('a', parsleyValidator.validators.pattern('/[a-z]+/i'))).to.be(true);
expect(parsleyValidator.validate('A', parsleyValidator.validators.pattern('/[a-z]+/i'))).to.be(true);
});

@@ -112,2 +125,4 @@ it('should have a length validator', function () {

expect(parsleyValidator.validate('fo', parsleyValidator.validators.minlength(3))).not.to.be(true);
$('body').append('<input type="text" id="element" value="foo" minlength="2" />');
expect($('#element').parsley().isValid()).to.be(true);
});

@@ -117,2 +132,4 @@ it('should have a maxlength validator', function () {

expect(parsleyValidator.validate('foobar', parsleyValidator.validators.maxlength(3))).not.to.be(true);
$('body').append('<input type="text" id="element" value="foo" maxlength="10" />');
expect($('#element').parsley().isValid()).to.be(true);
});

@@ -133,6 +150,12 @@ it('should have a check validator', function () {

it('should have an equalto validator', function () {
$('body').append('<input type="text" id="element" value="foo" />');
expect(parsleyValidator.validate('', parsleyValidator.validators.equalto('#element'))).not.to.be(true);
expect(parsleyValidator.validate('bar', parsleyValidator.validators.equalto('#element'))).not.to.be(true);
expect(parsleyValidator.validate('foo', parsleyValidator.validators.equalto('#element'))).to.be(true);
expect(parsleyValidator.validate('', parsleyValidator.validators.equalto('foo'))).not.to.be(true);
expect(parsleyValidator.validate('bar', parsleyValidator.validators.equalto('foo'))).not.to.be(true);
expect(parsleyValidator.validate('foo', parsleyValidator.validators.equalto('foo'))).to.be(true);
$('body').append('<input type="text" id="element" data-parsley-equalto="#equalto" required /><input type="text" id="equalto" value="foo" />');
expect($('#element').psly().isValid()).to.be(false);
$('#element').val('fo');
expect($('#element').psly().isValid()).to.be(false);
$('#element').val('foo');
expect($('#element').psly().isValid()).to.be(true);
$('#equalto').remove();
});

@@ -139,0 +162,0 @@ it('should handle proper error message for validators', function () {

@@ -10,2 +10,3 @@ require(['config'], function () {

// setup mocha
mocha.checkLeaks();
mocha.setup('bdd');

@@ -28,2 +29,3 @@ mocha.reporter('html');

require([
'features/utils',
'features/parsley',

@@ -34,8 +36,12 @@ 'features/options',

'features/field',
'features/multiple',
'features/form',
'features/validator',
'features/ui',
'features/utils'
], function (parsleyBase, options, pubsub, abstract, field, form, validator, ui, utils) {
'features/ui'
], function (utils, parsleyBase, options, pubsub, abstract, field, multiple, form, validator, ui) {
describe('ParsleyStandard', function () {
// beforeEach(function () {
// window.ParsleyConfig = $.extend(true, {}, window.ParsleyConfig, { excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden], input[disabled]' });
// });
utils(ParsleyUtils);
parsleyBase(Parsley);

@@ -46,12 +52,34 @@ options(ParsleyOptionsFactory);

field(ParsleyField, Parsley);
multiple(Parsley);
form(ParsleyForm, Parsley);
validator(ParsleyValidator);
ui(ParsleyUI);
utils(ParsleyUtils);
});
// tested by it('should handle remote validator option') in `features/remote`
window.ParsleyExtend = {
asyncValidators: {
custom: {
fn: function (xhr) {
return xhr.status === 404;
}
}
}
};
require([
'features/remote'
], function (remote) {
remote();
'features/remote',
'features/abstract',
'features/field',
'features/form'
], function (remote, abstract, field, form) {
describe('Parsley+Remote', function () {
// beforeEach(function () {
// window.ParsleyConfig = $.extend(true, {}, window.ParsleyConfig, { excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden], input[disabled]' });
// });
remote();
abstract(Parsley);
field(ParsleyField, Parsley);
form(ParsleyForm, Parsley);
});

@@ -58,0 +86,0 @@ require([

@@ -8,4 +8,4 @@ # UPGRADE FROM 1.x to 2.0

- there is only one global `ParsleyValidator` instance. Adding / removing
validators are not made anymore on `ParsleyForm` or `ParsleyField` instances
but directly against ParsleyValidator. Same goes for errors messages
validators is not made on `ParsleyForm` or `ParsleyField` instances anymore,
but directly against `ParsleyValidator`. Same goes for errors messages.

@@ -15,4 +15,4 @@

- options is now a flat 1 dim depth object.
These options have disapered:
- `options` is now a flat 1 dim depth object.
- These options have been removed:
- `listeners`

@@ -23,3 +23,3 @@ - `validators`

- `validateIfUnchanged`
These options have been renamed:
- These options have been renamed:
- `validationMinlength` into `validationTreshold`

@@ -34,7 +34,7 @@ - `errors.classHandler` into `classHandler`

- `required` validator accepts now `false` value and become innactive
- `rangelength` validator is now renamed as `length`. Same Requirements
- `rangecheck` validator is now renamed as `check`. Same Requirements
- `notnull`, `type="urlstrict"`, `type="tel"` have disapeared from built-ins
validators
- `required` validator now accepts `false` value and becomes inactive.
- `rangelength` validator is now renamed as `length`. Same requirements.
- `rangecheck` validator is now renamed as `check`. Same requirements.
- `notnull`, `type="urlstrict"`, `type="tel"` have disappeared from built-in
validators.
- types `phone`, `urlstrict`, `dateIso` have been removed. They could be

@@ -46,7 +46,7 @@ crafted and submitted by someone in `extra/`

- `.parsley-validated` class is not added anymore on binded fields
- `.parsley-validated` class is not added anymore on bound fields
- `novalidate` attr is now automatically added to `<form>`
- `.parsley-error-list` is now `.parsley-errors-list`
- to customize `type` validator error message, you do not need anymore to add
the precise type.
- to customize `type` validator error message, you do not need to add
the precise type anymore.
eg: `parsley-type-email-message="msg"` becomes

@@ -64,5 +64,5 @@ `data-parsley-type-message="msg"`

- could be global with `$.listen()` and listen for every Parsley instance
- can now be global with `$.listen()` and listen for every Parsley instance
firing it (the way `ParsleyUI` works)
- could be Field / Form specific by using `.subscribe()` and `.unsuscribe()`
- can be Field / Form specific by using `.subscribe()` and `.unsubscribe()`
on a Parsley instance.

@@ -75,2 +75,2 @@

- parsley.extend is no more. Instead, extra validators are now placed in a
dir and could be builded with a script in a single file
dir and can be built with a script into a single file.

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc