536 lines
16 KiB
JavaScript
536 lines
16 KiB
JavaScript
/*!
|
|
* Laravel Javascript Validation
|
|
*
|
|
* https://github.com/proengsoft/laravel-jsvalidation
|
|
*
|
|
* Helper functions used by validators
|
|
*
|
|
* Copyright (c) 2017 Proengsoft
|
|
* Released under the MIT license
|
|
*/
|
|
|
|
import strlen from 'locutus/php/strings/strlen';
|
|
import array_diff from 'locutus/php/array/array_diff';
|
|
import strtotime from 'locutus/php/datetime/strtotime';
|
|
import is_numeric from 'locutus/php/var/is_numeric';
|
|
|
|
$.extend(true, laravelValidation, {
|
|
|
|
helpers: {
|
|
|
|
/**
|
|
* Numeric rules
|
|
*/
|
|
numericRules: ['Integer', 'Numeric'],
|
|
|
|
/**
|
|
* Gets the file information from file input.
|
|
*
|
|
* @param fieldObj
|
|
* @param index
|
|
* @returns {{file: *, extension: string, size: number}}
|
|
*/
|
|
fileinfo: function (fieldObj, index) {
|
|
var FileName = fieldObj.value;
|
|
index = typeof index !== 'undefined' ? index : 0;
|
|
if ( fieldObj.files !== null ) {
|
|
if (typeof fieldObj.files[index] !== 'undefined') {
|
|
return {
|
|
file: FileName,
|
|
extension: FileName.substr(FileName.lastIndexOf('.') + 1),
|
|
size: fieldObj.files[index].size / 1024,
|
|
type: fieldObj.files[index].type
|
|
};
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
|
|
|
|
/**
|
|
* Gets the selectors for th specified field names.
|
|
*
|
|
* @param names
|
|
* @returns {string}
|
|
*/
|
|
selector: function (names) {
|
|
var selector = [];
|
|
if (! this.isArray(names)) {
|
|
names = [names];
|
|
}
|
|
for (var i = 0; i < names.length; i++) {
|
|
selector.push("[name='" + names[i] + "']");
|
|
}
|
|
return selector.join();
|
|
},
|
|
|
|
|
|
/**
|
|
* Check if element has numeric rules.
|
|
*
|
|
* @param element
|
|
* @returns {boolean}
|
|
*/
|
|
hasNumericRules: function (element) {
|
|
return this.hasRules(element, this.numericRules);
|
|
},
|
|
|
|
/**
|
|
* Check if element has passed rules.
|
|
*
|
|
* @param element
|
|
* @param rules
|
|
* @returns {boolean}
|
|
*/
|
|
hasRules: function (element, rules) {
|
|
|
|
var found = false;
|
|
if (typeof rules === 'string') {
|
|
rules = [rules];
|
|
}
|
|
|
|
var validator = $.data(element.form, "validator");
|
|
var listRules = [];
|
|
var cache = validator.arrayRulesCache;
|
|
if (element.name in cache) {
|
|
$.each(cache[element.name], function (index, arrayRule) {
|
|
listRules.push(arrayRule);
|
|
});
|
|
}
|
|
if (element.name in validator.settings.rules) {
|
|
listRules.push(validator.settings.rules[element.name]);
|
|
}
|
|
$.each(listRules, function(index,objRules){
|
|
if ('laravelValidation' in objRules) {
|
|
var _rules=objRules.laravelValidation;
|
|
for (var i = 0; i < _rules.length; i++) {
|
|
if ($.inArray(_rules[i][0],rules) !== -1) {
|
|
found = true;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
return found;
|
|
},
|
|
|
|
/**
|
|
* Return the string length using PHP function.
|
|
* http://php.net/manual/en/function.strlen.php
|
|
* http://phpjs.org/functions/strlen/
|
|
*
|
|
* @param string
|
|
*/
|
|
strlen: function (string) {
|
|
return strlen(string);
|
|
},
|
|
|
|
/**
|
|
* Get the size of the object depending of his type.
|
|
*
|
|
* @param obj
|
|
* @param element
|
|
* @param value
|
|
* @returns int
|
|
*/
|
|
getSize: function getSize(obj, element, value) {
|
|
|
|
if (this.hasNumericRules(element) && this.is_numeric(value)) {
|
|
return parseFloat(value);
|
|
} else if (this.isArray(value)) {
|
|
return parseFloat(value.length);
|
|
} else if (element.type === 'file') {
|
|
return parseFloat(Math.floor(this.fileinfo(element).size));
|
|
}
|
|
|
|
return parseFloat(this.strlen(value));
|
|
},
|
|
|
|
|
|
/**
|
|
* Return specified rule from element.
|
|
*
|
|
* @param rule
|
|
* @param element
|
|
* @returns object
|
|
*/
|
|
getLaravelValidation: function(rule, element) {
|
|
|
|
var found = undefined;
|
|
$.each($.validator.staticRules(element), function(key, rules) {
|
|
if (key==="laravelValidation") {
|
|
$.each(rules, function (i, value) {
|
|
if (value[0]===rule) {
|
|
found=value;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
return found;
|
|
},
|
|
|
|
/**
|
|
* Return he timestamp of value passed using format or default format in element.
|
|
*
|
|
* @param value
|
|
* @param format
|
|
* @returns {boolean|int}
|
|
*/
|
|
parseTime: function (value, format) {
|
|
|
|
var timeValue = false;
|
|
var fmt = new DateFormatter();
|
|
|
|
if (typeof value === 'number' && typeof format === 'undefined') {
|
|
return value;
|
|
}
|
|
|
|
if (typeof format === 'object') {
|
|
var dateRule = this.getLaravelValidation('DateFormat', format);
|
|
if (dateRule !== undefined) {
|
|
format = dateRule[1][0];
|
|
} else {
|
|
format = null;
|
|
}
|
|
}
|
|
|
|
if (format == null) {
|
|
timeValue = this.strtotime(value);
|
|
} else {
|
|
timeValue = fmt.parseDate(value, format);
|
|
if (timeValue instanceof Date && fmt.formatDate(timeValue, format) === value) {
|
|
timeValue = Math.round((timeValue.getTime() / 1000));
|
|
} else {
|
|
timeValue = false;
|
|
}
|
|
}
|
|
|
|
return timeValue;
|
|
},
|
|
|
|
/**
|
|
* Compare a given date against another using an operator.
|
|
*
|
|
* @param validator
|
|
* @param value
|
|
* @param element
|
|
* @param params
|
|
* @param operator
|
|
* @return {boolean}
|
|
*/
|
|
compareDates: function (validator, value, element, params, operator) {
|
|
|
|
var timeCompare = this.parseTime(params);
|
|
|
|
if (!timeCompare) {
|
|
var target = this.dependentElement(validator, element, params);
|
|
if (target === undefined) {
|
|
return false;
|
|
}
|
|
timeCompare = this.parseTime(validator.elementValue(target), target);
|
|
}
|
|
|
|
var timeValue = this.parseTime(value, element);
|
|
if (timeValue === false) {
|
|
return false;
|
|
}
|
|
|
|
switch (operator) {
|
|
case '<':
|
|
return timeValue < timeCompare;
|
|
|
|
case '<=':
|
|
return timeValue <= timeCompare;
|
|
|
|
case '==':
|
|
case '===':
|
|
return timeValue === timeCompare;
|
|
|
|
case '>':
|
|
return timeValue > timeCompare;
|
|
|
|
case '>=':
|
|
return timeValue >= timeCompare;
|
|
|
|
default:
|
|
throw new Error('Unsupported operator.');
|
|
}
|
|
},
|
|
|
|
/**
|
|
* This method allows you to intelligently guess the date by closely matching the specific format.
|
|
*
|
|
* @param value
|
|
* @param format
|
|
* @returns {Date}
|
|
*/
|
|
guessDate: function (value, format) {
|
|
var fmt = new DateFormatter();
|
|
return fmt.guessDate(value, format)
|
|
},
|
|
|
|
/**
|
|
* Returns Unix timestamp based on PHP function strototime.
|
|
* http://php.net/manual/es/function.strtotime.php
|
|
* http://phpjs.org/functions/strtotime/
|
|
*
|
|
* @param text
|
|
* @param now
|
|
* @returns {*}
|
|
*/
|
|
strtotime: function (text, now) {
|
|
return strtotime(text, now)
|
|
},
|
|
|
|
/**
|
|
* Returns if value is numeric.
|
|
* http://php.net/manual/es/var.is_numeric.php
|
|
* http://phpjs.org/functions/is_numeric/
|
|
*
|
|
* @param mixed_var
|
|
* @returns {*}
|
|
*/
|
|
is_numeric: function (mixed_var) {
|
|
return is_numeric(mixed_var)
|
|
},
|
|
|
|
/**
|
|
* Check whether the argument is of type Array.
|
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray#Polyfill
|
|
*
|
|
* @param arg
|
|
* @returns {boolean}
|
|
*/
|
|
isArray: function(arg) {
|
|
return Object.prototype.toString.call(arg) === '[object Array]';
|
|
},
|
|
|
|
/**
|
|
* Returns Array diff based on PHP function array_diff.
|
|
* http://php.net/manual/es/function.array_diff.php
|
|
* http://phpjs.org/functions/array_diff/
|
|
*
|
|
* @param arr1
|
|
* @param arr2
|
|
* @returns {*}
|
|
*/
|
|
arrayDiff: function (arr1, arr2) {
|
|
return array_diff(arr1, arr2);
|
|
},
|
|
|
|
/**
|
|
* Check whether two arrays are equal to one another.
|
|
*
|
|
* @param arr1
|
|
* @param arr2
|
|
* @returns {*}
|
|
*/
|
|
arrayEquals: function (arr1, arr2) {
|
|
if (! this.isArray(arr1) || ! this.isArray(arr2)) {
|
|
return false;
|
|
}
|
|
|
|
if (arr1.length !== arr2.length) {
|
|
return false;
|
|
}
|
|
|
|
return $.isEmptyObject(this.arrayDiff(arr1, arr2));
|
|
},
|
|
|
|
/**
|
|
* Makes element dependant from other.
|
|
*
|
|
* @param validator
|
|
* @param element
|
|
* @param name
|
|
* @returns {*}
|
|
*/
|
|
dependentElement: function(validator, element, name) {
|
|
|
|
var el=validator.findByName(name);
|
|
|
|
if ( el[0]!==undefined && validator.settings.onfocusout ) {
|
|
var event = 'blur';
|
|
if (el[0].tagName === 'SELECT' ||
|
|
el[0].tagName === 'OPTION' ||
|
|
el[0].type === 'checkbox' ||
|
|
el[0].type === 'radio'
|
|
) {
|
|
event = 'click';
|
|
}
|
|
|
|
var ruleName = '.validate-laravelValidation';
|
|
el.off( ruleName )
|
|
.off(event + ruleName + '-' + element.name)
|
|
.on( event + ruleName + '-' + element.name, function() {
|
|
$( element ).valid();
|
|
});
|
|
}
|
|
|
|
return el[0];
|
|
},
|
|
|
|
/**
|
|
* Parses error Ajax response and gets the message.
|
|
*
|
|
* @param response
|
|
* @returns {string[]}
|
|
*/
|
|
parseErrorResponse: function (response) {
|
|
var newResponse = ['Whoops, looks like something went wrong.'];
|
|
if ('responseText' in response) {
|
|
var errorMsg = response.responseText.match(/<h1\s*>(.*)<\/h1\s*>/i);
|
|
if (this.isArray(errorMsg)) {
|
|
newResponse = [errorMsg[1]];
|
|
}
|
|
}
|
|
return newResponse;
|
|
},
|
|
|
|
/**
|
|
* Escape string to use as Regular Expression.
|
|
*
|
|
* @param str
|
|
* @returns string
|
|
*/
|
|
escapeRegExp: function (str) {
|
|
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
|
},
|
|
|
|
/**
|
|
* Generate RegExp from wildcard attributes.
|
|
*
|
|
* @param name
|
|
* @returns {RegExp}
|
|
*/
|
|
regexFromWildcard: function (name) {
|
|
var nameParts = name.split('[*]');
|
|
if (nameParts.length === 1) nameParts.push('');
|
|
|
|
return new RegExp('^' + nameParts.map(function(x) {
|
|
return laravelValidation.helpers.escapeRegExp(x)
|
|
}).join('\\[[^\\]]*\\]') + '$');
|
|
},
|
|
|
|
/**
|
|
* Merge additional laravel validation rules into the current rule set.
|
|
*
|
|
* @param {object} rules
|
|
* @param {object} newRules
|
|
* @returns {object}
|
|
*/
|
|
mergeRules: function (rules, newRules) {
|
|
var rulesList = {
|
|
'laravelValidation': newRules.laravelValidation || [],
|
|
'laravelValidationRemote': newRules.laravelValidationRemote || []
|
|
};
|
|
|
|
for (var key in rulesList) {
|
|
if (rulesList[key].length === 0) {
|
|
continue;
|
|
}
|
|
|
|
if (typeof rules[key] === "undefined") {
|
|
rules[key] = [];
|
|
}
|
|
|
|
rules[key] = rules[key].concat(rulesList[key]);
|
|
}
|
|
|
|
return rules;
|
|
},
|
|
|
|
/**
|
|
* HTML entity encode a string.
|
|
*
|
|
* @param string
|
|
* @returns {string}
|
|
*/
|
|
encode: function (string) {
|
|
return $('<div/>').text(string).html();
|
|
},
|
|
|
|
/**
|
|
* Lookup name in an array.
|
|
*
|
|
* @param validator
|
|
* @param {string} name Name in dot notation format.
|
|
* @returns {*}
|
|
*/
|
|
findByArrayName: function (validator, name) {
|
|
var sqName = name.replace(/\.([^\.]+)/g, '[$1]'),
|
|
lookups = [
|
|
// Convert dot to square brackets. e.g. foo.bar.0 becomes foo[bar][0]
|
|
sqName,
|
|
// Append [] to the name e.g. foo becomes foo[] or foo.bar.0 becomes foo[bar][0][]
|
|
sqName + '[]',
|
|
// Remove key from last array e.g. foo[bar][0] becomes foo[bar][]
|
|
sqName.replace(/(.*)\[(.*)\]$/g, '$1[]')
|
|
];
|
|
|
|
for (var i = 0; i < lookups.length; i++) {
|
|
var elem = validator.findByName(lookups[i]);
|
|
if (elem.length > 0) {
|
|
return elem;
|
|
}
|
|
}
|
|
|
|
return $(null);
|
|
},
|
|
|
|
/**
|
|
* Attempt to find an element in the DOM matching the given name.
|
|
* Example names include:
|
|
* - domain.0 which matches domain[]
|
|
* - customfield.3 which matches customfield[3]
|
|
*
|
|
* @param validator
|
|
* @param {string} name
|
|
* @returns {*}
|
|
*/
|
|
findByName: function (validator, name) {
|
|
// Exact match.
|
|
var elem = validator.findByName(name);
|
|
if (elem.length > 0) {
|
|
return elem;
|
|
}
|
|
|
|
// Find name in data, using dot notation.
|
|
var delim = '.',
|
|
parts = name.split(delim);
|
|
for (var i = parts.length; i > 0; i--) {
|
|
var reconstructed = [];
|
|
for (var c = 0; c < i; c++) {
|
|
reconstructed.push(parts[c]);
|
|
}
|
|
|
|
elem = this.findByArrayName(validator, reconstructed.join(delim));
|
|
if (elem.length > 0) {
|
|
return elem;
|
|
}
|
|
}
|
|
|
|
return $(null);
|
|
},
|
|
|
|
/**
|
|
* If it's an array element, get all values.
|
|
*
|
|
* @param validator
|
|
* @param element
|
|
* @returns {*|string}
|
|
*/
|
|
allElementValues: function (validator, element) {
|
|
if (element.name.indexOf('[]') !== -1) {
|
|
return validator.findByName(element.name).map(function (i, e) {
|
|
return validator.elementValue(e);
|
|
}).get();
|
|
}
|
|
|
|
return validator.elementValue(element);
|
|
}
|
|
}
|
|
});
|