parsley-rails 2.0.7.0 → 2.4.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -5
  3. data/lib/parsley-rails/version.rb +1 -1
  4. data/parsley-rails.gemspec +2 -2
  5. data/update.sh +3 -4
  6. data/vendor/assets/javascripts/parsley.i18n.al.js +29 -0
  7. data/vendor/assets/javascripts/parsley.i18n.ar.js +4 -8
  8. data/vendor/assets/javascripts/parsley.i18n.bg.js +4 -8
  9. data/vendor/assets/javascripts/parsley.i18n.ca.js +29 -0
  10. data/vendor/assets/javascripts/parsley.i18n.cs.extra.js +3 -3
  11. data/vendor/assets/javascripts/parsley.i18n.cs.js +6 -10
  12. data/vendor/assets/javascripts/parsley.i18n.da.js +4 -9
  13. data/vendor/assets/javascripts/parsley.i18n.de.extra.js +3 -3
  14. data/vendor/assets/javascripts/parsley.i18n.de.js +7 -8
  15. data/vendor/assets/javascripts/parsley.i18n.el.extra.js +14 -0
  16. data/vendor/assets/javascripts/parsley.i18n.el.js +29 -0
  17. data/vendor/assets/javascripts/parsley.i18n.en.extra.js +5 -4
  18. data/vendor/assets/javascripts/parsley.i18n.en.js +5 -8
  19. data/vendor/assets/javascripts/parsley.i18n.es.js +4 -6
  20. data/vendor/assets/javascripts/parsley.i18n.eu.js +29 -0
  21. data/vendor/assets/javascripts/parsley.i18n.fa.js +9 -13
  22. data/vendor/assets/javascripts/parsley.i18n.fi.extra.js +3 -3
  23. data/vendor/assets/javascripts/parsley.i18n.fi.js +5 -9
  24. data/vendor/assets/javascripts/parsley.i18n.fr.extra.js +5 -4
  25. data/vendor/assets/javascripts/parsley.i18n.fr.js +4 -8
  26. data/vendor/assets/javascripts/parsley.i18n.he.extra.js +3 -3
  27. data/vendor/assets/javascripts/parsley.i18n.he.js +4 -8
  28. data/vendor/assets/javascripts/parsley.i18n.hr.extra.js +14 -0
  29. data/vendor/assets/javascripts/parsley.i18n.hr.js +29 -0
  30. data/vendor/assets/javascripts/parsley.i18n.hu.extra.js +14 -0
  31. data/vendor/assets/javascripts/parsley.i18n.hu.js +30 -0
  32. data/vendor/assets/javascripts/parsley.i18n.id.extra.js +3 -3
  33. data/vendor/assets/javascripts/parsley.i18n.id.js +4 -8
  34. data/vendor/assets/javascripts/parsley.i18n.it.extra.js +3 -3
  35. data/vendor/assets/javascripts/parsley.i18n.it.js +4 -8
  36. data/vendor/assets/javascripts/parsley.i18n.ja.js +4 -8
  37. data/vendor/assets/javascripts/parsley.i18n.ko.js +5 -9
  38. data/vendor/assets/javascripts/parsley.i18n.lt.js +29 -0
  39. data/vendor/assets/javascripts/parsley.i18n.lv.extra.js +14 -0
  40. data/vendor/assets/javascripts/parsley.i18n.lv.js +29 -0
  41. data/vendor/assets/javascripts/{parsley.i18n.ms_MY.extra.js → parsley.i18n.ms.extra.js} +4 -4
  42. data/vendor/assets/javascripts/{parsley.i18n.ms_MY.js → parsley.i18n.ms.js} +4 -8
  43. data/vendor/assets/javascripts/parsley.i18n.nl.extra.js +3 -3
  44. data/vendor/assets/javascripts/parsley.i18n.nl.js +4 -8
  45. data/vendor/assets/javascripts/parsley.i18n.no.js +29 -0
  46. data/vendor/assets/javascripts/parsley.i18n.pl.js +19 -23
  47. data/vendor/assets/javascripts/parsley.i18n.pt-br.js +4 -8
  48. data/vendor/assets/javascripts/parsley.i18n.pt-pt.js +29 -0
  49. data/vendor/assets/javascripts/parsley.i18n.ro.extra.js +14 -0
  50. data/vendor/assets/javascripts/parsley.i18n.ro.js +29 -0
  51. data/vendor/assets/javascripts/parsley.i18n.ru.extra.js +3 -3
  52. data/vendor/assets/javascripts/parsley.i18n.ru.js +4 -13
  53. data/vendor/assets/javascripts/parsley.i18n.sl.extra.js +14 -0
  54. data/vendor/assets/javascripts/parsley.i18n.sl.js +30 -0
  55. data/vendor/assets/javascripts/parsley.i18n.sq.js +29 -0
  56. data/vendor/assets/javascripts/parsley.i18n.sv.extra.js +3 -3
  57. data/vendor/assets/javascripts/parsley.i18n.sv.js +4 -8
  58. data/vendor/assets/javascripts/parsley.i18n.th.js +4 -8
  59. data/vendor/assets/javascripts/parsley.i18n.tr.js +22 -26
  60. data/vendor/assets/javascripts/parsley.i18n.uk.extra.js +9 -0
  61. data/vendor/assets/javascripts/parsley.i18n.uk.js +29 -0
  62. data/vendor/assets/javascripts/parsley.i18n.zh_cn.extra.js +3 -3
  63. data/vendor/assets/javascripts/parsley.i18n.zh_cn.js +4 -8
  64. data/vendor/assets/javascripts/parsley.i18n.zh_tw.js +16 -20
  65. data/vendor/assets/javascripts/parsley.js +1970 -1673
  66. data/vendor/assets/javascripts/parsley.min.js +18 -0
  67. metadata +27 -6
  68. data/vendor/assets/javascripts/parsley.remote.js +0 -2347
@@ -0,0 +1,18 @@
1
+ /*!
2
+ * Parsley.js
3
+ * Version 2.4.4 - built Thu, Aug 4th 2016, 9:54 pm
4
+ * http://parsleyjs.org
5
+ * Guillaume Potier - <guillaume@wisembly.com>
6
+ * Marc-Andre Lafortune - <petroselinum@marc-andre.ca>
7
+ * MIT Licensed
8
+ */
9
+ function _toConsumableArray(e){if(Array.isArray(e)){for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}return Array.from(e)}var _slice=Array.prototype.slice;!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],t):e.parsley=t(e.jQuery)}(this,function(e){"use strict";function t(e,t){return e.parsleyAdaptedCallback||(e.parsleyAdaptedCallback=function(){var i=Array.prototype.slice.call(arguments,0);i.unshift(this),e.apply(t||R,i)}),e.parsleyAdaptedCallback}function i(e){return 0===e.lastIndexOf(q,0)?e.substr(q.length):e}/**
10
+ * inputevent - Alleviate browser bugs for input events
11
+ * https://github.com/marcandre/inputevent
12
+ * @version v0.0.3 - (built Thu, Apr 14th 2016, 5:58 pm)
13
+ * @author Marc-Andre Lafortune <github@marc-andre.ca>
14
+ * @license MIT
15
+ */
16
+ function n(){var t=this,i=window||global;e.extend(this,{isNativeEvent:function(e){return e.originalEvent&&e.originalEvent.isTrusted!==!1},fakeInputEvent:function(i){t.isNativeEvent(i)&&e(i.target).trigger("input")},misbehaves:function(i){t.isNativeEvent(i)&&(t.behavesOk(i),e(document).on("change.inputevent",i.data.selector,t.fakeInputEvent),t.fakeInputEvent(i))},behavesOk:function(i){t.isNativeEvent(i)&&e(document).off("input.inputevent",i.data.selector,t.behavesOk).off("change.inputevent",i.data.selector,t.misbehaves)},install:function(){if(!i.inputEventPatched){i.inputEventPatched="0.0.3";for(var n=["select",'input[type="checkbox"]','input[type="radio"]','input[type="file"]'],r=0;r<n.length;r++){var s=n[r];e(document).on("input.inputevent",s,{selector:s},t.behavesOk).on("change.inputevent",s,{selector:s},t.misbehaves)}}},uninstall:function(){delete i.inputEventPatched,e(document).off(".inputevent")}})}var r=1,s={},a={attr:function(e,t,i){var n,r,s,a=new RegExp("^"+t,"i");if("undefined"==typeof i)i={};else for(n in i)i.hasOwnProperty(n)&&delete i[n];if("undefined"==typeof e||"undefined"==typeof e[0])return i;for(s=e[0].attributes,n=s.length;n--;)r=s[n],r&&r.specified&&a.test(r.name)&&(i[this.camelize(r.name.slice(t.length))]=this.deserializeValue(r.value));return i},checkAttr:function(e,t,i){return e.is("["+t+i+"]")},setAttr:function(e,t,i,n){e[0].setAttribute(this.dasherize(t+i),String(n))},generateID:function(){return""+r++},deserializeValue:function(t){var i;try{return t?"true"==t||("false"==t?!1:"null"==t?null:isNaN(i=Number(t))?/^[\[\{]/.test(t)?e.parseJSON(t):t:i):t}catch(n){return t}},camelize:function(e){return e.replace(/-+(.)?/g,function(e,t){return t?t.toUpperCase():""})},dasherize:function(e){return e.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()},warn:function(){var e;window.console&&"function"==typeof window.console.warn&&(e=window.console).warn.apply(e,arguments)},warnOnce:function(e){s[e]||(s[e]=!0,this.warn.apply(this,arguments))},_resetWarnings:function(){s={}},trimString:function(e){return e.replace(/^\s+|\s+$/g,"")},namespaceEvents:function(t,i){return t=this.trimString(t||"").split(/\s+/),t[0]?e.map(t,function(e){return e+"."+i}).join(" "):""},difference:function(t,i){var n=[];return e.each(t,function(e,t){-1==i.indexOf(t)&&n.push(t)}),n},all:function(t){return e.when.apply(e,_toConsumableArray(t).concat([42,42]))},objectCreate:Object.create||function(){var e=function(){};return function(t){if(arguments.length>1)throw Error("Second argument not supported");if("object"!=typeof t)throw TypeError("Argument must be an object");e.prototype=t;var i=new e;return e.prototype=null,i}}(),_SubmitSelector:'input[type="submit"], button:submit'},o=a,l={namespace:"data-parsley-",inputs:"input, textarea, select",excluded:"input[type=button], input[type=submit], input[type=reset], input[type=hidden]",priorityEnabled:!0,multiple:null,group:null,uiEnabled:!0,validationThreshold:3,focus:"first",trigger:!1,triggerAfterFailure:"input",errorClass:"parsley-error",successClass:"parsley-success",classHandler:function(e){},errorsContainer:function(e){},errorsWrapper:'<ul class="parsley-errors-list"></ul>',errorTemplate:"<li></li>"},u=function(){this.__id__=o.generateID()};u.prototype={asyncSupport:!0,_pipeAccordingToValidationResult:function(){var t=this,i=function(){var i=e.Deferred();return!0!==t.validationResult&&i.reject(),i.resolve().promise()};return[i,i]},actualizeOptions:function(){return o.attr(this.$element,this.options.namespace,this.domOptions),this.parent&&this.parent.actualizeOptions&&this.parent.actualizeOptions(),this},_resetOptions:function(e){this.domOptions=o.objectCreate(this.parent.options),this.options=o.objectCreate(this.domOptions);for(var t in e)e.hasOwnProperty(t)&&(this.options[t]=e[t]);this.actualizeOptions()},_listeners:null,on:function(e,t){this._listeners=this._listeners||{};var i=this._listeners[e]=this._listeners[e]||[];return i.push(t),this},subscribe:function(t,i){e.listenTo(this,t.toLowerCase(),i)},off:function(e,t){var i=this._listeners&&this._listeners[e];if(i)if(t)for(var n=i.length;n--;)i[n]===t&&i.splice(n,1);else delete this._listeners[e];return this},unsubscribe:function(t,i){e.unsubscribeTo(this,t.toLowerCase())},trigger:function(e,t,i){t=t||this;var n,r=this._listeners&&this._listeners[e];if(r)for(var s=r.length;s--;)if(n=r[s].call(t,t,i),n===!1)return n;return this.parent?this.parent.trigger(e,t,i):!0},reset:function(){if("ParsleyForm"!==this.__class__)return this._resetUI(),this._trigger("reset");for(var e=0;e<this.fields.length;e++)this.fields[e].reset();this._trigger("reset")},destroy:function(){if(this._destroyUI(),"ParsleyForm"!==this.__class__)return this.$element.removeData("Parsley"),this.$element.removeData("ParsleyFieldMultiple"),void this._trigger("destroy");for(var e=0;e<this.fields.length;e++)this.fields[e].destroy();this.$element.removeData("Parsley"),this._trigger("destroy")},asyncIsValid:function(e,t){return o.warnOnce("asyncIsValid is deprecated; please use whenValid instead"),this.whenValid({group:e,force:t})},_findRelated:function(){return this.options.multiple?this.parent.$element.find("["+this.options.namespace+'multiple="'+this.options.multiple+'"]'):this.$element}};var d={string:function(e){return e},integer:function(e){if(isNaN(e))throw'Requirement is not an integer: "'+e+'"';return parseInt(e,10)},number:function(e){if(isNaN(e))throw'Requirement is not a number: "'+e+'"';return parseFloat(e)},reference:function(t){var i=e(t);if(0===i.length)throw'No such reference: "'+t+'"';return i},"boolean":function(e){return"false"!==e},object:function(e){return o.deserializeValue(e)},regexp:function(e){var t="";return/^\/.*\/(?:[gimy]*)$/.test(e)?(t=e.replace(/.*\/([gimy]*)$/,"$1"),e=e.replace(new RegExp("^/(.*?)/"+t+"$"),"$1")):e="^"+e+"$",new RegExp(e,t)}},h=function(e,t){var i=e.match(/^\s*\[(.*)\]\s*$/);if(!i)throw'Requirement is not an array: "'+e+'"';var n=i[1].split(",").map(o.trimString);if(n.length!==t)throw"Requirement has "+n.length+" values when "+t+" are needed";return n},p=function(e,t){var i=d[e||"string"];if(!i)throw'Unknown requirement specification: "'+e+'"';return i(t)},c=function(e,t,i){var n=null,r={};for(var s in e)if(s){var a=i(s);"string"==typeof a&&(a=p(e[s],a)),r[s]=a}else n=p(e[s],t);return[n,r]},f=function(t){e.extend(!0,this,t)};f.prototype={validate:function(t,i){if(this.fn)return arguments.length>3&&(i=[].slice.call(arguments,1,-1)),this.fn.call(this,t,i);if(e.isArray(t)){if(!this.validateMultiple)throw"Validator `"+this.name+"` does not handle multiple values";return this.validateMultiple.apply(this,arguments)}if(this.validateNumber)return isNaN(t)?!1:(arguments[0]=parseFloat(arguments[0]),this.validateNumber.apply(this,arguments));if(this.validateString)return this.validateString.apply(this,arguments);throw"Validator `"+this.name+"` only handles multiple values"},parseRequirements:function(t,i){if("string"!=typeof t)return e.isArray(t)?t:[t];var n=this.requirementType;if(e.isArray(n)){for(var r=h(t,n.length),s=0;s<r.length;s++)r[s]=p(n[s],r[s]);return r}return e.isPlainObject(n)?c(n,t,i):[p(n,t)]},requirementType:"string",priority:2};var m=function(e,t){this.__class__="ParsleyValidatorRegistry",this.locale="en",this.init(e||{},t||{})},g={email:/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,number:/^-?(\d*\.)?\d+(e[-+]?\d+)?$/i,integer:/^-?\d+$/,digits:/^\d+$/,alphanum:/^\w+$/i,url:new RegExp("^(?:(?:https?|ftp)://)?(?:\\S+(?::\\S*)?@)?(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:/\\S*)?$","i")};g.range=g.number;var v=function(e){var t=(""+e).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);return t?Math.max(0,(t[1]?t[1].length:0)-(t[2]?+t[2]:0)):0};m.prototype={init:function(t,i){this.catalog=i,this.validators=e.extend({},this.validators);for(var n in t)this.addValidator(n,t[n].fn,t[n].priority);window.Parsley.trigger("parsley:validator:init")},setLocale:function(e){if("undefined"==typeof this.catalog[e])throw new Error(e+" is not available in the catalog");return this.locale=e,this},addCatalog:function(e,t,i){return"object"==typeof t&&(this.catalog[e]=t),!0===i?this.setLocale(e):this},addMessage:function(e,t,i){return"undefined"==typeof this.catalog[e]&&(this.catalog[e]={}),this.catalog[e][t]=i,this},addMessages:function(e,t){for(var i in t)this.addMessage(e,i,t[i]);return this},addValidator:function(e,t,i){if(this.validators[e])o.warn('Validator "'+e+'" is already defined.');else if(l.hasOwnProperty(e))return void o.warn('"'+e+'" is a restricted keyword and is not a valid validator name.');return this._setValidator.apply(this,arguments)},updateValidator:function(e,t,i){return this.validators[e]?this._setValidator.apply(this,arguments):(o.warn('Validator "'+e+'" is not already defined.'),this.addValidator.apply(this,arguments))},removeValidator:function(e){return this.validators[e]||o.warn('Validator "'+e+'" is not defined.'),delete this.validators[e],this},_setValidator:function(e,t,i){"object"!=typeof t&&(t={fn:t,priority:i}),t.validate||(t=new f(t)),this.validators[e]=t;for(var n in t.messages||{})this.addMessage(n,e,t.messages[n]);return this},getErrorMessage:function(e){var t;if("type"===e.name){var i=this.catalog[this.locale][e.name]||{};t=i[e.requirements]}else t=this.formatMessage(this.catalog[this.locale][e.name],e.requirements);return t||this.catalog[this.locale].defaultMessage||this.catalog.en.defaultMessage},formatMessage:function(e,t){if("object"==typeof t){for(var i in t)e=this.formatMessage(e,t[i]);return e}return"string"==typeof e?e.replace(/%s/i,t):""},validators:{notblank:{validateString:function(e){return/\S/.test(e)},priority:2},required:{validateMultiple:function(e){return e.length>0},validateString:function(e){return/\S/.test(e)},priority:512},type:{validateString:function(e,t){var i=arguments.length<=2||void 0===arguments[2]?{}:arguments[2],n=i.step,r=void 0===n?"1":n,s=i.base,a=void 0===s?0:s,o=g[t];if(!o)throw new Error("validator type `"+t+"` is not supported");if(!o.test(e))return!1;if("number"===t&&!/^any$/i.test(r||"")){var l=Number(e),u=Math.max(v(r),v(a));if(v(l)>u)return!1;var d=function(e){return Math.round(e*Math.pow(10,u))};if((d(l)-d(a))%d(r)!=0)return!1}return!0},requirementType:{"":"string",step:"string",base:"number"},priority:256},pattern:{validateString:function(e,t){return t.test(e)},requirementType:"regexp",priority:64},minlength:{validateString:function(e,t){return e.length>=t},requirementType:"integer",priority:30},maxlength:{validateString:function(e,t){return e.length<=t},requirementType:"integer",priority:30},length:{validateString:function(e,t,i){return e.length>=t&&e.length<=i},requirementType:["integer","integer"],priority:30},mincheck:{validateMultiple:function(e,t){return e.length>=t},requirementType:"integer",priority:30},maxcheck:{validateMultiple:function(e,t){return e.length<=t},requirementType:"integer",priority:30},check:{validateMultiple:function(e,t,i){return e.length>=t&&e.length<=i},requirementType:["integer","integer"],priority:30},min:{validateNumber:function(e,t){return e>=t},requirementType:"number",priority:30},max:{validateNumber:function(e,t){return t>=e},requirementType:"number",priority:30},range:{validateNumber:function(e,t,i){return e>=t&&i>=e},requirementType:["number","number"],priority:30},equalto:{validateString:function(t,i){var n=e(i);return n.length?t===n.val():t===i},priority:256}}};var y={},_=function k(e,t,i){for(var n=[],r=[],s=0;s<e.length;s++){for(var a=!1,o=0;o<t.length;o++)if(e[s].assert.name===t[o].assert.name){a=!0;break}a?r.push(e[s]):n.push(e[s])}return{kept:r,added:n,removed:i?[]:k(t,e,!0).added}};y.Form={_actualizeTriggers:function(){var e=this;this.$element.on("submit.Parsley",function(t){e.onSubmitValidate(t)}),this.$element.on("click.Parsley",o._SubmitSelector,function(t){e.onSubmitButton(t)}),!1!==this.options.uiEnabled&&this.$element.attr("novalidate","")},focus:function(){if(this._focusedField=null,!0===this.validationResult||"none"===this.options.focus)return null;for(var e=0;e<this.fields.length;e++){var t=this.fields[e];if(!0!==t.validationResult&&t.validationResult.length>0&&"undefined"==typeof t.options.noFocus&&(this._focusedField=t.$element,"first"===this.options.focus))break}return null===this._focusedField?null:this._focusedField.focus()},_destroyUI:function(){this.$element.off(".Parsley")}},y.Field={_reflowUI:function(){if(this._buildUI(),this._ui){var e=_(this.validationResult,this._ui.lastValidationResult);this._ui.lastValidationResult=this.validationResult,this._manageStatusClass(),this._manageErrorsMessages(e),this._actualizeTriggers(),!e.kept.length&&!e.added.length||this._failedOnce||(this._failedOnce=!0,this._actualizeTriggers())}},getErrorsMessages:function(){if(!0===this.validationResult)return[];for(var e=[],t=0;t<this.validationResult.length;t++)e.push(this.validationResult[t].errorMessage||this._getErrorMessage(this.validationResult[t].assert));return e},addError:function(e){var t=arguments.length<=1||void 0===arguments[1]?{}:arguments[1],i=t.message,n=t.assert,r=t.updateClass,s=void 0===r?!0:r;this._buildUI(),this._addError(e,{message:i,assert:n}),s&&this._errorClass()},updateError:function(e){var t=arguments.length<=1||void 0===arguments[1]?{}:arguments[1],i=t.message,n=t.assert,r=t.updateClass,s=void 0===r?!0:r;this._buildUI(),this._updateError(e,{message:i,assert:n}),s&&this._errorClass()},removeError:function(e){var t=arguments.length<=1||void 0===arguments[1]?{}:arguments[1],i=t.updateClass,n=void 0===i?!0:i;this._buildUI(),this._removeError(e),n&&this._manageStatusClass()},_manageStatusClass:function(){this.hasConstraints()&&this.needsValidation()&&!0===this.validationResult?this._successClass():this.validationResult.length>0?this._errorClass():this._resetClass()},_manageErrorsMessages:function(t){if("undefined"==typeof this.options.errorsMessagesDisabled){if("undefined"!=typeof this.options.errorMessage)return t.added.length||t.kept.length?(this._insertErrorWrapper(),0===this._ui.$errorsWrapper.find(".parsley-custom-error-message").length&&this._ui.$errorsWrapper.append(e(this.options.errorTemplate).addClass("parsley-custom-error-message")),this._ui.$errorsWrapper.addClass("filled").find(".parsley-custom-error-message").html(this.options.errorMessage)):this._ui.$errorsWrapper.removeClass("filled").find(".parsley-custom-error-message").remove();for(var i=0;i<t.removed.length;i++)this._removeError(t.removed[i].assert.name);for(i=0;i<t.added.length;i++)this._addError(t.added[i].assert.name,{message:t.added[i].errorMessage,assert:t.added[i].assert});for(i=0;i<t.kept.length;i++)this._updateError(t.kept[i].assert.name,{message:t.kept[i].errorMessage,assert:t.kept[i].assert})}},_addError:function(t,i){var n=i.message,r=i.assert;this._insertErrorWrapper(),this._ui.$errorsWrapper.addClass("filled").append(e(this.options.errorTemplate).addClass("parsley-"+t).html(n||this._getErrorMessage(r)))},_updateError:function(e,t){var i=t.message,n=t.assert;this._ui.$errorsWrapper.addClass("filled").find(".parsley-"+e).html(i||this._getErrorMessage(n))},_removeError:function(e){this._ui.$errorsWrapper.removeClass("filled").find(".parsley-"+e).remove()},_getErrorMessage:function(e){var t=e.name+"Message";return"undefined"!=typeof this.options[t]?window.Parsley.formatMessage(this.options[t],e.requirements):window.Parsley.getErrorMessage(e)},_buildUI:function(){if(!this._ui&&!1!==this.options.uiEnabled){var t={};this.$element.attr(this.options.namespace+"id",this.__id__),t.$errorClassHandler=this._manageClassHandler(),t.errorsWrapperId="parsley-id-"+(this.options.multiple?"multiple-"+this.options.multiple:this.__id__),t.$errorsWrapper=e(this.options.errorsWrapper).attr("id",t.errorsWrapperId),t.lastValidationResult=[],t.validationInformationVisible=!1,this._ui=t}},_manageClassHandler:function(){if("string"==typeof this.options.classHandler&&e(this.options.classHandler).length)return e(this.options.classHandler);var t=this.options.classHandler.call(this,this);return"undefined"!=typeof t&&t.length?t:this._inputHolder()},_inputHolder:function(){return!this.options.multiple||this.$element.is("select")?this.$element:this.$element.parent()},_insertErrorWrapper:function(){var t;if(0!==this._ui.$errorsWrapper.parent().length)return this._ui.$errorsWrapper.parent();if("string"==typeof this.options.errorsContainer){if(e(this.options.errorsContainer).length)return e(this.options.errorsContainer).append(this._ui.$errorsWrapper);o.warn("The errors container `"+this.options.errorsContainer+"` does not exist in DOM")}else"function"==typeof this.options.errorsContainer&&(t=this.options.errorsContainer.call(this,this));return"undefined"!=typeof t&&t.length?t.append(this._ui.$errorsWrapper):this._inputHolder().after(this._ui.$errorsWrapper)},_actualizeTriggers:function(){var e,t=this,i=this._findRelated();i.off(".Parsley"),this._failedOnce?i.on(o.namespaceEvents(this.options.triggerAfterFailure,"Parsley"),function(){t.validate()}):(e=o.namespaceEvents(this.options.trigger,"Parsley"))&&i.on(e,function(e){t._eventValidate(e)})},_eventValidate:function(e){!(!/key|input/.test(e.type)||this._ui&&this._ui.validationInformationVisible)&&this.getValue().length<=this.options.validationThreshold||this.validate()},_resetUI:function(){this._failedOnce=!1,this._actualizeTriggers(),"undefined"!=typeof this._ui&&(this._ui.$errorsWrapper.removeClass("filled").children().remove(),this._resetClass(),this._ui.lastValidationResult=[],this._ui.validationInformationVisible=!1)},_destroyUI:function(){this._resetUI(),"undefined"!=typeof this._ui&&this._ui.$errorsWrapper.remove(),delete this._ui},_successClass:function(){this._ui.validationInformationVisible=!0,this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass)},_errorClass:function(){this._ui.validationInformationVisible=!0,this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass)},_resetClass:function(){this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass)}};var w=function(t,i,n){this.__class__="ParsleyForm",this.$element=e(t),this.domOptions=i,this.options=n,this.parent=window.Parsley,this.fields=[],this.validationResult=null},b={pending:null,resolved:!0,rejected:!1};w.prototype={onSubmitValidate:function(e){var t=this;if(!0!==e.parsley){var i=this._$submitSource||this.$element.find(o._SubmitSelector).first();if(this._$submitSource=null,this.$element.find(".parsley-synthetic-submit-button").prop("disabled",!0),!i.is("[formnovalidate]")){var n=this.whenValidate({event:e});"resolved"===n.state()&&!1!==this._trigger("submit")||(e.stopImmediatePropagation(),e.preventDefault(),"pending"===n.state()&&n.done(function(){t._submit(i)}))}}},onSubmitButton:function(t){this._$submitSource=e(t.currentTarget)},_submit:function(t){if(!1!==this._trigger("submit")){if(t){var i=this.$element.find(".parsley-synthetic-submit-button").prop("disabled",!1);0===i.length&&(i=e('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element)),i.attr({name:t.attr("name"),value:t.attr("value")})}this.$element.trigger(e.extend(e.Event("submit"),{parsley:!0}))}},validate:function(t){if(arguments.length>=1&&!e.isPlainObject(t)){o.warnOnce("Calling validate on a parsley form without passing arguments as an object is deprecated.");var i=_slice.call(arguments),n=i[0],r=i[1],s=i[2];t={group:n,force:r,event:s}}return b[this.whenValidate(t).state()]},whenValidate:function(){var t,i=this,n=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],r=n.group,s=n.force,a=n.event;this.submitEvent=a,a&&(this.submitEvent=e.extend({},a,{preventDefault:function(){o.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`"),i.validationResult=!1}})),this.validationResult=!0,this._trigger("validate"),this._refreshFields();var l=this._withoutReactualizingFormOptions(function(){return e.map(i.fields,function(e){return e.whenValidate({force:s,group:r})})});return(t=o.all(l).done(function(){i._trigger("success")}).fail(function(){i.validationResult=!1,i.focus(),i._trigger("error")}).always(function(){i._trigger("validated")})).pipe.apply(t,_toConsumableArray(this._pipeAccordingToValidationResult()))},isValid:function(t){if(arguments.length>=1&&!e.isPlainObject(t)){o.warnOnce("Calling isValid on a parsley form without passing arguments as an object is deprecated.");var i=_slice.call(arguments),n=i[0],r=i[1];t={group:n,force:r}}return b[this.whenValid(t).state()]},whenValid:function(){var t=this,i=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],n=i.group,r=i.force;this._refreshFields();var s=this._withoutReactualizingFormOptions(function(){return e.map(t.fields,function(e){return e.whenValid({group:n,force:r})})});return o.all(s)},_refreshFields:function(){return this.actualizeOptions()._bindFields()},_bindFields:function(){var t=this,i=this.fields;return this.fields=[],this.fieldsMappedById={},this._withoutReactualizingFormOptions(function(){t.$element.find(t.options.inputs).not(t.options.excluded).each(function(e,i){var n=new window.Parsley.Factory(i,{},t);"ParsleyField"!==n.__class__&&"ParsleyFieldMultiple"!==n.__class__||!0===n.options.excluded||"undefined"==typeof t.fieldsMappedById[n.__class__+"-"+n.__id__]&&(t.fieldsMappedById[n.__class__+"-"+n.__id__]=n,t.fields.push(n))}),e.each(o.difference(i,t.fields),function(e,t){t._trigger("reset")})}),this},_withoutReactualizingFormOptions:function(e){var t=this.actualizeOptions;this.actualizeOptions=function(){return this};var i=e();return this.actualizeOptions=t,i},_trigger:function(e){return this.trigger("form:"+e)}};var F=function(t,i,n,r,s){if(!/ParsleyField/.test(t.__class__))throw new Error("ParsleyField or ParsleyFieldMultiple instance expected");var a=window.Parsley._validatorRegistry.validators[i],o=new f(a);e.extend(this,{validator:o,name:i,requirements:n,priority:r||t.options[i+"Priority"]||o.priority,isDomConstraint:!0===s}),this._parseRequirements(t.options)},C=function(e){var t=e[0].toUpperCase();return t+e.slice(1)};F.prototype={validate:function(e,t){var i;return(i=this.validator).validate.apply(i,[e].concat(_toConsumableArray(this.requirementList),[t]))},_parseRequirements:function(e){var t=this;this.requirementList=this.validator.parseRequirements(this.requirements,function(i){return e[t.name+C(i)]})}};var $=function(t,i,n,r){this.__class__="ParsleyField",this.$element=e(t),"undefined"!=typeof r&&(this.parent=r),this.options=n,this.domOptions=i,this.constraints=[],this.constraintsByName={},this.validationResult=!0,this._bindConstraints()},x={pending:null,resolved:!0,rejected:!1};$.prototype={validate:function(t){arguments.length>=1&&!e.isPlainObject(t)&&(o.warnOnce("Calling validate on a parsley field without passing arguments as an object is deprecated."),t={options:t});var i=this.whenValidate(t);if(!i)return!0;switch(i.state()){case"pending":return null;case"resolved":return!0;case"rejected":return this.validationResult}},whenValidate:function(){var e,t=this,i=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],n=i.force,r=i.group;return this.refreshConstraints(),!r||this._isInGroup(r)?(this.value=this.getValue(),this._trigger("validate"),(e=this.whenValid({force:n,value:this.value,_refreshed:!0}).always(function(){t._reflowUI()}).done(function(){t._trigger("success")}).fail(function(){t._trigger("error")}).always(function(){t._trigger("validated")})).pipe.apply(e,_toConsumableArray(this._pipeAccordingToValidationResult()))):void 0},hasConstraints:function(){return 0!==this.constraints.length},needsValidation:function(e){return"undefined"==typeof e&&(e=this.getValue()),!(!e.length&&!this._isRequired()&&"undefined"==typeof this.options.validateIfEmpty)},_isInGroup:function(t){return e.isArray(this.options.group)?-1!==e.inArray(t,this.options.group):this.options.group===t},isValid:function(t){if(arguments.length>=1&&!e.isPlainObject(t)){o.warnOnce("Calling isValid on a parsley field without passing arguments as an object is deprecated.");var i=_slice.call(arguments),n=i[0],r=i[1];t={force:n,value:r}}var s=this.whenValid(t);return s?x[s.state()]:!0},whenValid:function(){var t=this,i=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],n=i.force,r=void 0===n?!1:n,s=i.value,a=i.group,l=i._refreshed;if(l||this.refreshConstraints(),!a||this._isInGroup(a)){if(this.validationResult=!0,!this.hasConstraints())return e.when();if("undefined"!=typeof s&&null!==s||(s=this.getValue()),!this.needsValidation(s)&&!0!==r)return e.when();var u=this._getGroupedConstraints(),d=[];return e.each(u,function(i,n){var r=o.all(e.map(n,function(e){return t._validateConstraint(s,e)}));return d.push(r),"rejected"===r.state()?!1:void 0}),o.all(d)}},_validateConstraint:function(t,i){var n=this,r=i.validate(t,this);return!1===r&&(r=e.Deferred().reject()),o.all([r]).fail(function(e){n.validationResult instanceof Array||(n.validationResult=[]),n.validationResult.push({assert:i,errorMessage:"string"==typeof e&&e})})},getValue:function(){var e;return e="function"==typeof this.options.value?this.options.value(this):"undefined"!=typeof this.options.value?this.options.value:this.$element.val(),"undefined"==typeof e||null===e?"":this._handleWhitespace(e)},refreshConstraints:function(){return this.actualizeOptions()._bindConstraints()},addConstraint:function(e,t,i,n){if(window.Parsley._validatorRegistry.validators[e]){var r=new F(this,e,t,i,n);"undefined"!==this.constraintsByName[r.name]&&this.removeConstraint(r.name),this.constraints.push(r),this.constraintsByName[r.name]=r}return this},removeConstraint:function(e){for(var t=0;t<this.constraints.length;t++)if(e===this.constraints[t].name){this.constraints.splice(t,1);break}return delete this.constraintsByName[e],this},updateConstraint:function(e,t,i){return this.removeConstraint(e).addConstraint(e,t,i)},_bindConstraints:function(){for(var e=[],t={},i=0;i<this.constraints.length;i++)!1===this.constraints[i].isDomConstraint&&(e.push(this.constraints[i]),t[this.constraints[i].name]=this.constraints[i]);this.constraints=e,this.constraintsByName=t;for(var n in this.options)this.addConstraint(n,this.options[n],void 0,!0);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),"undefined"!=typeof this.$element.attr("minlength")&&"undefined"!=typeof this.$element.attr("maxlength")?this.addConstraint("length",[this.$element.attr("minlength"),this.$element.attr("maxlength")],void 0,!0):"undefined"!=typeof this.$element.attr("minlength")?this.addConstraint("minlength",this.$element.attr("minlength"),void 0,!0):"undefined"!=typeof this.$element.attr("maxlength")&&this.addConstraint("maxlength",this.$element.attr("maxlength"),void 0,!0);var e=this.$element.attr("type");return"undefined"==typeof e?this:"number"===e?this.addConstraint("type",["number",{step:this.$element.attr("step"),base:this.$element.attr("min")||this.$element.attr("value")}],void 0,!0):/^(email|url|range)$/i.test(e)?this.addConstraint("type",e,void 0,!0):this},_isRequired:function(){return"undefined"==typeof this.constraintsByName.required?!1:!1!==this.constraintsByName.required.requirements},_trigger:function(e){return this.trigger("field:"+e)},_handleWhitespace:function(e){return!0===this.options.trimValue&&o.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"'),"squish"===this.options.whitespace&&(e=e.replace(/\s{2,}/g," ")),"trim"!==this.options.whitespace&&"squish"!==this.options.whitespace&&!0!==this.options.trimValue||(e=o.trimString(e)),e},_getGroupedConstraints:function(){if(!1===this.options.priorityEnabled)return[this.constraints];for(var e=[],t={},i=0;i<this.constraints.length;i++){var n=this.constraints[i].priority;t[n]||e.push(t[n]=[]),t[n].push(this.constraints[i])}return e.sort(function(e,t){return t[0].priority-e[0].priority}),e}};var E=$,P=function(){this.__class__="ParsleyFieldMultiple"};P.prototype={addElement:function(e){return this.$elements.push(e),this},refreshConstraints:function(){var t;if(this.constraints=[],this.$element.is("select"))return this.actualizeOptions()._bindConstraints(),this;for(var i=0;i<this.$elements.length;i++)if(e("html").has(this.$elements[i]).length){t=this.$elements[i].data("ParsleyFieldMultiple").refreshConstraints().constraints;for(var n=0;n<t.length;n++)this.addConstraint(t[n].name,t[n].requirements,t[n].priority,t[n].isDomConstraint)}else this.$elements.splice(i,1);return this},getValue:function(){if("function"==typeof this.options.value)return this.options.value(this);if("undefined"!=typeof this.options.value)return this.options.value;if(this.$element.is("input[type=radio]"))return this._findRelated().filter(":checked").val()||"";if(this.$element.is("input[type=checkbox]")){var t=[];return this._findRelated().filter(":checked").each(function(){t.push(e(this).val())}),t}return this.$element.is("select")&&null===this.$element.val()?[]:this.$element.val()},_init:function(){return this.$elements=[this.$element],this}};var V=function(t,i,n){this.$element=e(t);var r=this.$element.data("Parsley");if(r)return"undefined"!=typeof n&&r.parent===window.Parsley&&(r.parent=n,r._resetOptions(r.options)),"object"==typeof i&&e.extend(r.options,i),r;if(!this.$element.length)throw new Error("You must bind Parsley on an existing element.");if("undefined"!=typeof n&&"ParsleyForm"!==n.__class__)throw new Error("Parent instance must be a ParsleyForm instance");return this.parent=n||window.Parsley,this.init(i)};V.prototype={init:function(e){return this.__class__="Parsley",this.__version__="2.4.4",this.__id__=o.generateID(),this._resetOptions(e),this.$element.is("form")||o.checkAttr(this.$element,this.options.namespace,"validate")&&!this.$element.is(this.options.inputs)?this.bind("parsleyForm"):this.isMultiple()?this.handleMultiple():this.bind("parsleyField")},isMultiple:function(){return this.$element.is("input[type=radio], input[type=checkbox]")||this.$element.is("select")&&"undefined"!=typeof this.$element.attr("multiple")},handleMultiple:function(){var t,i,n=this;if(this.options.multiple||("undefined"!=typeof this.$element.attr("name")&&this.$element.attr("name").length?this.options.multiple=t=this.$element.attr("name"):"undefined"!=typeof this.$element.attr("id")&&this.$element.attr("id").length&&(this.options.multiple=this.$element.attr("id"))),
17
+ this.$element.is("select")&&"undefined"!=typeof this.$element.attr("multiple"))return this.options.multiple=this.options.multiple||this.__id__,this.bind("parsleyFieldMultiple");if(!this.options.multiple)return o.warn("To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.",this.$element),this;this.options.multiple=this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g,""),"undefined"!=typeof t&&e('input[name="'+t+'"]').each(function(t,i){e(i).is("input[type=radio], input[type=checkbox]")&&e(i).attr(n.options.namespace+"multiple",n.options.multiple)});for(var r=this._findRelated(),s=0;s<r.length;s++)if(i=e(r.get(s)).data("Parsley"),"undefined"!=typeof i){this.$element.data("ParsleyFieldMultiple")||i.addElement(this.$element);break}return this.bind("parsleyField",!0),i||this.bind("parsleyFieldMultiple")},bind:function(t,i){var n;switch(t){case"parsleyForm":n=e.extend(new w(this.$element,this.domOptions,this.options),new u,window.ParsleyExtend)._bindFields();break;case"parsleyField":n=e.extend(new E(this.$element,this.domOptions,this.options,this.parent),new u,window.ParsleyExtend);break;case"parsleyFieldMultiple":n=e.extend(new E(this.$element,this.domOptions,this.options,this.parent),new P,new u,window.ParsleyExtend)._init();break;default:throw new Error(t+"is not a supported Parsley type")}return this.options.multiple&&o.setAttr(this.$element,this.options.namespace,"multiple",this.options.multiple),"undefined"!=typeof i?(this.$element.data("ParsleyFieldMultiple",n),n):(this.$element.data("Parsley",n),n._actualizeTriggers(),n._trigger("init"),n)}};var M=e.fn.jquery.split(".");if(parseInt(M[0])<=1&&parseInt(M[1])<8)throw"The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";M.forEach||o.warn("Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim");var O=e.extend(new u,{$element:e(document),actualizeOptions:null,_resetOptions:null,Factory:V,version:"2.4.4"});e.extend(E.prototype,y.Field,u.prototype),e.extend(w.prototype,y.Form,u.prototype),e.extend(V.prototype,u.prototype),e.fn.parsley=e.fn.psly=function(t){if(this.length>1){var i=[];return this.each(function(){i.push(e(this).parsley(t))}),i}return e(this).length?new V(this,t):void o.warn("You must bind Parsley on an existing element.")},"undefined"==typeof window.ParsleyExtend&&(window.ParsleyExtend={}),O.options=e.extend(o.objectCreate(l),window.ParsleyConfig),window.ParsleyConfig=O.options,window.Parsley=window.psly=O,window.ParsleyUtils=o;var A=window.Parsley._validatorRegistry=new m(window.ParsleyConfig.validators,window.ParsleyConfig.i18n);window.ParsleyValidator={},e.each("setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator".split(" "),function(t,i){window.Parsley[i]=e.proxy(A,i),window.ParsleyValidator[i]=function(){var e;return o.warnOnce("Accessing the method '"+i+"' through ParsleyValidator is deprecated. Simply call 'window.Parsley."+i+"(...)'"),(e=window.Parsley)[i].apply(e,arguments)}}),window.Parsley.UI=y,window.ParsleyUI={removeError:function(e,t,i){var n=!0!==i;return o.warnOnce("Accessing ParsleyUI is deprecated. Call 'removeError' on the instance directly. Please comment in issue 1073 as to your need to call this method."),e.removeError(t,{updateClass:n})},getErrorsMessages:function(e){return o.warnOnce("Accessing ParsleyUI is deprecated. Call 'getErrorsMessages' on the instance directly."),e.getErrorsMessages()}},e.each("addError updateError".split(" "),function(e,t){window.ParsleyUI[t]=function(e,i,n,r,s){var a=!0!==s;return o.warnOnce("Accessing ParsleyUI is deprecated. Call '"+t+"' on the instance directly. Please comment in issue 1073 as to your need to call this method."),e[t](i,{message:n,assert:r,updateClass:a})}}),!1!==window.ParsleyConfig.autoBind&&e(function(){e("[data-parsley-validate]").length&&e("[data-parsley-validate]").parsley()});var R=e({}),T=function(){o.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley")},q="parsley:";e.listen=function(e,n){var r;if(T(),"object"==typeof arguments[1]&&"function"==typeof arguments[2]&&(r=arguments[1],n=arguments[2]),"function"!=typeof n)throw new Error("Wrong parameters");window.Parsley.on(i(e),t(n,r))},e.listenTo=function(e,n,r){if(T(),!(e instanceof E||e instanceof w))throw new Error("Must give Parsley instance");if("string"!=typeof n||"function"!=typeof r)throw new Error("Wrong parameters");e.on(i(n),t(r))},e.unsubscribe=function(e,t){if(T(),"string"!=typeof e||"function"!=typeof t)throw new Error("Wrong arguments");window.Parsley.off(i(e),t.parsleyAdaptedCallback)},e.unsubscribeTo=function(e,t){if(T(),!(e instanceof E||e instanceof w))throw new Error("Must give Parsley instance");e.off(i(t))},e.unsubscribeAll=function(t){T(),window.Parsley.off(i(t)),e("form,input,textarea,select").each(function(){var n=e(this).data("Parsley");n&&n.off(i(t))})},e.emit=function(e,t){var n;T();var r=t instanceof E||t instanceof w,s=Array.prototype.slice.call(arguments,r?2:1);s.unshift(i(e)),r||(t=window.Parsley),(n=t).trigger.apply(n,_toConsumableArray(s))};e.extend(!0,O,{asyncValidators:{"default":{fn:function(e){return e.status>=200&&e.status<300},url:!1},reverse:{fn:function(e){return e.status<200||e.status>=300},url:!1}},addAsyncValidator:function(e,t,i,n){return O.asyncValidators[e]={fn:t,url:i||!1,options:n||{}},this}}),O.addValidator("remote",{requirementType:{"":"string",validator:"string",reverse:"boolean",options:"object"},validateString:function(t,i,n,r){var s,a,o={},l=n.validator||(!0===n.reverse?"reverse":"default");if("undefined"==typeof O.asyncValidators[l])throw new Error("Calling an undefined async validator: `"+l+"`");i=O.asyncValidators[l].url||i,i.indexOf("{value}")>-1?i=i.replace("{value}",encodeURIComponent(t)):o[r.$element.attr("name")||r.$element.attr("id")]=t;var u=e.extend(!0,n.options||{},O.asyncValidators[l].options);s=e.extend(!0,{},{url:i,data:o,type:"GET"},u),r.trigger("field:ajaxoptions",r,s),a=e.param(s),"undefined"==typeof O._remoteCache&&(O._remoteCache={});var d=O._remoteCache[a]=O._remoteCache[a]||e.ajax(s),h=function(){var t=O.asyncValidators[l].fn.call(r,d,i,n);return t||(t=e.Deferred().reject()),e.when(t)};return d.then(h,h)},priority:-1}),O.on("form:submit",function(){O._remoteCache={}}),window.ParsleyExtend.addAsyncValidator=function(){return ParsleyUtils.warnOnce("Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`"),O.addAsyncValidator.apply(O,arguments)},O.addMessages("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 fewer.",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 fewer.",check:"You must select between %s and %s choices.",equalto:"This value should be the same."}),O.setLocale("en");var D=new n;D.install();var I=O;return I});
18
+ //# sourceMappingURL=parsley.min.js.map
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parsley-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.7.0
4
+ version: 2.4.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jiri Pospisil
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-31 00:00:00.000000000 Z
11
+ date: 2016-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -40,16 +40,21 @@ files:
40
40
  - lib/parsley-rails/version.rb
41
41
  - parsley-rails.gemspec
42
42
  - update.sh
43
+ - vendor/assets/javascripts/parsley.i18n.al.js
43
44
  - vendor/assets/javascripts/parsley.i18n.ar.js
44
45
  - vendor/assets/javascripts/parsley.i18n.bg.js
46
+ - vendor/assets/javascripts/parsley.i18n.ca.js
45
47
  - vendor/assets/javascripts/parsley.i18n.cs.extra.js
46
48
  - vendor/assets/javascripts/parsley.i18n.cs.js
47
49
  - vendor/assets/javascripts/parsley.i18n.da.js
48
50
  - vendor/assets/javascripts/parsley.i18n.de.extra.js
49
51
  - vendor/assets/javascripts/parsley.i18n.de.js
52
+ - vendor/assets/javascripts/parsley.i18n.el.extra.js
53
+ - vendor/assets/javascripts/parsley.i18n.el.js
50
54
  - vendor/assets/javascripts/parsley.i18n.en.extra.js
51
55
  - vendor/assets/javascripts/parsley.i18n.en.js
52
56
  - vendor/assets/javascripts/parsley.i18n.es.js
57
+ - vendor/assets/javascripts/parsley.i18n.eu.js
53
58
  - vendor/assets/javascripts/parsley.i18n.fa.js
54
59
  - vendor/assets/javascripts/parsley.i18n.fi.extra.js
55
60
  - vendor/assets/javascripts/parsley.i18n.fi.js
@@ -57,31 +62,47 @@ files:
57
62
  - vendor/assets/javascripts/parsley.i18n.fr.js
58
63
  - vendor/assets/javascripts/parsley.i18n.he.extra.js
59
64
  - vendor/assets/javascripts/parsley.i18n.he.js
65
+ - vendor/assets/javascripts/parsley.i18n.hr.extra.js
66
+ - vendor/assets/javascripts/parsley.i18n.hr.js
67
+ - vendor/assets/javascripts/parsley.i18n.hu.extra.js
68
+ - vendor/assets/javascripts/parsley.i18n.hu.js
60
69
  - vendor/assets/javascripts/parsley.i18n.id.extra.js
61
70
  - vendor/assets/javascripts/parsley.i18n.id.js
62
71
  - vendor/assets/javascripts/parsley.i18n.it.extra.js
63
72
  - vendor/assets/javascripts/parsley.i18n.it.js
64
73
  - vendor/assets/javascripts/parsley.i18n.ja.js
65
74
  - vendor/assets/javascripts/parsley.i18n.ko.js
66
- - vendor/assets/javascripts/parsley.i18n.ms_MY.extra.js
67
- - vendor/assets/javascripts/parsley.i18n.ms_MY.js
75
+ - vendor/assets/javascripts/parsley.i18n.lt.js
76
+ - vendor/assets/javascripts/parsley.i18n.lv.extra.js
77
+ - vendor/assets/javascripts/parsley.i18n.lv.js
78
+ - vendor/assets/javascripts/parsley.i18n.ms.extra.js
79
+ - vendor/assets/javascripts/parsley.i18n.ms.js
68
80
  - vendor/assets/javascripts/parsley.i18n.nl.extra.js
69
81
  - vendor/assets/javascripts/parsley.i18n.nl.js
82
+ - vendor/assets/javascripts/parsley.i18n.no.js
70
83
  - vendor/assets/javascripts/parsley.i18n.pl.js
71
84
  - vendor/assets/javascripts/parsley.i18n.pt-br.js
85
+ - vendor/assets/javascripts/parsley.i18n.pt-pt.js
86
+ - vendor/assets/javascripts/parsley.i18n.ro.extra.js
87
+ - vendor/assets/javascripts/parsley.i18n.ro.js
72
88
  - vendor/assets/javascripts/parsley.i18n.ru.extra.js
73
89
  - vendor/assets/javascripts/parsley.i18n.ru.js
90
+ - vendor/assets/javascripts/parsley.i18n.sl.extra.js
91
+ - vendor/assets/javascripts/parsley.i18n.sl.js
92
+ - vendor/assets/javascripts/parsley.i18n.sq.js
74
93
  - vendor/assets/javascripts/parsley.i18n.sv.extra.js
75
94
  - vendor/assets/javascripts/parsley.i18n.sv.js
76
95
  - vendor/assets/javascripts/parsley.i18n.th.js
77
96
  - vendor/assets/javascripts/parsley.i18n.tr.js
97
+ - vendor/assets/javascripts/parsley.i18n.uk.extra.js
98
+ - vendor/assets/javascripts/parsley.i18n.uk.js
78
99
  - vendor/assets/javascripts/parsley.i18n.zh_cn.extra.js
79
100
  - vendor/assets/javascripts/parsley.i18n.zh_cn.js
80
101
  - vendor/assets/javascripts/parsley.i18n.zh_tw.js
81
102
  - vendor/assets/javascripts/parsley.js
82
- - vendor/assets/javascripts/parsley.remote.js
103
+ - vendor/assets/javascripts/parsley.min.js
83
104
  - vendor/assets/stylesheets/parsley.css
84
- homepage: https://github.com/mekishizufu/parsley-rails
105
+ homepage: https://github.com/jiripospisil/parsley-rails
85
106
  licenses:
86
107
  - MIT
87
108
  metadata: {}
@@ -1,2347 +0,0 @@
1
- // `window.ParsleyExtend`, like `ParsleyAbstract`, is inherited by `ParsleyField` and `ParsleyForm`
2
- // That way, we could add new methods or redefine some for these both classes. In particular case
3
- // We are adding async validation methods that returns promises, bind them properly to triggered
4
- // Events like onkeyup when field is invalid or on form submit. These validation methods adds an
5
- // Extra `remote` validator which could not be simply added like other `ParsleyExtra` validators
6
- // Because returns promises instead of booleans.
7
- window.ParsleyExtend = window.ParsleyExtend || {};
8
- window.ParsleyExtend = $.extend(window.ParsleyExtend, {
9
- asyncSupport: true,
10
-
11
- asyncValidators: $.extend({
12
- 'default': {
13
- fn: function (xhr) {
14
- return 'resolved' === xhr.state();
15
- },
16
- url: false
17
- },
18
- reverse: {
19
- fn: function (xhr) {
20
- // If reverse option is set, a failing ajax request is considered successful
21
- return 'rejected' === xhr.state();
22
- },
23
- url: false
24
- }
25
- }, window.ParsleyExtend.asyncValidators),
26
-
27
- addAsyncValidator: function (name, fn, url, options) {
28
- this.asyncValidators[name.toLowerCase()] = {
29
- fn: fn,
30
- url: url || false,
31
- options: options || {}
32
- };
33
-
34
- return this;
35
- },
36
-
37
- asyncValidate: function () {
38
- if ('ParsleyForm' === this.__class__)
39
- return this._asyncValidateForm.apply(this, arguments);
40
-
41
- return this._asyncValidateField.apply(this, arguments);
42
- },
43
-
44
- asyncIsValid: function () {
45
- if ('ParsleyField' === this.__class__)
46
- return this._asyncIsValidField.apply(this, arguments);
47
-
48
- return this._asyncIsValidForm.apply(this, arguments);
49
- },
50
-
51
- onSubmitValidate: function (event) {
52
- var that = this;
53
-
54
- // This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior
55
- if (true === event.parsley)
56
- return;
57
-
58
- // Clone the event object
59
- this.submitEvent = $.extend(true, {}, event);
60
-
61
- // Prevent form submit and immediately stop its event propagation
62
- if (event instanceof $.Event) {
63
- event.stopImmediatePropagation();
64
- event.preventDefault();
65
- }
66
-
67
- return this._asyncValidateForm(undefined, event)
68
- .done(function () {
69
- // If user do not have prevented the event, re-submit form
70
- if (!that.submitEvent.isDefaultPrevented())
71
- that.$element.trigger($.extend($.Event('submit'), { parsley: true }));
72
- });
73
- },
74
-
75
- eventValidate: function (event) {
76
- // For keyup, keypress, keydown.. events that could be a little bit obstrusive
77
- // do not validate if val length < min threshold on first validation. Once field have been validated once and info
78
- // about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
79
- if (new RegExp('key').test(event.type))
80
- if (!this._ui.validationInformationVisible && this.getValue().length <= this.options.validationThreshold)
81
- return;
82
-
83
- this._ui.validatedOnce = true;
84
- this.asyncValidate();
85
- },
86
-
87
- // Returns Promise
88
- _asyncValidateForm: function (group, event) {
89
- var
90
- that = this,
91
- promises = [];
92
-
93
- this._refreshFields();
94
-
95
- $.emit('parsley:form:validate', this);
96
-
97
- for (var i = 0; i < this.fields.length; i++) {
98
-
99
- // do not validate a field if not the same as given validation group
100
- if (group && group !== this.fields[i].options.group)
101
- continue;
102
-
103
- promises.push(this.fields[i]._asyncValidateField());
104
- }
105
-
106
- return $.when.apply($, promises)
107
- .done(function () {
108
- $.emit('parsley:form:success', that);
109
- })
110
- .fail(function () {
111
- $.emit('parsley:form:error', that);
112
- })
113
- .always(function () {
114
- $.emit('parsley:form:validated', that);
115
- });
116
- },
117
-
118
- _asyncIsValidForm: function (group, force) {
119
- var promises = [];
120
- this._refreshFields();
121
-
122
- for (var i = 0; i < this.fields.length; i++) {
123
-
124
- // do not validate a field if not the same as given validation group
125
- if (group && group !== this.fields[i].options.group)
126
- continue;
127
-
128
- promises.push(this.fields[i]._asyncIsValidField(force));
129
- }
130
-
131
- return $.when.apply($, promises);
132
- },
133
-
134
- _asyncValidateField: function (force) {
135
- var that = this;
136
-
137
- $.emit('parsley:field:validate', this);
138
-
139
- return this._asyncIsValidField(force)
140
- .done(function () {
141
- $.emit('parsley:field:success', that);
142
- })
143
- .fail(function () {
144
- $.emit('parsley:field:error', that);
145
- })
146
- .always(function () {
147
- $.emit('parsley:field:validated', that);
148
- });
149
- },
150
-
151
- _asyncIsValidField: function (force, value) {
152
- var
153
- deferred = $.Deferred(),
154
- remoteConstraintIndex;
155
-
156
- // If regular isValid (matching regular constraints) returns `false`, no need to go further
157
- // Directly reject promise, do not run remote validator and save server load
158
- if (false === this.isValid(force, value))
159
- deferred.rejectWith(this);
160
-
161
- // If regular constraints are valid, and there is a remote validator registered, run it
162
- else if ('undefined' !== typeof this.constraintsByName.remote)
163
- this._remote(deferred);
164
-
165
- // Otherwise all is good, resolve promise
166
- else
167
- deferred.resolveWith(this);
168
-
169
- // Return promise
170
- return deferred.promise();
171
- },
172
-
173
- _remote: function (deferred) {
174
- var
175
- that = this,
176
- data = {},
177
- ajaxOptions,
178
- csr,
179
- validator = this.options.remoteValidator || (true === this.options.remoteReverse ? 'reverse' : 'default');
180
-
181
- validator = validator.toLowerCase();
182
-
183
- if ('undefined' === typeof this.asyncValidators[validator])
184
- throw new Error('Calling an undefined async validator: `' + validator + '`');
185
-
186
- // Fill data with current value
187
- data[this.$element.attr('name') || this.$element.attr('id')] = this.getValue();
188
-
189
- // Merge options passed in from the function with the ones in the attribute
190
- this.options.remoteOptions = $.extend(true, this.options.remoteOptions || {} , this.asyncValidators[validator].options);
191
-
192
- // All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`
193
- ajaxOptions = $.extend(true, {}, {
194
- url: this.asyncValidators[validator].url || this.options.remote,
195
- data: data,
196
- type: 'GET'
197
- }, this.options.remoteOptions || {});
198
-
199
- // Generate store key based on ajax options
200
- csr = $.param(ajaxOptions);
201
-
202
- // Initialise querry cache
203
- if ('undefined' === typeof this._remoteCache)
204
- this._remoteCache = {};
205
-
206
- // Try to retrieve stored xhr
207
- if (!this._remoteCache[csr]) {
208
- // Prevent multi burst xhr queries
209
- if (this._xhr && 'pending' === this._xhr.state())
210
- this._xhr.abort();
211
-
212
- // Make ajax call
213
- this._xhr = $.ajax(ajaxOptions)
214
-
215
- // Store remote call result to avoid next calls with exact same parameters
216
- this._remoteCache[csr] = this._xhr;
217
- }
218
-
219
- this._remoteCache[csr]
220
- .done(function (data, textStatus, xhr) {
221
- that._handleRemoteResult(validator, xhr, deferred);
222
- })
223
- .fail(function (xhr, status, message) {
224
- // If we aborted the query, do not handle nothing for this value
225
- if ('abort' === status)
226
- return;
227
-
228
- that._handleRemoteResult(validator, xhr, deferred);
229
- });
230
- },
231
-
232
- _handleRemoteResult: function (validator, xhr, deferred) {
233
- // If true, simply resolve and exit
234
- if ('function' === typeof this.asyncValidators[validator].fn && this.asyncValidators[validator].fn.call(this, xhr)) {
235
- deferred.resolveWith(this);
236
-
237
- return;
238
- }
239
-
240
- // Else, create a proper remote validation Violation to trigger right UI
241
- this.validationResult = [
242
- new window.ParsleyValidator.Validator.Violation(
243
- this.constraintsByName.remote,
244
- this.getValue(),
245
- null
246
- )
247
- ];
248
-
249
- deferred.rejectWith(this);
250
- }
251
- });
252
-
253
- // Remote validator is just an always true sync validator with lowest (-1) priority possible
254
- // It will be overloaded in `validateThroughValidator()` that will do the heavy async work
255
- // This 'hack' is needed not to mess up too much with error messages and stuff in `ParsleyUI`
256
- window.ParsleyConfig = window.ParsleyConfig || {};
257
- window.ParsleyConfig.validators = window.ParsleyConfig.validators || {};
258
- window.ParsleyConfig.validators.remote = {
259
- fn: function () {
260
- return true;
261
- },
262
- priority: -1
263
- };
264
-
265
- /*!
266
- * Parsleyjs
267
- * Guillaume Potier - <guillaume@wisembly.com>
268
- * Version 2.0.6 - built Sat Jan 24 2015 14:44:37
269
- * MIT Licensed
270
- *
271
- */
272
- !(function (factory) {
273
- if (typeof define === 'function' && define.amd) {
274
- // AMD. Register as an anonymous module depending on jQuery.
275
- define(['jquery'], factory);
276
- } else {
277
- // No AMD. Register plugin with global jQuery object.
278
- factory(jQuery);
279
- }
280
- }(function ($) {
281
- // small hack for requirejs if jquery is loaded through map and not path
282
- // see http://requirejs.org/docs/jquery.html
283
- if ('undefined' === typeof $ && 'undefined' !== typeof window.jQuery)
284
- $ = window.jQuery;
285
- var ParsleyUtils = {
286
- // Parsley DOM-API
287
- // returns object from dom attributes and values
288
- // if attr is given, returns bool if attr present in DOM or not
289
- attr: function ($element, namespace, checkAttr) {
290
- var
291
- attribute,
292
- obj = {},
293
- msie = this.msieversion(),
294
- regex = new RegExp('^' + namespace, 'i');
295
- if ('undefined' === typeof $element || 'undefined' === typeof $element[0])
296
- return {};
297
- for (var i in $element[0].attributes) {
298
- attribute = $element[0].attributes[i];
299
- if ('undefined' !== typeof attribute && null !== attribute && (!msie || msie >= 8 || attribute.specified) && regex.test(attribute.name)) {
300
- if ('undefined' !== typeof checkAttr && new RegExp(checkAttr + '$', 'i').test(attribute.name))
301
- return true;
302
- obj[this.camelize(attribute.name.replace(namespace, ''))] = this.deserializeValue(attribute.value);
303
- }
304
- }
305
- return 'undefined' === typeof checkAttr ? obj : false;
306
- },
307
- setAttr: function ($element, namespace, attr, value) {
308
- $element[0].setAttribute(this.dasherize(namespace + attr), String(value));
309
- },
310
- // Recursive object / array getter
311
- get: function (obj, path) {
312
- var
313
- i = 0,
314
- paths = (path || '').split('.');
315
- while (this.isObject(obj) || this.isArray(obj)) {
316
- obj = obj[paths[i++]];
317
- if (i === paths.length)
318
- return obj;
319
- }
320
- return undefined;
321
- },
322
- hash: function (length) {
323
- return String(Math.random()).substring(2, length ? length + 2 : 9);
324
- },
325
- /** Third party functions **/
326
- // Underscore isArray
327
- isArray: function (mixed) {
328
- return Object.prototype.toString.call(mixed) === '[object Array]';
329
- },
330
- // Underscore isObject
331
- isObject: function (mixed) {
332
- return mixed === Object(mixed);
333
- },
334
- // Zepto deserialize function
335
- deserializeValue: function (value) {
336
- var num;
337
- try {
338
- return value ?
339
- value == "true" ||
340
- (value == "false" ? false :
341
- value == "null" ? null :
342
- !isNaN(num = Number(value)) ? num :
343
- /^[\[\{]/.test(value) ? $.parseJSON(value) :
344
- value)
345
- : value;
346
- } catch (e) { return value; }
347
- },
348
- // Zepto camelize function
349
- camelize: function (str) {
350
- return str.replace(/-+(.)?/g, function(match, chr) {
351
- return chr ? chr.toUpperCase() : '';
352
- });
353
- },
354
- // Zepto dasherize function
355
- dasherize: function (str) {
356
- return str.replace(/::/g, '/')
357
- .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
358
- .replace(/([a-z\d])([A-Z])/g, '$1_$2')
359
- .replace(/_/g, '-')
360
- .toLowerCase();
361
- },
362
- // http://support.microsoft.com/kb/167820
363
- // http://stackoverflow.com/questions/19999388/jquery-check-if-user-is-using-ie
364
- msieversion: function () {
365
- var
366
- ua = window.navigator.userAgent,
367
- msie = ua.indexOf('MSIE ');
368
- if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./))
369
- return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
370
- return 0;
371
- }
372
- };
373
- // All these options could be overriden and specified directly in DOM using
374
- // `data-parsley-` default DOM-API
375
- // eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
376
- // eg: `data-parsley-stop-on-first-failing-constraint="false"`
377
- var ParsleyDefaults = {
378
- // ### General
379
- // Default data-namespace for DOM API
380
- namespace: 'data-parsley-',
381
- // Supported inputs by default
382
- inputs: 'input, textarea, select',
383
- // Excluded inputs by default
384
- excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',
385
- // Stop validating field on highest priority failing constraint
386
- priorityEnabled: true,
387
- // ### UI
388
- // Enable\Disable error messages
389
- uiEnabled: true,
390
- // Key events threshold before validation
391
- validationThreshold: 3,
392
- // Focused field on form validation error. 'fist'|'last'|'none'
393
- focus: 'first',
394
- // `$.Event()` that will trigger validation. eg: `keyup`, `change`...
395
- trigger: false,
396
- // Class that would be added on every failing validation Parsley field
397
- errorClass: 'parsley-error',
398
- // Same for success validation
399
- successClass: 'parsley-success',
400
- // Return the `$element` that will receive these above success or error classes
401
- // Could also be (and given directly from DOM) a valid selector like `'#div'`
402
- classHandler: function (ParsleyField) {},
403
- // Return the `$element` where errors will be appended
404
- // Could also be (and given directly from DOM) a valid selector like `'#div'`
405
- errorsContainer: function (ParsleyField) {},
406
- // ul elem that would receive errors' list
407
- errorsWrapper: '<ul class="parsley-errors-list"></ul>',
408
- // li elem that would receive error message
409
- errorTemplate: '<li></li>'
410
- };
411
-
412
- var ParsleyAbstract = function() {};
413
- ParsleyAbstract.prototype = {
414
- asyncSupport: false,
415
- actualizeOptions: function () {
416
- this.options = this.OptionsFactory.get(this);
417
- return this;
418
- },
419
- // ParsleyValidator validate proxy function . Could be replaced by third party scripts
420
- validateThroughValidator: function (value, constraints, priority) {
421
- return window.ParsleyValidator.validate(value, constraints, priority);
422
- },
423
- // Subscribe an event and a handler for a specific field or a specific form
424
- // If on a ParsleyForm instance, it will be attached to form instance and also
425
- // To every field instance for this form
426
- subscribe: function (name, fn) {
427
- $.listenTo(this, name.toLowerCase(), fn);
428
- return this;
429
- },
430
- // Same as subscribe above. Unsubscribe an event for field, or form + its fields
431
- unsubscribe: function (name) {
432
- $.unsubscribeTo(this, name.toLowerCase());
433
- return this;
434
- },
435
- // Reset UI
436
- reset: function () {
437
- // Field case: just emit a reset event for UI
438
- if ('ParsleyForm' !== this.__class__)
439
- return $.emit('parsley:field:reset', this);
440
- // Form case: emit a reset event for each field
441
- for (var i = 0; i < this.fields.length; i++)
442
- $.emit('parsley:field:reset', this.fields[i]);
443
- $.emit('parsley:form:reset', this);
444
- },
445
- // Destroy Parsley instance (+ UI)
446
- destroy: function () {
447
- // Field case: emit destroy event to clean UI and then destroy stored instance
448
- if ('ParsleyForm' !== this.__class__) {
449
- this.$element.removeData('Parsley');
450
- this.$element.removeData('ParsleyFieldMultiple');
451
- $.emit('parsley:field:destroy', this);
452
- return;
453
- }
454
- // Form case: destroy all its fields and then destroy stored instance
455
- for (var i = 0; i < this.fields.length; i++)
456
- this.fields[i].destroy();
457
- this.$element.removeData('Parsley');
458
- $.emit('parsley:form:destroy', this);
459
- }
460
- };
461
- /*!
462
- * validator.js
463
- * Guillaume Potier - <guillaume@wisembly.com>
464
- * Version 1.0.1 - built Mon Aug 25 2014 16:10:10
465
- * MIT Licensed
466
- *
467
- */
468
- var Validator = ( function ( ) {
469
- var exports = {};
470
- /**
471
- * Validator
472
- */
473
- var Validator = function ( options ) {
474
- this.__class__ = 'Validator';
475
- this.__version__ = '1.0.1';
476
- this.options = options || {};
477
- this.bindingKey = this.options.bindingKey || '_validatorjsConstraint';
478
- };
479
- Validator.prototype = {
480
- constructor: Validator,
481
- /*
482
- * Validate string: validate( string, Assert, string ) || validate( string, [ Assert, Assert ], [ string, string ] )
483
- * Validate object: validate( object, Constraint, string ) || validate( object, Constraint, [ string, string ] )
484
- * Validate binded object: validate( object, string ) || validate( object, [ string, string ] )
485
- */
486
- validate: function ( objectOrString, AssertsOrConstraintOrGroup, group ) {
487
- if ( 'string' !== typeof objectOrString && 'object' !== typeof objectOrString )
488
- throw new Error( 'You must validate an object or a string' );
489
- // string / array validation
490
- if ( 'string' === typeof objectOrString || _isArray(objectOrString) )
491
- return this._validateString( objectOrString, AssertsOrConstraintOrGroup, group );
492
- // binded object validation
493
- if ( this.isBinded( objectOrString ) )
494
- return this._validateBindedObject( objectOrString, AssertsOrConstraintOrGroup );
495
- // regular object validation
496
- return this._validateObject( objectOrString, AssertsOrConstraintOrGroup, group );
497
- },
498
- bind: function ( object, constraint ) {
499
- if ( 'object' !== typeof object )
500
- throw new Error( 'Must bind a Constraint to an object' );
501
- object[ this.bindingKey ] = new Constraint( constraint );
502
- return this;
503
- },
504
- unbind: function ( object ) {
505
- if ( 'undefined' === typeof object._validatorjsConstraint )
506
- return this;
507
- delete object[ this.bindingKey ];
508
- return this;
509
- },
510
- isBinded: function ( object ) {
511
- return 'undefined' !== typeof object[ this.bindingKey ];
512
- },
513
- getBinded: function ( object ) {
514
- return this.isBinded( object ) ? object[ this.bindingKey ] : null;
515
- },
516
- _validateString: function ( string, assert, group ) {
517
- var result, failures = [];
518
- if ( !_isArray( assert ) )
519
- assert = [ assert ];
520
- for ( var i = 0; i < assert.length; i++ ) {
521
- if ( ! ( assert[ i ] instanceof Assert) )
522
- throw new Error( 'You must give an Assert or an Asserts array to validate a string' );
523
- result = assert[ i ].check( string, group );
524
- if ( result instanceof Violation )
525
- failures.push( result );
526
- }
527
- return failures.length ? failures : true;
528
- },
529
- _validateObject: function ( object, constraint, group ) {
530
- if ( 'object' !== typeof constraint )
531
- throw new Error( 'You must give a constraint to validate an object' );
532
- if ( constraint instanceof Constraint )
533
- return constraint.check( object, group );
534
- return new Constraint( constraint ).check( object, group );
535
- },
536
- _validateBindedObject: function ( object, group ) {
537
- return object[ this.bindingKey ].check( object, group );
538
- }
539
- };
540
- Validator.errorCode = {
541
- must_be_a_string: 'must_be_a_string',
542
- must_be_an_array: 'must_be_an_array',
543
- must_be_a_number: 'must_be_a_number',
544
- must_be_a_string_or_array: 'must_be_a_string_or_array'
545
- };
546
- /**
547
- * Constraint
548
- */
549
- var Constraint = function ( data, options ) {
550
- this.__class__ = 'Constraint';
551
- this.options = options || {};
552
- this.nodes = {};
553
- if ( data ) {
554
- try {
555
- this._bootstrap( data );
556
- } catch ( err ) {
557
- throw new Error( 'Should give a valid mapping object to Constraint', err, data );
558
- }
559
- }
560
- };
561
- Constraint.prototype = {
562
- constructor: Constraint,
563
- check: function ( object, group ) {
564
- var result, failures = {};
565
- // check all constraint nodes.
566
- for ( var property in this.nodes ) {
567
- var isRequired = false;
568
- var constraint = this.get(property);
569
- var constraints = _isArray( constraint ) ? constraint : [constraint];
570
- for (var i = constraints.length - 1; i >= 0; i--) {
571
- if ( 'Required' === constraints[i].__class__ ) {
572
- isRequired = constraints[i].requiresValidation( group );
573
- continue;
574
- }
575
- }
576
- if ( ! this.has( property, object ) && ! this.options.strict && ! isRequired ) {
577
- continue;
578
- }
579
- try {
580
- if (! this.has( property, this.options.strict || isRequired ? object : undefined ) ) {
581
- // we trigger here a HaveProperty Assert violation to have uniform Violation object in the end
582
- new Assert().HaveProperty( property ).validate( object );
583
- }
584
- result = this._check( property, object[ property ], group );
585
- // check returned an array of Violations or an object mapping Violations
586
- if ( ( _isArray( result ) && result.length > 0 ) || ( !_isArray( result ) && !_isEmptyObject( result ) ) ) {
587
- failures[ property ] = result;
588
- }
589
- } catch ( violation ) {
590
- failures[ property ] = violation;
591
- }
592
- }
593
- return _isEmptyObject(failures) ? true : failures;
594
- },
595
- add: function ( node, object ) {
596
- if ( object instanceof Assert || ( _isArray( object ) && object[ 0 ] instanceof Assert ) ) {
597
- this.nodes[ node ] = object;
598
- return this;
599
- }
600
- if ( 'object' === typeof object && !_isArray( object ) ) {
601
- this.nodes[ node ] = object instanceof Constraint ? object : new Constraint( object );
602
- return this;
603
- }
604
- throw new Error( 'Should give an Assert, an Asserts array, a Constraint', object );
605
- },
606
- has: function ( node, nodes ) {
607
- nodes = 'undefined' !== typeof nodes ? nodes : this.nodes;
608
- return 'undefined' !== typeof nodes[ node ];
609
- },
610
- get: function ( node, placeholder ) {
611
- return this.has( node ) ? this.nodes[ node ] : placeholder || null;
612
- },
613
- remove: function ( node ) {
614
- var _nodes = [];
615
- for ( var i in this.nodes )
616
- if ( i !== node )
617
- _nodes[ i ] = this.nodes[ i ];
618
- this.nodes = _nodes;
619
- return this;
620
- },
621
- _bootstrap: function ( data ) {
622
- if ( data instanceof Constraint )
623
- return this.nodes = data.nodes;
624
- for ( var node in data )
625
- this.add( node, data[ node ] );
626
- },
627
- _check: function ( node, value, group ) {
628
- // Assert
629
- if ( this.nodes[ node ] instanceof Assert )
630
- return this._checkAsserts( value, [ this.nodes[ node ] ], group );
631
- // Asserts
632
- if ( _isArray( this.nodes[ node ] ) )
633
- return this._checkAsserts( value, this.nodes[ node ], group );
634
- // Constraint -> check api
635
- if ( this.nodes[ node ] instanceof Constraint )
636
- return this.nodes[ node ].check( value, group );
637
- throw new Error( 'Invalid node', this.nodes[ node ] );
638
- },
639
- _checkAsserts: function ( value, asserts, group ) {
640
- var result, failures = [];
641
- for ( var i = 0; i < asserts.length; i++ ) {
642
- result = asserts[ i ].check( value, group );
643
- if ( 'undefined' !== typeof result && true !== result )
644
- failures.push( result );
645
- // Some asserts (Collection for example) could return an object
646
- // if ( result && ! ( result instanceof Violation ) )
647
- // return result;
648
- //
649
- // // Vast assert majority return Violation
650
- // if ( result instanceof Violation )
651
- // failures.push( result );
652
- }
653
- return failures;
654
- }
655
- };
656
- /**
657
- * Violation
658
- */
659
- var Violation = function ( assert, value, violation ) {
660
- this.__class__ = 'Violation';
661
- if ( ! ( assert instanceof Assert ) )
662
- throw new Error( 'Should give an assertion implementing the Assert interface' );
663
- this.assert = assert;
664
- this.value = value;
665
- if ( 'undefined' !== typeof violation )
666
- this.violation = violation;
667
- };
668
- Violation.prototype = {
669
- show: function () {
670
- var show = {
671
- assert: this.assert.__class__,
672
- value: this.value
673
- };
674
- if ( this.violation )
675
- show.violation = this.violation;
676
- return show;
677
- },
678
- __toString: function () {
679
- if ( 'undefined' !== typeof this.violation )
680
- this.violation = '", ' + this.getViolation().constraint + ' expected was ' + this.getViolation().expected;
681
- return this.assert.__class__ + ' assert failed for "' + this.value + this.violation || '';
682
- },
683
- getViolation: function () {
684
- var constraint, expected;
685
- for ( constraint in this.violation )
686
- expected = this.violation[ constraint ];
687
- return { constraint: constraint, expected: expected };
688
- }
689
- };
690
- /**
691
- * Assert
692
- */
693
- var Assert = function ( group ) {
694
- this.__class__ = 'Assert';
695
- this.__parentClass__ = this.__class__;
696
- this.groups = [];
697
- if ( 'undefined' !== typeof group )
698
- this.addGroup( group );
699
- };
700
- Assert.prototype = {
701
- construct: Assert,
702
- requiresValidation: function ( group ) {
703
- if ( group && !this.hasGroup( group ) )
704
- return false;
705
- if ( !group && this.hasGroups() )
706
- return false;
707
- return true;
708
- },
709
- check: function ( value, group ) {
710
- if ( !this.requiresValidation( group ) )
711
- return;
712
- try {
713
- return this.validate( value, group );
714
- } catch ( violation ) {
715
- return violation;
716
- }
717
- },
718
- hasGroup: function ( group ) {
719
- if ( _isArray( group ) )
720
- return this.hasOneOf( group );
721
- // All Asserts respond to "Any" group
722
- if ( 'Any' === group )
723
- return true;
724
- // Asserts with no group also respond to "Default" group. Else return false
725
- if ( !this.hasGroups() )
726
- return 'Default' === group;
727
- return -1 !== this.groups.indexOf( group );
728
- },
729
- hasOneOf: function ( groups ) {
730
- for ( var i = 0; i < groups.length; i++ )
731
- if ( this.hasGroup( groups[ i ] ) )
732
- return true;
733
- return false;
734
- },
735
- hasGroups: function () {
736
- return this.groups.length > 0;
737
- },
738
- addGroup: function ( group ) {
739
- if ( _isArray( group ) )
740
- return this.addGroups( group );
741
- if ( !this.hasGroup( group ) )
742
- this.groups.push( group );
743
- return this;
744
- },
745
- removeGroup: function ( group ) {
746
- var _groups = [];
747
- for ( var i = 0; i < this.groups.length; i++ )
748
- if ( group !== this.groups[ i ] )
749
- _groups.push( this.groups[ i ] );
750
- this.groups = _groups;
751
- return this;
752
- },
753
- addGroups: function ( groups ) {
754
- for ( var i = 0; i < groups.length; i++ )
755
- this.addGroup( groups[ i ] );
756
- return this;
757
- },
758
- /**
759
- * Asserts definitions
760
- */
761
- HaveProperty: function ( node ) {
762
- this.__class__ = 'HaveProperty';
763
- this.node = node;
764
- this.validate = function ( object ) {
765
- if ( 'undefined' === typeof object[ this.node ] )
766
- throw new Violation( this, object, { value: this.node } );
767
- return true;
768
- };
769
- return this;
770
- },
771
- Blank: function () {
772
- this.__class__ = 'Blank';
773
- this.validate = function ( value ) {
774
- if ( 'string' !== typeof value )
775
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
776
- if ( '' !== value.replace( /^\s+/g, '' ).replace( /\s+$/g, '' ) )
777
- throw new Violation( this, value );
778
- return true;
779
- };
780
- return this;
781
- },
782
- Callback: function ( fn ) {
783
- this.__class__ = 'Callback';
784
- this.arguments = Array.prototype.slice.call( arguments );
785
- if ( 1 === this.arguments.length )
786
- this.arguments = [];
787
- else
788
- this.arguments.splice( 0, 1 );
789
- if ( 'function' !== typeof fn )
790
- throw new Error( 'Callback must be instanciated with a function' );
791
- this.fn = fn;
792
- this.validate = function ( value ) {
793
- var result = this.fn.apply( this, [ value ].concat( this.arguments ) );
794
- if ( true !== result )
795
- throw new Violation( this, value, { result: result } );
796
- return true;
797
- };
798
- return this;
799
- },
800
- Choice: function ( list ) {
801
- this.__class__ = 'Choice';
802
- if ( !_isArray( list ) && 'function' !== typeof list )
803
- throw new Error( 'Choice must be instanciated with an array or a function' );
804
- this.list = list;
805
- this.validate = function ( value ) {
806
- var list = 'function' === typeof this.list ? this.list() : this.list;
807
- for ( var i = 0; i < list.length; i++ )
808
- if ( value === list[ i ] )
809
- return true;
810
- throw new Violation( this, value, { choices: list } );
811
- };
812
- return this;
813
- },
814
- Collection: function ( assertOrConstraint ) {
815
- this.__class__ = 'Collection';
816
- this.constraint = 'undefined' !== typeof assertOrConstraint ? (assertOrConstraint instanceof Assert ? assertOrConstraint : new Constraint( assertOrConstraint )) : false;
817
- this.validate = function ( collection, group ) {
818
- var result, validator = new Validator(), count = 0, failures = {}, groups = this.groups.length ? this.groups : group;
819
- if ( !_isArray( collection ) )
820
- throw new Violation( this, collection, { value: Validator.errorCode.must_be_an_array } );
821
- for ( var i = 0; i < collection.length; i++ ) {
822
- result = this.constraint ?
823
- validator.validate( collection[ i ], this.constraint, groups ) :
824
- validator.validate( collection[ i ], groups );
825
- if ( !_isEmptyObject( result ) )
826
- failures[ count ] = result;
827
- count++;
828
- }
829
- return !_isEmptyObject( failures ) ? failures : true;
830
- };
831
- return this;
832
- },
833
- Count: function ( count ) {
834
- this.__class__ = 'Count';
835
- this.count = count;
836
- this.validate = function ( array ) {
837
- if ( !_isArray( array ) )
838
- throw new Violation( this, array, { value: Validator.errorCode.must_be_an_array } );
839
- var count = 'function' === typeof this.count ? this.count( array ) : this.count;
840
- if ( isNaN( Number( count ) ) )
841
- throw new Error( 'Count must be a valid interger', count );
842
- if ( count !== array.length )
843
- throw new Violation( this, array, { count: count } );
844
- return true;
845
- };
846
- return this;
847
- },
848
- Email: function () {
849
- this.__class__ = 'Email';
850
- this.validate = function ( value ) {
851
- var regExp = /^((([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;
852
- if ( 'string' !== typeof value )
853
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
854
- if ( !regExp.test( value ) )
855
- throw new Violation( this, value );
856
- return true;
857
- };
858
- return this;
859
- },
860
- EqualTo: function ( reference ) {
861
- this.__class__ = 'EqualTo';
862
- if ( 'undefined' === typeof reference )
863
- throw new Error( 'EqualTo must be instanciated with a value or a function' );
864
- this.reference = reference;
865
- this.validate = function ( value ) {
866
- var reference = 'function' === typeof this.reference ? this.reference( value ) : this.reference;
867
- if ( reference !== value )
868
- throw new Violation( this, value, { value: reference } );
869
- return true;
870
- };
871
- return this;
872
- },
873
- GreaterThan: function ( threshold ) {
874
- this.__class__ = 'GreaterThan';
875
- if ( 'undefined' === typeof threshold )
876
- throw new Error( 'Should give a threshold value' );
877
- this.threshold = threshold;
878
- this.validate = function ( value ) {
879
- if ( '' === value || isNaN( Number( value ) ) )
880
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
881
- if ( this.threshold >= value )
882
- throw new Violation( this, value, { threshold: this.threshold } );
883
- return true;
884
- };
885
- return this;
886
- },
887
- GreaterThanOrEqual: function ( threshold ) {
888
- this.__class__ = 'GreaterThanOrEqual';
889
- if ( 'undefined' === typeof threshold )
890
- throw new Error( 'Should give a threshold value' );
891
- this.threshold = threshold;
892
- this.validate = function ( value ) {
893
- if ( '' === value || isNaN( Number( value ) ) )
894
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
895
- if ( this.threshold > value )
896
- throw new Violation( this, value, { threshold: this.threshold } );
897
- return true;
898
- };
899
- return this;
900
- },
901
- InstanceOf: function ( classRef ) {
902
- this.__class__ = 'InstanceOf';
903
- if ( 'undefined' === typeof classRef )
904
- throw new Error( 'InstanceOf must be instanciated with a value' );
905
- this.classRef = classRef;
906
- this.validate = function ( value ) {
907
- if ( true !== (value instanceof this.classRef) )
908
- throw new Violation( this, value, { classRef: this.classRef } );
909
- return true;
910
- };
911
- return this;
912
- },
913
- Length: function ( boundaries ) {
914
- this.__class__ = 'Length';
915
- if ( !boundaries.min && !boundaries.max )
916
- throw new Error( 'Lenth assert must be instanciated with a { min: x, max: y } object' );
917
- this.min = boundaries.min;
918
- this.max = boundaries.max;
919
- this.validate = function ( value ) {
920
- if ( 'string' !== typeof value && !_isArray( value ) )
921
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string_or_array } );
922
- if ( 'undefined' !== typeof this.min && this.min === this.max && value.length !== this.min )
923
- throw new Violation( this, value, { min: this.min, max: this.max } );
924
- if ( 'undefined' !== typeof this.max && value.length > this.max )
925
- throw new Violation( this, value, { max: this.max } );
926
- if ( 'undefined' !== typeof this.min && value.length < this.min )
927
- throw new Violation( this, value, { min: this.min } );
928
- return true;
929
- };
930
- return this;
931
- },
932
- LessThan: function ( threshold ) {
933
- this.__class__ = 'LessThan';
934
- if ( 'undefined' === typeof threshold )
935
- throw new Error( 'Should give a threshold value' );
936
- this.threshold = threshold;
937
- this.validate = function ( value ) {
938
- if ( '' === value || isNaN( Number( value ) ) )
939
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
940
- if ( this.threshold <= value )
941
- throw new Violation( this, value, { threshold: this.threshold } );
942
- return true;
943
- };
944
- return this;
945
- },
946
- LessThanOrEqual: function ( threshold ) {
947
- this.__class__ = 'LessThanOrEqual';
948
- if ( 'undefined' === typeof threshold )
949
- throw new Error( 'Should give a threshold value' );
950
- this.threshold = threshold;
951
- this.validate = function ( value ) {
952
- if ( '' === value || isNaN( Number( value ) ) )
953
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
954
- if ( this.threshold < value )
955
- throw new Violation( this, value, { threshold: this.threshold } );
956
- return true;
957
- };
958
- return this;
959
- },
960
- NotNull: function () {
961
- this.__class__ = 'NotNull';
962
- this.validate = function ( value ) {
963
- if ( null === value || 'undefined' === typeof value )
964
- throw new Violation( this, value );
965
- return true;
966
- };
967
- return this;
968
- },
969
- NotBlank: function () {
970
- this.__class__ = 'NotBlank';
971
- this.validate = function ( value ) {
972
- if ( 'string' !== typeof value )
973
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
974
- if ( '' === value.replace( /^\s+/g, '' ).replace( /\s+$/g, '' ) )
975
- throw new Violation( this, value );
976
- return true;
977
- };
978
- return this;
979
- },
980
- Null: function () {
981
- this.__class__ = 'Null';
982
- this.validate = function ( value ) {
983
- if ( null !== value )
984
- throw new Violation( this, value );
985
- return true;
986
- };
987
- return this;
988
- },
989
- Range: function ( min, max ) {
990
- this.__class__ = 'Range';
991
- if ( 'undefined' === typeof min || 'undefined' === typeof max )
992
- throw new Error( 'Range assert expects min and max values' );
993
- this.min = min;
994
- this.max = max;
995
- this.validate = function ( value ) {
996
- try {
997
- // validate strings and objects with their Length
998
- if ( ( 'string' === typeof value && isNaN( Number( value ) ) ) || _isArray( value ) )
999
- new Assert().Length( { min: this.min, max: this.max } ).validate( value );
1000
- // validate numbers with their value
1001
- else
1002
- new Assert().GreaterThanOrEqual( this.min ).validate( value ) && new Assert().LessThanOrEqual( this.max ).validate( value );
1003
- return true;
1004
- } catch ( violation ) {
1005
- throw new Violation( this, value, violation.violation );
1006
- }
1007
- return true;
1008
- };
1009
- return this;
1010
- },
1011
- Regexp: function ( regexp, flag ) {
1012
- this.__class__ = 'Regexp';
1013
- if ( 'undefined' === typeof regexp )
1014
- throw new Error( 'You must give a regexp' );
1015
- this.regexp = regexp;
1016
- this.flag = flag || '';
1017
- this.validate = function ( value ) {
1018
- if ( 'string' !== typeof value )
1019
- throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
1020
- if ( !new RegExp( this.regexp, this.flag ).test( value ) )
1021
- throw new Violation( this, value, { regexp: this.regexp, flag: this.flag } );
1022
- return true;
1023
- };
1024
- return this;
1025
- },
1026
- Required: function () {
1027
- this.__class__ = 'Required';
1028
- this.validate = function ( value ) {
1029
- if ( 'undefined' === typeof value )
1030
- throw new Violation( this, value );
1031
- try {
1032
- if ( 'string' === typeof value )
1033
- new Assert().NotNull().validate( value ) && new Assert().NotBlank().validate( value );
1034
- else if ( true === _isArray( value ) )
1035
- new Assert().Length( { min: 1 } ).validate( value );
1036
- } catch ( violation ) {
1037
- throw new Violation( this, value );
1038
- }
1039
- return true;
1040
- };
1041
- return this;
1042
- },
1043
- // Unique() or Unique ( { key: foo } )
1044
- Unique: function ( object ) {
1045
- this.__class__ = 'Unique';
1046
- if ( 'object' === typeof object )
1047
- this.key = object.key;
1048
- this.validate = function ( array ) {
1049
- var value, store = [];
1050
- if ( !_isArray( array ) )
1051
- throw new Violation( this, array, { value: Validator.errorCode.must_be_an_array } );
1052
- for ( var i = 0; i < array.length; i++ ) {
1053
- value = 'object' === typeof array[ i ] ? array[ i ][ this.key ] : array[ i ];
1054
- if ( 'undefined' === typeof value )
1055
- continue;
1056
- if ( -1 !== store.indexOf( value ) )
1057
- throw new Violation( this, array, { value: value } );
1058
- store.push( value );
1059
- }
1060
- return true;
1061
- };
1062
- return this;
1063
- }
1064
- };
1065
- // expose to the world these awesome classes
1066
- exports.Assert = Assert;
1067
- exports.Validator = Validator;
1068
- exports.Violation = Violation;
1069
- exports.Constraint = Constraint;
1070
- /**
1071
- * Some useful object prototypes / functions here
1072
- */
1073
- // IE8<= compatibility
1074
- // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf
1075
- if (!Array.prototype.indexOf)
1076
- Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
1077
-
1078
- if (this === null) {
1079
- throw new TypeError();
1080
- }
1081
- var t = Object(this);
1082
- var len = t.length >>> 0;
1083
- if (len === 0) {
1084
- return -1;
1085
- }
1086
- var n = 0;
1087
- if (arguments.length > 1) {
1088
- n = Number(arguments[1]);
1089
- if (n != n) { // shortcut for verifying if it's NaN
1090
- n = 0;
1091
- } else if (n !== 0 && n != Infinity && n != -Infinity) {
1092
- n = (n > 0 || -1) * Math.floor(Math.abs(n));
1093
- }
1094
- }
1095
- if (n >= len) {
1096
- return -1;
1097
- }
1098
- var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
1099
- for (; k < len; k++) {
1100
- if (k in t && t[k] === searchElement) {
1101
- return k;
1102
- }
1103
- }
1104
- return -1;
1105
- };
1106
- // Test if object is empty, useful for Constraint violations check
1107
- var _isEmptyObject = function ( obj ) {
1108
- for ( var property in obj )
1109
- return false;
1110
- return true;
1111
- };
1112
- var _isArray = function ( obj ) {
1113
- return Object.prototype.toString.call( obj ) === '[object Array]';
1114
- };
1115
- // AMD export
1116
- if ( typeof define === 'function' && define.amd ) {
1117
- define( 'vendors/validator.js/dist/validator',[],function() {
1118
- return exports;
1119
- } );
1120
- // commonjs export
1121
- } else if ( typeof module !== 'undefined' && module.exports ) {
1122
- module.exports = exports;
1123
- // browser
1124
- } else {
1125
- window[ 'undefined' !== typeof validatorjs_ns ? validatorjs_ns : 'Validator' ] = exports;
1126
- }
1127
-
1128
- return exports;
1129
- } )( );
1130
-
1131
- // This is needed for Browserify usage that requires Validator.js through module.exports
1132
- Validator = 'undefined' !== typeof Validator ? Validator : ('undefined' !== typeof module ? module.exports : null);
1133
- var ParsleyValidator = function (validators, catalog) {
1134
- this.__class__ = 'ParsleyValidator';
1135
- this.Validator = Validator;
1136
- // Default Parsley locale is en
1137
- this.locale = 'en';
1138
- this.init(validators || {}, catalog || {});
1139
- };
1140
- ParsleyValidator.prototype = {
1141
- init: function (validators, catalog) {
1142
- this.catalog = catalog;
1143
- for (var name in validators)
1144
- this.addValidator(name, validators[name].fn, validators[name].priority, validators[name].requirementsTransformer);
1145
- $.emit('parsley:validator:init');
1146
- },
1147
- // Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
1148
- setLocale: function (locale) {
1149
- if ('undefined' === typeof this.catalog[locale])
1150
- throw new Error(locale + ' is not available in the catalog');
1151
- this.locale = locale;
1152
- return this;
1153
- },
1154
- // Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
1155
- addCatalog: function (locale, messages, set) {
1156
- if ('object' === typeof messages)
1157
- this.catalog[locale] = messages;
1158
- if (true === set)
1159
- return this.setLocale(locale);
1160
- return this;
1161
- },
1162
- // Add a specific message for a given constraint in a given locale
1163
- addMessage: function (locale, name, message) {
1164
- if ('undefined' === typeof this.catalog[locale])
1165
- this.catalog[locale] = {};
1166
- this.catalog[locale][name.toLowerCase()] = message;
1167
- return this;
1168
- },
1169
- validate: function (value, constraints, priority) {
1170
- return new this.Validator.Validator().validate.apply(new Validator.Validator(), arguments);
1171
- },
1172
- // Add a new validator
1173
- addValidator: function (name, fn, priority, requirementsTransformer) {
1174
- this.validators[name.toLowerCase()] = function (requirements) {
1175
- return $.extend(new Validator.Assert().Callback(fn, requirements), {
1176
- priority: priority,
1177
- requirementsTransformer: requirementsTransformer
1178
- });
1179
- };
1180
- return this;
1181
- },
1182
- updateValidator: function (name, fn, priority, requirementsTransformer) {
1183
- return this.addValidator(name, fn, priority, requirementsTransformer);
1184
- },
1185
- removeValidator: function (name) {
1186
- delete this.validators[name];
1187
- return this;
1188
- },
1189
- getErrorMessage: function (constraint) {
1190
- var message;
1191
- // Type constraints are a bit different, we have to match their requirements too to find right error message
1192
- if ('type' === constraint.name)
1193
- message = this.catalog[this.locale][constraint.name][constraint.requirements];
1194
- else
1195
- message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
1196
- return '' !== message ? message : this.catalog[this.locale].defaultMessage;
1197
- },
1198
- // Kind of light `sprintf()` implementation
1199
- formatMessage: function (string, parameters) {
1200
- if ('object' === typeof parameters) {
1201
- for (var i in parameters)
1202
- string = this.formatMessage(string, parameters[i]);
1203
- return string;
1204
- }
1205
- return 'string' === typeof string ? string.replace(new RegExp('%s', 'i'), parameters) : '';
1206
- },
1207
- // Here is the Parsley default validators list.
1208
- // This is basically Validatorjs validators, with different API for some of them
1209
- // and a Parsley priority set
1210
- validators: {
1211
- notblank: function () {
1212
- return $.extend(new Validator.Assert().NotBlank(), { priority: 2 });
1213
- },
1214
- required: function () {
1215
- return $.extend(new Validator.Assert().Required(), { priority: 512 });
1216
- },
1217
- type: function (type) {
1218
- var assert;
1219
- switch (type) {
1220
- case 'email':
1221
- assert = new Validator.Assert().Email();
1222
- break;
1223
- // range type just ensure we have a number here
1224
- case 'range':
1225
- case 'number':
1226
- assert = new Validator.Assert().Regexp('^-?(?:\\d+|\\d{1,3}(?:,\\d{3})+)?(?:\\.\\d+)?$');
1227
- break;
1228
- case 'integer':
1229
- assert = new Validator.Assert().Regexp('^-?\\d+$');
1230
- break;
1231
- case 'digits':
1232
- assert = new Validator.Assert().Regexp('^\\d+$');
1233
- break;
1234
- case 'alphanum':
1235
- assert = new Validator.Assert().Regexp('^\\w+$', 'i');
1236
- break;
1237
- case 'url':
1238
- assert = new Validator.Assert().Regexp('(https?:\\/\\/)?(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,24}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)', 'i');
1239
- break;
1240
- default:
1241
- throw new Error('validator type `' + type + '` is not supported');
1242
- }
1243
- return $.extend(assert, { priority: 256 });
1244
- },
1245
- pattern: function (regexp) {
1246
- var flags = '';
1247
- // Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
1248
- if (!!(/^\/.*\/(?:[gimy]*)$/.test(regexp))) {
1249
- // Replace the regexp literal string with the first match group: ([gimy]*)
1250
- // If no flag is present, this will be a blank string
1251
- flags = regexp.replace(/.*\/([gimy]*)$/, '$1');
1252
- // Again, replace the regexp literal string with the first match group:
1253
- // everything excluding the opening and closing slashes and the flags
1254
- regexp = regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
1255
- }
1256
- return $.extend(new Validator.Assert().Regexp(regexp, flags), { priority: 64 });
1257
- },
1258
- minlength: function (value) {
1259
- return $.extend(new Validator.Assert().Length({ min: value }), {
1260
- priority: 30,
1261
- requirementsTransformer: function () {
1262
- return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
1263
- }
1264
- });
1265
- },
1266
- maxlength: function (value) {
1267
- return $.extend(new Validator.Assert().Length({ max: value }), {
1268
- priority: 30,
1269
- requirementsTransformer: function () {
1270
- return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
1271
- }
1272
- });
1273
- },
1274
- length: function (array) {
1275
- return $.extend(new Validator.Assert().Length({ min: array[0], max: array[1] }), { priority: 32 });
1276
- },
1277
- mincheck: function (length) {
1278
- return this.minlength(length);
1279
- },
1280
- maxcheck: function (length) {
1281
- return this.maxlength(length);
1282
- },
1283
- check: function (array) {
1284
- return this.length(array);
1285
- },
1286
- min: function (value) {
1287
- return $.extend(new Validator.Assert().GreaterThanOrEqual(value), {
1288
- priority: 30,
1289
- requirementsTransformer: function () {
1290
- return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
1291
- }
1292
- });
1293
- },
1294
- max: function (value) {
1295
- return $.extend(new Validator.Assert().LessThanOrEqual(value), {
1296
- priority: 30,
1297
- requirementsTransformer: function () {
1298
- return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
1299
- }
1300
- });
1301
- },
1302
- range: function (array) {
1303
- return $.extend(new Validator.Assert().Range(array[0], array[1]), {
1304
- priority: 32,
1305
- requirementsTransformer: function () {
1306
- for (var i = 0; i < array.length; i++)
1307
- array[i] = 'string' === typeof array[i] && !isNaN(array[i]) ? parseInt(array[i], 10) : array[i];
1308
- return array;
1309
- }
1310
- });
1311
- },
1312
- equalto: function (value) {
1313
- return $.extend(new Validator.Assert().EqualTo(value), {
1314
- priority: 256,
1315
- requirementsTransformer: function () {
1316
- return $(value).length ? $(value).val() : value;
1317
- }
1318
- });
1319
- }
1320
- }
1321
- };
1322
-
1323
- var ParsleyUI = function (options) {
1324
- this.__class__ = 'ParsleyUI';
1325
- };
1326
- ParsleyUI.prototype = {
1327
- listen: function () {
1328
- $.listen('parsley:form:init', this, this.setupForm);
1329
- $.listen('parsley:field:init', this, this.setupField);
1330
- $.listen('parsley:field:validated', this, this.reflow);
1331
- $.listen('parsley:form:validated', this, this.focus);
1332
- $.listen('parsley:field:reset', this, this.reset);
1333
- $.listen('parsley:form:destroy', this, this.destroy);
1334
- $.listen('parsley:field:destroy', this, this.destroy);
1335
- return this;
1336
- },
1337
- reflow: function (fieldInstance) {
1338
- // If this field has not an active UI (case for multiples) don't bother doing something
1339
- if ('undefined' === typeof fieldInstance._ui || false === fieldInstance._ui.active)
1340
- return;
1341
- // Diff between two validation results
1342
- var diff = this._diff(fieldInstance.validationResult, fieldInstance._ui.lastValidationResult);
1343
- // Then store current validation result for next reflow
1344
- fieldInstance._ui.lastValidationResult = fieldInstance.validationResult;
1345
- // Field have been validated at least once if here. Useful for binded key events...
1346
- fieldInstance._ui.validatedOnce = true;
1347
- // Handle valid / invalid / none field class
1348
- this.manageStatusClass(fieldInstance);
1349
- // Add, remove, updated errors messages
1350
- this.manageErrorsMessages(fieldInstance, diff);
1351
- // Triggers impl
1352
- this.actualizeTriggers(fieldInstance);
1353
- // If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user
1354
- if ((diff.kept.length || diff.added.length) && 'undefined' === typeof fieldInstance._ui.failedOnce)
1355
- this.manageFailingFieldTrigger(fieldInstance);
1356
- },
1357
- // Returns an array of field's error message(s)
1358
- getErrorsMessages: function (fieldInstance) {
1359
- // No error message, field is valid
1360
- if (true === fieldInstance.validationResult)
1361
- return [];
1362
- var messages = [];
1363
- for (var i = 0; i < fieldInstance.validationResult.length; i++)
1364
- messages.push(this._getErrorMessage(fieldInstance, fieldInstance.validationResult[i].assert));
1365
- return messages;
1366
- },
1367
- manageStatusClass: function (fieldInstance) {
1368
- if (true === fieldInstance.validationResult)
1369
- this._successClass(fieldInstance);
1370
- else if (fieldInstance.validationResult.length > 0)
1371
- this._errorClass(fieldInstance);
1372
- else
1373
- this._resetClass(fieldInstance);
1374
- },
1375
- manageErrorsMessages: function (fieldInstance, diff) {
1376
- if ('undefined' !== typeof fieldInstance.options.errorsMessagesDisabled)
1377
- return;
1378
- // Case where we have errorMessage option that configure an unique field error message, regardless failing validators
1379
- if ('undefined' !== typeof fieldInstance.options.errorMessage) {
1380
- if ((diff.added.length || diff.kept.length)) {
1381
- if (0 === fieldInstance._ui.$errorsWrapper.find('.parsley-custom-error-message').length)
1382
- fieldInstance._ui.$errorsWrapper
1383
- .append(
1384
- $(fieldInstance.options.errorTemplate)
1385
- .addClass('parsley-custom-error-message')
1386
- );
1387
- return fieldInstance._ui.$errorsWrapper
1388
- .addClass('filled')
1389
- .find('.parsley-custom-error-message')
1390
- .html(fieldInstance.options.errorMessage);
1391
- }
1392
- return fieldInstance._ui.$errorsWrapper
1393
- .removeClass('filled')
1394
- .find('.parsley-custom-error-message')
1395
- .remove();
1396
- }
1397
- // Show, hide, update failing constraints messages
1398
- for (var i = 0; i < diff.removed.length; i++)
1399
- this.removeError(fieldInstance, diff.removed[i].assert.name, true);
1400
- for (i = 0; i < diff.added.length; i++)
1401
- this.addError(fieldInstance, diff.added[i].assert.name, undefined, diff.added[i].assert, true);
1402
- for (i = 0; i < diff.kept.length; i++)
1403
- this.updateError(fieldInstance, diff.kept[i].assert.name, undefined, diff.kept[i].assert, true);
1404
- },
1405
- // TODO: strange API here, intuitive for manual usage with addError(pslyInstance, 'foo', 'bar')
1406
- // but a little bit complex for above internal usage, with forced undefined parameter...
1407
- addError: function (fieldInstance, name, message, assert, doNotUpdateClass) {
1408
- fieldInstance._ui.$errorsWrapper
1409
- .addClass('filled')
1410
- .append(
1411
- $(fieldInstance.options.errorTemplate)
1412
- .addClass('parsley-' + name)
1413
- .html(message || this._getErrorMessage(fieldInstance, assert))
1414
- );
1415
- if (true !== doNotUpdateClass)
1416
- this._errorClass(fieldInstance);
1417
- },
1418
- // Same as above
1419
- updateError: function (fieldInstance, name, message, assert, doNotUpdateClass) {
1420
- fieldInstance._ui.$errorsWrapper
1421
- .addClass('filled')
1422
- .find('.parsley-' + name)
1423
- .html(message || this._getErrorMessage(fieldInstance, assert));
1424
- if (true !== doNotUpdateClass)
1425
- this._errorClass(fieldInstance);
1426
- },
1427
- // Same as above twice
1428
- removeError: function (fieldInstance, name, doNotUpdateClass) {
1429
- fieldInstance._ui.$errorsWrapper
1430
- .removeClass('filled')
1431
- .find('.parsley-' + name)
1432
- .remove();
1433
- // edge case possible here: remove a standard Parsley error that is still failing in fieldInstance.validationResult
1434
- // but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
1435
- if (true !== doNotUpdateClass)
1436
- this.manageStatusClass(fieldInstance);
1437
- },
1438
- focus: function (formInstance) {
1439
- if (true === formInstance.validationResult || 'none' === formInstance.options.focus)
1440
- return formInstance._focusedField = null;
1441
- formInstance._focusedField = null;
1442
- for (var i = 0; i < formInstance.fields.length; i++)
1443
- if (true !== formInstance.fields[i].validationResult && formInstance.fields[i].validationResult.length > 0 && 'undefined' === typeof formInstance.fields[i].options.noFocus) {
1444
- if ('first' === formInstance.options.focus) {
1445
- formInstance._focusedField = formInstance.fields[i].$element;
1446
- return formInstance._focusedField.focus();
1447
- }
1448
- formInstance._focusedField = formInstance.fields[i].$element;
1449
- }
1450
- if (null === formInstance._focusedField)
1451
- return null;
1452
- return formInstance._focusedField.focus();
1453
- },
1454
- _getErrorMessage: function (fieldInstance, constraint) {
1455
- var customConstraintErrorMessage = constraint.name + 'Message';
1456
- if ('undefined' !== typeof fieldInstance.options[customConstraintErrorMessage])
1457
- return window.ParsleyValidator.formatMessage(fieldInstance.options[customConstraintErrorMessage], constraint.requirements);
1458
- return window.ParsleyValidator.getErrorMessage(constraint);
1459
- },
1460
- _diff: function (newResult, oldResult, deep) {
1461
- var
1462
- added = [],
1463
- kept = [];
1464
- for (var i = 0; i < newResult.length; i++) {
1465
- var found = false;
1466
- for (var j = 0; j < oldResult.length; j++)
1467
- if (newResult[i].assert.name === oldResult[j].assert.name) {
1468
- found = true;
1469
- break;
1470
- }
1471
- if (found)
1472
- kept.push(newResult[i]);
1473
- else
1474
- added.push(newResult[i]);
1475
- }
1476
- return {
1477
- kept: kept,
1478
- added: added,
1479
- removed: !deep ? this._diff(oldResult, newResult, true).added : []
1480
- };
1481
- },
1482
- setupForm: function (formInstance) {
1483
- formInstance.$element.on('submit.Parsley', false, $.proxy(formInstance.onSubmitValidate, formInstance));
1484
- // UI could be disabled
1485
- if (false === formInstance.options.uiEnabled)
1486
- return;
1487
- formInstance.$element.attr('novalidate', '');
1488
- },
1489
- setupField: function (fieldInstance) {
1490
- var _ui = { active: false };
1491
- // UI could be disabled
1492
- if (false === fieldInstance.options.uiEnabled)
1493
- return;
1494
- _ui.active = true;
1495
- // Give field its Parsley id in DOM
1496
- fieldInstance.$element.attr(fieldInstance.options.namespace + 'id', fieldInstance.__id__);
1497
- /** Generate important UI elements and store them in fieldInstance **/
1498
- // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
1499
- _ui.$errorClassHandler = this._manageClassHandler(fieldInstance);
1500
- // $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer
1501
- _ui.errorsWrapperId = 'parsley-id-' + ('undefined' !== typeof fieldInstance.options.multiple ? 'multiple-' + fieldInstance.options.multiple : fieldInstance.__id__);
1502
- _ui.$errorsWrapper = $(fieldInstance.options.errorsWrapper).attr('id', _ui.errorsWrapperId);
1503
- // ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly
1504
- _ui.lastValidationResult = [];
1505
- _ui.validatedOnce = false;
1506
- _ui.validationInformationVisible = false;
1507
- // Store it in fieldInstance for later
1508
- fieldInstance._ui = _ui;
1509
- // Stops excluded inputs from getting errorContainer added
1510
- if( !fieldInstance.$element.is(fieldInstance.options.excluded) ) {
1511
- /** Mess with DOM now **/
1512
- this._insertErrorWrapper(fieldInstance);
1513
- }
1514
- // Bind triggers first time
1515
- this.actualizeTriggers(fieldInstance);
1516
- },
1517
- // Determine which element will have `parsley-error` and `parsley-success` classes
1518
- _manageClassHandler: function (fieldInstance) {
1519
- // An element selector could be passed through DOM with `data-parsley-class-handler=#foo`
1520
- if ('string' === typeof fieldInstance.options.classHandler && $(fieldInstance.options.classHandler).length)
1521
- return $(fieldInstance.options.classHandler);
1522
- // Class handled could also be determined by function given in Parsley options
1523
- var $handler = fieldInstance.options.classHandler(fieldInstance);
1524
- // If this function returned a valid existing DOM element, go for it
1525
- if ('undefined' !== typeof $handler && $handler.length)
1526
- return $handler;
1527
- // Otherwise, if simple element (input, texatrea, select...) it will perfectly host the classes
1528
- if ('undefined' === typeof fieldInstance.options.multiple || fieldInstance.$element.is('select'))
1529
- return fieldInstance.$element;
1530
- // But if multiple element (radio, checkbox), that would be their parent
1531
- return fieldInstance.$element.parent();
1532
- },
1533
- _insertErrorWrapper: function (fieldInstance) {
1534
- var $errorsContainer;
1535
- if ('string' === typeof fieldInstance.options.errorsContainer) {
1536
- if ($(fieldInstance.options.errorsContainer).length)
1537
- return $(fieldInstance.options.errorsContainer).append(fieldInstance._ui.$errorsWrapper);
1538
- else if (window.console && window.console.warn)
1539
- window.console.warn('The errors container `' + fieldInstance.options.errorsContainer + '` does not exist in DOM');
1540
- }
1541
- else if ('function' === typeof fieldInstance.options.errorsContainer)
1542
- $errorsContainer = fieldInstance.options.errorsContainer(fieldInstance);
1543
- if ('undefined' !== typeof $errorsContainer && $errorsContainer.length)
1544
- return $errorsContainer.append(fieldInstance._ui.$errorsWrapper);
1545
- return 'undefined' === typeof fieldInstance.options.multiple ? fieldInstance.$element.after(fieldInstance._ui.$errorsWrapper) : fieldInstance.$element.parent().after(fieldInstance._ui.$errorsWrapper);
1546
- },
1547
- actualizeTriggers: function (fieldInstance) {
1548
- var $toBind = fieldInstance.$element;
1549
- if (fieldInstance.options.multiple)
1550
- $toBind = $('[' + fieldInstance.options.namespace + 'multiple="' + fieldInstance.options.multiple + '"]')
1551
- // Remove Parsley events already binded on this field
1552
- $toBind.off('.Parsley');
1553
- // If no trigger is set, all good
1554
- if (false === fieldInstance.options.trigger)
1555
- return;
1556
- var triggers = fieldInstance.options.trigger.replace(/^\s+/g , '').replace(/\s+$/g , '');
1557
- if ('' === triggers)
1558
- return;
1559
- // Bind fieldInstance.eventValidate if exists (for parsley.ajax for example), ParsleyUI.eventValidate otherwise
1560
- $toBind.on(
1561
- triggers.split(' ').join('.Parsley ') + '.Parsley',
1562
- $.proxy('function' === typeof fieldInstance.eventValidate ? fieldInstance.eventValidate : this.eventValidate, fieldInstance));
1563
- },
1564
- // Called through $.proxy with fieldInstance. `this` context is ParsleyField
1565
- eventValidate: function(event) {
1566
- // For keyup, keypress, keydown... events that could be a little bit obstrusive
1567
- // do not validate if val length < min threshold on first validation. Once field have been validated once and info
1568
- // about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
1569
- if (new RegExp('key').test(event.type))
1570
- if (!this._ui.validationInformationVisible && this.getValue().length <= this.options.validationThreshold)
1571
- return;
1572
- this._ui.validatedOnce = true;
1573
- this.validate();
1574
- },
1575
- manageFailingFieldTrigger: function (fieldInstance) {
1576
- fieldInstance._ui.failedOnce = true;
1577
- // Radio and checkboxes fields must bind every field multiple
1578
- if (fieldInstance.options.multiple)
1579
- $('[' + fieldInstance.options.namespace + 'multiple="' + fieldInstance.options.multiple + '"]').each(function () {
1580
- if (!new RegExp('change', 'i').test($(this).parsley().options.trigger || ''))
1581
- return $(this).on('change.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
1582
- });
1583
- // Select case
1584
- if (fieldInstance.$element.is('select'))
1585
- if (!new RegExp('change', 'i').test(fieldInstance.options.trigger || ''))
1586
- return fieldInstance.$element.on('change.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
1587
- // All other inputs fields
1588
- if (!new RegExp('keyup', 'i').test(fieldInstance.options.trigger || ''))
1589
- return fieldInstance.$element.on('keyup.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
1590
- },
1591
- reset: function (parsleyInstance) {
1592
- // Reset all event listeners
1593
- parsleyInstance.$element.off('.Parsley');
1594
- parsleyInstance.$element.off('.ParsleyFailedOnce');
1595
- // Nothing to do if UI never initialized for this field
1596
- if ('undefined' === typeof parsleyInstance._ui)
1597
- return;
1598
- if ('ParsleyForm' === parsleyInstance.__class__)
1599
- return;
1600
- // Reset all errors' li
1601
- parsleyInstance._ui.$errorsWrapper
1602
- .removeClass('filled')
1603
- .children()
1604
- .remove();
1605
- // Reset validation class
1606
- this._resetClass(parsleyInstance);
1607
- // Reset validation flags and last validation result
1608
- parsleyInstance._ui.validatedOnce = false;
1609
- parsleyInstance._ui.lastValidationResult = [];
1610
- parsleyInstance._ui.validationInformationVisible = false;
1611
- },
1612
- destroy: function (parsleyInstance) {
1613
- this.reset(parsleyInstance);
1614
- if ('ParsleyForm' === parsleyInstance.__class__)
1615
- return;
1616
- if ('undefined' !== typeof parsleyInstance._ui)
1617
- parsleyInstance._ui.$errorsWrapper.remove();
1618
- delete parsleyInstance._ui;
1619
- },
1620
- _successClass: function (fieldInstance) {
1621
- fieldInstance._ui.validationInformationVisible = true;
1622
- fieldInstance._ui.$errorClassHandler.removeClass(fieldInstance.options.errorClass).addClass(fieldInstance.options.successClass);
1623
- },
1624
- _errorClass: function (fieldInstance) {
1625
- fieldInstance._ui.validationInformationVisible = true;
1626
- fieldInstance._ui.$errorClassHandler.removeClass(fieldInstance.options.successClass).addClass(fieldInstance.options.errorClass);
1627
- },
1628
- _resetClass: function (fieldInstance) {
1629
- fieldInstance._ui.$errorClassHandler.removeClass(fieldInstance.options.successClass).removeClass(fieldInstance.options.errorClass);
1630
- }
1631
- };
1632
-
1633
- var ParsleyOptionsFactory = function (defaultOptions, globalOptions, userOptions, namespace) {
1634
- this.__class__ = 'OptionsFactory';
1635
- this.__id__ = ParsleyUtils.hash(4);
1636
- this.formOptions = null;
1637
- this.fieldOptions = null;
1638
- this.staticOptions = $.extend(true, {}, defaultOptions, globalOptions, userOptions, { namespace: namespace });
1639
- };
1640
- ParsleyOptionsFactory.prototype = {
1641
- get: function (parsleyInstance) {
1642
- if ('undefined' === typeof parsleyInstance.__class__)
1643
- throw new Error('Parsley Instance expected');
1644
- switch (parsleyInstance.__class__) {
1645
- case 'Parsley':
1646
- return this.staticOptions;
1647
- case 'ParsleyForm':
1648
- return this.getFormOptions(parsleyInstance);
1649
- case 'ParsleyField':
1650
- case 'ParsleyFieldMultiple':
1651
- return this.getFieldOptions(parsleyInstance);
1652
- default:
1653
- throw new Error('Instance ' + parsleyInstance.__class__ + ' is not supported');
1654
- }
1655
- },
1656
- getFormOptions: function (formInstance) {
1657
- this.formOptions = ParsleyUtils.attr(formInstance.$element, this.staticOptions.namespace);
1658
- // not deep extend, since formOptions is a 1 level deep object
1659
- return $.extend({}, this.staticOptions, this.formOptions);
1660
- },
1661
- getFieldOptions: function (fieldInstance) {
1662
- this.fieldOptions = ParsleyUtils.attr(fieldInstance.$element, this.staticOptions.namespace);
1663
- if (null === this.formOptions && 'undefined' !== typeof fieldInstance.parent)
1664
- this.formOptions = this.getFormOptions(fieldInstance.parent);
1665
- // not deep extend, since formOptions and fieldOptions is a 1 level deep object
1666
- return $.extend({}, this.staticOptions, this.formOptions, this.fieldOptions);
1667
- }
1668
- };
1669
-
1670
- var ParsleyForm = function (element, OptionsFactory) {
1671
- this.__class__ = 'ParsleyForm';
1672
- this.__id__ = ParsleyUtils.hash(4);
1673
- if ('OptionsFactory' !== ParsleyUtils.get(OptionsFactory, '__class__'))
1674
- throw new Error('You must give an OptionsFactory instance');
1675
- this.OptionsFactory = OptionsFactory;
1676
- this.$element = $(element);
1677
- this.validationResult = null;
1678
- this.options = this.OptionsFactory.get(this);
1679
- };
1680
- ParsleyForm.prototype = {
1681
- onSubmitValidate: function (event) {
1682
- this.validate(undefined, undefined, event);
1683
- // prevent form submission if validation fails
1684
- if (false === this.validationResult && event instanceof $.Event) {
1685
- event.stopImmediatePropagation();
1686
- event.preventDefault();
1687
- }
1688
- return this;
1689
- },
1690
- // @returns boolean
1691
- validate: function (group, force, event) {
1692
- this.submitEvent = event;
1693
- this.validationResult = true;
1694
- var fieldValidationResult = [];
1695
- $.emit('parsley:form:validate', this);
1696
- // Refresh form DOM options and form's fields that could have changed
1697
- this._refreshFields();
1698
- // loop through fields to validate them one by one
1699
- for (var i = 0; i < this.fields.length; i++) {
1700
- // do not validate a field if not the same as given validation group
1701
- if (group && !this._isFieldInGroup(this.fields[i], group))
1702
- continue;
1703
- fieldValidationResult = this.fields[i].validate(force);
1704
- if (true !== fieldValidationResult && fieldValidationResult.length > 0 && this.validationResult)
1705
- this.validationResult = false;
1706
- }
1707
- $.emit('parsley:form:' + (this.validationResult ? 'success' : 'error'), this);
1708
- $.emit('parsley:form:validated', this);
1709
- return this.validationResult;
1710
- },
1711
- // Iterate over refreshed fields, and stop on first failure
1712
- isValid: function (group, force) {
1713
- this._refreshFields();
1714
- for (var i = 0; i < this.fields.length; i++) {
1715
- // do not validate a field if not the same as given validation group
1716
- if (group && !this._isFieldInGroup(this.fields[i], group))
1717
- continue;
1718
- if (false === this.fields[i].isValid(force))
1719
- return false;
1720
- }
1721
- return true;
1722
- },
1723
- _isFieldInGroup: function (field, group) {
1724
- if(ParsleyUtils.isArray(field.options.group))
1725
- return -1 !== $.inArray(group, field.options.group);
1726
- return field.options.group === group;
1727
- },
1728
- _refreshFields: function () {
1729
- return this.actualizeOptions()._bindFields();
1730
- },
1731
- _bindFields: function () {
1732
- var self = this;
1733
- this.fields = [];
1734
- this.fieldsMappedById = {};
1735
- this.$element.find(this.options.inputs).each(function () {
1736
- var fieldInstance = new window.Parsley(this, {}, self);
1737
- // Only add valid and not excluded `ParsleyField` and `ParsleyFieldMultiple` children
1738
- if (('ParsleyField' === fieldInstance.__class__ || 'ParsleyFieldMultiple' === fieldInstance.__class__) && !fieldInstance.$element.is(fieldInstance.options.excluded))
1739
- if ('undefined' === typeof self.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__]) {
1740
- self.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__] = fieldInstance;
1741
- self.fields.push(fieldInstance);
1742
- }
1743
- });
1744
- return this;
1745
- }
1746
- };
1747
-
1748
- var ConstraintFactory = function (parsleyField, name, requirements, priority, isDomConstraint) {
1749
- var assert = {};
1750
- if (!new RegExp('ParsleyField').test(ParsleyUtils.get(parsleyField, '__class__')))
1751
- throw new Error('ParsleyField or ParsleyFieldMultiple instance expected');
1752
- if ('function' === typeof window.ParsleyValidator.validators[name])
1753
- assert = window.ParsleyValidator.validators[name](requirements);
1754
- if ('Assert' !== assert.__parentClass__)
1755
- throw new Error('Valid validator expected');
1756
- var getPriority = function () {
1757
- if ('undefined' !== typeof parsleyField.options[name + 'Priority'])
1758
- return parsleyField.options[name + 'Priority'];
1759
- return ParsleyUtils.get(assert, 'priority') || 2;
1760
- };
1761
- priority = priority || getPriority();
1762
- // If validator have a requirementsTransformer, execute it
1763
- if ('function' === typeof assert.requirementsTransformer) {
1764
- requirements = assert.requirementsTransformer();
1765
- // rebuild assert with new requirements
1766
- assert = window.ParsleyValidator.validators[name](requirements);
1767
- }
1768
- return $.extend(assert, {
1769
- name: name,
1770
- requirements: requirements,
1771
- priority: priority,
1772
- groups: [priority],
1773
- isDomConstraint: isDomConstraint || ParsleyUtils.attr(parsleyField.$element, parsleyField.options.namespace, name)
1774
- });
1775
- };
1776
-
1777
- var ParsleyField = function (field, OptionsFactory, parsleyFormInstance) {
1778
- this.__class__ = 'ParsleyField';
1779
- this.__id__ = ParsleyUtils.hash(4);
1780
- this.$element = $(field);
1781
- // If we have a parent `ParsleyForm` instance given, use its `OptionsFactory`, and save parent
1782
- if ('undefined' !== typeof parsleyFormInstance) {
1783
- this.parent = parsleyFormInstance;
1784
- this.OptionsFactory = this.parent.OptionsFactory;
1785
- this.options = this.OptionsFactory.get(this);
1786
- // Else, take the `Parsley` one
1787
- } else {
1788
- this.OptionsFactory = OptionsFactory;
1789
- this.options = this.OptionsFactory.get(this);
1790
- }
1791
- // Initialize some properties
1792
- this.constraints = [];
1793
- this.constraintsByName = {};
1794
- this.validationResult = [];
1795
- // Bind constraints
1796
- this._bindConstraints();
1797
- };
1798
- ParsleyField.prototype = {
1799
- // # Public API
1800
- // Validate field and $.emit some events for mainly `ParsleyUI`
1801
- // @returns validationResult:
1802
- // - `true` if all constraints pass
1803
- // - `[]` if not required field and empty (not validated)
1804
- // - `[Violation, [Violation...]]` if there were validation errors
1805
- validate: function (force) {
1806
- this.value = this.getValue();
1807
- // Field Validate event. `this.value` could be altered for custom needs
1808
- $.emit('parsley:field:validate', this);
1809
- $.emit('parsley:field:' + (this.isValid(force, this.value) ? 'success' : 'error'), this);
1810
- // Field validated event. `this.validationResult` could be altered for custom needs too
1811
- $.emit('parsley:field:validated', this);
1812
- return this.validationResult;
1813
- },
1814
- // Just validate field. Do not trigger any event
1815
- // Same @return as `validate()`
1816
- isValid: function (force, value) {
1817
- // Recompute options and rebind constraints to have latest changes
1818
- this.refreshConstraints();
1819
- // Sort priorities to validate more important first
1820
- var priorities = this._getConstraintsSortedPriorities();
1821
- if (0 === priorities.length)
1822
- return this.validationResult = [];
1823
- // Value could be passed as argument, needed to add more power to 'parsley:field:validate'
1824
- if ('undefined' === typeof value || null === value)
1825
- value = this.getValue();
1826
- // If a field is empty and not required, leave it alone, it's just fine
1827
- // Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
1828
- if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty && true !== force)
1829
- return this.validationResult = [];
1830
- // If we want to validate field against all constraints, just call Validator and let it do the job
1831
- if (false === this.options.priorityEnabled)
1832
- return true === (this.validationResult = this.validateThroughValidator(value, this.constraints, 'Any'));
1833
- // Else, iterate over priorities one by one, and validate related asserts one by one
1834
- for (var i = 0; i < priorities.length; i++)
1835
- if (true !== (this.validationResult = this.validateThroughValidator(value, this.constraints, priorities[i])))
1836
- return false;
1837
- return true;
1838
- },
1839
- // @returns Parsley field computed value that could be overrided or configured in DOM
1840
- getValue: function () {
1841
- var value;
1842
- // Value could be overriden in DOM
1843
- if ('undefined' !== typeof this.options.value)
1844
- value = this.options.value;
1845
- else
1846
- value = this.$element.val();
1847
- // Handle wrong DOM or configurations
1848
- if ('undefined' === typeof value || null === value)
1849
- return '';
1850
- // Use `data-parsley-trim-value="true"` to auto trim inputs entry
1851
- if (true === this.options.trimValue)
1852
- return value.replace(/^\s+|\s+$/g, '');
1853
- return value;
1854
- },
1855
- // Actualize options that could have change since previous validation
1856
- // Re-bind accordingly constraints (could be some new, removed or updated)
1857
- refreshConstraints: function () {
1858
- return this.actualizeOptions()._bindConstraints();
1859
- },
1860
- /**
1861
- * Add a new constraint to a field
1862
- *
1863
- * @method addConstraint
1864
- * @param {String} name
1865
- * @param {Mixed} requirements optional
1866
- * @param {Number} priority optional
1867
- * @param {Boolean} isDomConstraint optional
1868
- */
1869
- addConstraint: function (name, requirements, priority, isDomConstraint) {
1870
- name = name.toLowerCase();
1871
- if ('function' === typeof window.ParsleyValidator.validators[name]) {
1872
- var constraint = new ConstraintFactory(this, name, requirements, priority, isDomConstraint);
1873
- // if constraint already exist, delete it and push new version
1874
- if ('undefined' !== this.constraintsByName[constraint.name])
1875
- this.removeConstraint(constraint.name);
1876
- this.constraints.push(constraint);
1877
- this.constraintsByName[constraint.name] = constraint;
1878
- }
1879
- return this;
1880
- },
1881
- // Remove a constraint
1882
- removeConstraint: function (name) {
1883
- for (var i = 0; i < this.constraints.length; i++)
1884
- if (name === this.constraints[i].name) {
1885
- this.constraints.splice(i, 1);
1886
- break;
1887
- }
1888
- delete this.constraintsByName[name];
1889
- return this;
1890
- },
1891
- // Update a constraint (Remove + re-add)
1892
- updateConstraint: function (name, parameters, priority) {
1893
- return this.removeConstraint(name)
1894
- .addConstraint(name, parameters, priority);
1895
- },
1896
- // # Internals
1897
- // Internal only.
1898
- // Bind constraints from config + options + DOM
1899
- _bindConstraints: function () {
1900
- var constraints = [], constraintsByName = {};
1901
- // clean all existing DOM constraints to only keep javascript user constraints
1902
- for (var i = 0; i < this.constraints.length; i++)
1903
- if (false === this.constraints[i].isDomConstraint) {
1904
- constraints.push(this.constraints[i]);
1905
- constraintsByName[this.constraints[i].name] = this.constraints[i];
1906
- }
1907
- this.constraints = constraints;
1908
- this.constraintsByName = constraintsByName;
1909
- // then re-add Parsley DOM-API constraints
1910
- for (var name in this.options)
1911
- this.addConstraint(name, this.options[name]);
1912
- // finally, bind special HTML5 constraints
1913
- return this._bindHtml5Constraints();
1914
- },
1915
- // Internal only.
1916
- // Bind specific HTML5 constraints to be HTML5 compliant
1917
- _bindHtml5Constraints: function () {
1918
- // html5 required
1919
- if (this.$element.hasClass('required') || this.$element.attr('required'))
1920
- this.addConstraint('required', true, undefined, true);
1921
- // html5 pattern
1922
- if ('string' === typeof this.$element.attr('pattern'))
1923
- this.addConstraint('pattern', this.$element.attr('pattern'), undefined, true);
1924
- // range
1925
- if ('undefined' !== typeof this.$element.attr('min') && 'undefined' !== typeof this.$element.attr('max'))
1926
- this.addConstraint('range', [this.$element.attr('min'), this.$element.attr('max')], undefined, true);
1927
- // HTML5 min
1928
- else if ('undefined' !== typeof this.$element.attr('min'))
1929
- this.addConstraint('min', this.$element.attr('min'), undefined, true);
1930
- // HTML5 max
1931
- else if ('undefined' !== typeof this.$element.attr('max'))
1932
- this.addConstraint('max', this.$element.attr('max'), undefined, true);
1933
-
1934
- // length
1935
- if ('undefined' !== typeof this.$element.attr('minlength') && 'undefined' !== typeof this.$element.attr('maxlength'))
1936
- this.addConstraint('length', [this.$element.attr('minlength'), this.$element.attr('maxlength')], undefined, true);
1937
- // HTML5 minlength
1938
- else if ('undefined' !== typeof this.$element.attr('minlength'))
1939
- this.addConstraint('minlength', this.$element.attr('minlength'), undefined, true);
1940
- // HTML5 maxlength
1941
- else if ('undefined' !== typeof this.$element.attr('maxlength'))
1942
- this.addConstraint('maxlength', this.$element.attr('maxlength'), undefined, true);
1943
-
1944
- // html5 types
1945
- var type = this.$element.attr('type');
1946
- if ('undefined' === typeof type)
1947
- return this;
1948
- // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
1949
- if ('number' === type) {
1950
- if (('undefined' === typeof this.$element.attr('step')) || (0 === parseFloat(this.$element.attr('step')) % 1)) {
1951
- return this.addConstraint('type', 'integer', undefined, true);
1952
- } else {
1953
- return this.addConstraint('type', 'number', undefined, true);
1954
- }
1955
- // Regular other HTML5 supported types
1956
- } else if (new RegExp(type, 'i').test('email url range')) {
1957
- return this.addConstraint('type', type, undefined, true);
1958
- }
1959
- return this;
1960
- },
1961
- // Internal only.
1962
- // Field is required if have required constraint without `false` value
1963
- _isRequired: function () {
1964
- if ('undefined' === typeof this.constraintsByName.required)
1965
- return false;
1966
- return false !== this.constraintsByName.required.requirements;
1967
- },
1968
- // Internal only.
1969
- // Sort constraints by priority DESC
1970
- _getConstraintsSortedPriorities: function () {
1971
- var priorities = [];
1972
- // Create array unique of priorities
1973
- for (var i = 0; i < this.constraints.length; i++)
1974
- if (-1 === priorities.indexOf(this.constraints[i].priority))
1975
- priorities.push(this.constraints[i].priority);
1976
- // Sort them by priority DESC
1977
- priorities.sort(function (a, b) { return b - a; });
1978
- return priorities;
1979
- }
1980
- };
1981
-
1982
- var ParsleyMultiple = function () {
1983
- this.__class__ = 'ParsleyFieldMultiple';
1984
- };
1985
- ParsleyMultiple.prototype = {
1986
- // Add new `$element` sibling for multiple field
1987
- addElement: function ($element) {
1988
- this.$elements.push($element);
1989
- return this;
1990
- },
1991
- // See `ParsleyField.refreshConstraints()`
1992
- refreshConstraints: function () {
1993
- var fieldConstraints;
1994
- this.constraints = [];
1995
- // Select multiple special treatment
1996
- if (this.$element.is('select')) {
1997
- this.actualizeOptions()._bindConstraints();
1998
- return this;
1999
- }
2000
- // Gather all constraints for each input in the multiple group
2001
- for (var i = 0; i < this.$elements.length; i++) {
2002
- // Check if element have not been dynamically removed since last binding
2003
- if (!$('html').has(this.$elements[i]).length) {
2004
- this.$elements.splice(i, 1);
2005
- continue;
2006
- }
2007
- fieldConstraints = this.$elements[i].data('ParsleyFieldMultiple').refreshConstraints().constraints;
2008
- for (var j = 0; j < fieldConstraints.length; j++)
2009
- this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);
2010
- }
2011
- return this;
2012
- },
2013
- // See `ParsleyField.getValue()`
2014
- getValue: function () {
2015
- // Value could be overriden in DOM
2016
- if ('undefined' !== typeof this.options.value)
2017
- return this.options.value;
2018
- // Radio input case
2019
- if (this.$element.is('input[type=radio]'))
2020
- return $('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]:checked').val() || '';
2021
- // checkbox input case
2022
- if (this.$element.is('input[type=checkbox]')) {
2023
- var values = [];
2024
- $('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]:checked').each(function () {
2025
- values.push($(this).val());
2026
- });
2027
- return values.length ? values : [];
2028
- }
2029
- // Select multiple case
2030
- if (this.$element.is('select') && null === this.$element.val())
2031
- return [];
2032
- // Default case that should never happen
2033
- return this.$element.val();
2034
- },
2035
- _init: function (multiple) {
2036
- this.$elements = [this.$element];
2037
- this.options.multiple = multiple;
2038
- return this;
2039
- }
2040
- };
2041
-
2042
- var
2043
- o = $({}),
2044
- subscribed = {};
2045
- // $.listen(name, callback);
2046
- // $.listen(name, context, callback);
2047
- $.listen = function (name) {
2048
- if ('undefined' === typeof subscribed[name])
2049
- subscribed[name] = [];
2050
- if ('function' === typeof arguments[1])
2051
- return subscribed[name].push({ fn: arguments[1] });
2052
- if ('object' === typeof arguments[1] && 'function' === typeof arguments[2])
2053
- return subscribed[name].push({ fn: arguments[2], ctxt: arguments[1] });
2054
- throw new Error('Wrong parameters');
2055
- };
2056
- $.listenTo = function (instance, name, fn) {
2057
- if ('undefined' === typeof subscribed[name])
2058
- subscribed[name] = [];
2059
- if (!(instance instanceof ParsleyField) && !(instance instanceof ParsleyForm))
2060
- throw new Error('Must give Parsley instance');
2061
- if ('string' !== typeof name || 'function' !== typeof fn)
2062
- throw new Error('Wrong parameters');
2063
- subscribed[name].push({ instance: instance, fn: fn });
2064
- };
2065
- $.unsubscribe = function (name, fn) {
2066
- if ('undefined' === typeof subscribed[name])
2067
- return;
2068
- if ('string' !== typeof name || 'function' !== typeof fn)
2069
- throw new Error('Wrong arguments');
2070
- for (var i = 0; i < subscribed[name].length; i++)
2071
- if (subscribed[name][i].fn === fn)
2072
- return subscribed[name].splice(i, 1);
2073
- };
2074
- $.unsubscribeTo = function (instance, name) {
2075
- if ('undefined' === typeof subscribed[name])
2076
- return;
2077
- if (!(instance instanceof ParsleyField) && !(instance instanceof ParsleyForm))
2078
- throw new Error('Must give Parsley instance');
2079
- for (var i = 0; i < subscribed[name].length; i++)
2080
- if ('undefined' !== typeof subscribed[name][i].instance && subscribed[name][i].instance.__id__ === instance.__id__)
2081
- return subscribed[name].splice(i, 1);
2082
- };
2083
- $.unsubscribeAll = function (name) {
2084
- if ('undefined' === typeof subscribed[name])
2085
- return;
2086
- delete subscribed[name];
2087
- };
2088
- // $.emit(name [, arguments...]);
2089
- // $.emit(name, instance [, arguments...]);
2090
- $.emit = function (name, instance) {
2091
- if ('undefined' === typeof subscribed[name])
2092
- return;
2093
- // loop through registered callbacks for this event
2094
- for (var i = 0; i < subscribed[name].length; i++) {
2095
- // if instance is not registered, simple emit
2096
- if ('undefined' === typeof subscribed[name][i].instance) {
2097
- subscribed[name][i].fn.apply('undefined' !== typeof subscribed[name][i].ctxt ? subscribed[name][i].ctxt : o, Array.prototype.slice.call(arguments, 1));
2098
- continue;
2099
- }
2100
- // if instance registered but no instance given for the emit, continue
2101
- if (!(instance instanceof ParsleyField) && !(instance instanceof ParsleyForm))
2102
- continue;
2103
- // if instance is registered and same id, emit
2104
- if (subscribed[name][i].instance.__id__ === instance.__id__) {
2105
- subscribed[name][i].fn.apply(o, Array.prototype.slice.call(arguments, 1));
2106
- continue;
2107
- }
2108
- // if registered instance is a Form and fired one is a Field, loop over all its fields and emit if field found
2109
- if (subscribed[name][i].instance instanceof ParsleyForm && instance instanceof ParsleyField)
2110
- for (var j = 0; j < subscribed[name][i].instance.fields.length; j++)
2111
- if (subscribed[name][i].instance.fields[j].__id__ === instance.__id__) {
2112
- subscribed[name][i].fn.apply(o, Array.prototype.slice.call(arguments, 1));
2113
- continue;
2114
- }
2115
- }
2116
- };
2117
- $.subscribed = function () { return subscribed; };
2118
-
2119
- // ParsleyConfig definition if not already set
2120
- window.ParsleyConfig = window.ParsleyConfig || {};
2121
- window.ParsleyConfig.i18n = window.ParsleyConfig.i18n || {};
2122
- // Define then the messages
2123
- window.ParsleyConfig.i18n.en = $.extend(window.ParsleyConfig.i18n.en || {}, {
2124
- defaultMessage: "This value seems to be invalid.",
2125
- type: {
2126
- email: "This value should be a valid email.",
2127
- url: "This value should be a valid url.",
2128
- number: "This value should be a valid number.",
2129
- integer: "This value should be a valid integer.",
2130
- digits: "This value should be digits.",
2131
- alphanum: "This value should be alphanumeric."
2132
- },
2133
- notblank: "This value should not be blank.",
2134
- required: "This value is required.",
2135
- pattern: "This value seems to be invalid.",
2136
- min: "This value should be greater than or equal to %s.",
2137
- max: "This value should be lower than or equal to %s.",
2138
- range: "This value should be between %s and %s.",
2139
- minlength: "This value is too short. It should have %s characters or more.",
2140
- maxlength: "This value is too long. It should have %s characters or fewer.",
2141
- length: "This value length is invalid. It should be between %s and %s characters long.",
2142
- mincheck: "You must select at least %s choices.",
2143
- maxcheck: "You must select %s choices or fewer.",
2144
- check: "You must select between %s and %s choices.",
2145
- equalto: "This value should be the same."
2146
- });
2147
- // If file is loaded after Parsley main file, auto-load locale
2148
- if ('undefined' !== typeof window.ParsleyValidator)
2149
- window.ParsleyValidator.addCatalog('en', window.ParsleyConfig.i18n.en, true);
2150
-
2151
- // Parsley.js 2.0.6
2152
- // http://parsleyjs.org
2153
- // (c) 20012-2014 Guillaume Potier, Wisembly
2154
- // Parsley may be freely distributed under the MIT license.
2155
-
2156
- // ### Parsley factory
2157
- var Parsley = function (element, options, parsleyFormInstance) {
2158
- this.__class__ = 'Parsley';
2159
- this.__version__ = '2.0.6';
2160
- this.__id__ = ParsleyUtils.hash(4);
2161
- // Parsley must be instantiated with a DOM element or jQuery $element
2162
- if ('undefined' === typeof element)
2163
- throw new Error('You must give an element');
2164
- if ('undefined' !== typeof parsleyFormInstance && 'ParsleyForm' !== parsleyFormInstance.__class__)
2165
- throw new Error('Parent instance must be a ParsleyForm instance');
2166
- return this.init($(element), options, parsleyFormInstance);
2167
- };
2168
- Parsley.prototype = {
2169
- init: function ($element, options, parsleyFormInstance) {
2170
- if (!$element.length)
2171
- throw new Error('You must bind Parsley on an existing element.');
2172
- this.$element = $element;
2173
- // If element have already been binded, returns its saved Parsley instance
2174
- if (this.$element.data('Parsley')) {
2175
- var savedparsleyFormInstance = this.$element.data('Parsley');
2176
- // If saved instance have been binded without a ParsleyForm parent and there is one given in this call, add it
2177
- if ('undefined' !== typeof parsleyFormInstance)
2178
- savedparsleyFormInstance.parent = parsleyFormInstance;
2179
- return savedparsleyFormInstance;
2180
- }
2181
- // Handle 'static' options
2182
- this.OptionsFactory = new ParsleyOptionsFactory(ParsleyDefaults, ParsleyUtils.get(window, 'ParsleyConfig') || {}, options, this.getNamespace(options));
2183
- this.options = this.OptionsFactory.get(this);
2184
- // A ParsleyForm instance is obviously a `<form>` elem but also every node that is not an input and have `data-parsley-validate` attribute
2185
- if (this.$element.is('form') || (ParsleyUtils.attr(this.$element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)))
2186
- return this.bind('parsleyForm');
2187
- // Every other supported element and not excluded element is binded as a `ParsleyField` or `ParsleyFieldMultiple`
2188
- else if (this.$element.is(this.options.inputs) && !this.$element.is(this.options.excluded))
2189
- return this.isMultiple() ? this.handleMultiple(parsleyFormInstance) : this.bind('parsleyField', parsleyFormInstance);
2190
- return this;
2191
- },
2192
- isMultiple: function () {
2193
- 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'));
2194
- },
2195
- // Multiples fields are a real nightmare :(
2196
- // Maybe some refacto would be appreciated here...
2197
- handleMultiple: function (parsleyFormInstance) {
2198
- var
2199
- that = this,
2200
- name,
2201
- multiple,
2202
- parsleyMultipleInstance;
2203
- // Get parsleyFormInstance options if exist, mixed with element attributes
2204
- this.options = $.extend(this.options, parsleyFormInstance ? parsleyFormInstance.OptionsFactory.get(parsleyFormInstance) : {}, ParsleyUtils.attr(this.$element, this.options.namespace));
2205
- // Handle multiple name
2206
- if (this.options.multiple)
2207
- multiple = this.options.multiple;
2208
- else if ('undefined' !== typeof this.$element.attr('name') && this.$element.attr('name').length)
2209
- multiple = name = this.$element.attr('name');
2210
- else if ('undefined' !== typeof this.$element.attr('id') && this.$element.attr('id').length)
2211
- multiple = this.$element.attr('id');
2212
- // Special select multiple input
2213
- if (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple')) {
2214
- return this.bind('parsleyFieldMultiple', parsleyFormInstance, multiple || this.__id__);
2215
- // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
2216
- } else if ('undefined' === typeof multiple) {
2217
- if (window.console && window.console.warn)
2218
- 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);
2219
- return this;
2220
- }
2221
- // Remove special chars
2222
- multiple = multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
2223
- // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
2224
- if ('undefined' !== typeof name) {
2225
- $('input[name="' + name + '"]').each(function () {
2226
- if ($(this).is('input[type=radio], input[type=checkbox]'))
2227
- $(this).attr(that.options.namespace + 'multiple', multiple);
2228
- });
2229
- }
2230
- // Check here if we don't already have a related multiple instance saved
2231
- if ($('[' + this.options.namespace + 'multiple=' + multiple +']').length) {
2232
- for (var i = 0; i < $('[' + this.options.namespace + 'multiple=' + multiple +']').length; i++) {
2233
- if ('undefined' !== typeof $($('[' + this.options.namespace + 'multiple=' + multiple +']').get(i)).data('Parsley')) {
2234
- parsleyMultipleInstance = $($('[' + this.options.namespace + 'multiple=' + multiple +']').get(i)).data('Parsley');
2235
- if (!this.$element.data('ParsleyFieldMultiple')) {
2236
- parsleyMultipleInstance.addElement(this.$element);
2237
- this.$element.attr(this.options.namespace + 'id', parsleyMultipleInstance.__id__);
2238
- }
2239
- break;
2240
- }
2241
- }
2242
- }
2243
- // Create a secret ParsleyField instance for every multiple field. It would be stored in `data('ParsleyFieldMultiple')`
2244
- // And would be useful later to access classic `ParsleyField` stuff while being in a `ParsleyFieldMultiple` instance
2245
- this.bind('parsleyField', parsleyFormInstance, multiple, true);
2246
- return parsleyMultipleInstance || this.bind('parsleyFieldMultiple', parsleyFormInstance, multiple);
2247
- },
2248
- // Retrieve namespace used for DOM-API
2249
- getNamespace: function (options) {
2250
- // `data-parsley-namespace=<namespace>`
2251
- if ('undefined' !== typeof this.$element.data('parsleyNamespace'))
2252
- return this.$element.data('parsleyNamespace');
2253
- if ('undefined' !== typeof ParsleyUtils.get(options, 'namespace'))
2254
- return options.namespace;
2255
- if ('undefined' !== typeof ParsleyUtils.get(window, 'ParsleyConfig.namespace'))
2256
- return window.ParsleyConfig.namespace;
2257
- return ParsleyDefaults.namespace;
2258
- },
2259
- // Return proper `ParsleyForm`, `ParsleyField` or `ParsleyFieldMultiple`
2260
- bind: function (type, parentParsleyFormInstance, multiple, doNotStore) {
2261
- var parsleyInstance;
2262
- switch (type) {
2263
- case 'parsleyForm':
2264
- parsleyInstance = $.extend(
2265
- new ParsleyForm(this.$element, this.OptionsFactory),
2266
- new ParsleyAbstract(),
2267
- window.ParsleyExtend
2268
- )._bindFields();
2269
- break;
2270
- case 'parsleyField':
2271
- parsleyInstance = $.extend(
2272
- new ParsleyField(this.$element, this.OptionsFactory, parentParsleyFormInstance),
2273
- new ParsleyAbstract(),
2274
- window.ParsleyExtend
2275
- );
2276
- break;
2277
- case 'parsleyFieldMultiple':
2278
- parsleyInstance = $.extend(
2279
- new ParsleyField(this.$element, this.OptionsFactory, parentParsleyFormInstance),
2280
- new ParsleyAbstract(),
2281
- new ParsleyMultiple(),
2282
- window.ParsleyExtend
2283
- )._init(multiple);
2284
- break;
2285
- default:
2286
- throw new Error(type + 'is not a supported Parsley type');
2287
- }
2288
- if ('undefined' !== typeof multiple)
2289
- ParsleyUtils.setAttr(this.$element, this.options.namespace, 'multiple', multiple);
2290
- if ('undefined' !== typeof doNotStore) {
2291
- this.$element.data('ParsleyFieldMultiple', parsleyInstance);
2292
- return parsleyInstance;
2293
- }
2294
- // Store instance if `ParsleyForm`, `ParsleyField` or `ParsleyFieldMultiple`
2295
- if (new RegExp('ParsleyF', 'i').test(parsleyInstance.__class__)) {
2296
- // Store for later access the freshly binded instance in DOM element itself using jQuery `data()`
2297
- this.$element.data('Parsley', parsleyInstance);
2298
- // Tell the world we got a new ParsleyForm or ParsleyField instance!
2299
- $.emit('parsley:' + ('parsleyForm' === type ? 'form' : 'field') + ':init', parsleyInstance);
2300
- }
2301
- return parsleyInstance;
2302
- }
2303
- };
2304
- // ### jQuery API
2305
- // `$('.elem').parsley(options)` or `$('.elem').psly(options)`
2306
- $.fn.parsley = $.fn.psly = function (options) {
2307
- if (this.length > 1) {
2308
- var instances = [];
2309
- this.each(function () {
2310
- instances.push($(this).parsley(options));
2311
- });
2312
- return instances;
2313
- }
2314
- // Return undefined if applied to non existing DOM element
2315
- if (!$(this).length) {
2316
- if (window.console && window.console.warn)
2317
- window.console.warn('You must bind Parsley on an existing element.');
2318
- return;
2319
- }
2320
- return new Parsley(this, options);
2321
- };
2322
- // ### ParsleyUI
2323
- // UI is a class apart that only listen to some events and them modify DOM accordingly
2324
- // Could be overriden by defining a `window.ParsleyConfig.ParsleyUI` appropriate class (with `listen()` method basically)
2325
- window.ParsleyUI = 'function' === typeof ParsleyUtils.get(window, 'ParsleyConfig.ParsleyUI') ?
2326
- new window.ParsleyConfig.ParsleyUI().listen() : new ParsleyUI().listen();
2327
- // ### ParsleyField and ParsleyForm extension
2328
- // Ensure that defined if not already the case
2329
- if ('undefined' === typeof window.ParsleyExtend)
2330
- window.ParsleyExtend = {};
2331
- // ### ParsleyConfig
2332
- // Ensure that defined if not already the case
2333
- if ('undefined' === typeof window.ParsleyConfig)
2334
- window.ParsleyConfig = {};
2335
- // ### Globals
2336
- window.Parsley = window.psly = Parsley;
2337
- window.ParsleyUtils = ParsleyUtils;
2338
- window.ParsleyValidator = new ParsleyValidator(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
2339
- // ### PARSLEY auto-binding
2340
- // Prevent it by setting `ParsleyConfig.autoBind` to `false`
2341
- if (false !== ParsleyUtils.get(window, 'ParsleyConfig.autoBind'))
2342
- $(function () {
2343
- // Works only on `data-parsley-validate`.
2344
- if ($('[data-parsley-validate]').length)
2345
- $('[data-parsley-validate]').parsley();
2346
- });
2347
- }));