parsley-rails 2.0.7.0 → 2.4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
- }));