@precision-nutrition/vee-validate
Version:
Simple Vue.js input validation plugin
2,019 lines (1,628 loc) • 242 kB
JavaScript
/**
* vee-validate v2.1.8
* (c) 2018 Abdelrahman Awad
* @license MIT
*/
//
var isTextInput = function (el) {
return includes(['text', 'password', 'search', 'email', 'tel', 'url', 'textarea', 'number'], el.type);
};
var isCheckboxOrRadioInput = function (el) {
return includes(['radio', 'checkbox'], el.type);
};
var isDateInput = function (el) {
return includes(['date', 'week', 'month', 'datetime-local', 'time'], el.type);
};
/**
* Gets the data attribute. the name must be kebab-case.
*/
var getDataAttribute = function (el, name) { return el.getAttribute(("data-vv-" + name)); };
/**
* Checks if the values are either null or undefined.
*/
var isNullOrUndefined = function () {
var values = [], len = arguments.length;
while ( len-- ) values[ len ] = arguments[ len ];
return values.every(function (value) {
return value === null || value === undefined;
});
};
/**
* Creates the default flags object.
*/
var createFlags = function () { return ({
untouched: true,
touched: false,
dirty: false,
pristine: true,
valid: null,
invalid: null,
validated: false,
pending: false,
required: false,
changed: false
}); };
/**
* Shallow object comparison.
*/
var isEqual = function (lhs, rhs) {
if (lhs instanceof RegExp && rhs instanceof RegExp) {
return isEqual(lhs.source, rhs.source) && isEqual(lhs.flags, rhs.flags);
}
if (Array.isArray(lhs) && Array.isArray(rhs)) {
if (lhs.length !== rhs.length) { return false; }
for (var i = 0; i < lhs.length; i++) {
if (!isEqual(lhs[i], rhs[i])) {
return false;
}
}
return true;
}
// if both are objects, compare each key recursively.
if (isObject(lhs) && isObject(rhs)) {
return Object.keys(lhs).every(function (key) {
return isEqual(lhs[key], rhs[key]);
}) && Object.keys(rhs).every(function (key) {
return isEqual(lhs[key], rhs[key]);
});
}
return lhs === rhs;
};
/**
* Determines the input field scope.
*/
var getScope = function (el) {
var scope = getDataAttribute(el, 'scope');
if (isNullOrUndefined(scope)) {
var form = getForm(el);
if (form) {
scope = getDataAttribute(form, 'scope');
}
}
return !isNullOrUndefined(scope) ? scope : null;
};
/**
* Get the closest form element.
*/
var getForm = function (el) {
if (isNullOrUndefined(el)) { return null; }
if (el.tagName === 'FORM') { return el; }
if (!isNullOrUndefined(el.form)) { return el.form; }
return !isNullOrUndefined(el.parentNode) ? getForm(el.parentNode) : null;
};
/**
* Gets the value in an object safely.
*/
var getPath = function (path, target, def) {
if ( def === void 0 ) def = undefined;
if (!path || !target) { return def; }
var value = target;
path.split('.').every(function (prop) {
if (prop in value) {
value = value[prop];
return true;
}
value = def;
return false;
});
return value;
};
/**
* Checks if path exists within an object.
*/
var hasPath = function (path, target) {
var obj = target;
return path.split('.').every(function (prop) {
if (prop in obj) {
obj = obj[prop];
return true;
}
return false;
});
};
/**
* Parses a rule string expression.
*/
var parseRule = function (rule) {
var params = [];
var name = rule.split(':')[0];
if (includes(rule, ':')) {
params = rule.split(':').slice(1).join(':').split(',');
}
return { name: name, params: params };
};
/**
* Debounces a function.
*/
var debounce = function (fn, wait, token) {
if ( wait === void 0 ) wait = 0;
if ( token === void 0 ) token = { cancelled: false };
if (wait === 0) {
return fn;
}
var timeout;
return function () {
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
var later = function () {
timeout = null;
// check if the fn call was cancelled.
if (!token.cancelled) { fn.apply(void 0, args); }
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (!timeout) { fn.apply(void 0, args); }
};
};
/**
* Appends a rule definition to a list of rules.
*/
var appendRule = function (rule, rules) {
if (!rules) {
return normalizeRules(rule);
}
if (!rule) {
return normalizeRules(rules);
}
if (typeof rules === 'string') {
rules = normalizeRules(rules);
}
return assign({}, rules, normalizeRules(rule));
};
/**
* Normalizes the given rules expression.
*/
var normalizeRules = function (rules) {
// if falsy value return an empty object.
if (!rules) {
return {};
}
if (isObject(rules)) {
// $FlowFixMe
return Object.keys(rules).reduce(function (prev, curr) {
var params = [];
// $FlowFixMe
if (rules[curr] === true) {
params = [];
} else if (Array.isArray(rules[curr])) {
params = rules[curr];
} else if (isObject(rules[curr])) {
params = rules[curr];
} else {
params = [rules[curr]];
}
// $FlowFixMe
if (rules[curr] !== false) {
prev[curr] = params;
}
return prev;
}, {});
}
if (typeof rules !== 'string') {
warn('rules must be either a string or an object.');
return {};
}
return rules.split('|').reduce(function (prev, rule) {
var parsedRule = parseRule(rule);
if (!parsedRule.name) {
return prev;
}
prev[parsedRule.name] = parsedRule.params;
return prev;
}, {});
};
/**
* Emits a warning to the console.
*/
var warn = function (message) {
console.warn(("[vee-validate] " + message)); // eslint-disable-line
};
/**
* Creates a branded error object.
*/
var createError = function (message) { return new Error(("[vee-validate] " + message)); };
/**
* Checks if the value is an object.
*/
var isObject = function (obj) { return obj !== null && obj && typeof obj === 'object' && ! Array.isArray(obj); };
/**
* Checks if a function is callable.
*/
var isCallable = function (func) { return typeof func === 'function'; };
/**
* Check if element has the css class on it.
*/
var hasClass = function (el, className) {
if (el.classList) {
return el.classList.contains(className);
}
return !!el.className.match(new RegExp(("(\\s|^)" + className + "(\\s|$)")));
};
/**
* Adds the provided css className to the element.
*/
var addClass = function (el, className) {
if (el.classList) {
el.classList.add(className);
return;
}
if (!hasClass(el, className)) {
el.className += " " + className;
}
};
/**
* Remove the provided css className from the element.
*/
var removeClass = function (el, className) {
if (el.classList) {
el.classList.remove(className);
return;
}
if (hasClass(el, className)) {
var reg = new RegExp(("(\\s|^)" + className + "(\\s|$)"));
el.className = el.className.replace(reg, ' ');
}
};
/**
* Adds or removes a class name on the input depending on the status flag.
*/
var toggleClass = function (el, className, status) {
if (!el || !className) { return; }
if (Array.isArray(className)) {
className.forEach(function (item) { return toggleClass(el, item, status); });
return;
}
if (status) {
return addClass(el, className);
}
removeClass(el, className);
};
/**
* Converts an array-like object to array, provides a simple polyfill for Array.from
*/
var toArray = function (arrayLike) {
if (isCallable(Array.from)) {
return Array.from(arrayLike);
}
var array = [];
var length = arrayLike.length;
/* istanbul ignore next */
for (var i = 0; i < length; i++) {
array.push(arrayLike[i]);
}
/* istanbul ignore next */
return array;
};
/**
* Assign polyfill from the mdn.
*/
var assign = function (target) {
var others = [], len = arguments.length - 1;
while ( len-- > 0 ) others[ len ] = arguments[ len + 1 ];
/* istanbul ignore else */
if (isCallable(Object.assign)) {
return Object.assign.apply(Object, [ target ].concat( others ));
}
/* istanbul ignore next */
if (target == null) {
throw new TypeError('Cannot convert undefined or null to object');
}
/* istanbul ignore next */
var to = Object(target);
/* istanbul ignore next */
others.forEach(function (arg) {
// Skip over if undefined or null
if (arg != null) {
Object.keys(arg).forEach(function (key) {
to[key] = arg[key];
});
}
});
/* istanbul ignore next */
return to;
};
var id = 0;
var idTemplate = '{id}';
/**
* Generates a unique id.
*/
var uniqId = function () {
// handle too many uses of uniqId, although unlikely.
if (id >= 9999) {
id = 0;
// shift the template.
idTemplate = idTemplate.replace('{id}', '_{id}');
}
id++;
var newId = idTemplate.replace('{id}', String(id));
return newId;
};
/**
* finds the first element that satisfies the predicate callback, polyfills array.find
*/
var find = function (arrayLike, predicate) {
var array = Array.isArray(arrayLike) ? arrayLike : toArray(arrayLike);
for (var i = 0; i < array.length; i++) {
if (predicate(array[i])) {
return array[i];
}
}
return undefined;
};
var isBuiltInComponent = function (vnode) {
if (!vnode) {
return false;
}
var tag = vnode.componentOptions.tag;
return /^(keep-alive|transition|transition-group)$/.test(tag);
};
var makeDelayObject = function (events, delay, delayConfig) {
if (typeof delay === 'number') {
return events.reduce(function (prev, e) {
prev[e] = delay;
return prev;
}, {});
}
return events.reduce(function (prev, e) {
if (typeof delay === 'object' && e in delay) {
prev[e] = delay[e];
return prev;
}
if (typeof delayConfig === 'number') {
prev[e] = delayConfig;
return prev;
}
prev[e] = (delayConfig && delayConfig[e]) || 0;
return prev;
}, {});
};
var deepParseInt = function (input) {
if (typeof input === 'number') { return input; }
if (typeof input === 'string') { return parseInt(input); }
var map = {};
for (var element in input) {
map[element] = parseInt(input[element]);
}
return map;
};
var merge = function (target, source) {
if (! (isObject(target) && isObject(source))) {
return target;
}
Object.keys(source).forEach(function (key) {
var obj, obj$1;
if (isObject(source[key])) {
if (! target[key]) {
assign(target, ( obj = {}, obj[key] = {}, obj ));
}
merge(target[key], source[key]);
return;
}
assign(target, ( obj$1 = {}, obj$1[key] = source[key], obj$1 ));
});
return target;
};
var fillRulesFromElement = function (el, rules) {
if (el.required) {
rules = appendRule('required', rules);
}
if (isTextInput(el)) {
if (el.type === 'email') {
rules = appendRule(("email" + (el.multiple ? ':multiple' : '')), rules);
}
if (el.pattern) {
rules = appendRule({ regex: el.pattern }, rules);
}
// 524288 is the max on some browsers and test environments.
if (el.maxLength >= 0 && el.maxLength < 524288) {
rules = appendRule(("max:" + (el.maxLength)), rules);
}
if (el.minLength > 0) {
rules = appendRule(("min:" + (el.minLength)), rules);
}
if (el.type === 'number') {
rules = appendRule('decimal', rules);
if (el.min !== '') {
rules = appendRule(("min_value:" + (el.min)), rules);
}
if (el.max !== '') {
rules = appendRule(("max_value:" + (el.max)), rules);
}
}
return rules;
}
if (isDateInput(el)) {
var timeFormat = el.step && Number(el.step) < 60 ? 'HH:mm:ss' : 'HH:mm';
if (el.type === 'date') {
return appendRule('date_format:YYYY-MM-DD', rules);
}
if (el.type === 'datetime-local') {
return appendRule(("date_format:YYYY-MM-DDT" + timeFormat), rules);
}
if (el.type === 'month') {
return appendRule('date_format:YYYY-MM', rules);
}
if (el.type === 'week') {
return appendRule('date_format:YYYY-[W]WW', rules);
}
if (el.type === 'time') {
return appendRule(("date_format:" + timeFormat), rules);
}
}
return rules;
};
var values = function (obj) {
if (isCallable(Object.values)) {
return Object.values(obj);
}
// fallback to keys()
/* istanbul ignore next */
return Object.keys(obj).map(function (k) { return obj[k]; });
};
var parseSelector = function (selector) {
var rule = null;
if (includes(selector, ':')) {
rule = selector.split(':').pop();
selector = selector.replace((":" + rule), '');
}
if (selector[0] === '#') {
return {
id: selector.slice(1),
rule: rule,
name: null,
scope: null
};
}
var scope = null;
var name = selector;
if (includes(selector, '.')) {
var parts = selector.split('.');
scope = parts[0];
name = parts.slice(1).join('.');
}
return {
id: null,
scope: scope,
name: name,
rule: rule
};
};
var includes = function (collection, item) {
return collection.indexOf(item) !== -1;
};
var isEmptyArray = function (arr) {
return Array.isArray(arr) && arr.length === 0;
};
//
var LOCALE = 'en';
var Dictionary = function Dictionary (dictionary) {
if ( dictionary === void 0 ) dictionary = {};
this.container = {};
this.merge(dictionary);
};
var prototypeAccessors = { locale: { configurable: true } };
prototypeAccessors.locale.get = function () {
return LOCALE;
};
prototypeAccessors.locale.set = function (value) {
LOCALE = value || 'en';
};
Dictionary.prototype.hasLocale = function hasLocale (locale) {
return !!this.container[locale];
};
Dictionary.prototype.setDateFormat = function setDateFormat (locale, format) {
if (!this.container[locale]) {
this.container[locale] = {};
}
this.container[locale].dateFormat = format;
};
Dictionary.prototype.getDateFormat = function getDateFormat (locale) {
if (!this.container[locale] || !this.container[locale].dateFormat) {
return null;
}
return this.container[locale].dateFormat;
};
Dictionary.prototype.getMessage = function getMessage (locale, key, data) {
var message = null;
if (!this.hasMessage(locale, key)) {
message = this._getDefaultMessage(locale);
} else {
message = this.container[locale].messages[key];
}
return isCallable(message) ? message.apply(void 0, data) : message;
};
/**
* Gets a specific message for field. falls back to the rule message.
*/
Dictionary.prototype.getFieldMessage = function getFieldMessage (locale, field, key, data) {
if (!this.hasLocale(locale)) {
return this.getMessage(locale, key, data);
}
var dict = this.container[locale].custom && this.container[locale].custom[field];
if (!dict || !dict[key]) {
return this.getMessage(locale, key, data);
}
var message = dict[key];
return isCallable(message) ? message.apply(void 0, data) : message;
};
Dictionary.prototype._getDefaultMessage = function _getDefaultMessage (locale) {
if (this.hasMessage(locale, '_default')) {
return this.container[locale].messages._default;
}
return this.container.en.messages._default;
};
Dictionary.prototype.getAttribute = function getAttribute (locale, key, fallback) {
if ( fallback === void 0 ) fallback = '';
if (!this.hasAttribute(locale, key)) {
return fallback;
}
return this.container[locale].attributes[key];
};
Dictionary.prototype.hasMessage = function hasMessage (locale, key) {
return !! (
this.hasLocale(locale) &&
this.container[locale].messages &&
this.container[locale].messages[key]
);
};
Dictionary.prototype.hasAttribute = function hasAttribute (locale, key) {
return !! (
this.hasLocale(locale) &&
this.container[locale].attributes &&
this.container[locale].attributes[key]
);
};
Dictionary.prototype.merge = function merge$1 (dictionary) {
merge(this.container, dictionary);
};
Dictionary.prototype.setMessage = function setMessage (locale, key, message) {
if (! this.hasLocale(locale)) {
this.container[locale] = {
messages: {},
attributes: {}
};
}
this.container[locale].messages[key] = message;
};
Dictionary.prototype.setAttribute = function setAttribute (locale, key, attribute) {
if (! this.hasLocale(locale)) {
this.container[locale] = {
messages: {},
attributes: {}
};
}
this.container[locale].attributes[key] = attribute;
};
Object.defineProperties( Dictionary.prototype, prototypeAccessors );
var drivers = {
default: new Dictionary({
en: {
messages: {},
attributes: {},
custom: {}
}
})
};
var currentDriver = 'default';
var DictionaryResolver = function DictionaryResolver () {};
DictionaryResolver._checkDriverName = function _checkDriverName (driver) {
if (!driver) {
throw createError('you must provide a name to the dictionary driver');
}
};
DictionaryResolver.setDriver = function setDriver (driver, implementation) {
if ( implementation === void 0 ) implementation = null;
this._checkDriverName(driver);
if (implementation) {
drivers[driver] = implementation;
}
currentDriver = driver;
};
DictionaryResolver.getDriver = function getDriver () {
return drivers[currentDriver];
};
//
var ErrorBag = function ErrorBag (errorBag, id) {
if ( errorBag === void 0 ) errorBag = null;
if ( id === void 0 ) id = null;
this.vmId = id || null;
// make this bag a mirror of the provided one, sharing the same items reference.
if (errorBag && errorBag instanceof ErrorBag) {
this.items = errorBag.items;
} else {
this.items = [];
}
};
ErrorBag.prototype[typeof Symbol === 'function' ? Symbol.iterator : '@@iterator'] = function () {
var this$1 = this;
var index = 0;
return {
next: function () {
return { value: this$1.items[index++], done: index > this$1.items.length };
}
};
};
/**
* Adds an error to the internal array.
*/
ErrorBag.prototype.add = function add (error) {
var ref;
(ref = this.items).push.apply(
ref, this._normalizeError(error)
);
};
/**
* Normalizes passed errors to an error array.
*/
ErrorBag.prototype._normalizeError = function _normalizeError (error) {
var this$1 = this;
if (Array.isArray(error)) {
return error.map(function (e) {
e.scope = !isNullOrUndefined(e.scope) ? e.scope : null;
e.vmId = !isNullOrUndefined(e.vmId) ? e.vmId : (this$1.vmId || null);
return e;
});
}
error.scope = !isNullOrUndefined(error.scope) ? error.scope : null;
error.vmId = !isNullOrUndefined(error.vmId) ? error.vmId : (this.vmId || null);
return [error];
};
/**
* Regenrates error messages if they have a generator function.
*/
ErrorBag.prototype.regenerate = function regenerate () {
this.items.forEach(function (i) {
i.msg = isCallable(i.regenerate) ? i.regenerate() : i.msg;
});
};
/**
* Updates a field error with the new field scope.
*/
ErrorBag.prototype.update = function update (id, error) {
var item = find(this.items, function (i) { return i.id === id; });
if (!item) {
return;
}
var idx = this.items.indexOf(item);
this.items.splice(idx, 1);
item.scope = error.scope;
this.items.push(item);
};
/**
* Gets all error messages from the internal array.
*/
ErrorBag.prototype.all = function all (scope) {
var this$1 = this;
var filterFn = function (item) {
var matchesScope = true;
var matchesVM = true;
if (!isNullOrUndefined(scope)) {
matchesScope = item.scope === scope;
}
if (!isNullOrUndefined(this$1.vmId)) {
matchesVM = item.vmId === this$1.vmId;
}
return matchesVM && matchesScope;
};
return this.items.filter(filterFn).map(function (e) { return e.msg; });
};
/**
* Checks if there are any errors in the internal array.
*/
ErrorBag.prototype.any = function any (scope) {
var this$1 = this;
var filterFn = function (item) {
var matchesScope = true;
var matchesVM = true;
if (!isNullOrUndefined(scope)) {
matchesScope = item.scope === scope;
}
if (!isNullOrUndefined(this$1.vmId)) {
matchesVM = item.vmId === this$1.vmId;
}
return matchesVM && matchesScope;
};
return !!this.items.filter(filterFn).length;
};
/**
* Removes all items from the internal array.
*/
ErrorBag.prototype.clear = function clear (scope) {
var this$1 = this;
var matchesVM = isNullOrUndefined(this.vmId) ? function () { return true; } : function (i) { return i.vmId === this$1.vmId; };
if (isNullOrUndefined(scope)) {
scope = null;
}
for (var i = 0; i < this.items.length; ++i) {
if (matchesVM(this.items[i]) && this.items[i].scope === scope) {
this.items.splice(i, 1);
--i;
}
}
};
/**
* Collects errors into groups or for a specific field.
*/
ErrorBag.prototype.collect = function collect (field, scope, map) {
var this$1 = this;
if ( map === void 0 ) map = true;
var isSingleField = !isNullOrUndefined(field) && !field.includes('*');
var groupErrors = function (items) {
var errors = items.reduce(function (collection, error) {
if (!isNullOrUndefined(this$1.vmId) && error.vmId !== this$1.vmId) {
return collection;
}
if (!collection[error.field]) {
collection[error.field] = [];
}
collection[error.field].push(map ? error.msg : error);
return collection;
}, {});
// reduce the collection to be a single array.
if (isSingleField) {
return values(errors)[0] || [];
}
return errors;
};
if (isNullOrUndefined(field)) {
return groupErrors(this.items);
}
var selector = isNullOrUndefined(scope) ? String(field) : (scope + "." + field);
var ref = this._makeCandidateFilters(selector);
var isPrimary = ref.isPrimary;
var isAlt = ref.isAlt;
var collected = this.items.reduce(function (prev, curr) {
if (isPrimary(curr)) {
prev.primary.push(curr);
}
if (isAlt(curr)) {
prev.alt.push(curr);
}
return prev;
}, { primary: [], alt: [] });
collected = collected.primary.length ? collected.primary : collected.alt;
return groupErrors(collected);
};
/**
* Gets the internal array length.
*/
ErrorBag.prototype.count = function count () {
var this$1 = this;
if (this.vmId) {
return this.items.filter(function (e) { return e.vmId === this$1.vmId; }).length;
}
return this.items.length;
};
/**
* Finds and fetches the first error message for the specified field id.
*/
ErrorBag.prototype.firstById = function firstById (id) {
var error = find(this.items, function (i) { return i.id === id; });
return error ? error.msg : undefined;
};
/**
* Gets the first error message for a specific field.
*/
ErrorBag.prototype.first = function first (field, scope) {
if ( scope === void 0 ) scope = null;
var selector = isNullOrUndefined(scope) ? field : (scope + "." + field);
var match = this._match(selector);
return match && match.msg;
};
/**
* Returns the first error rule for the specified field
*/
ErrorBag.prototype.firstRule = function firstRule (field, scope) {
var errors = this.collect(field, scope, false);
return (errors.length && errors[0].rule) || undefined;
};
/**
* Checks if the internal array has at least one error for the specified field.
*/
ErrorBag.prototype.has = function has (field, scope) {
if ( scope === void 0 ) scope = null;
return !!this.first(field, scope);
};
/**
* Gets the first error message for a specific field and a rule.
*/
ErrorBag.prototype.firstByRule = function firstByRule (name, rule, scope) {
if ( scope === void 0 ) scope = null;
var error = this.collect(name, scope, false).filter(function (e) { return e.rule === rule; })[0];
return (error && error.msg) || undefined;
};
/**
* Gets the first error message for a specific field that not match the rule.
*/
ErrorBag.prototype.firstNot = function firstNot (name, rule, scope) {
if ( rule === void 0 ) rule = 'required';
if ( scope === void 0 ) scope = null;
var error = this.collect(name, scope, false).filter(function (e) { return e.rule !== rule; })[0];
return (error && error.msg) || undefined;
};
/**
* Removes errors by matching against the id or ids.
*/
ErrorBag.prototype.removeById = function removeById (id) {
var condition = function (item) { return item.id === id; };
if (Array.isArray(id)) {
condition = function (item) { return id.indexOf(item.id) !== -1; };
}
for (var i = 0; i < this.items.length; ++i) {
if (condition(this.items[i])) {
this.items.splice(i, 1);
--i;
}
}
};
/**
* Removes all error messages associated with a specific field.
*/
ErrorBag.prototype.remove = function remove (field, scope, vmId) {
if (isNullOrUndefined(field)) {
return;
}
var selector = isNullOrUndefined(scope) ? String(field) : (scope + "." + field);
var ref = this._makeCandidateFilters(selector);
var isPrimary = ref.isPrimary;
var shouldRemove = function (item) {
if (isNullOrUndefined(vmId)) { return isPrimary(item); }
return isPrimary(item) && item.vmId === vmId;
};
for (var i = 0; i < this.items.length; ++i) {
if (shouldRemove(this.items[i])) {
this.items.splice(i, 1);
--i;
}
}
};
ErrorBag.prototype._makeCandidateFilters = function _makeCandidateFilters (selector) {
var this$1 = this;
var matchesRule = function () { return true; };
var matchesScope = function () { return true; };
var matchesName = function () { return true; };
var matchesVM = function () { return true; };
var ref = parseSelector(selector);
var id = ref.id;
var rule = ref.rule;
var scope = ref.scope;
var name = ref.name;
if (rule) {
matchesRule = function (item) { return item.rule === rule; };
}
// match by id, can be combined with rule selection.
if (id) {
return {
isPrimary: function (item) { return matchesRule(item) && (function (item) { return id === item.id; }); },
isAlt: function () { return false; }
};
}
if (isNullOrUndefined(scope)) {
// if no scope specified, make sure the found error has no scope.
matchesScope = function (item) { return isNullOrUndefined(item.scope); };
} else {
matchesScope = function (item) { return item.scope === scope; };
}
if (!isNullOrUndefined(name) && name !== '*') {
matchesName = function (item) { return item.field === name; };
}
if (!isNullOrUndefined(this.vmId)) {
matchesVM = function (item) { return item.vmId === this$1.vmId; };
}
// matches the first candidate.
var isPrimary = function (item) {
return matchesVM(item) && matchesName(item) && matchesRule(item) && matchesScope(item);
};
// matches a second candidate, which is a field with a name containing the '.' character.
var isAlt = function (item) {
return matchesVM(item) && matchesRule(item) && item.field === (scope + "." + name);
};
return {
isPrimary: isPrimary,
isAlt: isAlt
};
};
ErrorBag.prototype._match = function _match (selector) {
if (isNullOrUndefined(selector)) {
return undefined;
}
var ref = this._makeCandidateFilters(selector);
var isPrimary = ref.isPrimary;
var isAlt = ref.isAlt;
return this.items.reduce(function (prev, item, idx, arr) {
var isLast = idx === arr.length - 1;
if (prev.primary) {
return isLast ? prev.primary : prev;
}
if (isPrimary(item)) {
prev.primary = item;
}
if (isAlt(item)) {
prev.alt = item;
}
// keep going.
if (!isLast) {
return prev;
}
return prev.primary || prev.alt;
}, {});
};
// VNode Utils
// Gets the model object on the vnode.
function findModel (vnode) {
if (!vnode.data) {
return null;
}
// Component Model
if (vnode.data.model) {
return vnode.data.model;
}
return !!(vnode.data.directives) && find(vnode.data.directives, function (d) { return d.name === 'model'; });
}
function extractVNodes (vnode) {
if (findModel(vnode)) {
return [vnode];
}
var children = Array.isArray(vnode) ? vnode : vnode.children;
if (!Array.isArray(children)) {
return [];
}
return children.reduce(function (nodes, node) {
var candidates = extractVNodes(node);
if (candidates.length) {
nodes.push.apply(nodes, candidates);
}
return nodes;
}, []);
}
// Resolves v-model config if exists.
function findModelConfig (vnode) {
if (!vnode.componentOptions) { return null; }
return vnode.componentOptions.Ctor.options.model;
}
// Adds a listener to vnode listener object.
function mergeVNodeListeners (obj, eventName, handler) {
// Has a single listener.
if (isCallable(obj[eventName])) {
var prevHandler = obj[eventName];
obj[eventName] = [prevHandler];
}
// has other listeners.
if (Array.isArray(obj[eventName])) {
obj[eventName].push(handler);
return;
}
// no listener at all.
if (isNullOrUndefined(obj[eventName])) {
obj[eventName] = [handler];
}
}
// Adds a listener to a native HTML vnode.
function addNativeNodeListener (node, eventName, handler) {
if (isNullOrUndefined(node.data.on)) {
node.data.on = {};
}
mergeVNodeListeners(node.data.on, eventName, handler);
}
// Adds a listener to a Vue component vnode.
function addComponentNodeListener (node, eventName, handler) {
/* istanbul ignore next */
if (!node.componentOptions.listeners) {
node.componentOptions.listeners = {};
}
mergeVNodeListeners(node.componentOptions.listeners, eventName, handler);
}
function addVNodeListener (vnode, eventName, handler) {
if (vnode.componentOptions) {
addComponentNodeListener(vnode, eventName, handler);
}
addNativeNodeListener(vnode, eventName, handler);
}
// Determines if `change` should be used over `input` for listeners.
function getInputEventName (vnode, model) {
// Is a component.
if (vnode.componentOptions) {
var ref = findModelConfig(vnode) || { event: 'input' };
var event = ref.event;
return event;
}
// Lazy Models typically use change event
if (model && model.modifiers && model.modifiers.lazy) {
return 'change';
}
// is a textual-type input.
if (vnode.data.attrs && isTextInput({ type: vnode.data.attrs.type || 'text' })) {
return 'input';
}
return 'change';
}
function normalizeSlots (slots, ctx) {
return Object.keys(slots).reduce(function (arr, key) {
slots[key].forEach(function (vnode) {
if (!vnode.context) {
slots[key].context = ctx;
if (!vnode.data) {
vnode.data = {};
}
vnode.data.slot = key;
}
});
return arr.concat(slots[key]);
}, []);
}
function createRenderless (h, vnode) {
// a single-root slot yay!
if (!Array.isArray(vnode)) {
return vnode;
}
if (vnode.length === 1) {
return vnode[0];
}
if (process.env.NODE_ENV !== 'production') {
warn('Your slot should have one root element. Rendering a span as the root.');
}
// Renders a multi-root node, should throw a Vue error.
return vnode;
}
/**
* Generates the options required to construct a field.
*/
var Resolver = function Resolver () {};
Resolver.generate = function generate (el, binding, vnode) {
var model = Resolver.resolveModel(binding, vnode);
var options = pluginInstance.resolveConfig(vnode.context);
return {
name: Resolver.resolveName(el, vnode),
el: el,
listen: !binding.modifiers.disable,
bails: binding.modifiers.bails ? true : (binding.modifiers.continues === true ? false : undefined),
scope: Resolver.resolveScope(el, binding, vnode),
vm: Resolver.makeVM(vnode.context),
expression: binding.value,
component: vnode.componentInstance,
classes: options.classes,
classNames: options.classNames,
getter: Resolver.resolveGetter(el, vnode, model),
events: Resolver.resolveEvents(el, vnode) || options.events,
model: model,
delay: Resolver.resolveDelay(el, vnode, options),
rules: Resolver.resolveRules(el, binding, vnode),
immediate: !!binding.modifiers.initial || !!binding.modifiers.immediate,
validity: options.validity,
aria: options.aria,
initialValue: Resolver.resolveInitialValue(vnode)
};
};
Resolver.getCtorConfig = function getCtorConfig (vnode) {
if (!vnode.componentInstance) { return null; }
var config = getPath('componentInstance.$options.$_veeValidate', vnode);
return config;
};
/**
* Resolves the rules defined on an element.
*/
Resolver.resolveRules = function resolveRules (el, binding, vnode) {
var rules = '';
if (!binding.value && (!binding || !binding.expression)) {
rules = getDataAttribute(el, 'rules');
}
if (binding.value && includes(['string', 'object'], typeof binding.value.rules)) {
rules = binding.value.rules;
} else if (binding.value) {
rules = binding.value;
}
if (vnode.componentInstance) {
return rules;
}
// If validity is disabled, ignore field rules.
var normalized = normalizeRules(rules);
if (!pluginInstance.config.validity) {
return normalized;
}
return assign({}, fillRulesFromElement(el, {}), normalized);
};
/**
* @param {*} vnode
*/
Resolver.resolveInitialValue = function resolveInitialValue (vnode) {
var model = vnode.data.model || find(vnode.data.directives, function (d) { return d.name === 'model'; });
return model && model.value;
};
/**
* Creates a non-circular partial VM instance from a Vue instance.
* @param {*} vm
*/
Resolver.makeVM = function makeVM (vm) {
return {
get $el () {
return vm.$el;
},
get $refs () {
return vm.$refs;
},
$watch: vm.$watch ? vm.$watch.bind(vm) : function () {},
$validator: vm.$validator ? {
errors: vm.$validator.errors,
validate: vm.$validator.validate.bind(vm.$validator),
update: vm.$validator.update.bind(vm.$validator)
} : null
};
};
/**
* Resolves the delay value.
* @param {*} el
* @param {*} vnode
* @param {Object} options
*/
Resolver.resolveDelay = function resolveDelay (el, vnode, options) {
var delay = getDataAttribute(el, 'delay');
var globalDelay = (options && 'delay' in options) ? options.delay : 0;
if (!delay && vnode.componentInstance && vnode.componentInstance.$attrs) {
delay = vnode.componentInstance.$attrs['data-vv-delay'];
}
if (!isObject(globalDelay)) {
return deepParseInt(delay || globalDelay);
}
if (!isNullOrUndefined(delay)) {
globalDelay.input = delay;
}
return deepParseInt(globalDelay);
};
/**
* Resolves the events to validate in response to.
* @param {*} el
* @param {*} vnode
*/
Resolver.resolveEvents = function resolveEvents (el, vnode) {
// resolve it from the root element.
var events = getDataAttribute(el, 'validate-on');
// resolve from data-vv-validate-on if its a vue component.
if (!events && vnode.componentInstance && vnode.componentInstance.$attrs) {
events = vnode.componentInstance.$attrs['data-vv-validate-on'];
}
// resolve it from $_veeValidate options.
if (!events && vnode.componentInstance) {
var config = Resolver.getCtorConfig(vnode);
events = config && config.events;
}
if (!events && pluginInstance.config.events) {
events = pluginInstance.config.events;
}
// resolve the model event if its configured for custom components.
if (events && vnode.componentInstance && includes(events, 'input')) {
var ref = vnode.componentInstance.$options.model || { event: 'input' };
var event = ref.event;
// if the prop was configured but not the model.
if (!event) {
return events;
}
events = events.replace('input', event);
}
return events;
};
/**
* Resolves the scope for the field.
* @param {*} el
* @param {*} binding
*/
Resolver.resolveScope = function resolveScope (el, binding, vnode) {
if ( vnode === void 0 ) vnode = {};
var scope = null;
if (vnode.componentInstance && isNullOrUndefined(scope)) {
scope = vnode.componentInstance.$attrs && vnode.componentInstance.$attrs['data-vv-scope'];
}
return !isNullOrUndefined(scope) ? scope : getScope(el);
};
/**
* Checks if the node directives contains a v-model or a specified arg.
* Args take priority over models.
*
* @return {Object}
*/
Resolver.resolveModel = function resolveModel (binding, vnode) {
if (binding.arg) {
return { expression: binding.arg };
}
var model = findModel(vnode);
if (!model) {
return null;
}
// https://github.com/vuejs/vue/blob/dev/src/core/util/lang.js#L26
var watchable = !/[^\w.$]/.test(model.expression) && hasPath(model.expression, vnode.context);
var lazy = !!(model.modifiers && model.modifiers.lazy);
if (!watchable) {
return { expression: null, lazy: lazy };
}
return { expression: model.expression, lazy: lazy };
};
/**
* Resolves the field name to trigger validations.
* @return {String} The field name.
*/
Resolver.resolveName = function resolveName (el, vnode) {
var name = getDataAttribute(el, 'name');
if (!name && !vnode.componentInstance) {
return el.name;
}
if (!name && vnode.componentInstance && vnode.componentInstance.$attrs) {
name = vnode.componentInstance.$attrs['data-vv-name'] || vnode.componentInstance.$attrs['name'];
}
if (!name && vnode.componentInstance) {
var config = Resolver.getCtorConfig(vnode);
if (config && isCallable(config.name)) {
var boundGetter = config.name.bind(vnode.componentInstance);
return boundGetter();
}
return vnode.componentInstance.name;
}
return name;
};
/**
* Returns a value getter input type.
*/
Resolver.resolveGetter = function resolveGetter (el, vnode, model) {
if (model && model.expression) {
return function () {
return getPath(model.expression, vnode.context);
};
}
if (vnode.componentInstance) {
var path = getDataAttribute(el, 'value-path') || (vnode.componentInstance.$attrs && vnode.componentInstance.$attrs['data-vv-value-path']);
if (path) {
return function () {
return getPath(path, vnode.componentInstance);
};
}
var config = Resolver.getCtorConfig(vnode);
if (config && isCallable(config.value)) {
var boundGetter = config.value.bind(vnode.componentInstance);
return function () {
return boundGetter();
};
}
var ref = vnode.componentInstance.$options.model || { prop: 'value' };
var prop = ref.prop;
return function () {
return vnode.componentInstance[prop];
};
}
switch (el.type) {
case 'checkbox': return function () {
var els = document.querySelectorAll(("input[name=\"" + (el.name) + "\"]"));
els = toArray(els).filter(function (el) { return el.checked; });
if (!els.length) { return undefined; }
return els.map(function (checkbox) { return checkbox.value; });
};
case 'radio': return function () {
var els = document.querySelectorAll(("input[name=\"" + (el.name) + "\"]"));
var elm = find(els, function (el) { return el.checked; });
return elm && elm.value;
};
case 'file': return function (context) {
return toArray(el.files);
};
case 'select-multiple': return function () {
return toArray(el.options).filter(function (opt) { return opt.selected; }).map(function (opt) { return opt.value; });
};
default: return function () {
return el && el.value;
};
}
};
var RULES = {};
var RuleContainer = function RuleContainer () {};
var staticAccessors = { rules: { configurable: true } };
RuleContainer.add = function add (name, ref) {
var validate = ref.validate;
var options = ref.options;
var paramNames = ref.paramNames;
RULES[name] = {
validate: validate,
options: options,
paramNames: paramNames
};
};
staticAccessors.rules.get = function () {
return RULES;
};
RuleContainer.has = function has (name) {
return !!RULES[name];
};
RuleContainer.isImmediate = function isImmediate (name) {
return !!(RULES[name] && RULES[name].options.immediate);
};
RuleContainer.isTargetRule = function isTargetRule (name) {
return !!(RULES[name] && RULES[name].options.hasTarget);
};
RuleContainer.remove = function remove (ruleName) {
delete RULES[ruleName];
};
RuleContainer.getParamNames = function getParamNames (ruleName) {
return RULES[ruleName] && RULES[ruleName].paramNames;
};
RuleContainer.getOptions = function getOptions (ruleName) {
return RULES[ruleName] && RULES[ruleName].options;
};
RuleContainer.getValidatorMethod = function getValidatorMethod (ruleName) {
return RULES[ruleName] ? RULES[ruleName].validate : null;
};
Object.defineProperties( RuleContainer, staticAccessors );
//
var isEvent = function (evt) {
return (typeof Event !== 'undefined' && isCallable(Event) && evt instanceof Event) || (evt && evt.srcElement);
};
var normalizeEvents = function (evts) {
if (!evts) { return []; }
return (typeof evts === 'string' ? evts.split('|') : evts);
};
var supportsPassive = true;
var detectPassiveSupport = function () {
try {
var opts = Object.defineProperty({}, 'passive', {
get: function get () {
supportsPassive = true;
}
});
window.addEventListener('testPassive', null, opts);
window.removeEventListener('testPassive', null, opts);
} catch (e) {
supportsPassive = false;
}
return supportsPassive;
};
var addEventListener = function (el, eventName, cb) {
el.addEventListener(eventName, cb, supportsPassive ? { passive: true } : false);
};
//
var DEFAULT_OPTIONS = {
targetOf: null,
immediate: false,
scope: null,
listen: true,
name: null,
rules: {},
vm: null,
classes: false,
validity: true,
aria: true,
events: 'input|blur',
delay: 0,
classNames: {
touched: 'touched', // the control has been blurred
untouched: 'untouched', // the control hasn't been blurred
valid: 'valid', // model is valid
invalid: 'invalid', // model is invalid
pristine: 'pristine', // control has not been interacted with
dirty: 'dirty' // control has been interacted with
}
};
var Field = function Field (options) {
if ( options === void 0 ) options = {};
this.id = uniqId();
this.el = options.el;
this.updated = false;
this.dependencies = [];
this.vmId = options.vmId;
this.watchers = [];
this.events = [];
this.delay = 0;
this.rules = {};
this._cacheId(options);
this.classNames = assign({}, DEFAULT_OPTIONS.classNames);
options = assign({}, DEFAULT_OPTIONS, options);
this._delay = !isNullOrUndefined(options.delay) ? options.delay : 0; // cache initial delay
this.validity = options.validity;
this.aria = options.aria;
this.flags = createFlags();
this.vm = options.vm;
this.componentInstance = options.component;
this.ctorConfig = this.componentInstance ? getPath('$options.$_veeValidate', this.componentInstance) : undefined;
this.update(options);
// set initial value.
this.initialValue = this.value;
this.updated = false;
};
var prototypeAccessors$1 = { validator: { configurable: true },isRequired: { configurable: true },isDisabled: { configurable: true },alias: { configurable: true },value: { configurable: true },bails: { configurable: true },rejectsFalse: { configurable: true } };
prototypeAccessors$1.validator.get = function () {
if (!this.vm || !this.vm.$validator) {
return { validate: function () {} };
}
return this.vm.$validator;
};
prototypeAccessors$1.isRequired.get = function () {
return !!this.rules.required;
};
prototypeAccessors$1.isDisabled.get = function () {
return !!(this.componentInstance && this.componentInstance.disabled) || !!(this.el && this.el.disabled);
};
/**
* Gets the display name (user-friendly name).
*/
prototypeAccessors$1.alias.get = function () {
if (this._alias) {
return this._alias;
}
var alias = null;
if (this.ctorConfig && this.ctorConfig.alias) {
alias = isCallable(this.ctorConfig.alias) ? this.ctorConfig.alias.call(this.componentInstance) : this.ctorConfig.alias;
}
if (!alias && this.el) {
alias = getDataAttribute(this.el, 'as');
}
if (!alias && this.componentInstance) {
return this.componentInstance.$attrs && this.componentInstance.$attrs['data-vv-as'];
}
return alias;
};
/**
* Gets the input value.
*/
prototypeAccessors$1.value.get = function () {
if (!isCallable(this.getter)) {
return undefined;
}
return this.getter();
};
prototypeAccessors$1.bails.get = function () {
return this._bails;
};
/**
* If the field rejects false as a valid value for the required rule.
*/
prototypeAccessors$1.rejectsFalse.get = function () {
if (this.componentInstance && this.ctorConfig) {
return !!this.ctorConfig.rejectsFalse;
}
if (!this.el) {
return false;
}
return this.el.type === 'checkbox';
};
/**
* Determines if the instance matches the options provided.
*/
Field.prototype.matches = function matches (options) {
var this$1 = this;
if (!options) {
return true;
}
if (options.id) {
return this.id === options.id;
}
var matchesComponentId = isNullOrUndefined(options.vmId) ? function () { return true; } : function (id) { return id === this$1.vmId; };
if (!matchesComponentId(options.vmId)) {
return false;
}
if (options.name === undefined && options.scope === undefined) {
return true;
}
if (options.scope === undefined) {
return this.name === options.name;
}
if (options.name === undefined) {
return this.scope === options.scope;
}
return options.name === this.name && options.scope === this.scope;
};
/**
* Caches the field id.
*/
Field.prototype._cacheId = function _cacheId (options) {
if (this.el && !options.targetOf) {
this.el._veeValidateId = this.id;
}
};
/**
* Keeps a reference of the most current validation run.
*/
Field.prototype.waitFor = function waitFor (pendingPromise) {
this._waitingFor = pendingPromise;
};
Field.prototype.isWaitingFor = function isWaitingFor (promise) {
return this._waitingFor === promise;
};
/**
* Updates the field with changed data.
*/
Field.prototype.update = function update (options) {
this.targetOf = options.targetOf || null;
this.immediate = options.immediate || this.immediate || false;
// update errors scope if the field scope was changed.
if (!isNullOrUndefined(options.scope) && options.scope !== this.scope && isCallable(this.validator.update)) {
this.validator.update(this.id, { scope: options.scope });
}
this.scope = !isNullOrUndefined(options.scope) ? options.scope
: !isNullOrUndefined(this.scope) ? this.scope : null;
this.name = (!isNullOrUndefined(options.name) ? String(options.name) : options.name) || this.name || null;
this.rules = options.rules !== undefined ? normalizeRules(options.rules) : this.rules;
this._bails = options.bails !== undefined ? options.bails : this._bails;
this.model = options.model || this.model;
this.listen = options.listen !== undefined ? options.listen : this.listen;
this.classes = (options.classes || this.classes || false) && !this.componentInstance;
this.classNames = isObject(options.classNames) ? merge(this.classNames, options.classNames) : this.classNames;
this.getter = isCallable(options.getter) ? options.getter : this.getter;
this._alias = options.alias || this._alias;
this.events = (options.events) ? normalizeEvents(options.events) : this.events;
this.delay = makeDelayObject(this.events, options.delay || this.delay, this._delay);
this.updateDependencies();
this.addActionListeners();
if (process.env.NODE_ENV !== 'production' && !this.name && !this.targetOf) {
warn('A field is missing a "name" or "data-vv-name" attribute');
}
// update required flag flags
if (options.rules !== undefined) {
this.flags.required = this.isRequired;
}
// validate if it was validated before and field was updated and there was a rules mutation.
if (this.flags.validated && options.rules !== undefined && this.updated) {
this.validator.validate(("#" + (this.id)));
}
this.updated = true;
this.addValueListeners();
// no need to continue.
if (!this.el) {
return;
}
this.updateClasses();
this.updateAriaAttrs();
};
/**
* Resets field flags and errors.
*/
Field.prototype.reset = function reset () {
var this$1 = this;
if (this._cancellationToken) {
this._cancellationToken.cancelled = true;
delete this._cancellationToken;
}
var defaults = createFlags();
Object.keys(this.flags).filter(function (flag) { return flag !== 'required'; }).forEach(function (flag) {
this$1.flags[flag] = defaults[flag];
});
this.addValueListeners();
this.addActionListeners();
this.updateClasses();
this.updateAriaAttrs();
this.updateCustomValidity();
};
/**
* Sets the flags and their negated counterparts, and updates the classes and re-adds action listeners.
*/
Field.prototype.setFlags = function setFlags (flags) {
var this$1 = this;
var negated = {
pristine: 'dirty',
dirty: 'pristine',
valid: 'invalid',
invalid: 'valid',
touched: 'untouched',
untouched: 'touched'
};
Object.keys(flags).forEach(function (flag) {
this$1.flags[flag] = flags[flag];
// if it has a negation and was not specified, set it as well.
if (negated[flag] && flags[negated[flag]] === undefined) {
this$1.flags[negated[flag]] = !flags[flag];
}
});
if (
flags.untouched !== undefined ||
flags.touched !== undefined ||
flags.dirty !== undefined ||
flags.pristine !== undefined
) {
this.addActionListeners();
}
this.updateClasses();
this.updateAriaAttrs();
this.updateCustomValidity();
};
/**
* Determines if the field requires references to target fields.
*/
Field.prototype.updateDependencies = function updateDependencies () {
var this$1 = this;
// reset dependencies.
this.dependencies.forEach(function (d) { return d.field.destroy(); });
this.dependencies = [];
// we get the selectors fo