UNPKG

@grigorov-it/mazer

Version:

Free and Open-source Bootstrap 5 Admin Dashboard Template and Landing Page

1,299 lines (1,106 loc) 95 kB
/*! * Parsley.js * Version 2.9.2 - built Tue, Dec 10th 2019, 6:18 pm * 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 // (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) : typeof define === 'function' && define.amd ? define(['jquery'], factory) : (global = global || self, global.parsley = factory(global.jQuery)); }(this, (function ($) { 'use strict'; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; }; } else { _typeof = function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } var globalID = 1; var pastWarnings = {}; var Utils = { // 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 (!element) return obj; attributes = element.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.hasAttribute(namespace + _checkAttr); }, setAttr: function setAttr(element, namespace, attr, value) { element.setAttribute(this.dasherize(namespace + attr), String(value)); }, getType: function getType(element) { return element.getAttribute('type') || 'text'; }, generateID: function generateID() { return '' + globalID++; }, /** Third party functions **/ deserializeValue: function deserializeValue(value) { var num; try { return value ? value == "true" || (value == "false" ? false : value == "null" ? null : !isNaN(num = Number(value)) ? num : /^[\[\{]/.test(value) ? JSON.parse(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, ''); }, parse: { date: function date(string) { var parsed = string.match(/^(\d{4,})-(\d\d)-(\d\d)$/); if (!parsed) return null; var _parsed$map = parsed.map(function (x) { return parseInt(x, 10); }), _parsed$map2 = _slicedToArray(_parsed$map, 4), _ = _parsed$map2[0], year = _parsed$map2[1], month = _parsed$map2[2], day = _parsed$map2[3]; var date = new Date(year, month - 1, day); if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) return null; return date; }, string: function string(_string) { return _string; }, integer: function integer(string) { if (isNaN(string)) return null; return parseInt(string, 10); }, number: function number(string) { if (isNaN(string)) throw null; return parseFloat(string); }, 'boolean': function _boolean(string) { return !/^\s*false\s*$/i.test(string); }, object: function object(string) { return Utils.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); } }, parseRequirement: function parseRequirement(requirementType, string) { var converter = this.parse[requirementType || 'string']; if (!converter) throw 'Unknown requirement specification: "' + requirementType + '"'; var converted = converter(string); if (converted === null) throw "Requirement is not a ".concat(requirementType, ": \"").concat(string, "\""); return converted; }, namespaceEvents: function namespaceEvents(events, namespace) { events = this.trimString(events || '').split(/\s+/); if (!events[0]) return ''; return $.map(events, function (evt) { return "".concat(evt, ".").concat(namespace); }).join(' '); }, difference: function difference(array, remove) { // This is O(N^2), should be optimized var result = []; $.each(array, function (_, elem) { if (remove.indexOf(elem) == -1) result.push(elem); }); return result; }, // Alter-ego to native Promise.all, but for jQuery all: function all(promises) { // jQuery treats $.when() and $.when(singlePromise) differently; let's avoid that and add spurious elements return $.when.apply($, _toConsumableArray(promises).concat([42, 42])); }, // 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; }; }(), _SubmitSelector: 'input[type="submit"], button:submit' }; // 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 Defaults = { // ### 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(Field) {}, // Return the `$element` where errors will be appended // Could also be (and given directly from DOM) a valid selector like `'#div'` errorsContainer: function errorsContainer(Field) {}, // 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 Base = function Base() { this.__id__ = Utils.generateID(); }; Base.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() { Utils.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 = Utils.objectCreate(this.parent.options); this.options = Utils.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; 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; }, asyncIsValid: function asyncIsValid(group, force) { Utils.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.querySelectorAll("[".concat(this.options.namespace, "multiple=\"").concat(this.options.multiple, "\"]"))) : this.$element; } }; 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(Utils.trimString); if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed'; return values; }; 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 = Utils.parseRequirement(requirementSpec[key], value); extra[key] = value; } else { main = Utils.parseRequirement(requirementSpec[key], string); } } return [main, extra]; }; // A Validator needs to implement the methods `validate` and `parseRequirements` var Validator = function Validator(spec) { $.extend(true, this, spec); }; Validator.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(value, requirementFirstArg); } if (Array.isArray(value)) { if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values'; return this.validateMultiple.apply(this, arguments); } else { var instance = arguments[arguments.length - 1]; if (this.validateDate && instance._isDateInput()) { arguments[0] = Utils.parse.date(arguments[0]); if (arguments[0] === null) return false; return this.validateDate.apply(this, arguments); } if (this.validateNumber) { if (!value) // Builtin validators all accept empty strings, except `required` of course return true; 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 Array.isArray(requirements) ? requirements : [requirements]; } var type = this.requirementType; if (Array.isArray(type)) { var values = convertArrayRequirement(requirements, type.length); for (var i = 0; i < values.length; i++) { values[i] = Utils.parseRequirement(type[i], values[i]); } return values; } else if ($.isPlainObject(type)) { return convertExtraOptionRequirement(type, requirements, extraOptionReader); } else { return [Utils.parseRequirement(type, requirements)]; } }, // Defaults: requirementType: 'string', priority: 2 }; var ValidatorRegistry = function ValidatorRegistry(validators, catalog) { this.__class__ = 'ValidatorRegistry'; // Default Parsley locale is en this.locale = 'en'; this.init(validators || {}, catalog || {}); }; var typeTesters = { email: /^((([a-zA-Z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-zA-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-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))$/, // 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, date: { test: function test(value) { return Utils.parse.date(value) !== null; } }, 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-zA-Z\\u00a1-\\uffff0-9]-*)*[a-zA-Z\\u00a1-\\uffff0-9]+)" + // domain name "(?:\\.(?:[a-zA-Z\\u00a1-\\uffff0-9]-*)*[a-zA-Z\\u00a1-\\uffff0-9]+)*" + // TLD identifier "(?:\\.(?:[a-zA-Z\\u00a1-\\uffff]{2,}))" + ")" + // port number "(?::\\d{2,5})?" + // resource path "(?:/\\S*)?" + "$") }; typeTesters.range = typeTesters.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)); }; // parseArguments('number', ['1', '2']) => [1, 2] var parseArguments = function parseArguments(type, args) { return args.map(Utils.parse[type]); }; // operatorToValidator returns a validating function for an operator function, applied to the given type var operatorToValidator = function operatorToValidator(type, operator) { return function (value) { for (var _len = arguments.length, requirementsAndInput = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { requirementsAndInput[_key - 1] = arguments[_key]; } requirementsAndInput.pop(); // Get rid of `input` argument return operator.apply(void 0, [value].concat(_toConsumableArray(parseArguments(type, requirementsAndInput)))); }; }; var comparisonOperator = function comparisonOperator(operator) { return { validateDate: operatorToValidator('date', operator), validateNumber: operatorToValidator('number', operator), requirementType: operator.length <= 2 ? 'string' : ['string', 'string'], // Support operators with a 1 or 2 requirement(s) priority: 30 }; }; ValidatorRegistry.prototype = { init: function init(validators, catalog) { this.catalog = catalog; // Copy prototype's validators: this.validators = _extends({}, 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]) Utils.warn('Validator "' + name + '" is already defined.');else if (Defaults.hasOwnProperty(name)) { Utils.warn('"' + name + '" is a restricted keyword and is not a valid validator name.'); return; } return this._setValidator.apply(this, arguments); }, hasValidator: function hasValidator(name) { return !!this.validators[name]; }, updateValidator: function updateValidator(name, arg1, arg2) { if (!this.validators[name]) { Utils.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]) Utils.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 Validator(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] : {}, _ref$step = _ref.step, step = _ref$step === void 0 ? 'any' : _ref$step, _ref$base = _ref.base, base = _ref$base === void 0 ? 0 : _ref$base; var tester = typeTesters[type]; if (!tester) { throw new Error('validator type `' + type + '` is not supported'); } if (!value) return true; // Builtin validators all accept empty strings, except `required` of course if (!tester.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) { if (!value) return true; // Builtin validators all accept empty strings, except `required` of course return regexp.test(value); }, requirementType: 'regexp', priority: 64 }, minlength: { validateString: function validateString(value, requirement) { if (!value) return true; // Builtin validators all accept empty strings, except `required` of course 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) { if (!value) return true; // Builtin validators all accept empty strings, except `required` of course 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: comparisonOperator(function (value, requirement) { return value >= requirement; }), max: comparisonOperator(function (value, requirement) { return value <= requirement; }), range: comparisonOperator(function (value, min, max) { return value >= min && value <= max; }), equalto: { validateString: function validateString(value, refOrValue) { if (!value) return true; // Builtin validators all accept empty strings, except `required` of course var $reference = $(refOrValue); if ($reference.length) return value === $reference.val();else return value === refOrValue; }, priority: 256 }, euvatin: { validateString: function validateString(value, refOrValue) { if (!value) { return true; // Builtin validators all accept empty strings, except `required` of course } var re = /^[A-Z][A-Z][A-Za-z0-9 -]{2,}$/; return re.test(value); }, priority: 30 } } }; var UI = {}; 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 : [] }; }; UI.Form = { _actualizeTriggers: function _actualizeTriggers() { var _this = this; this.$element.on('submit.Parsley', function (evt) { _this.onSubmitValidate(evt); }); this.$element.on('click.Parsley', Utils._SubmitSelector, function (evt) { _this.onSubmitButton(evt); }); // UI could be disabled if (false === this.options.uiEnabled) return; this.element.setAttribute('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'); } }; UI.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 _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, message = _ref.message, assert = _ref.assert, _ref$updateClass = _ref.updateClass, updateClass = _ref$updateClass === void 0 ? true : _ref$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 _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, message = _ref2.message, assert = _ref2.assert, _ref2$updateClass = _ref2.updateClass, updateClass = _ref2$updateClass === void 0 ? true : _ref2$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 _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref3$updateClass = _ref3.updateClass, updateClass = _ref3$updateClass === void 0 ? true : _ref3$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')); this._ui.$errorClassHandler.attr('aria-describedby', this._ui.errorsWrapperId); return this._ui.$errorsWrapper.addClass('filled').attr('aria-hidden', 'false').find('.parsley-custom-error-message').html(this.options.errorMessage); } this._ui.$errorClassHandler.removeAttr('aria-describedby'); return this._ui.$errorsWrapper.removeClass('filled').attr('aria-hidden', 'true').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, _ref4) { var message = _ref4.message, assert = _ref4.assert; this._insertErrorWrapper(); this._ui.$errorClassHandler.attr('aria-describedby', this._ui.errorsWrapperId); this._ui.$errorsWrapper.addClass('filled').attr('aria-hidden', 'false').append($(this.options.errorTemplate).addClass('parsley-' + name).html(message || this._getErrorMessage(assert))); }, _updateError: function _updateError(name, _ref5) { var message = _ref5.message, assert = _ref5.assert; this._ui.$errorsWrapper.addClass('filled').find('.parsley-' + name).html(message || this._getErrorMessage(assert)); }, _removeError: function _removeError(name) { this._ui.$errorClassHandler.removeAttr('aria-describedby'); this._ui.$errorsWrapper.removeClass('filled').attr('aria-hidden', 'true').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.setAttribute(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() { // Class handled could also be determined by function given in Parsley options 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 $handlerFunction = this.options.classHandler; // It might also be the function name of a global function if ('string' === typeof this.options.classHandler && 'function' === typeof window[this.options.classHandler]) $handlerFunction = window[this.options.classHandler]; if ('function' === typeof $handlerFunction) { var $handler = $handlerFunction.call(this, this); // If this function returned a valid existing DOM element, go for it if ('undefined' !== typeof $handler && $handler.length) return $handler; } else if ('object' === _typeof($handlerFunction) && $handlerFunction instanceof jQuery && $handlerFunction.length) { return $handlerFunction; } else if ($handlerFunction) { Utils.warn('The class handler `' + $handlerFunction + '` does not exist in DOM nor as a global JS function'); } return this._inputHolder(); }, _inputHolder: function _inputHolder() { // if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container if (!this.options.multiple || this.element.nodeName === 'SELECT') return this.$element; // But if multiple element (radio, checkbox), that would be their parent return this.$element.parent(); }, _insertErrorWrapper: function _insertErrorWrapper() { var $errorsContainer = this.options.errorsContainer; // Nothing to do if already inserted if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent(); if ('string' === typeof $errorsContainer) { if ($($errorsContainer).length) return $($errorsContainer).append(this._ui.$errorsWrapper);else if ('function' === typeof window[$errorsContainer]) $errorsContainer = window[$errorsContainer];else Utils.warn('The errors container `' + $errorsContainer + '` does not exist in DOM nor as a global JS function'); } if ('function' === typeof $errorsContainer) $errorsContainer = $errorsContainer.call(this, this); if ('object' === _typeof($errorsContainer) && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper); return this._inputHolder().after(this._ui.$errorsWrapper); }, _actualizeTriggers: function _actualizeTriggers() { var _this2 = this; var $toBind = this._findRelated(); var trigger; // Remove Parsley events already bound on this field $toBind.off('.Parsley'); if (this._failedOnce) $toBind.on(Utils.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () { _this2._validateIfNeeded(); });else if (trigger = Utils.namespaceEvents(this.options.trigger, 'Parsley')) { $toBind.on(trigger, function (event) { _this2._validateIfNeeded(event); }); } }, _validateIfNeeded: function _validateIfNeeded(event) { var _this3 = this; // 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 (event && /key|input/.test(event.type)) if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold) return; if (this.options.debounce) { window.clearTimeout(this._debounced); this._debounced = window.setTimeout(function () { return _this3.validate(); }, this.options.debounce); } else 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 Form = function Form(element, domOptions, options) { this.__class__ = 'Form'; this.element = element; this.$element = $(element); this.domOptions = domOptions; this.options = options; this.parent = window.Parsley; this.fields = []; this.validationResult = null; }; var statusMapping = { pending: null, resolved: true, rejected: false }; Form.prototype = { onSubmitValidate: function onSubmitValidate(event) { var _this = 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(Utils._SubmitSelector)[0]; this._submitSource = null; this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true); if (submitSource && null !== submitSource.getAttribute('formnovalidate')) return; window.Parsley._remoteCache = {}; var promise = this.whenValidate({ event: event }); if ('resolved' === promise.state() && false !== this._trigger('submit')) ; else { // Rejected or pending: cancel this submit event.stopImmediatePropagation(); event.preventDefault(); if ('pending' === promise.state()) promise.done(function () { _this._submit(submitSource); }); } }, onSubmitButton: function onSubmitButton(event) { this._submitSource = event.currentTarget; }, // 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.getAttribute('name'), value: submitSource.getAttribute('value') }); } this.$element.trigger(_extends($.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