12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357 |
- /*!
- * Parsley.js
- * Version 2.3.13 - built Tue, May 31st 2016, 8:55 am
- * http://parsleyjs.org
- * Guillaume Potier - <guillaume@wisembly.com>
- * Marc-Andre Lafortune - <petroselinum@marc-andre.ca>
- * MIT Licensed
- */
- // The source code below is generated by babel as
- // Parsley is written in ECMAScript 6
- //
- var _slice = Array.prototype.slice;
- function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) : typeof define === 'function' && define.amd ? define(['jquery'], factory) : global.parsley = factory(global.jQuery);
- })(this, function ($) {
- 'use strict';
- var globalID = 1;
- var pastWarnings = {};
- var ParsleyUtils__ParsleyUtils = {
- // Parsley DOM-API
- // returns object from dom attributes and values
- attr: function attr($element, namespace, obj) {
- var i;
- var attribute;
- var attributes;
- var regex = new RegExp('^' + namespace, 'i');
- if ('undefined' === typeof obj) obj = {};else {
- // Clear all own properties. This won't affect prototype's values
- for (i in obj) {
- if (obj.hasOwnProperty(i)) delete obj[i];
- }
- }
- if ('undefined' === typeof $element || 'undefined' === typeof $element[0]) return obj;
- attributes = $element[0].attributes;
- for (i = attributes.length; i--;) {
- attribute = attributes[i];
- if (attribute && attribute.specified && regex.test(attribute.name)) {
- obj[this.camelize(attribute.name.slice(namespace.length))] = this.deserializeValue(attribute.value);
- }
- }
- return obj;
- },
- checkAttr: function checkAttr($element, namespace, _checkAttr) {
- return $element.is('[' + namespace + _checkAttr + ']');
- },
- setAttr: function setAttr($element, namespace, attr, value) {
- $element[0].setAttribute(this.dasherize(namespace + attr), String(value));
- },
- generateID: function generateID() {
- return '' + globalID++;
- },
- /** Third party functions **/
- // Zepto deserialize function
- deserializeValue: function deserializeValue(value) {
- var num;
- try {
- return value ? value == "true" || (value == "false" ? false : value == "null" ? null : !isNaN(num = Number(value)) ? num : /^[\[\{]/.test(value) ? $.parseJSON(value) : value) : value;
- } catch (e) {
- return value;
- }
- },
- // Zepto camelize function
- camelize: function camelize(str) {
- return str.replace(/-+(.)?/g, function (match, chr) {
- return chr ? chr.toUpperCase() : '';
- });
- },
- // Zepto dasherize function
- dasherize: function dasherize(str) {
- return str.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 warn() {
- var _window$console;
- if (window.console && 'function' === typeof window.console.warn) (_window$console = window.console).warn.apply(_window$console, arguments);
- },
- warnOnce: function warnOnce(msg) {
- if (!pastWarnings[msg]) {
- pastWarnings[msg] = true;
- this.warn.apply(this, arguments);
- }
- },
- _resetWarnings: function _resetWarnings() {
- pastWarnings = {};
- },
- trimString: function trimString(string) {
- return string.replace(/^\s+|\s+$/g, '');
- },
- namespaceEvents: function namespaceEvents(events, namespace) {
- events = this.trimString(events || '').split(/\s+/);
- if (!events[0]) return '';
- return $.map(events, function (evt) {
- return evt + '.' + namespace;
- }).join(' ');
- },
- // Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill
- objectCreate: Object.create || (function () {
- var Object = function Object() {};
- return function (prototype) {
- if (arguments.length > 1) {
- throw Error('Second argument not supported');
- }
- if (typeof prototype != 'object') {
- throw TypeError('Argument must be an object');
- }
- Object.prototype = prototype;
- var result = new Object();
- Object.prototype = null;
- return result;
- };
- })()
- };
- var ParsleyUtils__default = ParsleyUtils__ParsleyUtils;
- // All these options could be overriden and specified directly in DOM using
- // `data-parsley-` default DOM-API
- // eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
- // eg: `data-parsley-stop-on-first-failing-constraint="false"`
- var ParsleyDefaults = {
- // ### General
- // Default data-namespace for DOM API
- namespace: 'data-parsley-',
- // Supported inputs by default
- inputs: 'input, textarea, select',
- // Excluded inputs by default
- excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',
- // Stop validating field on highest priority failing constraint
- priorityEnabled: true,
- // ### Field only
- // identifier used to group together inputs (e.g. radio buttons...)
- multiple: null,
- // identifier (or array of identifiers) used to validate only a select group of inputs
- group: null,
- // ### UI
- // Enable\Disable error messages
- uiEnabled: true,
- // Key events threshold before validation
- validationThreshold: 3,
- // Focused field on form validation error. 'first'|'last'|'none'
- focus: 'first',
- // event(s) that will trigger validation before first failure. eg: `input`...
- trigger: false,
- // event(s) that will trigger validation after first failure.
- triggerAfterFailure: 'input',
- // Class that would be added on every failing validation Parsley field
- errorClass: 'parsley-error',
- // Same for success validation
- successClass: 'parsley-success',
- // Return the `$element` that will receive these above success or error classes
- // Could also be (and given directly from DOM) a valid selector like `'#div'`
- classHandler: function classHandler(ParsleyField) {},
- // Return the `$element` where errors will be appended
- // Could also be (and given directly from DOM) a valid selector like `'#div'`
- errorsContainer: function errorsContainer(ParsleyField) {},
- // ul elem that would receive errors' list
- errorsWrapper: '<ul class="parsley-errors-list"></ul>',
- // li elem that would receive error message
- errorTemplate: '<li></li>'
- };
- var ParsleyAbstract = function ParsleyAbstract() {
- this.__id__ = ParsleyUtils__default.generateID();
- };
- ParsleyAbstract.prototype = {
- asyncSupport: true, // Deprecated
- _pipeAccordingToValidationResult: function _pipeAccordingToValidationResult() {
- var _this = this;
- var pipe = function pipe() {
- var r = $.Deferred();
- if (true !== _this.validationResult) r.reject();
- return r.resolve().promise();
- };
- return [pipe, pipe];
- },
- actualizeOptions: function actualizeOptions() {
- ParsleyUtils__default.attr(this.$element, this.options.namespace, this.domOptions);
- if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
- return this;
- },
- _resetOptions: function _resetOptions(initOptions) {
- this.domOptions = ParsleyUtils__default.objectCreate(this.parent.options);
- this.options = ParsleyUtils__default.objectCreate(this.domOptions);
- // Shallow copy of ownProperties of initOptions:
- for (var i in initOptions) {
- if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
- }
- this.actualizeOptions();
- },
- _listeners: null,
- // Register a callback for the given event name
- // Callback is called with context as the first argument and the `this`
- // The context is the current parsley instance, or window.Parsley if global
- // A return value of `false` will interrupt the calls
- on: function on(name, fn) {
- this._listeners = this._listeners || {};
- var queue = this._listeners[name] = this._listeners[name] || [];
- queue.push(fn);
- return this;
- },
- // Deprecated. Use `on` instead
- subscribe: function subscribe(name, fn) {
- $.listenTo(this, name.toLowerCase(), fn);
- },
- // Unregister a callback (or all if none is given) for the given event name
- off: function off(name, fn) {
- var queue = this._listeners && this._listeners[name];
- if (queue) {
- if (!fn) {
- delete this._listeners[name];
- } else {
- for (var i = queue.length; i--;) if (queue[i] === fn) queue.splice(i, 1);
- }
- }
- return this;
- },
- // Deprecated. Use `off`
- unsubscribe: function unsubscribe(name, fn) {
- $.unsubscribeTo(this, name.toLowerCase());
- },
- // Trigger an event of the given name
- // A return value of `false` interrupts the callback chain
- // Returns false if execution was interrupted
- trigger: function trigger(name, target, extraArg) {
- target = target || this;
- var queue = this._listeners && this._listeners[name];
- var result;
- var parentResult;
- if (queue) {
- for (var i = queue.length; i--;) {
- result = queue[i].call(target, target, extraArg);
- if (result === false) return result;
- }
- }
- if (this.parent) {
- return this.parent.trigger(name, target, extraArg);
- }
- return true;
- },
- // Reset UI
- reset: function reset() {
- // Field case: just emit a reset event for UI
- if ('ParsleyForm' !== this.__class__) {
- this._resetUI();
- return this._trigger('reset');
- }
- // Form case: emit a reset event for each field
- for (var i = 0; i < this.fields.length; i++) this.fields[i].reset();
- this._trigger('reset');
- },
- // Destroy Parsley instance (+ UI)
- destroy: function destroy() {
- // Field case: emit destroy event to clean UI and then destroy stored instance
- this._destroyUI();
- if ('ParsleyForm' !== this.__class__) {
- this.$element.removeData('Parsley');
- this.$element.removeData('ParsleyFieldMultiple');
- this._trigger('destroy');
- return;
- }
- // Form case: destroy all its fields and then destroy stored instance
- for (var i = 0; i < this.fields.length; i++) this.fields[i].destroy();
- this.$element.removeData('Parsley');
- this._trigger('destroy');
- },
- asyncIsValid: function asyncIsValid(group, force) {
- ParsleyUtils__default.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
- return this.whenValid({ group: group, force: force });
- },
- _findRelated: function _findRelated() {
- return this.options.multiple ? this.parent.$element.find('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]') : this.$element;
- }
- };
- var requirementConverters = {
- string: function string(_string) {
- return _string;
- },
- integer: function integer(string) {
- if (isNaN(string)) throw 'Requirement is not an integer: "' + string + '"';
- return parseInt(string, 10);
- },
- number: function number(string) {
- if (isNaN(string)) throw 'Requirement is not a number: "' + string + '"';
- return parseFloat(string);
- },
- reference: function reference(string) {
- // Unused for now
- var result = $(string);
- if (result.length === 0) throw 'No such reference: "' + string + '"';
- return result;
- },
- boolean: function boolean(string) {
- return string !== 'false';
- },
- object: function object(string) {
- return ParsleyUtils__default.deserializeValue(string);
- },
- regexp: function regexp(_regexp) {
- var flags = '';
- // Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
- if (/^\/.*\/(?:[gimy]*)$/.test(_regexp)) {
- // Replace the regexp literal string with the first match group: ([gimy]*)
- // If no flag is present, this will be a blank string
- flags = _regexp.replace(/.*\/([gimy]*)$/, '$1');
- // Again, replace the regexp literal string with the first match group:
- // everything excluding the opening and closing slashes and the flags
- _regexp = _regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
- } else {
- // Anchor regexp:
- _regexp = '^' + _regexp + '$';
- }
- return new RegExp(_regexp, flags);
- }
- };
- var convertArrayRequirement = function convertArrayRequirement(string, length) {
- var m = string.match(/^\s*\[(.*)\]\s*$/);
- if (!m) throw 'Requirement is not an array: "' + string + '"';
- var values = m[1].split(',').map(ParsleyUtils__default.trimString);
- if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
- return values;
- };
- var convertRequirement = function convertRequirement(requirementType, string) {
- var converter = requirementConverters[requirementType || 'string'];
- if (!converter) throw 'Unknown requirement specification: "' + requirementType + '"';
- return converter(string);
- };
- var convertExtraOptionRequirement = function convertExtraOptionRequirement(requirementSpec, string, extraOptionReader) {
- var main = null;
- var extra = {};
- for (var key in requirementSpec) {
- if (key) {
- var value = extraOptionReader(key);
- if ('string' === typeof value) value = convertRequirement(requirementSpec[key], value);
- extra[key] = value;
- } else {
- main = convertRequirement(requirementSpec[key], string);
- }
- }
- return [main, extra];
- };
- // A Validator needs to implement the methods `validate` and `parseRequirements`
- var ParsleyValidator = function ParsleyValidator(spec) {
- $.extend(true, this, spec);
- };
- ParsleyValidator.prototype = {
- // Returns `true` iff the given `value` is valid according the given requirements.
- validate: function validate(value, requirementFirstArg) {
- if (this.fn) {
- // Legacy style validator
- if (arguments.length > 3) // If more args then value, requirement, instance...
- requirementFirstArg = [].slice.call(arguments, 1, -1); // Skip first arg (value) and last (instance), combining the rest
- return this.fn.call(this, value, requirementFirstArg);
- }
- if ($.isArray(value)) {
- if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
- return this.validateMultiple.apply(this, arguments);
- } else {
- if (this.validateNumber) {
- if (isNaN(value)) return false;
- arguments[0] = parseFloat(arguments[0]);
- return this.validateNumber.apply(this, arguments);
- }
- if (this.validateString) {
- return this.validateString.apply(this, arguments);
- }
- throw 'Validator `' + this.name + '` only handles multiple values';
- }
- },
- // Parses `requirements` into an array of arguments,
- // according to `this.requirementType`
- parseRequirements: function parseRequirements(requirements, extraOptionReader) {
- if ('string' !== typeof requirements) {
- // Assume requirement already parsed
- // but make sure we return an array
- return $.isArray(requirements) ? requirements : [requirements];
- }
- var type = this.requirementType;
- if ($.isArray(type)) {
- var values = convertArrayRequirement(requirements, type.length);
- for (var i = 0; i < values.length; i++) values[i] = convertRequirement(type[i], values[i]);
- return values;
- } else if ($.isPlainObject(type)) {
- return convertExtraOptionRequirement(type, requirements, extraOptionReader);
- } else {
- return [convertRequirement(type, requirements)];
- }
- },
- // Defaults:
- requirementType: 'string',
- priority: 2
- };
- var ParsleyValidatorRegistry = function ParsleyValidatorRegistry(validators, catalog) {
- this.__class__ = 'ParsleyValidatorRegistry';
- // Default Parsley locale is en
- this.locale = 'en';
- this.init(validators || {}, catalog || {});
- };
- var typeRegexes = {
- 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,
- // Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers
- number: /^-?(\d*\.)?\d+(e[-+]?\d+)?$/i,
- integer: /^-?\d+$/,
- digits: /^\d+$/,
- alphanum: /^\w+$/i,
- url: new RegExp("^" +
- // protocol identifier
- "(?:(?:https?|ftp)://)?" + // ** mod: make scheme optional
- // user:pass authentication
- "(?:\\S+(?::\\S*)?@)?" + "(?:" +
- // IP address exclusion
- // private & local networks
- // "(?!(?:10|127)(?:\\.\\d{1,3}){3})" + // ** mod: allow local networks
- // "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
- // "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
- // IP address dotted notation octets
- // excludes loopback network 0.0.0.0
- // excludes reserved space >= 224.0.0.0
- // excludes network & broacast addresses
- // (first & last IP address of each class)
- "(?:[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]))" + "|" +
- // host name
- '(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)' +
- // domain name
- '(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*' +
- // TLD identifier
- '(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))' + ")" +
- // port number
- "(?::\\d{2,5})?" +
- // resource path
- "(?:/\\S*)?" + "$", 'i')
- };
- typeRegexes.range = typeRegexes.number;
- // See http://stackoverflow.com/a/10454560/8279
- var decimalPlaces = function decimalPlaces(num) {
- var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
- if (!match) {
- return 0;
- }
- return Math.max(0,
- // Number of digits right of decimal point.
- (match[1] ? match[1].length : 0) - (
- // Adjust for scientific notation.
- match[2] ? +match[2] : 0));
- };
- ParsleyValidatorRegistry.prototype = {
- init: function init(validators, catalog) {
- this.catalog = catalog;
- // Copy prototype's validators:
- this.validators = $.extend({}, this.validators);
- for (var name in validators) this.addValidator(name, validators[name].fn, validators[name].priority);
- window.Parsley.trigger('parsley:validator:init');
- },
- // Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
- setLocale: function setLocale(locale) {
- if ('undefined' === typeof this.catalog[locale]) throw new Error(locale + ' is not available in the catalog');
- this.locale = locale;
- return this;
- },
- // Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
- addCatalog: function addCatalog(locale, messages, set) {
- if ('object' === typeof messages) this.catalog[locale] = messages;
- if (true === set) return this.setLocale(locale);
- return this;
- },
- // Add a specific message for a given constraint in a given locale
- addMessage: function addMessage(locale, name, message) {
- if ('undefined' === typeof this.catalog[locale]) this.catalog[locale] = {};
- this.catalog[locale][name] = message;
- return this;
- },
- // Add messages for a given locale
- addMessages: function addMessages(locale, nameMessageObject) {
- for (var name in nameMessageObject) this.addMessage(locale, name, nameMessageObject[name]);
- return this;
- },
- // Add a new validator
- //
- // addValidator('custom', {
- // requirementType: ['integer', 'integer'],
- // validateString: function(value, from, to) {},
- // priority: 22,
- // messages: {
- // en: "Hey, that's no good",
- // fr: "Aye aye, pas bon du tout",
- // }
- // })
- //
- // Old API was addValidator(name, function, priority)
- //
- addValidator: function addValidator(name, arg1, arg2) {
- if (this.validators[name]) ParsleyUtils__default.warn('Validator "' + name + '" is already defined.');else if (ParsleyDefaults.hasOwnProperty(name)) {
- ParsleyUtils__default.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
- return;
- }
- return this._setValidator.apply(this, arguments);
- },
- updateValidator: function updateValidator(name, arg1, arg2) {
- if (!this.validators[name]) {
- ParsleyUtils__default.warn('Validator "' + name + '" is not already defined.');
- return this.addValidator.apply(this, arguments);
- }
- return this._setValidator.apply(this, arguments);
- },
- removeValidator: function removeValidator(name) {
- if (!this.validators[name]) ParsleyUtils__default.warn('Validator "' + name + '" is not defined.');
- delete this.validators[name];
- return this;
- },
- _setValidator: function _setValidator(name, validator, priority) {
- if ('object' !== typeof validator) {
- // Old style validator, with `fn` and `priority`
- validator = {
- fn: validator,
- priority: priority
- };
- }
- if (!validator.validate) {
- validator = new ParsleyValidator(validator);
- }
- this.validators[name] = validator;
- for (var locale in validator.messages || {}) this.addMessage(locale, name, validator.messages[locale]);
- return this;
- },
- getErrorMessage: function getErrorMessage(constraint) {
- var message;
- // Type constraints are a bit different, we have to match their requirements too to find right error message
- if ('type' === constraint.name) {
- var typeMessages = this.catalog[this.locale][constraint.name] || {};
- message = typeMessages[constraint.requirements];
- } else message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
- return message || this.catalog[this.locale].defaultMessage || this.catalog.en.defaultMessage;
- },
- // Kind of light `sprintf()` implementation
- formatMessage: function formatMessage(string, parameters) {
- if ('object' === typeof parameters) {
- for (var i in parameters) string = this.formatMessage(string, parameters[i]);
- return string;
- }
- return 'string' === typeof string ? string.replace(/%s/i, parameters) : '';
- },
- // Here is the Parsley default validators list.
- // A validator is an object with the following key values:
- // - priority: an integer
- // - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these
- // - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise
- // Alternatively, a validator can be a function that returns such an object
- //
- validators: {
- notblank: {
- validateString: function validateString(value) {
- return (/\S/.test(value)
- );
- },
- priority: 2
- },
- required: {
- validateMultiple: function validateMultiple(values) {
- return values.length > 0;
- },
- validateString: function validateString(value) {
- return (/\S/.test(value)
- );
- },
- priority: 512
- },
- type: {
- validateString: function validateString(value, type) {
- var _ref = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
- var _ref$step = _ref.step;
- var step = _ref$step === undefined ? '1' : _ref$step;
- var _ref$base = _ref.base;
- var base = _ref$base === undefined ? 0 : _ref$base;
- var regex = typeRegexes[type];
- if (!regex) {
- throw new Error('validator type `' + type + '` is not supported');
- }
- if (!regex.test(value)) return false;
- if ('number' === type) {
- if (!/^any$/i.test(step || '')) {
- var nb = Number(value);
- var decimals = Math.max(decimalPlaces(step), decimalPlaces(base));
- if (decimalPlaces(nb) > decimals) // Value can't have too many decimals
- return false;
- // Be careful of rounding errors by using integers.
- var toInt = function toInt(f) {
- return Math.round(f * Math.pow(10, decimals));
- };
- if ((toInt(nb) - toInt(base)) % toInt(step) != 0) return false;
- }
- }
- return true;
- },
- requirementType: {
- '': 'string',
- step: 'string',
- base: 'number'
- },
- priority: 256
- },
- pattern: {
- validateString: function validateString(value, regexp) {
- return regexp.test(value);
- },
- requirementType: 'regexp',
- priority: 64
- },
- minlength: {
- validateString: function validateString(value, requirement) {
- return value.length >= requirement;
- },
- requirementType: 'integer',
- priority: 30
- },
- maxlength: {
- validateString: function validateString(value, requirement) {
- return value.length <= requirement;
- },
- requirementType: 'integer',
- priority: 30
- },
- length: {
- validateString: function validateString(value, min, max) {
- return value.length >= min && value.length <= max;
- },
- requirementType: ['integer', 'integer'],
- priority: 30
- },
- mincheck: {
- validateMultiple: function validateMultiple(values, requirement) {
- return values.length >= requirement;
- },
- requirementType: 'integer',
- priority: 30
- },
- maxcheck: {
- validateMultiple: function validateMultiple(values, requirement) {
- return values.length <= requirement;
- },
- requirementType: 'integer',
- priority: 30
- },
- check: {
- validateMultiple: function validateMultiple(values, min, max) {
- return values.length >= min && values.length <= max;
- },
- requirementType: ['integer', 'integer'],
- priority: 30
- },
- min: {
- validateNumber: function validateNumber(value, requirement) {
- return value >= requirement;
- },
- requirementType: 'number',
- priority: 30
- },
- max: {
- validateNumber: function validateNumber(value, requirement) {
- return value <= requirement;
- },
- requirementType: 'number',
- priority: 30
- },
- range: {
- validateNumber: function validateNumber(value, min, max) {
- return value >= min && value <= max;
- },
- requirementType: ['number', 'number'],
- priority: 30
- },
- equalto: {
- validateString: function validateString(value, refOrValue) {
- var $reference = $(refOrValue);
- if ($reference.length) return value === $reference.val();else return value === refOrValue;
- },
- priority: 256
- }
- }
- };
- var ParsleyUI = {};
- var diffResults = function diffResults(newResult, oldResult, deep) {
- var added = [];
- var kept = [];
- for (var i = 0; i < newResult.length; i++) {
- var found = false;
- for (var j = 0; j < oldResult.length; j++) if (newResult[i].assert.name === oldResult[j].assert.name) {
- found = true;
- break;
- }
- if (found) kept.push(newResult[i]);else added.push(newResult[i]);
- }
- return {
- kept: kept,
- added: added,
- removed: !deep ? diffResults(oldResult, newResult, true).added : []
- };
- };
- ParsleyUI.Form = {
- _actualizeTriggers: function _actualizeTriggers() {
- var _this2 = this;
- this.$element.on('submit.Parsley', function (evt) {
- _this2.onSubmitValidate(evt);
- });
- this.$element.on('click.Parsley', 'input[type="submit"], button[type="submit"]', function (evt) {
- _this2.onSubmitButton(evt);
- });
- // UI could be disabled
- if (false === this.options.uiEnabled) return;
- this.$element.attr('novalidate', '');
- },
- focus: function focus() {
- this._focusedField = null;
- if (true === this.validationResult || 'none' === this.options.focus) return null;
- for (var i = 0; i < this.fields.length; i++) {
- var field = this.fields[i];
- if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {
- this._focusedField = field.$element;
- if ('first' === this.options.focus) break;
- }
- }
- if (null === this._focusedField) return null;
- return this._focusedField.focus();
- },
- _destroyUI: function _destroyUI() {
- // Reset all event listeners
- this.$element.off('.Parsley');
- }
- };
- ParsleyUI.Field = {
- _reflowUI: function _reflowUI() {
- this._buildUI();
- // If this field doesn't have an active UI don't bother doing something
- if (!this._ui) return;
- // Diff between two validation results
- var diff = diffResults(this.validationResult, this._ui.lastValidationResult);
- // Then store current validation result for next reflow
- this._ui.lastValidationResult = this.validationResult;
- // Handle valid / invalid / none field class
- this._manageStatusClass();
- // Add, remove, updated errors messages
- this._manageErrorsMessages(diff);
- // Triggers impl
- this._actualizeTriggers();
- // If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user
- if ((diff.kept.length || diff.added.length) && !this._failedOnce) {
- this._failedOnce = true;
- this._actualizeTriggers();
- }
- },
- // Returns an array of field's error message(s)
- getErrorsMessages: function getErrorsMessages() {
- // No error message, field is valid
- if (true === this.validationResult) return [];
- var messages = [];
- for (var i = 0; i < this.validationResult.length; i++) messages.push(this.validationResult[i].errorMessage || this._getErrorMessage(this.validationResult[i].assert));
- return messages;
- },
- // It's a goal of Parsley that this method is no longer required [#1073]
- addError: function addError(name) {
- var _ref2 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
- var message = _ref2.message;
- var assert = _ref2.assert;
- var _ref2$updateClass = _ref2.updateClass;
- var updateClass = _ref2$updateClass === undefined ? true : _ref2$updateClass;
- this._buildUI();
- this._addError(name, { message: message, assert: assert });
- if (updateClass) this._errorClass();
- },
- // It's a goal of Parsley that this method is no longer required [#1073]
- updateError: function updateError(name) {
- var _ref3 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
- var message = _ref3.message;
- var assert = _ref3.assert;
- var _ref3$updateClass = _ref3.updateClass;
- var updateClass = _ref3$updateClass === undefined ? true : _ref3$updateClass;
- this._buildUI();
- this._updateError(name, { message: message, assert: assert });
- if (updateClass) this._errorClass();
- },
- // It's a goal of Parsley that this method is no longer required [#1073]
- removeError: function removeError(name) {
- var _ref4 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
- var _ref4$updateClass = _ref4.updateClass;
- var updateClass = _ref4$updateClass === undefined ? true : _ref4$updateClass;
- this._buildUI();
- this._removeError(name);
- // edge case possible here: remove a standard Parsley error that is still failing in this.validationResult
- // but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
- if (updateClass) this._manageStatusClass();
- },
- _manageStatusClass: function _manageStatusClass() {
- if (this.hasConstraints() && this.needsValidation() && true === this.validationResult) this._successClass();else if (this.validationResult.length > 0) this._errorClass();else this._resetClass();
- },
- _manageErrorsMessages: function _manageErrorsMessages(diff) {
- if ('undefined' !== typeof this.options.errorsMessagesDisabled) return;
- // Case where we have errorMessage option that configure an unique field error message, regardless failing validators
- if ('undefined' !== typeof this.options.errorMessage) {
- if (diff.added.length || diff.kept.length) {
- this._insertErrorWrapper();
- if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length) this._ui.$errorsWrapper.append($(this.options.errorTemplate).addClass('parsley-custom-error-message'));
- return this._ui.$errorsWrapper.addClass('filled').find('.parsley-custom-error-message').html(this.options.errorMessage);
- }
- return this._ui.$errorsWrapper.removeClass('filled').find('.parsley-custom-error-message').remove();
- }
- // Show, hide, update failing constraints messages
- for (var i = 0; i < diff.removed.length; i++) this._removeError(diff.removed[i].assert.name);
- for (i = 0; i < diff.added.length; i++) this._addError(diff.added[i].assert.name, { message: diff.added[i].errorMessage, assert: diff.added[i].assert });
- for (i = 0; i < diff.kept.length; i++) this._updateError(diff.kept[i].assert.name, { message: diff.kept[i].errorMessage, assert: diff.kept[i].assert });
- },
- _addError: function _addError(name, _ref5) {
- var message = _ref5.message;
- var assert = _ref5.assert;
- this._insertErrorWrapper();
- this._ui.$errorsWrapper.addClass('filled').append($(this.options.errorTemplate).addClass('parsley-' + name).html(message || this._getErrorMessage(assert)));
- },
- _updateError: function _updateError(name, _ref6) {
- var message = _ref6.message;
- var assert = _ref6.assert;
- this._ui.$errorsWrapper.addClass('filled').find('.parsley-' + name).html(message || this._getErrorMessage(assert));
- },
- _removeError: function _removeError(name) {
- this._ui.$errorsWrapper.removeClass('filled').find('.parsley-' + name).remove();
- },
- _getErrorMessage: function _getErrorMessage(constraint) {
- var customConstraintErrorMessage = constraint.name + 'Message';
- if ('undefined' !== typeof this.options[customConstraintErrorMessage]) return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements);
- return window.Parsley.getErrorMessage(constraint);
- },
- _buildUI: function _buildUI() {
- // UI could be already built or disabled
- if (this._ui || false === this.options.uiEnabled) return;
- var _ui = {};
- // Give field its Parsley id in DOM
- this.$element.attr(this.options.namespace + 'id', this.__id__);
- /** Generate important UI elements and store them in this **/
- // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
- _ui.$errorClassHandler = this._manageClassHandler();
- // $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer
- _ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__);
- _ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId);
- // ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly
- _ui.lastValidationResult = [];
- _ui.validationInformationVisible = false;
- // Store it in this for later
- this._ui = _ui;
- },
- // Determine which element will have `parsley-error` and `parsley-success` classes
- _manageClassHandler: function _manageClassHandler() {
- // An element selector could be passed through DOM with `data-parsley-class-handler=#foo`
- if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length) return $(this.options.classHandler);
- // Class handled could also be determined by function given in Parsley options
- var $handler = this.options.classHandler.call(this, this);
- // If this function returned a valid existing DOM element, go for it
- if ('undefined' !== typeof $handler && $handler.length) return $handler;
- // Otherwise, if simple element (input, texatrea, select...) it will perfectly host the classes
- if (!this.options.multiple || this.$element.is('select')) return this.$element;
- // But if multiple element (radio, checkbox), that would be their parent
- return this.$element.parent();
- },
- _insertErrorWrapper: function _insertErrorWrapper() {
- var $errorsContainer;
- // Nothing to do if already inserted
- if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
- if ('string' === typeof this.options.errorsContainer) {
- if ($(this.options.errorsContainer).length) return $(this.options.errorsContainer).append(this._ui.$errorsWrapper);else ParsleyUtils__default.warn('The errors container `' + this.options.errorsContainer + '` does not exist in DOM');
- } else if ('function' === typeof this.options.errorsContainer) $errorsContainer = this.options.errorsContainer.call(this, this);
- if ('undefined' !== typeof $errorsContainer && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
- var $from = this.$element;
- if (this.options.multiple) $from = $from.parent();
- return $from.after(this._ui.$errorsWrapper);
- },
- _actualizeTriggers: function _actualizeTriggers() {
- var _this3 = this;
- var $toBind = this._findRelated();
- var trigger;
- // Remove Parsley events already bound on this field
- $toBind.off('.Parsley');
- if (this._failedOnce) $toBind.on(ParsleyUtils__default.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
- _this3.validate();
- });else if (trigger = ParsleyUtils__default.namespaceEvents(this.options.trigger, 'Parsley')) {
- $toBind.on(trigger, function (event) {
- _this3._eventValidate(event);
- });
- }
- },
- _eventValidate: function _eventValidate(event) {
- // For keyup, keypress, keydown, input... events that could be a little bit obstrusive
- // do not validate if val length < min threshold on first validation. Once field have been validated once and info
- // about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
- if (/key|input/.test(event.type)) if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold) return;
- this.validate();
- },
- _resetUI: function _resetUI() {
- // Reset all event listeners
- this._failedOnce = false;
- this._actualizeTriggers();
- // Nothing to do if UI never initialized for this field
- if ('undefined' === typeof this._ui) return;
- // Reset all errors' li
- this._ui.$errorsWrapper.removeClass('filled').children().remove();
- // Reset validation class
- this._resetClass();
- // Reset validation flags and last validation result
- this._ui.lastValidationResult = [];
- this._ui.validationInformationVisible = false;
- },
- _destroyUI: function _destroyUI() {
- this._resetUI();
- if ('undefined' !== typeof this._ui) this._ui.$errorsWrapper.remove();
- delete this._ui;
- },
- _successClass: function _successClass() {
- this._ui.validationInformationVisible = true;
- this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass);
- },
- _errorClass: function _errorClass() {
- this._ui.validationInformationVisible = true;
- this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass);
- },
- _resetClass: function _resetClass() {
- this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass);
- }
- };
- var ParsleyForm = function ParsleyForm(element, domOptions, options) {
- this.__class__ = 'ParsleyForm';
- this.$element = $(element);
- this.domOptions = domOptions;
- this.options = options;
- this.parent = window.Parsley;
- this.fields = [];
- this.validationResult = null;
- };
- var ParsleyForm__statusMapping = { pending: null, resolved: true, rejected: false };
- ParsleyForm.prototype = {
- onSubmitValidate: function onSubmitValidate(event) {
- var _this4 = this;
- // This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior
- if (true === event.parsley) return;
- // If we didn't come here through a submit button, use the first one in the form
- var $submitSource = this._$submitSource || this.$element.find('input[type="submit"], button[type="submit"]').first();
- this._$submitSource = null;
- this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
- if ($submitSource.is('[formnovalidate]')) return;
- var promise = this.whenValidate({ event: event });
- if ('resolved' === promise.state() && false !== this._trigger('submit')) {
- // All good, let event go through. We make this distinction because browsers
- // differ in their handling of `submit` being called from inside a submit event [#1047]
- } else {
- // Rejected or pending: cancel this submit
- event.stopImmediatePropagation();
- event.preventDefault();
- if ('pending' === promise.state()) promise.done(function () {
- _this4._submit($submitSource);
- });
- }
- },
- onSubmitButton: function onSubmitButton(event) {
- this._$submitSource = $(event.target);
- },
- // internal
- // _submit submits the form, this time without going through the validations.
- // Care must be taken to "fake" the actual submit button being clicked.
- _submit: function _submit($submitSource) {
- if (false === this._trigger('submit')) return;
- // Add submit button's data
- if ($submitSource) {
- var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
- if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element);
- $synthetic.attr({
- name: $submitSource.attr('name'),
- value: $submitSource.attr('value')
- });
- }
- this.$element.trigger($.extend($.Event('submit'), { parsley: true }));
- },
- // Performs validation on fields while triggering events.
- // @returns `true` if all validations succeeds, `false`
- // if a failure is immediately detected, or `null`
- // if dependant on a promise.
- // Consider using `whenValidate` instead.
- validate: function validate(options) {
- if (arguments.length >= 1 && !$.isPlainObject(options)) {
- ParsleyUtils__default.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
- var _arguments = _slice.call(arguments);
- var group = _arguments[0];
- var force = _arguments[1];
- var event = _arguments[2];
- options = { group: group, force: force, event: event };
- }
- return ParsleyForm__statusMapping[this.whenValidate(options).state()];
- },
- whenValidate: function whenValidate() {
- var _$$when$done$fail$always,
- _this5 = this;
- var _ref7 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
- var group = _ref7.group;
- var force = _ref7.force;
- var event = _ref7.event;
- this.submitEvent = event;
- if (event) {
- this.submitEvent = $.extend({}, event, { preventDefault: function preventDefault() {
- ParsleyUtils__default.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
- _this5.validationResult = false;
- } });
- }
- this.validationResult = true;
- // fire validate event to eventually modify things before very validation
- this._trigger('validate');
- // Refresh form DOM options and form's fields that could have changed
- this._refreshFields();
- var promises = this._withoutReactualizingFormOptions(function () {
- return $.map(_this5.fields, function (field) {
- return field.whenValidate({ force: force, group: group });
- });
- });
- return (_$$when$done$fail$always = $.when.apply($, _toConsumableArray(promises)).done(function () {
- _this5._trigger('success');
- }).fail(function () {
- _this5.validationResult = false;
- _this5.focus();
- _this5._trigger('error');
- }).always(function () {
- _this5._trigger('validated');
- })).pipe.apply(_$$when$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
- },
- // Iterate over refreshed fields, and stop on first failure.
- // Returns `true` if all fields are valid, `false` if a failure is detected
- // or `null` if the result depends on an unresolved promise.
- // Prefer using `whenValid` instead.
- isValid: function isValid(options) {
- if (arguments.length >= 1 && !$.isPlainObject(options)) {
- ParsleyUtils__default.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
- var _arguments2 = _slice.call(arguments);
- var group = _arguments2[0];
- var force = _arguments2[1];
- options = { group: group, force: force };
- }
- return ParsleyForm__statusMapping[this.whenValid(options).state()];
- },
- // Iterate over refreshed fields and validate them.
- // Returns a promise.
- // A validation that immediately fails will interrupt the validations.
- whenValid: function whenValid() {
- var _this6 = this;
- var _ref8 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
- var group = _ref8.group;
- var force = _ref8.force;
- this._refreshFields();
- var promises = this._withoutReactualizingFormOptions(function () {
- return $.map(_this6.fields, function (field) {
- return field.whenValid({ group: group, force: force });
- });
- });
- return $.when.apply($, _toConsumableArray(promises));
- },
- _refreshFields: function _refreshFields() {
- return this.actualizeOptions()._bindFields();
- },
- _bindFields: function _bindFields() {
- var _this7 = this;
- var oldFields = this.fields;
- this.fields = [];
- this.fieldsMappedById = {};
- this._withoutReactualizingFormOptions(function () {
- _this7.$element.find(_this7.options.inputs).not(_this7.options.excluded).each(function (_, element) {
- var fieldInstance = new window.Parsley.Factory(element, {}, _this7);
- // Only add valid and not excluded `ParsleyField` and `ParsleyFieldMultiple` children
- if (('ParsleyField' === fieldInstance.__class__ || 'ParsleyFieldMultiple' === fieldInstance.__class__) && true !== fieldInstance.options.excluded) if ('undefined' === typeof _this7.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__]) {
- _this7.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__] = fieldInstance;
- _this7.fields.push(fieldInstance);
- }
- });
- $(oldFields).not(_this7.fields).each(function (_, field) {
- field._trigger('reset');
- });
- });
- return this;
- },
- // Internal only.
- // Looping on a form's fields to do validation or similar
- // will trigger reactualizing options on all of them, which
- // in turn will reactualize the form's options.
- // To avoid calling actualizeOptions so many times on the form
- // for nothing, _withoutReactualizingFormOptions temporarily disables
- // the method actualizeOptions on this form while `fn` is called.
- _withoutReactualizingFormOptions: function _withoutReactualizingFormOptions(fn) {
- var oldActualizeOptions = this.actualizeOptions;
- this.actualizeOptions = function () {
- return this;
- };
- var result = fn();
- this.actualizeOptions = oldActualizeOptions;
- return result;
- },
- // Internal only.
- // Shortcut to trigger an event
- // Returns true iff event is not interrupted and default not prevented.
- _trigger: function _trigger(eventName) {
- return this.trigger('form:' + eventName);
- }
- };
- var ConstraintFactory = function ConstraintFactory(parsleyField, name, requirements, priority, isDomConstraint) {
- if (!/ParsleyField/.test(parsleyField.__class__)) throw new Error('ParsleyField or ParsleyFieldMultiple instance expected');
- var validatorSpec = window.Parsley._validatorRegistry.validators[name];
- var validator = new ParsleyValidator(validatorSpec);
- $.extend(this, {
- validator: validator,
- name: name,
- requirements: requirements,
- priority: priority || parsleyField.options[name + 'Priority'] || validator.priority,
- isDomConstraint: true === isDomConstraint
- });
- this._parseRequirements(parsleyField.options);
- };
- var capitalize = function capitalize(str) {
- var cap = str[0].toUpperCase();
- return cap + str.slice(1);
- };
- ConstraintFactory.prototype = {
- validate: function validate(value, instance) {
- var _validator;
- return (_validator = this.validator).validate.apply(_validator, [value].concat(_toConsumableArray(this.requirementList), [instance]));
- },
- _parseRequirements: function _parseRequirements(options) {
- var _this8 = this;
- this.requirementList = this.validator.parseRequirements(this.requirements, function (key) {
- return options[_this8.name + capitalize(key)];
- });
- }
- };
- var ParsleyField = function ParsleyField(field, domOptions, options, parsleyFormInstance) {
- this.__class__ = 'ParsleyField';
- this.$element = $(field);
- // Set parent if we have one
- if ('undefined' !== typeof parsleyFormInstance) {
- this.parent = parsleyFormInstance;
- }
- this.options = options;
- this.domOptions = domOptions;
- // Initialize some properties
- this.constraints = [];
- this.constraintsByName = {};
- this.validationResult = true;
- // Bind constraints
- this._bindConstraints();
- };
- var parsley_field__statusMapping = { pending: null, resolved: true, rejected: false };
- ParsleyField.prototype = {
- // # Public API
- // Validate field and trigger some events for mainly `ParsleyUI`
- // @returns `true`, an array of the validators that failed, or
- // `null` if validation is not finished. Prefer using whenValidate
- validate: function validate(options) {
- if (arguments.length >= 1 && !$.isPlainObject(options)) {
- ParsleyUtils__default.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
- options = { options: options };
- }
- var promise = this.whenValidate(options);
- if (!promise) // If excluded with `group` option
- return true;
- switch (promise.state()) {
- case 'pending':
- return null;
- case 'resolved':
- return true;
- case 'rejected':
- return this.validationResult;
- }
- },
- // Validate field and trigger some events for mainly `ParsleyUI`
- // @returns a promise that succeeds only when all validations do
- // or `undefined` if field is not in the given `group`.
- whenValidate: function whenValidate() {
- var _whenValid$always$done$fail$always,
- _this9 = this;
- var _ref9 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
- var force = _ref9.force;
- var group = _ref9.group;
- // do not validate a field if not the same as given validation group
- this.refreshConstraints();
- if (group && !this._isInGroup(group)) return;
- this.value = this.getValue();
- // Field Validate event. `this.value` could be altered for custom needs
- this._trigger('validate');
- return (_whenValid$always$done$fail$always = this.whenValid({ force: force, value: this.value, _refreshed: true }).always(function () {
- _this9._reflowUI();
- }).done(function () {
- _this9._trigger('success');
- }).fail(function () {
- _this9._trigger('error');
- }).always(function () {
- _this9._trigger('validated');
- })).pipe.apply(_whenValid$always$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
- },
- hasConstraints: function hasConstraints() {
- return 0 !== this.constraints.length;
- },
- // An empty optional field does not need validation
- needsValidation: function needsValidation(value) {
- if ('undefined' === typeof value) value = this.getValue();
- // If a field is empty and not required, it is valid
- // Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
- if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty) return false;
- return true;
- },
- _isInGroup: function _isInGroup(group) {
- if ($.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
- return this.options.group === group;
- },
- // Just validate field. Do not trigger any event.
- // Returns `true` iff all constraints pass, `false` if there are failures,
- // or `null` if the result can not be determined yet (depends on a promise)
- // See also `whenValid`.
- isValid: function isValid(options) {
- if (arguments.length >= 1 && !$.isPlainObject(options)) {
- ParsleyUtils__default.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
- var _arguments3 = _slice.call(arguments);
- var force = _arguments3[0];
- var value = _arguments3[1];
- options = { force: force, value: value };
- }
- var promise = this.whenValid(options);
- if (!promise) // Excluded via `group`
- return true;
- return parsley_field__statusMapping[promise.state()];
- },
- // Just validate field. Do not trigger any event.
- // @returns a promise that succeeds only when all validations do
- // or `undefined` if the field is not in the given `group`.
- // The argument `force` will force validation of empty fields.
- // If a `value` is given, it will be validated instead of the value of the input.
- whenValid: function whenValid() {
- var _this10 = this;
- var _ref10 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
- var _ref10$force = _ref10.force;
- var force = _ref10$force === undefined ? false : _ref10$force;
- var value = _ref10.value;
- var group = _ref10.group;
- var _refreshed = _ref10._refreshed;
- // Recompute options and rebind constraints to have latest changes
- if (!_refreshed) this.refreshConstraints();
- // do not validate a field if not the same as given validation group
- if (group && !this._isInGroup(group)) return;
- this.validationResult = true;
- // A field without constraint is valid
- if (!this.hasConstraints()) return $.when();
- // Value could be passed as argument, needed to add more power to 'field:validate'
- if ('undefined' === typeof value || null === value) value = this.getValue();
- if (!this.needsValidation(value) && true !== force) return $.when();
- var groupedConstraints = this._getGroupedConstraints();
- var promises = [];
- $.each(groupedConstraints, function (_, constraints) {
- // Process one group of constraints at a time, we validate the constraints
- // and combine the promises together.
- var promise = $.when.apply($, _toConsumableArray($.map(constraints, function (constraint) {
- return _this10._validateConstraint(value, constraint);
- })));
- promises.push(promise);
- if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
- });
- return $.when.apply($, promises);
- },
- // @returns a promise
- _validateConstraint: function _validateConstraint(value, constraint) {
- var _this11 = this;
- var result = constraint.validate(value, this);
- // Map false to a failed promise
- if (false === result) result = $.Deferred().reject();
- // Make sure we return a promise and that we record failures
- return $.when(result).fail(function (errorMessage) {
- if (!(_this11.validationResult instanceof Array)) _this11.validationResult = [];
- _this11.validationResult.push({
- assert: constraint,
- errorMessage: 'string' === typeof errorMessage && errorMessage
- });
- });
- },
- // @returns Parsley field computed value that could be overrided or configured in DOM
- getValue: function getValue() {
- var value;
- // Value could be overriden in DOM or with explicit options
- if ('function' === typeof this.options.value) value = this.options.value(this);else if ('undefined' !== typeof this.options.value) value = this.options.value;else value = this.$element.val();
- // Handle wrong DOM or configurations
- if ('undefined' === typeof value || null === value) return '';
- return this._handleWhitespace(value);
- },
- // Actualize options that could have change since previous validation
- // Re-bind accordingly constraints (could be some new, removed or updated)
- refreshConstraints: function refreshConstraints() {
- return this.actualizeOptions()._bindConstraints();
- },
- /**
- * Add a new constraint to a field
- *
- * @param {String} name
- * @param {Mixed} requirements optional
- * @param {Number} priority optional
- * @param {Boolean} isDomConstraint optional
- */
- addConstraint: function addConstraint(name, requirements, priority, isDomConstraint) {
- if (window.Parsley._validatorRegistry.validators[name]) {
- var constraint = new ConstraintFactory(this, name, requirements, priority, isDomConstraint);
- // if constraint already exist, delete it and push new version
- if ('undefined' !== this.constraintsByName[constraint.name]) this.removeConstraint(constraint.name);
- this.constraints.push(constraint);
- this.constraintsByName[constraint.name] = constraint;
- }
- return this;
- },
- // Remove a constraint
- removeConstraint: function removeConstraint(name) {
- for (var i = 0; i < this.constraints.length; i++) if (name === this.constraints[i].name) {
- this.constraints.splice(i, 1);
- break;
- }
- delete this.constraintsByName[name];
- return this;
- },
- // Update a constraint (Remove + re-add)
- updateConstraint: function updateConstraint(name, parameters, priority) {
- return this.removeConstraint(name).addConstraint(name, parameters, priority);
- },
- // # Internals
- // Internal only.
- // Bind constraints from config + options + DOM
- _bindConstraints: function _bindConstraints() {
- var constraints = [];
- var constraintsByName = {};
- // clean all existing DOM constraints to only keep javascript user constraints
- for (var i = 0; i < this.constraints.length; i++) if (false === this.constraints[i].isDomConstraint) {
- constraints.push(this.constraints[i]);
- constraintsByName[this.constraints[i].name] = this.constraints[i];
- }
- this.constraints = constraints;
- this.constraintsByName = constraintsByName;
- // then re-add Parsley DOM-API constraints
- for (var name in this.options) this.addConstraint(name, this.options[name], undefined, true);
- // finally, bind special HTML5 constraints
- return this._bindHtml5Constraints();
- },
- // Internal only.
- // Bind specific HTML5 constraints to be HTML5 compliant
- _bindHtml5Constraints: function _bindHtml5Constraints() {
- // html5 required
- if (this.$element.hasClass('required') || this.$element.attr('required')) this.addConstraint('required', true, undefined, true);
- // html5 pattern
- if ('string' === typeof this.$element.attr('pattern')) this.addConstraint('pattern', this.$element.attr('pattern'), undefined, true);
- // range
- if ('undefined' !== typeof this.$element.attr('min') && 'undefined' !== typeof this.$element.attr('max')) this.addConstraint('range', [this.$element.attr('min'), this.$element.attr('max')], undefined, true);
- // HTML5 min
- else if ('undefined' !== typeof this.$element.attr('min')) this.addConstraint('min', this.$element.attr('min'), undefined, true);
- // HTML5 max
- else if ('undefined' !== typeof this.$element.attr('max')) this.addConstraint('max', this.$element.attr('max'), undefined, true);
- // length
- if ('undefined' !== typeof this.$element.attr('minlength') && 'undefined' !== typeof this.$element.attr('maxlength')) this.addConstraint('length', [this.$element.attr('minlength'), this.$element.attr('maxlength')], undefined, true);
- // HTML5 minlength
- else if ('undefined' !== typeof this.$element.attr('minlength')) this.addConstraint('minlength', this.$element.attr('minlength'), undefined, true);
- // HTML5 maxlength
- else if ('undefined' !== typeof this.$element.attr('maxlength')) this.addConstraint('maxlength', this.$element.attr('maxlength'), undefined, true);
- // html5 types
- var type = this.$element.attr('type');
- if ('undefined' === typeof type) return this;
- // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
- if ('number' === type) {
- return this.addConstraint('type', ['number', {
- step: this.$element.attr('step'),
- base: this.$element.attr('min') || this.$element.attr('value')
- }], undefined, true);
- // Regular other HTML5 supported types
- } else if (/^(email|url|range)$/i.test(type)) {
- return this.addConstraint('type', type, undefined, true);
- }
- return this;
- },
- // Internal only.
- // Field is required if have required constraint without `false` value
- _isRequired: function _isRequired() {
- if ('undefined' === typeof this.constraintsByName.required) return false;
- return false !== this.constraintsByName.required.requirements;
- },
- // Internal only.
- // Shortcut to trigger an event
- _trigger: function _trigger(eventName) {
- return this.trigger('field:' + eventName);
- },
- // Internal only
- // Handles whitespace in a value
- // Use `data-parsley-whitespace="squish"` to auto squish input value
- // Use `data-parsley-whitespace="trim"` to auto trim input value
- _handleWhitespace: function _handleWhitespace(value) {
- if (true === this.options.trimValue) ParsleyUtils__default.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
- if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
- if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = ParsleyUtils__default.trimString(value);
- return value;
- },
- // Internal only.
- // Returns the constraints, grouped by descending priority.
- // The result is thus an array of arrays of constraints.
- _getGroupedConstraints: function _getGroupedConstraints() {
- if (false === this.options.priorityEnabled) return [this.constraints];
- var groupedConstraints = [];
- var index = {};
- // Create array unique of priorities
- for (var i = 0; i < this.constraints.length; i++) {
- var p = this.constraints[i].priority;
- if (!index[p]) groupedConstraints.push(index[p] = []);
- index[p].push(this.constraints[i]);
- }
- // Sort them by priority DESC
- groupedConstraints.sort(function (a, b) {
- return b[0].priority - a[0].priority;
- });
- return groupedConstraints;
- }
- };
- var parsley_field = ParsleyField;
- var ParsleyMultiple = function ParsleyMultiple() {
- this.__class__ = 'ParsleyFieldMultiple';
- };
- ParsleyMultiple.prototype = {
- // Add new `$element` sibling for multiple field
- addElement: function addElement($element) {
- this.$elements.push($element);
- return this;
- },
- // See `ParsleyField.refreshConstraints()`
- refreshConstraints: function refreshConstraints() {
- var fieldConstraints;
- this.constraints = [];
- // Select multiple special treatment
- if (this.$element.is('select')) {
- this.actualizeOptions()._bindConstraints();
- return this;
- }
- // Gather all constraints for each input in the multiple group
- for (var i = 0; i < this.$elements.length; i++) {
- // Check if element have not been dynamically removed since last binding
- if (!$('html').has(this.$elements[i]).length) {
- this.$elements.splice(i, 1);
- continue;
- }
- fieldConstraints = this.$elements[i].data('ParsleyFieldMultiple').refreshConstraints().constraints;
- for (var j = 0; j < fieldConstraints.length; j++) this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);
- }
- return this;
- },
- // See `ParsleyField.getValue()`
- getValue: function getValue() {
- // Value could be overriden in DOM
- if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value;
- // Radio input case
- if (this.$element.is('input[type=radio]')) return this._findRelated().filter(':checked').val() || '';
- // checkbox input case
- if (this.$element.is('input[type=checkbox]')) {
- var values = [];
- this._findRelated().filter(':checked').each(function () {
- values.push($(this).val());
- });
- return values;
- }
- // Select multiple case
- if (this.$element.is('select') && null === this.$element.val()) return [];
- // Default case that should never happen
- return this.$element.val();
- },
- _init: function _init() {
- this.$elements = [this.$element];
- return this;
- }
- };
- var ParsleyFactory = function ParsleyFactory(element, options, parsleyFormInstance) {
- this.$element = $(element);
- // If the element has already been bound, returns its saved Parsley instance
- var savedparsleyFormInstance = this.$element.data('Parsley');
- if (savedparsleyFormInstance) {
- // If the saved instance has been bound without a ParsleyForm parent and there is one given in this call, add it
- if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) {
- savedparsleyFormInstance.parent = parsleyFormInstance;
- savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options);
- }
- return savedparsleyFormInstance;
- }
- // Parsley must be instantiated with a DOM element or jQuery $element
- if (!this.$element.length) throw new Error('You must bind Parsley on an existing element.');
- if ('undefined' !== typeof parsleyFormInstance && 'ParsleyForm' !== parsleyFormInstance.__class__) throw new Error('Parent instance must be a ParsleyForm instance');
- this.parent = parsleyFormInstance || window.Parsley;
- return this.init(options);
- };
- ParsleyFactory.prototype = {
- init: function init(options) {
- this.__class__ = 'Parsley';
- this.__version__ = '2.3.13';
- this.__id__ = ParsleyUtils__default.generateID();
- // Pre-compute options
- this._resetOptions(options);
- // A ParsleyForm instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
- if (this.$element.is('form') || ParsleyUtils__default.checkAttr(this.$element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm');
- // Every other element is bound as a `ParsleyField` or `ParsleyFieldMultiple`
- return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
- },
- isMultiple: function isMultiple() {
- return this.$element.is('input[type=radio], input[type=checkbox]') || this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple');
- },
- // Multiples fields are a real nightmare :(
- // Maybe some refactoring would be appreciated here...
- handleMultiple: function handleMultiple() {
- var _this12 = this;
- var name;
- var multiple;
- var parsleyMultipleInstance;
- // Handle multiple name
- if (this.options.multiple) ; // We already have our 'multiple' identifier
- else if ('undefined' !== typeof this.$element.attr('name') && this.$element.attr('name').length) this.options.multiple = name = this.$element.attr('name');else if ('undefined' !== typeof this.$element.attr('id') && this.$element.attr('id').length) this.options.multiple = this.$element.attr('id');
- // Special select multiple input
- if (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple')) {
- this.options.multiple = this.options.multiple || this.__id__;
- return this.bind('parsleyFieldMultiple');
- // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
- } else if (!this.options.multiple) {
- ParsleyUtils__default.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);
- return this;
- }
- // Remove special chars
- this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
- // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
- if ('undefined' !== typeof name) {
- $('input[name="' + name + '"]').each(function (i, input) {
- if ($(input).is('input[type=radio], input[type=checkbox]')) $(input).attr(_this12.options.namespace + 'multiple', _this12.options.multiple);
- });
- }
- // Check here if we don't already have a related multiple instance saved
- var $previouslyRelated = this._findRelated();
- for (var i = 0; i < $previouslyRelated.length; i++) {
- parsleyMultipleInstance = $($previouslyRelated.get(i)).data('Parsley');
- if ('undefined' !== typeof parsleyMultipleInstance) {
- if (!this.$element.data('ParsleyFieldMultiple')) {
- parsleyMultipleInstance.addElement(this.$element);
- }
- break;
- }
- }
- // Create a secret ParsleyField instance for every multiple field. It will be stored in `data('ParsleyFieldMultiple')`
- // And will be useful later to access classic `ParsleyField` stuff while being in a `ParsleyFieldMultiple` instance
- this.bind('parsleyField', true);
- return parsleyMultipleInstance || this.bind('parsleyFieldMultiple');
- },
- // Return proper `ParsleyForm`, `ParsleyField` or `ParsleyFieldMultiple`
- bind: function bind(type, doNotStore) {
- var parsleyInstance;
- switch (type) {
- case 'parsleyForm':
- parsleyInstance = $.extend(new ParsleyForm(this.$element, this.domOptions, this.options), new ParsleyAbstract(), window.ParsleyExtend)._bindFields();
- break;
- case 'parsleyField':
- parsleyInstance = $.extend(new parsley_field(this.$element, this.domOptions, this.options, this.parent), new ParsleyAbstract(), window.ParsleyExtend);
- break;
- case 'parsleyFieldMultiple':
- parsleyInstance = $.extend(new parsley_field(this.$element, this.domOptions, this.options, this.parent), new ParsleyMultiple(), new ParsleyAbstract(), window.ParsleyExtend)._init();
- break;
- default:
- throw new Error(type + 'is not a supported Parsley type');
- }
- if (this.options.multiple) ParsleyUtils__default.setAttr(this.$element, this.options.namespace, 'multiple', this.options.multiple);
- if ('undefined' !== typeof doNotStore) {
- this.$element.data('ParsleyFieldMultiple', parsleyInstance);
- return parsleyInstance;
- }
- // Store the freshly bound instance in a DOM element for later access using jQuery `data()`
- this.$element.data('Parsley', parsleyInstance);
- // Tell the world we have a new ParsleyForm or ParsleyField instance!
- parsleyInstance._actualizeTriggers();
- parsleyInstance._trigger('init');
- return parsleyInstance;
- }
- };
- var vernums = $.fn.jquery.split('.');
- if (parseInt(vernums[0]) <= 1 && parseInt(vernums[1]) < 8) {
- throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";
- }
- if (!vernums.forEach) {
- ParsleyUtils__default.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');
- }
- // Inherit `on`, `off` & `trigger` to Parsley:
- var Parsley = $.extend(new ParsleyAbstract(), {
- $element: $(document),
- actualizeOptions: null,
- _resetOptions: null,
- Factory: ParsleyFactory,
- version: '2.3.13'
- });
- // Supplement ParsleyField and Form with ParsleyAbstract
- // This way, the constructors will have access to those methods
- $.extend(parsley_field.prototype, ParsleyUI.Field, ParsleyAbstract.prototype);
- $.extend(ParsleyForm.prototype, ParsleyUI.Form, ParsleyAbstract.prototype);
- // Inherit actualizeOptions and _resetOptions:
- $.extend(ParsleyFactory.prototype, ParsleyAbstract.prototype);
- // ### jQuery API
- // `$('.elem').parsley(options)` or `$('.elem').psly(options)`
- $.fn.parsley = $.fn.psly = function (options) {
- if (this.length > 1) {
- var instances = [];
- this.each(function () {
- instances.push($(this).parsley(options));
- });
- return instances;
- }
- // Return undefined if applied to non existing DOM element
- if (!$(this).length) {
- ParsleyUtils__default.warn('You must bind Parsley on an existing element.');
- return;
- }
- return new ParsleyFactory(this, options);
- };
- // ### ParsleyField and ParsleyForm extension
- // Ensure the extension is now defined if it wasn't previously
- if ('undefined' === typeof window.ParsleyExtend) window.ParsleyExtend = {};
- // ### Parsley config
- // Inherit from ParsleyDefault, and copy over any existing values
- Parsley.options = $.extend(ParsleyUtils__default.objectCreate(ParsleyDefaults), window.ParsleyConfig);
- window.ParsleyConfig = Parsley.options; // Old way of accessing global options
- // ### Globals
- window.Parsley = window.psly = Parsley;
- window.ParsleyUtils = ParsleyUtils__default;
- // ### Define methods that forward to the registry, and deprecate all access except through window.Parsley
- var registry = window.Parsley._validatorRegistry = new ParsleyValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
- window.ParsleyValidator = {};
- $.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator'.split(' '), function (i, method) {
- window.Parsley[method] = $.proxy(registry, method);
- window.ParsleyValidator[method] = function () {
- var _window$Parsley;
- ParsleyUtils__default.warnOnce('Accessing the method \'' + method + '\' through ParsleyValidator is deprecated. Simply call \'window.Parsley.' + method + '(...)\'');
- return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments);
- };
- });
- // ### ParsleyUI
- // Deprecated global object
- window.Parsley.UI = ParsleyUI;
- window.ParsleyUI = {
- removeError: function removeError(instance, name, doNotUpdateClass) {
- var updateClass = true !== doNotUpdateClass;
- ParsleyUtils__default.warnOnce('Accessing ParsleyUI is deprecated. Call \'removeError\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
- return instance.removeError(name, { updateClass: updateClass });
- },
- getErrorsMessages: function getErrorsMessages(instance) {
- ParsleyUtils__default.warnOnce('Accessing ParsleyUI is deprecated. Call \'getErrorsMessages\' on the instance directly.');
- return instance.getErrorsMessages();
- }
- };
- $.each('addError updateError'.split(' '), function (i, method) {
- window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {
- var updateClass = true !== doNotUpdateClass;
- ParsleyUtils__default.warnOnce('Accessing ParsleyUI is deprecated. Call \'' + method + '\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
- return instance[method](name, { message: message, assert: assert, updateClass: updateClass });
- };
- });
- // ### PARSLEY auto-binding
- // Prevent it by setting `ParsleyConfig.autoBind` to `false`
- if (false !== window.ParsleyConfig.autoBind) {
- $(function () {
- // Works only on `data-parsley-validate`.
- if ($('[data-parsley-validate]').length) $('[data-parsley-validate]').parsley();
- });
- }
- var o = $({});
- var deprecated = function deprecated() {
- ParsleyUtils__default.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley");
- };
- // Returns an event handler that calls `fn` with the arguments it expects
- function adapt(fn, context) {
- // Store to allow unbinding
- if (!fn.parsleyAdaptedCallback) {
- fn.parsleyAdaptedCallback = function () {
- var args = Array.prototype.slice.call(arguments, 0);
- args.unshift(this);
- fn.apply(context || o, args);
- };
- }
- return fn.parsleyAdaptedCallback;
- }
- var eventPrefix = 'parsley:';
- // Converts 'parsley:form:validate' into 'form:validate'
- function eventName(name) {
- if (name.lastIndexOf(eventPrefix, 0) === 0) return name.substr(eventPrefix.length);
- return name;
- }
- // $.listen is deprecated. Use Parsley.on instead.
- $.listen = function (name, callback) {
- var context;
- deprecated();
- if ('object' === typeof arguments[1] && 'function' === typeof arguments[2]) {
- context = arguments[1];
- callback = arguments[2];
- }
- if ('function' !== typeof callback) throw new Error('Wrong parameters');
- window.Parsley.on(eventName(name), adapt(callback, context));
- };
- $.listenTo = function (instance, name, fn) {
- deprecated();
- if (!(instance instanceof parsley_field) && !(instance instanceof ParsleyForm)) throw new Error('Must give Parsley instance');
- if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong parameters');
- instance.on(eventName(name), adapt(fn));
- };
- $.unsubscribe = function (name, fn) {
- deprecated();
- if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong arguments');
- window.Parsley.off(eventName(name), fn.parsleyAdaptedCallback);
- };
- $.unsubscribeTo = function (instance, name) {
- deprecated();
- if (!(instance instanceof parsley_field) && !(instance instanceof ParsleyForm)) throw new Error('Must give Parsley instance');
- instance.off(eventName(name));
- };
- $.unsubscribeAll = function (name) {
- deprecated();
- window.Parsley.off(eventName(name));
- $('form,input,textarea,select').each(function () {
- var instance = $(this).data('Parsley');
- if (instance) {
- instance.off(eventName(name));
- }
- });
- };
- // $.emit is deprecated. Use jQuery events instead.
- $.emit = function (name, instance) {
- var _instance;
- deprecated();
- var instanceGiven = instance instanceof parsley_field || instance instanceof ParsleyForm;
- var args = Array.prototype.slice.call(arguments, instanceGiven ? 2 : 1);
- args.unshift(eventName(name));
- if (!instanceGiven) {
- instance = window.Parsley;
- }
- (_instance = instance).trigger.apply(_instance, _toConsumableArray(args));
- };
- var pubsub = {};
- $.extend(true, Parsley, {
- asyncValidators: {
- 'default': {
- fn: function fn(xhr) {
- // By default, only status 2xx are deemed successful.
- // Note: we use status instead of state() because responses with status 200
- // but invalid messages (e.g. an empty body for content type set to JSON) will
- // result in state() === 'rejected'.
- return xhr.status >= 200 && xhr.status < 300;
- },
- url: false
- },
- reverse: {
- fn: function fn(xhr) {
- // If reverse option is set, a failing ajax request is considered successful
- return xhr.status < 200 || xhr.status >= 300;
- },
- url: false
- }
- },
- addAsyncValidator: function addAsyncValidator(name, fn, url, options) {
- Parsley.asyncValidators[name] = {
- fn: fn,
- url: url || false,
- options: options || {}
- };
- return this;
- }
- });
- Parsley.addValidator('remote', {
- requirementType: {
- '': 'string',
- 'validator': 'string',
- 'reverse': 'boolean',
- 'options': 'object'
- },
- validateString: function validateString(value, url, options, instance) {
- var data = {};
- var ajaxOptions;
- var csr;
- var validator = options.validator || (true === options.reverse ? 'reverse' : 'default');
- if ('undefined' === typeof Parsley.asyncValidators[validator]) throw new Error('Calling an undefined async validator: `' + validator + '`');
- url = Parsley.asyncValidators[validator].url || url;
- // Fill current value
- if (url.indexOf('{value}') > -1) {
- url = url.replace('{value}', encodeURIComponent(value));
- } else {
- data[instance.$element.attr('name') || instance.$element.attr('id')] = value;
- }
- // Merge options passed in from the function with the ones in the attribute
- var remoteOptions = $.extend(true, options.options || {}, Parsley.asyncValidators[validator].options);
- // All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`
- ajaxOptions = $.extend(true, {}, {
- url: url,
- data: data,
- type: 'GET'
- }, remoteOptions);
- // Generate store key based on ajax options
- instance.trigger('field:ajaxoptions', instance, ajaxOptions);
- csr = $.param(ajaxOptions);
- // Initialise querry cache
- if ('undefined' === typeof Parsley._remoteCache) Parsley._remoteCache = {};
- // Try to retrieve stored xhr
- var xhr = Parsley._remoteCache[csr] = Parsley._remoteCache[csr] || $.ajax(ajaxOptions);
- var handleXhr = function handleXhr() {
- var result = Parsley.asyncValidators[validator].fn.call(instance, xhr, url, options);
- if (!result) // Map falsy results to rejected promise
- result = $.Deferred().reject();
- return $.when(result);
- };
- return xhr.then(handleXhr, handleXhr);
- },
- priority: -1
- });
- Parsley.on('form:submit', function () {
- Parsley._remoteCache = {};
- });
- window.ParsleyExtend.addAsyncValidator = function () {
- ParsleyUtils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');
- return Parsley.addAsyncValidator.apply(Parsley, arguments);
- };
- // This is included with the Parsley library itself,
- // thus there is no use in adding it to your project.
- Parsley.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."
- });
- Parsley.setLocale('en');
- /**
- * inputevent - Alleviate browser bugs for input events
- * https://github.com/marcandre/inputevent
- * @version v0.0.3 - (built Thu, Apr 14th 2016, 5:58 pm)
- * @author Marc-Andre Lafortune <github@marc-andre.ca>
- * @license MIT
- */
- function InputEvent() {
- var _this13 = this;
- var globals = window || global;
- // Slightly odd way construct our object. This way methods are force bound.
- // Used to test for duplicate library.
- $.extend(this, {
- // For browsers that do not support isTrusted, assumes event is native.
- isNativeEvent: function isNativeEvent(evt) {
- return evt.originalEvent && evt.originalEvent.isTrusted !== false;
- },
- fakeInputEvent: function fakeInputEvent(evt) {
- if (_this13.isNativeEvent(evt)) {
- $(evt.target).trigger('input');
- }
- },
- misbehaves: function misbehaves(evt) {
- if (_this13.isNativeEvent(evt)) {
- _this13.behavesOk(evt);
- $(document).on('change.inputevent', evt.data.selector, _this13.fakeInputEvent);
- _this13.fakeInputEvent(evt);
- }
- },
- behavesOk: function behavesOk(evt) {
- if (_this13.isNativeEvent(evt)) {
- $(document) // Simply unbinds the testing handler
- .off('input.inputevent', evt.data.selector, _this13.behavesOk).off('change.inputevent', evt.data.selector, _this13.misbehaves);
- }
- },
- // Bind the testing handlers
- install: function install() {
- if (globals.inputEventPatched) {
- return;
- }
- globals.inputEventPatched = '0.0.3';
- var _arr = ['select', 'input[type="checkbox"]', 'input[type="radio"]', 'input[type="file"]'];
- for (var _i = 0; _i < _arr.length; _i++) {
- var selector = _arr[_i];
- $(document).on('input.inputevent', selector, { selector: selector }, _this13.behavesOk).on('change.inputevent', selector, { selector: selector }, _this13.misbehaves);
- }
- },
- uninstall: function uninstall() {
- delete globals.inputEventPatched;
- $(document).off('.inputevent');
- }
- });
- };
- var inputevent = new InputEvent();
- inputevent.install();
- var parsley = Parsley;
- return parsley;
- });
- //# sourceMappingURL=parsley.js.map
|