validate.js
Advanced tools
Comparing version 0.4.0 to 0.5.0
{ | ||
"name": "validate.js", | ||
"main": ["validate.js", "validate.min.js"], | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"ignore": [ | ||
@@ -6,0 +6,0 @@ "**/.*", |
{ | ||
"name": "validate.js", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"author": "Nicklas Ansman <nicklas@ansman.se>", | ||
@@ -5,0 +5,0 @@ "description": "Declarative validations for JavaScript", |
@@ -524,2 +524,170 @@ describe("validate", function() { | ||
}); | ||
describe("isEmpty", function() { | ||
it("considers null and undefined values empty", function() { | ||
expect(validate.isEmpty(null)).toBe(true); | ||
expect(validate.isEmpty(undefined)).toBe(true); | ||
}); | ||
it("considers functions non empty", function() { | ||
expect(validate.isEmpty(function(){})).toBe(false); | ||
}); | ||
it("considers whitespace only strings empty", function() { | ||
expect(validate.isEmpty("")).toBe(true); | ||
expect(validate.isEmpty(" ")).toBe(true); | ||
expect(validate.isEmpty(" ")).toBe(true); | ||
expect(validate.isEmpty("foo")).toBe(false); | ||
}); | ||
it("considers empty arrays empty", function() { | ||
expect(validate.isEmpty([])).toBe(true); | ||
expect(validate.isEmpty([1])).toBe(false); | ||
}); | ||
it("considers empty objects empty", function() { | ||
expect(validate.isEmpty({})).toBe(true); | ||
expect(validate.isEmpty({foo: "bar"})).toBe(false); | ||
}); | ||
it("considers false and 0 non empty", function() { | ||
expect(validate.isEmpty(false)).toBe(false); | ||
expect(validate.isEmpty(0)).toBe(false); | ||
}); | ||
}); | ||
describe("collectFormValues", function() { | ||
it("handles empty input", function() { | ||
expect(validate.collectFormValues()).toEqual({}); | ||
}); | ||
it("handles simple forms", function() { | ||
var form = document.createElement("form"); | ||
form.innerHTML = '' + | ||
'<input type="text" name="text" value="example text">' + | ||
'<input type="text" name="empty-text">' + | ||
'<input type="email" name="email" value="example@email.com">' + | ||
'<input type="password" name="password" value="password!">' + | ||
'<input type="checkbox" name="selected-checkbox" value="checkbox" checked>' + | ||
'<input type="checkbox" name="deselected-checkbox" value="checkbox">' + | ||
'<input type="date" name="date" value="2015-03-08">' + | ||
'<input type="hidden" name="hidden" value="hidden">' + | ||
'<input type="number" name="number" value="4711">' + | ||
'<input type="url" name="url" value="http://validatejs.org">' + | ||
'<input type="radio" name="single-checked-radio" value="radio" checked>' + | ||
'<input type="radio" name="single-unchecked-radio" value="radio">' + | ||
'<radiogroup>' + | ||
' <input type="radio" name="checked-radio" value="radio1">' + | ||
' <input type="radio" name="checked-radio" value="radio2" checked>' + | ||
' <input type="radio" name="checked-radio" value="radio3">' + | ||
'</radiogroup>' + | ||
'<radiogroup>' + | ||
' <input type="radio" name="unchecked-radio" value="radio1">' + | ||
' <input type="radio" name="unchecked-radio" value="radio2">' + | ||
' <input type="radio" name="unchecked-radio" value="radio3">' + | ||
'</radiogroup>' + | ||
'<select name="selected-dropdown">' + | ||
' <option>' + | ||
' <option value="option1">' + | ||
' <option value="option2" selected>' + | ||
'</select>' + | ||
'<select name="unselected-dropdown">' + | ||
' <option>' + | ||
' <option value="option1">' + | ||
' <option value="option2">' + | ||
'</select>'; | ||
expect(validate.collectFormValues(form)).toEqual({ | ||
text: "example text", | ||
"empty-text": null, | ||
email: "example@email.com", | ||
password: "password!", | ||
"selected-checkbox": "checkbox", | ||
"deselected-checkbox": null, | ||
date: "2015-03-08", | ||
hidden: "hidden", | ||
number: 4711, | ||
url: "http://validatejs.org", | ||
"single-checked-radio": "radio", | ||
"single-unchecked-radio": null, | ||
"checked-radio": "radio2", | ||
"unchecked-radio": null, | ||
"selected-dropdown": "option2", | ||
"unselected-dropdown": null | ||
}); | ||
}); | ||
it("has an option to nullify empty and trim strings", function() { | ||
var form = document.createElement("form"); | ||
form.innerHTML = '' + | ||
'<input type="text" name="normal" value="normal">' + | ||
'<input type="text" name="empty">' + | ||
'<input type="text" name="whitespace" value=" ">' + | ||
'<input type="text" name="trimmed" value=" foo ">'; | ||
var options = {nullify: false}; | ||
expect(validate.collectFormValues(form, options)).toEqual({ | ||
normal: "normal", | ||
empty: "", | ||
whitespace: " ", | ||
trimmed: " foo " | ||
}); | ||
options = {nullify: true}; | ||
expect(validate.collectFormValues(form, options)).toEqual({ | ||
normal: "normal", | ||
empty: null, | ||
whitespace: " ", | ||
trimmed: " foo " | ||
}); | ||
options = {trim: true}; | ||
expect(validate.collectFormValues(form, options)).toEqual({ | ||
normal: "normal", | ||
empty: null, | ||
whitespace: null, | ||
trimmed: "foo" | ||
}); | ||
}); | ||
it("has a way to ignore elements", function() { | ||
var form = document.createElement("form"); | ||
form.innerHTML = '<input type="text" name="ignored" value="ignored" data-ignored>'; | ||
expect(validate.collectFormValues(form)).toEqual({}); | ||
}); | ||
it("uses true/false for checkboxes without a value", function() { | ||
var form = document.createElement("form"); | ||
form.innerHTML = '' + | ||
'<input type="checkbox" name="checked" checked>' + | ||
'<input type="checkbox" name="unchecked">'; | ||
expect(validate.collectFormValues(form)).toEqual({ | ||
checked: true, | ||
unchecked: false | ||
}); | ||
}); | ||
}); | ||
describe("isDomElement", function() { | ||
it("returns true of DOM elements", function() { | ||
var form = document.createElement("form") | ||
, div = document.createElement("div") | ||
, a = document.createElement("a"); | ||
expect(validate.isDomElement(form)).toBe(true); | ||
expect(validate.isDomElement(div)).toBe(true); | ||
expect(validate.isDomElement(a)).toBe(true); | ||
expect(validate.isDomElement(document)).toBe(true); | ||
}); | ||
it("returns false for other objects", function() { | ||
expect(validate.isDomElement({})).toBe(false); | ||
expect(validate.isDomElement(0)).toBe(false); | ||
expect(validate.isDomElement(true)).toBe(false); | ||
expect(validate.isDomElement("foo")).toBe(false); | ||
expect(validate.isDomElement("")).toBe(false); | ||
expect(validate.isDomElement([])).toBe(false); | ||
}); | ||
}); | ||
}); |
@@ -153,5 +153,6 @@ describe("validate", function() { | ||
, spy = jasmine.createSpy("options").andReturn(options) | ||
, constraints = {name: spy}; | ||
validate.runValidations(attrs, constraints, {}); | ||
expect(spy).toHaveBeenCalledWith("Nicklas", attrs, "name"); | ||
, constraints = {name: spy} | ||
, globalOptions = {foo: "bar"}; | ||
validate.runValidations(attrs, constraints, globalOptions); | ||
expect(spy).toHaveBeenCalledWith("Nicklas", attrs, "name", globalOptions, constraints); | ||
expect(pass).toHaveBeenCalledWith("Nicklas", options.pass, "name", attrs); | ||
@@ -164,5 +165,6 @@ }); | ||
, spy = jasmine.createSpy("options").andReturn(options) | ||
, constraints = {name: {pass: spy}}; | ||
validate.runValidations(attrs, constraints, {}); | ||
expect(spy).toHaveBeenCalledWith("Nicklas", attrs, "name"); | ||
, constraints = {name: {pass: spy}} | ||
, globalOptions = {foo: "bar"}; | ||
validate.runValidations(attrs, constraints, globalOptions); | ||
expect(spy).toHaveBeenCalledWith("Nicklas", attrs, "name", globalOptions, constraints); | ||
expect(pass).toHaveBeenCalledWith("Nicklas", options, "name", attrs); | ||
@@ -175,2 +177,19 @@ }); | ||
}); | ||
it("calls collectFormValues if the attributes is a DOM element", function() { | ||
var form = document.createElement("div"); | ||
form.innerHTML = '<input type="text" name="foo" value="bar">'; | ||
spyOn(validate, "collectFormValues").andCallThrough(); | ||
spyOn(validate.validators, "presence").andCallThrough(); | ||
var constraints = {foo: {presence: true}}; | ||
validate(form, constraints); | ||
expect(validate.collectFormValues).toHaveBeenCalledWith(form); | ||
expect(validate.validators.presence).toHaveBeenCalledWith( | ||
"bar", | ||
true, | ||
"foo", | ||
{foo: "bar"} | ||
); | ||
}); | ||
}); | ||
@@ -177,0 +196,0 @@ |
@@ -15,5 +15,7 @@ describe('validators.datetime', function() { | ||
it("allows non defined values", function() { | ||
it("allows empty values", function() { | ||
expect(datetime(null, {})).not.toBeDefined(); | ||
expect(datetime(undefined, {})).not.toBeDefined(); | ||
expect(datetime("", {})).not.toBeDefined(); | ||
expect(datetime(" ", {})).not.toBeDefined(); | ||
}); | ||
@@ -20,0 +22,0 @@ |
@@ -10,3 +10,3 @@ describe('validators.email', function() { | ||
it("allows non defined values and whitespace only strings", function() { | ||
it("allows empty values", function() { | ||
expect(email(null, {})).not.toBeDefined(); | ||
@@ -13,0 +13,0 @@ expect(email(undefined, {})).not.toBeDefined(); |
@@ -10,5 +10,7 @@ describe("validators.exclusion", function() { | ||
it("returns nothing if the value is not defined", function() { | ||
it("allows empty values", function() { | ||
expect(exclusion(null, {})).not.toBeDefined(); | ||
expect(exclusion(undefined, {})).not.toBeDefined(); | ||
expect(exclusion("", {})).not.toBeDefined(); | ||
expect(exclusion(" ", {})).not.toBeDefined(); | ||
}); | ||
@@ -15,0 +17,0 @@ |
@@ -11,3 +11,3 @@ describe("validators.format", function() { | ||
it("allows non defined values", function() { | ||
it("allows empty values", function() { | ||
expect(format(null, options1)).not.toBeDefined(); | ||
@@ -17,2 +17,6 @@ expect(format(null, options2)).not.toBeDefined(); | ||
expect(format(undefined, options2)).not.toBeDefined(); | ||
expect(format("", options1)).not.toBeDefined(); | ||
expect(format("", options2)).not.toBeDefined(); | ||
expect(format(" ", options1)).not.toBeDefined(); | ||
expect(format(" ", options2)).not.toBeDefined(); | ||
}); | ||
@@ -19,0 +23,0 @@ |
@@ -10,5 +10,7 @@ describe("validators.inclusion", function() { | ||
it("returns nothing if the value is not defined", function() { | ||
it("allows empty values", function() { | ||
expect(inclusion(null, {})).not.toBeDefined(); | ||
expect(inclusion(undefined, {})).not.toBeDefined(); | ||
expect(inclusion("", {})).not.toBeDefined(); | ||
expect(inclusion(" ", {})).not.toBeDefined(); | ||
}); | ||
@@ -15,0 +17,0 @@ |
@@ -82,6 +82,8 @@ describe('validator.length', function() { | ||
it("allows non defined values", function() { | ||
it("allows empty values", function() { | ||
var options = {is: 10, minimum: 20, maximum: 5}; | ||
expect(length(null, options)).not.toBeDefined(); | ||
expect(length(undefined, options)).not.toBeDefined(); | ||
expect(length("", options)).not.toBeDefined(); | ||
expect(length(" ", options)).not.toBeDefined(); | ||
}); | ||
@@ -95,3 +97,3 @@ | ||
expect(length(0, options)).toBeDefined(); | ||
expect(length({}, options)).toBeDefined(); | ||
expect(length({foo: "bar"}, options)).toBeDefined(); | ||
expect(length({lengthi: 10}, options)).toBeDefined(); | ||
@@ -98,0 +100,0 @@ expect(length({length: "foo"}, options)).toBeDefined(); |
@@ -19,5 +19,7 @@ describe("validators.numericality", function() { | ||
it("allows non defined values", function() { | ||
it("allows empty values", function() { | ||
expect(numericality(null, {})).not.toBeDefined(); | ||
expect(numericality(undefined, {})).not.toBeDefined(); | ||
expect(numericality("", {})).not.toBeDefined(); | ||
expect(numericality(" ", {})).not.toBeDefined(); | ||
}); | ||
@@ -35,4 +37,4 @@ | ||
expect(numericality(false, {})).toEqual(e); | ||
expect(numericality([], {})).toEqual(e); | ||
expect(numericality({}, {})).toEqual(e); | ||
expect(numericality([1], {})).toEqual(e); | ||
expect(numericality({foo: "bar"}, {})).toEqual(e); | ||
}); | ||
@@ -39,0 +41,0 @@ |
246
validate.js
@@ -1,2 +0,2 @@ | ||
// Validate.js 0.4.0 | ||
// Validate.js 0.5.0 | ||
// (c) 2013-2015 Nicklas Ansman, 2013 Wrapp | ||
@@ -52,2 +52,4 @@ // Validate.js may be freely distributed under the MIT license. | ||
v.extend(validate, { | ||
EMPTY_STRING_REGEXP: /^\s*$/, | ||
// This "class" is just a wrapper around a dictionary and is here to allow | ||
@@ -73,6 +75,15 @@ // you to differentiate between library errors and validation errors | ||
if (v.isDomElement(attributes)) { | ||
attributes = v.collectFormValues(attributes); | ||
} | ||
// Loops through each constraints, finds the correct validator and run it. | ||
for (attr in constraints) { | ||
value = v.getDeepObjectValue(attributes, attr); | ||
validators = v.result(constraints[attr], value, attributes, attr); | ||
// This allows the constraints for an attribute to be a function. | ||
// The function will be called with the value, attribute name, the complete dict of | ||
// attributes as well as the options and constraints passed in. | ||
// This is useful when you want to have different | ||
// validations depending on the attribute value. | ||
validators = v.result(constraints[attr], value, attributes, attr, options, constraints); | ||
@@ -89,6 +100,7 @@ for (validatorName in validators) { | ||
// This allows the options to be a function. The function will be | ||
// called with the value, attribute name and the complete dict of | ||
// attributes. This is useful when you want to have different | ||
// called with the value, attribute name, the complete dict of | ||
// attributes as well as the options and constraints passed in. | ||
// This is useful when you want to have different | ||
// validations depending on the attribute value. | ||
validatorOptions = v.result(validatorOptions, value, attributes, attr); | ||
validatorOptions = v.result(validatorOptions, value, attributes, attr, options, constraints); | ||
if (!validatorOptions) { | ||
@@ -239,2 +251,62 @@ continue; | ||
isDomElement: function(o) { | ||
if (!o) { | ||
return false; | ||
} | ||
if (!v.isFunction(o.querySelectorAll) || !v.isFunction(o.querySelector)) { | ||
return false; | ||
} | ||
if (v.isObject(document) && o === document) { | ||
return true; | ||
} | ||
// http://stackoverflow.com/a/384380/699304 | ||
/* istanbul ignore else */ | ||
if (typeof HTMLElement === "object") { | ||
return o instanceof HTMLElement; | ||
} else { | ||
return o && | ||
typeof o === "object" && | ||
o !== null && | ||
o.nodeType === 1 && | ||
typeof o.nodeName === "string"; | ||
} | ||
}, | ||
isEmpty: function(value) { | ||
var attr; | ||
// Null and undefined are empty | ||
if (!v.isDefined(value)) { | ||
return true; | ||
} | ||
// functions are non empty | ||
if (v.isFunction(value)) { | ||
return false; | ||
} | ||
// Whitespace only strings are empty | ||
if (v.isString(value)) { | ||
return v.EMPTY_STRING_REGEXP.test(value); | ||
} | ||
// For arrays we use the length property | ||
if (v.isArray(value)) { | ||
return value.length === 0; | ||
} | ||
// If we find at least one property we consider it non empty | ||
if (v.isObject(value)) { | ||
for (attr in value) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
return false; | ||
}, | ||
// Formats the specified strings with the given values like so: | ||
@@ -332,2 +404,69 @@ // ``` | ||
// This returns an object with all the values of the form. | ||
// It uses the input name as key and the value as value | ||
// So for example this: | ||
// <input type="text" name="email" value="foo@bar.com" /> | ||
// would return: | ||
// {email: "foo@bar.com"} | ||
collectFormValues: function(form, options) { | ||
var values = {} | ||
, i | ||
, input | ||
, inputs | ||
, value; | ||
if (!form) { | ||
return values; | ||
} | ||
options = options || {}; | ||
inputs = form.querySelectorAll("input[name]"); | ||
for (i = 0; i < inputs.length; ++i) { | ||
input = inputs.item(i); | ||
if (input.dataset.ignored !== undefined) { | ||
continue; | ||
} | ||
value = v.sanitizeFormValue(input.value, options); | ||
if (input.type === "number") { | ||
value = +value; | ||
} else if (input.type === "checkbox") { | ||
if (input.attributes.value) { | ||
if (!input.checked) { | ||
value = values[input.name] || null; | ||
} | ||
} else { | ||
value = input.checked; | ||
} | ||
} else if (input.type === "radio") { | ||
if (!input.checked) { | ||
value = values[input.name] || null; | ||
} | ||
} | ||
values[input.name] = value; | ||
} | ||
inputs = form.querySelectorAll("select[name]"); | ||
for (i = 0; i < inputs.length; ++i) { | ||
input = inputs.item(i); | ||
value = v.sanitizeFormValue(input.options[input.selectedIndex].value, options); | ||
values[input.name] = value; | ||
} | ||
return values; | ||
}, | ||
sanitizeFormValue: function(value, options) { | ||
if (options.trim && v.isString(value)) { | ||
value = value.trim(); | ||
} | ||
if (options.nullify !== false && value === "") { | ||
return null; | ||
} | ||
return value; | ||
}, | ||
capitalize: function(str) { | ||
@@ -506,39 +645,9 @@ if (!v.isString(str)) { | ||
options = v.extend({}, this.options, options); | ||
var message = options.message || this.message || "can't be blank" | ||
, attr; | ||
// Null and undefined aren't allowed | ||
if (!v.isDefined(value)) { | ||
return message; | ||
if (v.isEmpty(value)) { | ||
return options.message || this.message || "can't be blank"; | ||
} | ||
// functions are ok | ||
if (v.isFunction(value)) { | ||
return; | ||
} | ||
if (typeof value === 'string') { | ||
// Tests if the string contains only whitespace (tab, newline, space etc) | ||
if ((/^\s*$/).test(value)) { | ||
return message; | ||
} | ||
} | ||
else if (v.isArray(value)) { | ||
// For arrays we use the length property | ||
if (value.length === 0) { | ||
return message; | ||
} | ||
} | ||
else if (v.isObject(value)) { | ||
// If we find at least one property we consider it non empty | ||
for (attr in value) { | ||
return; | ||
} | ||
return message; | ||
} | ||
}, | ||
length: function(value, options, attribute) { | ||
// Null and undefined are fine | ||
if (!v.isDefined(value)) { | ||
// Empty values are allowed | ||
if (v.isEmpty(value)) { | ||
return; | ||
@@ -590,3 +699,4 @@ } | ||
numericality: function(value, options) { | ||
if (!v.isDefined(value)) { | ||
// Empty values are fine | ||
if (v.isEmpty(value)) { | ||
return; | ||
@@ -652,3 +762,4 @@ } | ||
datetime: v.extend(function(value, options) { | ||
if (!v.isDefined(value)) { | ||
// Empty values are fine | ||
if (v.isEmpty(value)) { | ||
return; | ||
@@ -666,2 +777,4 @@ } | ||
// 86400000 is the number of seconds in a day, this is used to remove | ||
// the time from the date | ||
if (isNaN(value) || options.dateOnly && value % 86400000 !== 0) { | ||
@@ -737,3 +850,4 @@ return options.message || this.notValid || "must be a valid date"; | ||
if (!v.isDefined(value)) { | ||
// Empty values are allowed | ||
if (v.isEmpty(value)) { | ||
return; | ||
@@ -754,3 +868,4 @@ } | ||
inclusion: function(value, options) { | ||
if (!v.isDefined(value)) { | ||
// Empty values are fine | ||
if (v.isEmpty(value)) { | ||
return; | ||
@@ -771,3 +886,4 @@ } | ||
exclusion: function(value, options) { | ||
if (!v.isDefined(value)) { | ||
// Empty values are fine | ||
if (v.isEmpty(value)) { | ||
return; | ||
@@ -788,3 +904,4 @@ } | ||
var message = options.message || this.message || "is not a valid email"; | ||
if (!v.isDefined(value)) { | ||
// Empty values are fine | ||
if (v.isEmpty(value)) { | ||
return; | ||
@@ -795,5 +912,2 @@ } | ||
} | ||
if ((/^\s*$/).test(value)) { | ||
return; | ||
} | ||
if (!this.PATTERN.exec(value)) { | ||
@@ -804,3 +918,29 @@ return message; | ||
PATTERN: /^[a-z0-9\u007F-\uffff!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9\u007F-\uffff!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z]{2,}$/i | ||
}) | ||
}), | ||
equality: function(value, options, attribute, attributes) { | ||
if (v.isEmpty(value)) { | ||
return; | ||
} | ||
if (v.isString(options)) { | ||
options = {attribute: options}; | ||
} | ||
options = v.extend({}, this.options, options); | ||
var message = options.message || | ||
this.message || | ||
"is not equal to %{attribute}"; | ||
if (v.isEmpty(options.attribute) || !v.isString(options.attribute)) { | ||
throw new Error("The attribute must be a non empty string"); | ||
} | ||
var otherValue = v.getDeepObjectValue(attributes, options.attribute) | ||
, comparator = options.comparator || function(v1, v2) { | ||
return v1 === v2; | ||
}; | ||
if (!comparator(value, otherValue, options, attribute, attributes)) { | ||
return v.format(message, {attribute: v.prettify(options.attribute)}); | ||
} | ||
} | ||
}; | ||
@@ -810,5 +950,5 @@ | ||
}).call(this, | ||
typeof exports !== 'undefined' ? exports : null, | ||
typeof module !== 'undefined' ? module : null, | ||
typeof define !== 'undefined' ? define : null, | ||
typeof require !== 'undefined' ? require : null); | ||
typeof exports !== 'undefined' ? /* istanbul ignore next */ exports : null, | ||
typeof module !== 'undefined' ? /* istanbul ignore next */ module : null, | ||
typeof define !== 'undefined' ? /* istanbul ignore next */ define : null, | ||
typeof require !== 'undefined' ? /* istanbul ignore next */ require : null); |
@@ -1,2 +0,2 @@ | ||
// validate.js 0.4.0 | ||
// validate.js 0.5.0 | ||
// http://validatejs.org/ | ||
@@ -6,3 +6,3 @@ // (c) 2013-2015 Nicklas Ansman, 2013 Wrapp | ||
(function(a,b,c,d){"use strict";var e=function(a,b,c){c=f.extend({},f.options,c);var d,g,h=f.runValidations(a,b,c);for(d in h)for(g in h[d])if(f.isPromise(h[d][g]))throw new Error("Use validate.async if you want support for promises");return e.processValidationResults(h,c)},f=e,g=this,h=/%\{([^\}]+)\}/g;f.extend=function(a){return[].slice.call(arguments,1).forEach(function(b){for(var c in b)a[c]=b[c]}),a},f.extend(e,{ValidationErrors:function(a){f.extend(this,a)},runValidations:function(a,b){var c,d,e,g,h,i,j,k=[];for(c in b){e=f.getDeepObjectValue(a,c),g=f.result(b[c],e,a,c);for(d in g){if(h=f.validators[d],!h)throw j=f.format("Unknown validator %{name}",{name:d}),new Error(j);i=g[d],i=f.result(i,e,a,c),i&&k.push({attribute:c,error:h.call(h,e,i,c,a)})}}return k},processValidationResults:function(a,b){var c={};a.forEach(function(a){var b=a.error,d=a.attribute;f.isString(b)&&(b=[b]),b&&(c[d]=(c[d]||[]).concat(b))});for(var d in c)return f.fullMessages(c,b)},async:function(a,b,c){c=f.extend({},f.async.options,c);var d=f.runValidations(a,b,c);return f.Promise(function(b,e){f.waitForResults(d).then(function(){var g=f.processValidationResults(d,c);g?(c.flatten||(g=new f.ValidationErrors(g)),e(g)):b(a)}).then(void 0,f.error)})},waitForResults:function(a){var b=a.reduce(function(a,b){return f.isPromise(b.error)?a.then(function(){return b.error.then(function(){b.error=null},function(a){a||f.warn("Validator promise was rejected but didn't return an error"),b.error=a}).then(void 0,f.error)}).then(void 0,f.error):a},f.Promise(function(a){a()}));return b.then(void 0,f.error)},result:function(a){var b=[].slice.call(arguments,1);return"function"==typeof a&&(a=a.apply(null,b)),a},isNumber:function(a){return"number"==typeof a&&!isNaN(a)},isFunction:function(a){return"function"==typeof a},isInteger:function(a){return f.isNumber(a)&&a%1===0},isObject:function(a){return a===Object(a)},isDefined:function(a){return null!==a&&void 0!==a},isPromise:function(a){return!!a&&"function"==typeof a.then},format:function(a,b){return a.replace(h,function(a,c){return String(b[c])})},prettify:function(a){return a.replace(/([^\s])\.([^\s])/g,"$1 $2").replace(/\\+/g,"").replace(/[_-]/g," ").replace(/([a-z])([A-Z])/g,function(a,b,c){return""+b+" "+c.toLowerCase()}).toLowerCase()},isString:function(a){return"string"==typeof a},isArray:function(a){return"[object Array]"==={}.toString.call(a)},contains:function(a,b){return f.isDefined(a)?f.isArray(a)?-1!==a.indexOf(b):b in a:!1},getDeepObjectValue:function(a,b){if(!f.isObject(a)||!f.isString(b))return void 0;var c,d="",e=!1;for(c=0;c<b.length;++c)switch(b[c]){case".":if(e)e=!1,d+=".";else{if(!(d in a))return void 0;a=a[d],d=""}break;case"\\":e?(e=!1,d+="\\"):e=!0;break;default:e=!1,d+=b[c]}return f.isDefined(a)&&d in a?a[d]:void 0},capitalize:function(a){return f.isString(a)?a[0].toUpperCase()+a.slice(1):a},fullMessages:function(a,b){function c(a,c){c.forEach(function(c){"^"===c[0]?c=c.slice(1):b.fullMessages!==!1&&(c=f.format("%{attr} %{message}",{attr:f.capitalize(f.prettify(a)),message:c})),c=c.replace(/\\\^/g,"^"),b.flatten?e.push(c):(e[a]||(e[a]=[])).push(c)})}b=b||{};var d,e=b.flatten?[]:{};if(!a)return e;for(d in a)c(d,a[d]);return e},Promise:f.extend(function(a){var b=f.Promise.nativePromise(a)||f.Promise.RSVPPromise(a)||f.Promise.whenPromise(a)||f.Promise.QPromise(a);if(!b)throw new Error("No promises could be detected");return b},{nativePromise:function(a){var b,c;return"undefined"!=typeof Promise?b=Promise:(c=f.tryRequire("es6-promise"),c&&(b=c.Promise)),b?new b(a):void 0},RSVPPromise:function(a){var b,c;return"undefined"!=typeof RSVP?b=RSVP.Promise:(c=f.tryRequire("rsvp"),c&&(b=c.Promise)),b?new b(a):void 0},whenPromise:function(a){var b,c;return"undefined"!=typeof when?b=when.promise:(c=f.tryRequire("when"),c&&(b=c.promise)),b?b(a):void 0},QPromise:function(a){var b,c;return"undefined"!=typeof Q?b=Q.promise:(c=f.tryRequire("q"),c&&(b=c.promise)),b?b(a):void 0}}),tryRequire:function(a){if(!f.require)return null;try{return f.require(a)}catch(b){return null}},require:d,exposeModule:function(a,b,c,d,e){c?(d&&d.exports&&(c=d.exports=a),c.validate=a):(b.validate=a,a.isFunction(e)&&e.amd&&e("validate",[],function(){return a}))},warn:function(a){"undefined"!=typeof console&&console.warn&&console.warn(a)},error:function(a){"undefined"!=typeof console&&console.error&&console.error(a)}}),e.validators={presence:function(a,b){b=f.extend({},this.options,b);var c,d=b.message||this.message||"can't be blank";if(!f.isDefined(a))return d;if(!f.isFunction(a))if("string"==typeof a){if(/^\s*$/.test(a))return d}else if(f.isArray(a)){if(0===a.length)return d}else if(f.isObject(a)){for(c in a)return;return d}},length:function(a,b,c){if(f.isDefined(a)){b=f.extend({},this.options,b);var d,e=b.is,g=b.maximum,h=b.minimum,i=b.tokenizer||function(a){return a},j=[];a=i(a);var k=a.length;return f.isNumber(k)?(f.isNumber(e)&&k!==e&&(d=b.wrongLength||this.wrongLength||"is the wrong length (should be %{count} characters)",j.push(f.format(d,{count:e}))),f.isNumber(h)&&h>k&&(d=b.tooShort||this.tooShort||"is too short (minimum is %{count} characters)",j.push(f.format(d,{count:h}))),f.isNumber(g)&&k>g&&(d=b.tooLong||this.tooLong||"is too long (maximum is %{count} characters)",j.push(f.format(d,{count:g}))),j.length>0?b.message||j:void 0):(f.error(f.format("Attribute %{attr} has a non numeric value for `length`",{attr:c})),b.message||this.notValid||"has an incorrect length")}},numericality:function(a,b){if(f.isDefined(a)){b=f.extend({},this.options,b);var c,d,e=[],g={greaterThan:function(a,b){return a>b},greaterThanOrEqualTo:function(a,b){return a>=b},equalTo:function(a,b){return a===b},lessThan:function(a,b){return b>a},lessThanOrEqualTo:function(a,b){return b>=a}};if(b.noStrings!==!0&&f.isString(a)&&(a=+a),!f.isNumber(a))return b.message||this.notValid||"is not a number";if(b.onlyInteger&&!f.isInteger(a))return b.message||this.notInteger||"must be an integer";for(c in g)if(d=b[c],f.isNumber(d)&&!g[c](a,d)){var h=this["not"+f.capitalize(c)]||"must be %{type} %{count}";e.push(f.format(h,{count:d,type:f.prettify(c)}))}return b.odd&&a%2!==1&&e.push(this.notOdd||"must be odd"),b.even&&a%2!==0&&e.push(this.notEven||"must be even"),e.length?b.message||e:void 0}},datetime:f.extend(function(a,b){if(f.isDefined(a)){b=f.extend({},this.options,b);var c,d=[],e=b.earliest?this.parse(b.earliest,b):0/0,g=b.latest?this.parse(b.latest,b):0/0;return a=this.parse(a,b),isNaN(a)||b.dateOnly&&a%864e5!==0?b.message||this.notValid||"must be a valid date":(!isNaN(e)&&e>a&&(c=this.tooEarly||"must be no earlier than %{date}",c=f.format(c,{date:this.format(e,b)}),d.push(c)),!isNaN(g)&&a>g&&(c=this.tooLate||"must be no later than %{date}",c=f.format(c,{date:this.format(g,b)}),d.push(c)),d.length?b.message||d:void 0)}},{parse:function(a){if(f.isFunction(g.XDate))return new g.XDate(a,!0).getTime();var b=f.tryRequire("moment")||g.moment;if(f.isDefined(b))return+b.utc(a);throw new Error("Neither XDate or moment.js was found")},format:function(a,b){var c=b.dateFormat;if(f.isFunction(g.XDate))return c=c||(b.dateOnly?"yyyy-MM-dd":"yyyy-MM-dd HH:mm:ss"),new XDate(a,!0).toString(c);var d=f.tryRequire("moment")||g.moment;if(f.isDefined(d))return c=c||(b.dateOnly?"YYYY-MM-DD":"YYYY-MM-DD HH:mm:ss"),d.utc(a).format(c);throw new Error("Neither XDate or moment.js was found")}}),date:function(a,b){return b=f.extend({},b,{dateOnly:!0}),f.validators.datetime.call(f.validators.datetime,a,b)},format:function(a,b){(f.isString(b)||b instanceof RegExp)&&(b={pattern:b}),b=f.extend({},this.options,b);var c,d=b.message||this.message||"is invalid",e=b.pattern;return f.isDefined(a)?f.isString(a)?(f.isString(e)&&(e=new RegExp(b.pattern,b.flags)),c=e.exec(a),c&&c[0].length==a.length?void 0:d):d:void 0},inclusion:function(a,b){if(f.isDefined(a)&&(f.isArray(b)&&(b={within:b}),b=f.extend({},this.options,b),!f.contains(b.within,a))){var c=b.message||this.message||"^%{value} is not included in the list";return f.format(c,{value:a})}},exclusion:function(a,b){if(f.isDefined(a)&&(f.isArray(b)&&(b={within:b}),b=f.extend({},this.options,b),f.contains(b.within,a))){var c=b.message||this.message||"^%{value} is restricted";return f.format(c,{value:a})}},email:f.extend(function(a,b){b=f.extend({},this.options,b);var c=b.message||this.message||"is not a valid email";if(f.isDefined(a)){if(!f.isString(a))return c;if(!/^\s*$/.test(a))return this.PATTERN.exec(a)?void 0:c}},{PATTERN:/^[a-z0-9\u007F-\uffff!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9\u007F-\uffff!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z]{2,}$/i})},e.exposeModule(e,g,a,b,c)}).call(this,"undefined"!=typeof exports?exports:null,"undefined"!=typeof module?module:null,"undefined"!=typeof define?define:null,"undefined"!=typeof require?require:null); | ||
(function(a,b,c,d){"use strict";var e=function(a,b,c){c=f.extend({},f.options,c);var d,g,h=f.runValidations(a,b,c);for(d in h)for(g in h[d])if(f.isPromise(h[d][g]))throw new Error("Use validate.async if you want support for promises");return e.processValidationResults(h,c)},f=e,g=this,h=/%\{([^\}]+)\}/g;f.extend=function(a){return[].slice.call(arguments,1).forEach(function(b){for(var c in b)a[c]=b[c]}),a},f.extend(e,{EMPTY_STRING_REGEXP:/^\s*$/,ValidationErrors:function(a){f.extend(this,a)},runValidations:function(a,b,c){var d,e,g,h,i,j,k,l=[];f.isDomElement(a)&&(a=f.collectFormValues(a));for(d in b){g=f.getDeepObjectValue(a,d),h=f.result(b[d],g,a,d,c,b);for(e in h){if(i=f.validators[e],!i)throw k=f.format("Unknown validator %{name}",{name:e}),new Error(k);j=h[e],j=f.result(j,g,a,d,c,b),j&&l.push({attribute:d,error:i.call(i,g,j,d,a)})}}return l},processValidationResults:function(a,b){var c={};a.forEach(function(a){var b=a.error,d=a.attribute;f.isString(b)&&(b=[b]),b&&(c[d]=(c[d]||[]).concat(b))});for(var d in c)return f.fullMessages(c,b)},async:function(a,b,c){c=f.extend({},f.async.options,c);var d=f.runValidations(a,b,c);return f.Promise(function(b,e){f.waitForResults(d).then(function(){var g=f.processValidationResults(d,c);g?(c.flatten||(g=new f.ValidationErrors(g)),e(g)):b(a)}).then(void 0,f.error)})},waitForResults:function(a){var b=a.reduce(function(a,b){return f.isPromise(b.error)?a.then(function(){return b.error.then(function(){b.error=null},function(a){a||f.warn("Validator promise was rejected but didn't return an error"),b.error=a}).then(void 0,f.error)}).then(void 0,f.error):a},f.Promise(function(a){a()}));return b.then(void 0,f.error)},result:function(a){var b=[].slice.call(arguments,1);return"function"==typeof a&&(a=a.apply(null,b)),a},isNumber:function(a){return"number"==typeof a&&!isNaN(a)},isFunction:function(a){return"function"==typeof a},isInteger:function(a){return f.isNumber(a)&&a%1===0},isObject:function(a){return a===Object(a)},isDefined:function(a){return null!==a&&void 0!==a},isPromise:function(a){return!!a&&"function"==typeof a.then},isDomElement:function(a){return a&&f.isFunction(a.querySelectorAll)&&f.isFunction(a.querySelector)?f.isObject(document)&&a===document?!0:"object"==typeof HTMLElement?a instanceof HTMLElement:a&&"object"==typeof a&&null!==a&&1===a.nodeType&&"string"==typeof a.nodeName:!1},isEmpty:function(a){var b;if(!f.isDefined(a))return!0;if(f.isFunction(a))return!1;if(f.isString(a))return f.EMPTY_STRING_REGEXP.test(a);if(f.isArray(a))return 0===a.length;if(f.isObject(a)){for(b in a)return!1;return!0}return!1},format:function(a,b){return a.replace(h,function(a,c){return String(b[c])})},prettify:function(a){return a.replace(/([^\s])\.([^\s])/g,"$1 $2").replace(/\\+/g,"").replace(/[_-]/g," ").replace(/([a-z])([A-Z])/g,function(a,b,c){return""+b+" "+c.toLowerCase()}).toLowerCase()},isString:function(a){return"string"==typeof a},isArray:function(a){return"[object Array]"==={}.toString.call(a)},contains:function(a,b){return f.isDefined(a)?f.isArray(a)?-1!==a.indexOf(b):b in a:!1},getDeepObjectValue:function(a,b){if(!f.isObject(a)||!f.isString(b))return void 0;var c,d="",e=!1;for(c=0;c<b.length;++c)switch(b[c]){case".":if(e)e=!1,d+=".";else{if(!(d in a))return void 0;a=a[d],d=""}break;case"\\":e?(e=!1,d+="\\"):e=!0;break;default:e=!1,d+=b[c]}return f.isDefined(a)&&d in a?a[d]:void 0},collectFormValues:function(a,b){var c,d,e,g,h={};if(!a)return h;for(b=b||{},e=a.querySelectorAll("input[name]"),c=0;c<e.length;++c)d=e.item(c),void 0===d.dataset.ignored&&(g=f.sanitizeFormValue(d.value,b),"number"===d.type?g=+g:"checkbox"===d.type?d.attributes.value?d.checked||(g=h[d.name]||null):g=d.checked:"radio"===d.type&&(d.checked||(g=h[d.name]||null)),h[d.name]=g);for(e=a.querySelectorAll("select[name]"),c=0;c<e.length;++c)d=e.item(c),g=f.sanitizeFormValue(d.options[d.selectedIndex].value,b),h[d.name]=g;return h},sanitizeFormValue:function(a,b){return b.trim&&f.isString(a)&&(a=a.trim()),b.nullify!==!1&&""===a?null:a},capitalize:function(a){return f.isString(a)?a[0].toUpperCase()+a.slice(1):a},fullMessages:function(a,b){function c(a,c){c.forEach(function(c){"^"===c[0]?c=c.slice(1):b.fullMessages!==!1&&(c=f.format("%{attr} %{message}",{attr:f.capitalize(f.prettify(a)),message:c})),c=c.replace(/\\\^/g,"^"),b.flatten?e.push(c):(e[a]||(e[a]=[])).push(c)})}b=b||{};var d,e=b.flatten?[]:{};if(!a)return e;for(d in a)c(d,a[d]);return e},Promise:f.extend(function(a){var b=f.Promise.nativePromise(a)||f.Promise.RSVPPromise(a)||f.Promise.whenPromise(a)||f.Promise.QPromise(a);if(!b)throw new Error("No promises could be detected");return b},{nativePromise:function(a){var b,c;return"undefined"!=typeof Promise?b=Promise:(c=f.tryRequire("es6-promise"),c&&(b=c.Promise)),b?new b(a):void 0},RSVPPromise:function(a){var b,c;return"undefined"!=typeof RSVP?b=RSVP.Promise:(c=f.tryRequire("rsvp"),c&&(b=c.Promise)),b?new b(a):void 0},whenPromise:function(a){var b,c;return"undefined"!=typeof when?b=when.promise:(c=f.tryRequire("when"),c&&(b=c.promise)),b?b(a):void 0},QPromise:function(a){var b,c;return"undefined"!=typeof Q?b=Q.promise:(c=f.tryRequire("q"),c&&(b=c.promise)),b?b(a):void 0}}),tryRequire:function(a){if(!f.require)return null;try{return f.require(a)}catch(b){return null}},require:d,exposeModule:function(a,b,c,d,e){c?(d&&d.exports&&(c=d.exports=a),c.validate=a):(b.validate=a,a.isFunction(e)&&e.amd&&e("validate",[],function(){return a}))},warn:function(a){"undefined"!=typeof console&&console.warn&&console.warn(a)},error:function(a){"undefined"!=typeof console&&console.error&&console.error(a)}}),e.validators={presence:function(a,b){return b=f.extend({},this.options,b),f.isEmpty(a)?b.message||this.message||"can't be blank":void 0},length:function(a,b,c){if(!f.isEmpty(a)){b=f.extend({},this.options,b);var d,e=b.is,g=b.maximum,h=b.minimum,i=b.tokenizer||function(a){return a},j=[];a=i(a);var k=a.length;return f.isNumber(k)?(f.isNumber(e)&&k!==e&&(d=b.wrongLength||this.wrongLength||"is the wrong length (should be %{count} characters)",j.push(f.format(d,{count:e}))),f.isNumber(h)&&h>k&&(d=b.tooShort||this.tooShort||"is too short (minimum is %{count} characters)",j.push(f.format(d,{count:h}))),f.isNumber(g)&&k>g&&(d=b.tooLong||this.tooLong||"is too long (maximum is %{count} characters)",j.push(f.format(d,{count:g}))),j.length>0?b.message||j:void 0):(f.error(f.format("Attribute %{attr} has a non numeric value for `length`",{attr:c})),b.message||this.notValid||"has an incorrect length")}},numericality:function(a,b){if(!f.isEmpty(a)){b=f.extend({},this.options,b);var c,d,e=[],g={greaterThan:function(a,b){return a>b},greaterThanOrEqualTo:function(a,b){return a>=b},equalTo:function(a,b){return a===b},lessThan:function(a,b){return b>a},lessThanOrEqualTo:function(a,b){return b>=a}};if(b.noStrings!==!0&&f.isString(a)&&(a=+a),!f.isNumber(a))return b.message||this.notValid||"is not a number";if(b.onlyInteger&&!f.isInteger(a))return b.message||this.notInteger||"must be an integer";for(c in g)if(d=b[c],f.isNumber(d)&&!g[c](a,d)){var h=this["not"+f.capitalize(c)]||"must be %{type} %{count}";e.push(f.format(h,{count:d,type:f.prettify(c)}))}return b.odd&&a%2!==1&&e.push(this.notOdd||"must be odd"),b.even&&a%2!==0&&e.push(this.notEven||"must be even"),e.length?b.message||e:void 0}},datetime:f.extend(function(a,b){if(!f.isEmpty(a)){b=f.extend({},this.options,b);var c,d=[],e=b.earliest?this.parse(b.earliest,b):0/0,g=b.latest?this.parse(b.latest,b):0/0;return a=this.parse(a,b),isNaN(a)||b.dateOnly&&a%864e5!==0?b.message||this.notValid||"must be a valid date":(!isNaN(e)&&e>a&&(c=this.tooEarly||"must be no earlier than %{date}",c=f.format(c,{date:this.format(e,b)}),d.push(c)),!isNaN(g)&&a>g&&(c=this.tooLate||"must be no later than %{date}",c=f.format(c,{date:this.format(g,b)}),d.push(c)),d.length?b.message||d:void 0)}},{parse:function(a){if(f.isFunction(g.XDate))return new g.XDate(a,!0).getTime();var b=f.tryRequire("moment")||g.moment;if(f.isDefined(b))return+b.utc(a);throw new Error("Neither XDate or moment.js was found")},format:function(a,b){var c=b.dateFormat;if(f.isFunction(g.XDate))return c=c||(b.dateOnly?"yyyy-MM-dd":"yyyy-MM-dd HH:mm:ss"),new XDate(a,!0).toString(c);var d=f.tryRequire("moment")||g.moment;if(f.isDefined(d))return c=c||(b.dateOnly?"YYYY-MM-DD":"YYYY-MM-DD HH:mm:ss"),d.utc(a).format(c);throw new Error("Neither XDate or moment.js was found")}}),date:function(a,b){return b=f.extend({},b,{dateOnly:!0}),f.validators.datetime.call(f.validators.datetime,a,b)},format:function(a,b){(f.isString(b)||b instanceof RegExp)&&(b={pattern:b}),b=f.extend({},this.options,b);var c,d=b.message||this.message||"is invalid",e=b.pattern;return f.isEmpty(a)?void 0:f.isString(a)?(f.isString(e)&&(e=new RegExp(b.pattern,b.flags)),c=e.exec(a),c&&c[0].length==a.length?void 0:d):d},inclusion:function(a,b){if(!f.isEmpty(a)&&(f.isArray(b)&&(b={within:b}),b=f.extend({},this.options,b),!f.contains(b.within,a))){var c=b.message||this.message||"^%{value} is not included in the list";return f.format(c,{value:a})}},exclusion:function(a,b){if(!f.isEmpty(a)&&(f.isArray(b)&&(b={within:b}),b=f.extend({},this.options,b),f.contains(b.within,a))){var c=b.message||this.message||"^%{value} is restricted";return f.format(c,{value:a})}},email:f.extend(function(a,b){b=f.extend({},this.options,b);var c=b.message||this.message||"is not a valid email";if(!f.isEmpty(a))return f.isString(a)&&this.PATTERN.exec(a)?void 0:c},{PATTERN:/^[a-z0-9\u007F-\uffff!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9\u007F-\uffff!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z]{2,}$/i}),equality:function(a,b,c,d){if(!f.isEmpty(a)){f.isString(b)&&(b={attribute:b}),b=f.extend({},this.options,b);var e=b.message||this.message||"is not equal to %{attribute}";if(f.isEmpty(b.attribute)||!f.isString(b.attribute))throw new Error("The attribute must be a non empty string");var g=f.getDeepObjectValue(d,b.attribute),h=b.comparator||function(a,b){return a===b};return h(a,g,b,c,d)?void 0:f.format(e,{attribute:f.prettify(b.attribute)})}}},e.exposeModule(e,g,a,b,c)}).call(this,"undefined"!=typeof exports?exports:null,"undefined"!=typeof module?module:null,"undefined"!=typeof define?define:null,"undefined"!=typeof require?require:null); | ||
//# sourceMappingURL=validate.min.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
960104
49
11522