Update: jQuery Validate & Unobtrusive Updated

This commit is contained in:
Gary Sharp
2014-05-10 20:26:57 +10:00
parent 4a08c8c275
commit c87ee6a0e7
9 changed files with 1189 additions and 966 deletions
File diff suppressed because it is too large Load Diff
@@ -8,9 +8,9 @@
<file>/ClientSource/Scripts/Core/jquery-ui-1.10.3.js</file>
<file>/ClientSource/Scripts/Core/jquery.watermark.js</file>
<file>/ClientSource/Scripts/Core/jquery.dataTables.js</file>
<file>/ClientSource/Scripts/Core/moment.js</file>
<file>/ClientSource/Scripts/Core/moment.en-au.js</file>
<file>/ClientSource/Scripts/Core/disco.moment.extensions.js</file>
<file>/ClientSource/Scripts/Core/moment.js</file>
<file>/ClientSource/Scripts/Core/moment.en-au.js</file>
<file>/ClientSource/Scripts/Core/disco.moment.extensions.js</file>
<file>/ClientSource/Scripts/Core/livestamp.js</file>
<file>/ClientSource/Scripts/Core/disco.dataTables.extensions.js</file>
<file>/ClientSource/Scripts/Core/disco.uicore.js</file>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,10 +1,10 @@
/*
/*
* This file has been commented to support Visual Studio Intellisense.
* You should not use this file at runtime inside the browser--it is only
* intended to be used only for design-time IntelliSense. Please use the
* standard jQuery library for all production use.
*
* Comment version: 1.11.1
* Comment version: 1.12.0
*/
/*
+202 -140
View File
@@ -1,18 +1,15 @@
/*!
* jQuery Validation Plugin 1.11.1
* jQuery Validation Plugin v1.12.0
*
* http://bassistance.de/jquery-plugins/jquery-plugin-validation/
* http://docs.jquery.com/Plugins/Validation
* http://jqueryvalidation.org/
*
* Copyright 2013 Jörn Zaefferer
* Released under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
* Copyright (c) 2014 Jörn Zaefferer
* Released under the MIT license
*/
(function($) {
$.extend($.fn, {
// http://docs.jquery.com/Plugins/Validation/validate
// http://jqueryvalidation.org/validate/
validate: function( options ) {
// if nothing is selected, return nothing; can't chain anyway
@@ -95,20 +92,22 @@ $.extend($.fn, {
return validator;
},
// http://docs.jquery.com/Plugins/Validation/valid
// http://jqueryvalidation.org/valid/
valid: function() {
var valid, validator;
if ( $(this[0]).is("form")) {
return this.validate().form();
valid = this.validate().form();
} else {
var valid = true;
var validator = $(this[0].form).validate();
valid = true;
validator = $(this[0].form).validate();
this.each(function() {
valid = valid && validator.element(this);
valid = validator.element(this) && valid;
});
return valid;
}
return valid;
},
// attributes: space seperated list of attributes to retrieve and remove
// attributes: space separated list of attributes to retrieve and remove
removeAttrs: function( attributes ) {
var result = {},
$element = this;
@@ -118,18 +117,19 @@ $.extend($.fn, {
});
return result;
},
// http://docs.jquery.com/Plugins/Validation/rules
// http://jqueryvalidation.org/rules/
rules: function( command, argument ) {
var element = this[0];
var element = this[0],
settings, staticRules, existingRules, data, param, filtered;
if ( command ) {
var settings = $.data(element.form, "validator").settings;
var staticRules = settings.rules;
var existingRules = $.validator.staticRules(element);
switch(command) {
settings = $.data(element.form, "validator").settings;
staticRules = settings.rules;
existingRules = $.validator.staticRules(element);
switch (command) {
case "add":
$.extend(existingRules, $.validator.normalizeRule(argument));
// remove messages from rules, but allow them to be set separetely
// remove messages from rules, but allow them to be set separately
delete existingRules.messages;
staticRules[element.name] = existingRules;
if ( argument.messages ) {
@@ -141,16 +141,19 @@ $.extend($.fn, {
delete staticRules[element.name];
return existingRules;
}
var filtered = {};
filtered = {};
$.each(argument.split(/\s/), function( index, method ) {
filtered[method] = existingRules[method];
delete existingRules[method];
if ( method === "required" ) {
$(element).removeAttr("aria-required");
}
});
return filtered;
}
}
var data = $.validator.normalizeRules(
data = $.validator.normalizeRules(
$.extend(
{},
$.validator.classRules(element),
@@ -161,9 +164,17 @@ $.extend($.fn, {
// make sure required is at front
if ( data.required ) {
var param = data.required;
param = data.required;
delete data.required;
data = $.extend({required: param}, data);
data = $.extend({ required: param }, data );
$(element).attr( "aria-required", "true" );
}
// make sure remote is at back
if ( data.remote ) {
param = data.remote;
delete data.remote;
data = $.extend( data, { remote: param });
}
return data;
@@ -172,11 +183,11 @@ $.extend($.fn, {
// Custom selectors
$.extend($.expr[":"], {
// http://docs.jquery.com/Plugins/Validation/blank
// http://jqueryvalidation.org/blank-selector/
blank: function( a ) { return !$.trim("" + $(a).val()); },
// http://docs.jquery.com/Plugins/Validation/filled
// http://jqueryvalidation.org/filled-selector/
filled: function( a ) { return !!$.trim("" + $(a).val()); },
// http://docs.jquery.com/Plugins/Validation/unchecked
// http://jqueryvalidation.org/unchecked-selector/
unchecked: function( a ) { return !$(a).prop("checked"); }
});
@@ -187,6 +198,7 @@ $.validator = function( options, form ) {
this.init();
};
// http://jqueryvalidation.org/jQuery.validator.format/
$.validator.format = function( source, params ) {
if ( arguments.length === 1 ) {
return function() {
@@ -224,7 +236,7 @@ $.extend($.validator, {
onsubmit: true,
ignore: ":hidden",
ignoreTitle: false,
onfocusin: function( element, event ) {
onfocusin: function( element ) {
this.lastActive = element;
// hide error label and remove error class on focus if enabled
@@ -235,7 +247,7 @@ $.extend($.validator, {
this.addWrapper(this.errorsFor(element)).hide();
}
},
onfocusout: function( element, event ) {
onfocusout: function( element ) {
if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
this.element(element);
}
@@ -247,13 +259,13 @@ $.extend($.validator, {
this.element(element);
}
},
onclick: function( element, event ) {
onclick: function( element ) {
// click on selects, radiobuttons and checkboxes
if ( element.name in this.submitted ) {
this.element(element);
}
// or option elements, check parent select in that case
else if ( element.parentNode.name in this.submitted ) {
} else if ( element.parentNode.name in this.submitted ) {
this.element(element.parentNode);
}
},
@@ -273,7 +285,7 @@ $.extend($.validator, {
}
},
// http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
// http://jqueryvalidation.org/jQuery.validator.setDefaults/
setDefaults: function( settings ) {
$.extend( $.validator.defaults, settings );
},
@@ -312,7 +324,8 @@ $.extend($.validator, {
this.invalid = {};
this.reset();
var groups = (this.groups = {});
var groups = (this.groups = {}),
rules;
$.each(this.settings.groups, function( key, value ) {
if ( typeof value === "string" ) {
value = value.split(/\s/);
@@ -321,16 +334,17 @@ $.extend($.validator, {
groups[name] = key;
});
});
var rules = this.settings.rules;
rules = this.settings.rules;
$.each(rules, function( key, value ) {
rules[key] = $.validator.normalizeRule(value);
});
function delegate(event) {
var validator = $.data(this[0].form, "validator"),
eventType = "on" + event.type.replace(/^validate/, "");
if ( validator.settings[eventType] ) {
validator.settings[eventType].call(validator, this[0], event);
eventType = "on" + event.type.replace(/^validate/, ""),
settings = validator.settings;
if ( settings[eventType] && !this.is( settings.ignore ) ) {
settings[eventType].call(validator, this[0], event);
}
}
$(this.currentForm)
@@ -345,15 +359,19 @@ $.extend($.validator, {
if ( this.settings.invalidHandler ) {
$(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
}
// Add aria-required to any Static/Data/Class required fields before first validation
// Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
$(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required", "true");
},
// http://docs.jquery.com/Plugins/Validation/Validator/form
// http://jqueryvalidation.org/Validator.form/
form: function() {
this.checkForm();
$.extend(this.submitted, this.errorMap);
this.invalid = $.extend({}, this.errorMap);
if ( !this.valid() ) {
$(this.currentForm).triggerHandler("invalid-form", [this]);
$(this.currentForm).triggerHandler("invalid-form", [ this ]);
}
this.showErrors();
return this.valid();
@@ -367,18 +385,30 @@ $.extend($.validator, {
return this.valid();
},
// http://docs.jquery.com/Plugins/Validation/Validator/element
// http://jqueryvalidation.org/Validator.element/
element: function( element ) {
element = this.validationTargetFor( this.clean( element ) );
this.lastElement = element;
this.prepareElement( element );
this.currentElements = $(element);
var result = this.check( element ) !== false;
if ( result ) {
delete this.invalid[element.name];
var cleanElement = this.clean( element ),
checkElement = this.validationTargetFor( cleanElement ),
result = true;
this.lastElement = checkElement;
if ( checkElement === undefined ) {
delete this.invalid[ cleanElement.name ];
} else {
this.invalid[element.name] = true;
this.prepareElement( checkElement );
this.currentElements = $( checkElement );
result = this.check( checkElement ) !== false;
if (result) {
delete this.invalid[checkElement.name];
} else {
this.invalid[checkElement.name] = true;
}
}
// Add aria-invalid status for screen readers
$( element ).attr( "aria-invalid", !result );
if ( !this.numberOfInvalids() ) {
// Hide error containers on last error
this.toHide = this.toHide.add( this.containers );
@@ -387,7 +417,7 @@ $.extend($.validator, {
return result;
},
// http://docs.jquery.com/Plugins/Validation/Validator/showErrors
// http://jqueryvalidation.org/Validator.showErrors/
showErrors: function( errors ) {
if ( errors ) {
// add items to error list and map
@@ -411,7 +441,7 @@ $.extend($.validator, {
}
},
// http://docs.jquery.com/Plugins/Validation/Validator/resetForm
// http://jqueryvalidation.org/Validator.resetForm/
resetForm: function() {
if ( $.fn.resetForm ) {
$(this.currentForm).resetForm();
@@ -420,7 +450,10 @@ $.extend($.validator, {
this.lastElement = null;
this.prepareForm();
this.hideErrors();
this.elements().removeClass( this.settings.errorClass ).removeData( "previousValue" );
this.elements()
.removeClass( this.settings.errorClass )
.removeData( "previousValue" )
.removeAttr( "aria-invalid" );
},
numberOfInvalids: function() {
@@ -428,8 +461,10 @@ $.extend($.validator, {
},
objectLength: function( obj ) {
var count = 0;
for ( var i in obj ) {
/* jshint unused: false */
var count = 0,
i;
for ( i in obj ) {
count++;
}
return count;
@@ -497,7 +532,7 @@ $.extend($.validator, {
},
errors: function() {
var errorClass = this.settings.errorClass.replace(" ", ".");
var errorClass = this.settings.errorClass.split(" ").join(".");
return $(this.settings.errorElement + "." + errorClass, this.errorContext);
},
@@ -521,13 +556,15 @@ $.extend($.validator, {
},
elementValue: function( element ) {
var type = $(element).attr("type"),
val = $(element).val();
var val,
$element = $(element),
type = $element.attr("type");
if ( type === "radio" || type === "checkbox" ) {
return $("input[name='" + $(element).attr("name") + "']:checked").val();
return $("input[name='" + $element.attr("name") + "']:checked").val();
}
val = $element.val();
if ( typeof val === "string" ) {
return val.replace(/\r/g, "");
}
@@ -537,20 +574,23 @@ $.extend($.validator, {
check: function( element ) {
element = this.validationTargetFor( this.clean( element ) );
var rules = $(element).rules();
var dependencyMismatch = false;
var val = this.elementValue(element);
var result;
var rules = $(element).rules(),
rulesCount = $.map( rules, function(n, i) {
return i;
}).length,
dependencyMismatch = false,
val = this.elementValue(element),
result, method, rule;
for (var method in rules ) {
var rule = { method: method, parameters: rules[method] };
for (method in rules ) {
rule = { method: method, parameters: rules[method] };
try {
result = $.validator.methods[method].call( this, val, element, rule.parameters );
// if a method indicates that the field is optional and therefore valid,
// don't mark it as valid when there are no other rules
if ( result === "dependency-mismatch" ) {
if ( result === "dependency-mismatch" && rulesCount === 1 ) {
dependencyMismatch = true;
continue;
}
@@ -583,8 +623,10 @@ $.extend($.validator, {
// return the custom message for the given element and validation method
// specified in the element's HTML5 data attribute
// return the generic message if present and no method specific message is present
customDataMessage: function( element, method ) {
return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase()));
return $( element ).data( "msg" + method[ 0 ].toUpperCase() +
method.substring( 1 ).toLowerCase() ) || $( element ).data("msg");
},
// return the custom message for the given element name and validation method
@@ -595,7 +637,7 @@ $.extend($.validator, {
// return the first defined argument, allowing empty strings
findDefined: function() {
for(var i = 0; i < arguments.length; i++) {
for (var i = 0; i < arguments.length; i++) {
if ( arguments[i] !== undefined ) {
return arguments[i];
}
@@ -624,7 +666,8 @@ $.extend($.validator, {
}
this.errorList.push({
message: message,
element: element
element: element,
method: rule.method
});
this.errorMap[element.name] = message;
@@ -639,9 +682,9 @@ $.extend($.validator, {
},
defaultShowErrors: function() {
var i, elements;
var i, elements, error;
for ( i = 0; this.errorList[i]; i++ ) {
var error = this.errorList[i];
error = this.errorList[i];
if ( this.settings.highlight ) {
this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
}
@@ -740,7 +783,7 @@ $.extend($.validator, {
},
getLength: function( value, element ) {
switch( element.nodeName.toLowerCase() ) {
switch ( element.nodeName.toLowerCase() ) {
case "select":
return $("option:selected", element).length;
case "input":
@@ -756,7 +799,7 @@ $.extend($.validator, {
},
dependTypes: {
"boolean": function( param, element ) {
"boolean": function( param ) {
return param;
},
"string": function( param, element ) {
@@ -790,7 +833,7 @@ $.extend($.validator, {
$(this.currentForm).submit();
this.formSubmitted = false;
} else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
$(this.currentForm).triggerHandler("invalid-form", [this]);
$(this.currentForm).triggerHandler("invalid-form", [ this ]);
this.formSubmitted = false;
}
},
@@ -806,14 +849,14 @@ $.extend($.validator, {
},
classRuleSettings: {
required: {required: true},
email: {email: true},
url: {url: true},
date: {date: true},
dateISO: {dateISO: true},
number: {number: true},
digits: {digits: true},
creditcard: {creditcard: true}
required: { required: true },
email: { email: true },
url: { url: true },
date: { date: true },
dateISO: { dateISO: true },
number: { number: true },
digits: { digits: true },
creditcard: { creditcard: true }
},
addClassRules: function( className, rules ) {
@@ -825,8 +868,9 @@ $.extend($.validator, {
},
classRules: function( element ) {
var rules = {};
var classes = $(element).attr("class");
var rules = {},
classes = $(element).attr("class");
if ( classes ) {
$.each(classes.split(" "), function() {
if ( this in $.validator.classRuleSettings ) {
@@ -838,16 +882,16 @@ $.extend($.validator, {
},
attributeRules: function( element ) {
var rules = {};
var $element = $(element);
var type = $element[0].getAttribute("type");
var rules = {},
$element = $(element),
type = element.getAttribute("type"),
method, value;
for (var method in $.validator.methods) {
var value;
for (method in $.validator.methods) {
// support for <input required> in both html5 and older browsers
if ( method === "required" ) {
value = $element.get(0).getAttribute(method);
value = element.getAttribute(method);
// Some browsers return an empty string for the required attribute
// and non-HTML5 browsers might have required="" markup
if ( value === "" ) {
@@ -865,9 +909,9 @@ $.extend($.validator, {
value = Number(value);
}
if ( value ) {
if ( value || value === 0 ) {
rules[method] = value;
} else if ( type === method && type !== 'range' ) {
} else if ( type === method && type !== "range" ) {
// exception: the jquery validate 'range' method
// does not test for the html5 'range' type
rules[method] = true;
@@ -884,19 +928,20 @@ $.extend($.validator, {
dataRules: function( element ) {
var method, value,
rules = {}, $element = $(element);
for (method in $.validator.methods) {
value = $element.data("rule-" + method.toLowerCase());
rules = {}, $element = $( element );
for ( method in $.validator.methods ) {
value = $element.data( "rule" + method[ 0 ].toUpperCase() + method.substring( 1 ).toLowerCase() );
if ( value !== undefined ) {
rules[method] = value;
rules[ method ] = value;
}
}
return rules;
},
staticRules: function( element ) {
var rules = {};
var validator = $.data(element.form, "validator");
var rules = {},
validator = $.data(element.form, "validator");
if ( validator.settings.rules ) {
rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
}
@@ -935,19 +980,19 @@ $.extend($.validator, {
});
// clean number parameters
$.each(['minlength', 'maxlength'], function() {
$.each([ "minlength", "maxlength" ], function() {
if ( rules[this] ) {
rules[this] = Number(rules[this]);
}
});
$.each(['rangelength', 'range'], function() {
$.each([ "rangelength", "range" ], function() {
var parts;
if ( rules[this] ) {
if ( $.isArray(rules[this]) ) {
rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
rules[this] = [ Number(rules[this][0]), Number(rules[this][1]) ];
} else if ( typeof rules[this] === "string" ) {
parts = rules[this].split(/[\s,]+/);
rules[this] = [Number(parts[0]), Number(parts[1])];
rules[this] = [ Number(parts[0]), Number(parts[1]) ];
}
}
});
@@ -955,12 +1000,12 @@ $.extend($.validator, {
if ( $.validator.autoCreateRanges ) {
// auto-create ranges
if ( rules.min && rules.max ) {
rules.range = [rules.min, rules.max];
rules.range = [ rules.min, rules.max ];
delete rules.min;
delete rules.max;
}
if ( rules.minlength && rules.maxlength ) {
rules.rangelength = [rules.minlength, rules.maxlength];
rules.rangelength = [ rules.minlength, rules.maxlength ];
delete rules.minlength;
delete rules.maxlength;
}
@@ -981,7 +1026,7 @@ $.extend($.validator, {
return data;
},
// http://docs.jquery.com/Plugins/Validation/Validator/addMethod
// http://jqueryvalidation.org/jQuery.validator.addMethod/
addMethod: function( name, method, message ) {
$.validator.methods[name] = method;
$.validator.messages[name] = message !== undefined ? message : $.validator.messages[name];
@@ -992,7 +1037,7 @@ $.extend($.validator, {
methods: {
// http://docs.jquery.com/Plugins/Validation/Methods/required
// http://jqueryvalidation.org/required-method/
required: function( value, element, param ) {
// check if dependency is met
if ( !this.depend(param, element) ) {
@@ -1009,40 +1054,43 @@ $.extend($.validator, {
return $.trim(value).length > 0;
},
// http://docs.jquery.com/Plugins/Validation/Methods/email
// http://jqueryvalidation.org/email-method/
email: function( value, element ) {
// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
// From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
// Retrieved 2014-01-14
// If you have a problem with this implementation, report a bug against the above spec
// Or use custom methods to implement your own email validation
return this.optional(element) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value);
},
// http://docs.jquery.com/Plugins/Validation/Methods/url
// http://jqueryvalidation.org/url-method/
url: function( value, element ) {
// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
},
// http://docs.jquery.com/Plugins/Validation/Methods/date
// http://jqueryvalidation.org/date-method/
date: function( value, element ) {
return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
},
// http://docs.jquery.com/Plugins/Validation/Methods/dateISO
// http://jqueryvalidation.org/dateISO-method/
dateISO: function( value, element ) {
return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value);
},
// http://docs.jquery.com/Plugins/Validation/Methods/number
// http://jqueryvalidation.org/number-method/
number: function( value, element ) {
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
},
// http://docs.jquery.com/Plugins/Validation/Methods/digits
// http://jqueryvalidation.org/digits-method/
digits: function( value, element ) {
return this.optional(element) || /^\d+$/.test(value);
},
// http://docs.jquery.com/Plugins/Validation/Methods/creditcard
// based on http://en.wikipedia.org/wiki/Luhn
// http://jqueryvalidation.org/creditcard-method/
// based on http://en.wikipedia.org/wiki/Luhn/
creditcard: function( value, element ) {
if ( this.optional(element) ) {
return "dependency-mismatch";
@@ -1053,12 +1101,19 @@ $.extend($.validator, {
}
var nCheck = 0,
nDigit = 0,
bEven = false;
bEven = false,
n, cDigit;
value = value.replace(/\D/g, "");
for (var n = value.length - 1; n >= 0; n--) {
var cDigit = value.charAt(n);
// Basing min and max length on
// http://developer.ean.com/general_info/Valid_Credit_Card_Types
if ( value.length < 13 || value.length > 19 ) {
return false;
}
for ( n = value.length - 1; n >= 0; n--) {
cDigit = value.charAt(n);
nDigit = parseInt(cDigit, 10);
if ( bEven ) {
if ( (nDigit *= 2) > 9 ) {
@@ -1072,40 +1127,40 @@ $.extend($.validator, {
return (nCheck % 10) === 0;
},
// http://docs.jquery.com/Plugins/Validation/Methods/minlength
// http://jqueryvalidation.org/minlength-method/
minlength: function( value, element, param ) {
var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
return this.optional(element) || length >= param;
},
// http://docs.jquery.com/Plugins/Validation/Methods/maxlength
// http://jqueryvalidation.org/maxlength-method/
maxlength: function( value, element, param ) {
var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
return this.optional(element) || length <= param;
},
// http://docs.jquery.com/Plugins/Validation/Methods/rangelength
// http://jqueryvalidation.org/rangelength-method/
rangelength: function( value, element, param ) {
var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
return this.optional(element) || ( length >= param[0] && length <= param[1] );
},
// http://docs.jquery.com/Plugins/Validation/Methods/min
// http://jqueryvalidation.org/min-method/
min: function( value, element, param ) {
return this.optional(element) || value >= param;
},
// http://docs.jquery.com/Plugins/Validation/Methods/max
// http://jqueryvalidation.org/max-method/
max: function( value, element, param ) {
return this.optional(element) || value <= param;
},
// http://docs.jquery.com/Plugins/Validation/Methods/range
// http://jqueryvalidation.org/range-method/
range: function( value, element, param ) {
return this.optional(element) || ( value >= param[0] && value <= param[1] );
},
// http://docs.jquery.com/Plugins/Validation/Methods/equalTo
// http://jqueryvalidation.org/equalTo-method/
equalTo: function( value, element, param ) {
// bind to the blur event of the target in order to revalidate whenever the target field is updated
// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
@@ -1118,29 +1173,31 @@ $.extend($.validator, {
return value === target.val();
},
// http://docs.jquery.com/Plugins/Validation/Methods/remote
// http://jqueryvalidation.org/remote-method/
remote: function( value, element, param ) {
if ( this.optional(element) ) {
return "dependency-mismatch";
}
var previous = this.previousValue(element);
var previous = this.previousValue(element),
validator, data;
if (!this.settings.messages[element.name] ) {
this.settings.messages[element.name] = {};
}
previous.originalMessage = this.settings.messages[element.name].remote;
this.settings.messages[element.name].remote = previous.message;
param = typeof param === "string" && {url:param} || param;
param = typeof param === "string" && { url: param } || param;
if ( previous.old === value ) {
return previous.valid;
}
previous.old = value;
var validator = this;
validator = this;
this.startRequest(element);
var data = {};
data = {};
data[element.name] = value;
$.ajax($.extend(true, {
url: param,
@@ -1148,19 +1205,22 @@ $.extend($.validator, {
port: "validate" + element.name,
dataType: "json",
data: data,
context: validator.currentForm,
success: function( response ) {
var valid = response === true || response === "true",
errors, message, submitted;
validator.settings.messages[element.name].remote = previous.originalMessage;
var valid = response === true || response === "true";
if ( valid ) {
var submitted = validator.formSubmitted;
submitted = validator.formSubmitted;
validator.prepareElement(element);
validator.formSubmitted = submitted;
validator.successList.push(element);
delete validator.invalid[element.name];
validator.showErrors();
} else {
var errors = {};
var message = response || validator.defaultMessage( element, "remote" );
errors = {};
message = response || validator.defaultMessage( element, "remote" );
errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
validator.invalid[element.name] = true;
validator.showErrors(errors);
@@ -1176,8 +1236,9 @@ $.extend($.validator, {
});
// deprecated, use $.validator.format instead
$.format = $.validator.format;
$.format = function deprecated() {
throw "$.format has been deprecated. Please use $.validator.format instead.";
};
}(jQuery));
@@ -1185,7 +1246,8 @@ $.format = $.validator.format;
// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
(function($) {
var pendingRequests = {};
var pendingRequests = {},
ajax;
// Use a prefilter if available (1.5+)
if ( $.ajaxPrefilter ) {
$.ajaxPrefilter(function( settings, _, xhr ) {
@@ -1199,7 +1261,7 @@ $.format = $.validator.format;
});
} else {
// Proxy ajax
var ajax = $.ajax;
ajax = $.ajax;
$.ajax = function( settings ) {
var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
port = ( "port" in settings ? settings : $.ajaxSettings ).port;
@@ -1,344 +1,394 @@
/* NUGET: BEGIN LICENSE TEXT
*
* Microsoft grants you the right to use these script files for the sole
* purpose of either: (i) interacting through your browser with the Microsoft
* website or online service, subject to the applicable licensing or use
* terms; or (ii) using the files as included with a Microsoft product subject
* to that product's license terms. Microsoft reserves all other rights to the
* files not expressly granted by Microsoft, whether by implication, estoppel
* or otherwise. Insofar as a script file is dual licensed under GPL,
* Microsoft neither took the code under GPL nor distributes it thereunder but
* under the terms set out in this paragraph. All notices and licenses
* below are for informational purposes only.
*
* NUGET: END LICENSE TEXT */
*
* Microsoft grants you the right to use these script files for the sole
* purpose of either: (i) interacting through your browser with the Microsoft
* website or online service, subject to the applicable licensing or use
* terms; or (ii) using the files as included with a Microsoft product subject
* to that product's license terms. Microsoft reserves all other rights to the
* files not expressly granted by Microsoft, whether by implication, estoppel
* or otherwise. Insofar as a script file is dual licensed under GPL,
* Microsoft neither took the code under GPL nor distributes it thereunder but
* under the terms set out in this paragraph. All notices and licenses
* below are for informational purposes only.
*
* NUGET: END LICENSE TEXT */
/*!
** Unobtrusive validation support library for jQuery and jQuery Validate
** Copyright (C) Microsoft Corporation. All rights reserved.
*/
/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
/*global document: false, jQuery: false */
(function ($) {
var $jQval = $.validator,
adapters,
data_validation = "unobtrusiveValidation";
function setValidationValues(options, ruleName, value) {
options.rules[ruleName] = value;
if (options.message) {
options.messages[ruleName] = options.message;
}
}
function splitAndTrim(value) {
return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
}
function escapeAttributeValue(value) {
// As mentioned on http://api.jquery.com/category/selectors/
return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
}
function getModelPrefix(fieldName) {
return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
}
function appendModelPrefix(value, prefix) {
if (value.indexOf("*.") === 0) {
value = value.replace("*.", prefix);
}
return value;
}
function onError(error, inputElement) { // 'this' is the form element
var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
replaceAttrValue = container.attr("data-valmsg-replace"),
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
container.removeClass("field-validation-valid").addClass("field-validation-error");
error.data("unobtrusiveContainer", container);
if (replace) {
container.empty();
error.removeClass("input-validation-error").appendTo(container);
}
else {
error.hide();
}
}
function onErrors(event, validator) { // 'this' is the form element
var container = $(this).find("[data-valmsg-summary=true]"),
list = container.find("ul");
if (list && list.length && validator.errorList.length) {
list.empty();
container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
$.each(validator.errorList, function () {
$("<li />").html(this.message).appendTo(list);
});
}
}
function onSuccess(error) { // 'this' is the form element
var container = error.data("unobtrusiveContainer"),
replaceAttrValue = container.attr("data-valmsg-replace"),
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
if (container) {
container.addClass("field-validation-valid").removeClass("field-validation-error");
error.removeData("unobtrusiveContainer");
if (replace) {
container.empty();
}
}
}
function onReset(event) { // 'this' is the form element
var $form = $(this);
$form.data("validator").resetForm();
$form.find(".validation-summary-errors")
.addClass("validation-summary-valid")
.removeClass("validation-summary-errors");
$form.find(".field-validation-error")
.addClass("field-validation-valid")
.removeClass("field-validation-error")
.removeData("unobtrusiveContainer")
.find(">*") // If we were using valmsg-replace, get the underlying error
.removeData("unobtrusiveContainer");
}
function validationInfo(form) {
var $form = $(form),
result = $form.data(data_validation),
onResetProxy = $.proxy(onReset, form);
if (!result) {
result = {
options: { // options structure passed to jQuery Validate's validate() method
errorClass: "input-validation-error",
errorElement: "span",
errorPlacement: $.proxy(onError, form),
invalidHandler: $.proxy(onErrors, form),
messages: {},
rules: {},
success: $.proxy(onSuccess, form)
},
attachValidation: function () {
$form
.unbind("reset." + data_validation, onResetProxy)
.bind("reset." + data_validation, onResetProxy)
.validate(this.options);
},
validate: function () { // a validation function that is called by unobtrusive Ajax
$form.validate();
return $form.valid();
}
};
$form.data(data_validation, result);
}
return result;
}
$jQval.unobtrusive = {
adapters: [],
parseElement: function (element, skipAttach) {
/// <summary>
/// Parses a single HTML element for unobtrusive validation attributes.
/// </summary>
/// <param name="element" domElement="true">The HTML element to be parsed.</param>
/// <param name="skipAttach" type="Boolean">[Optional] true to skip attaching the
/// validation to the form. If parsing just this single element, you should specify true.
/// If parsing several elements, you should specify false, and manually attach the validation
/// to the form when you are finished. The default is false.</param>
var $element = $(element),
form = $element.parents("form")[0],
valInfo, rules, messages;
if (!form) { // Cannot do client-side validation without a form
return;
}
valInfo = validationInfo(form);
valInfo.options.rules[element.name] = rules = {};
valInfo.options.messages[element.name] = messages = {};
$.each(this.adapters, function () {
var prefix = "data-val-" + this.name,
message = $element.attr(prefix),
paramValues = {};
if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
prefix += "-";
$.each(this.params, function () {
paramValues[this] = $element.attr(prefix + this);
});
this.adapt({
element: element,
form: form,
message: message,
params: paramValues,
rules: rules,
messages: messages
});
}
});
$.extend(rules, { "__dummy__": true });
if (!skipAttach) {
valInfo.attachValidation();
}
},
parse: function (selector) {
/// <summary>
/// Parses all the HTML elements in the specified selector. It looks for input elements decorated
/// with the [data-val=true] attribute value and enables validation according to the data-val-*
/// attribute values.
/// </summary>
/// <param name="selector" type="String">Any valid jQuery selector.</param>
var $forms = $(selector)
.parents("form")
.andSelf()
.add($(selector).find("form"))
.filter("form");
// :input is a psuedoselector provided by jQuery which selects input and input-like elements
// combining :input with other selectors significantly decreases performance.
$(selector).find(":input").filter("[data-val=true]").each(function () {
$jQval.unobtrusive.parseElement(this, true);
});
$forms.each(function () {
var info = validationInfo(this);
if (info) {
info.attachValidation();
}
});
}
};
adapters = $jQval.unobtrusive.adapters;
adapters.add = function (adapterName, params, fn) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
/// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
/// mmmm is the parameter name).</param>
/// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
/// attributes into jQuery Validate rules and/or messages.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
if (!fn) { // Called with no params, just a function
fn = params;
params = [];
}
this.push({ name: adapterName, params: params, adapt: fn });
return this;
};
adapters.addBool = function (adapterName, ruleName) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation rule has no parameter values.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
/// of adapterName will be used instead.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, function (options) {
setValidationValues(options, ruleName || adapterName, true);
});
};
adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
/// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="minRuleName" type="String">The name of the jQuery Validate rule to be used when you only
/// have a minimum value.</param>
/// <param name="maxRuleName" type="String">The name of the jQuery Validate rule to be used when you only
/// have a maximum value.</param>
/// <param name="minMaxRuleName" type="String">The name of the jQuery Validate rule to be used when you
/// have both a minimum and maximum value.</param>
/// <param name="minAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
/// contains the minimum value. The default is "min".</param>
/// <param name="maxAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
/// contains the maximum value. The default is "max".</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
var min = options.params.min,
max = options.params.max;
if (min && max) {
setValidationValues(options, minMaxRuleName, [min, max]);
}
else if (min) {
setValidationValues(options, minRuleName, min);
}
else if (max) {
setValidationValues(options, maxRuleName, max);
}
});
};
adapters.addSingleVal = function (adapterName, attribute, ruleName) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation rule has a single value.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>
/// <param name="attribute" type="String">[Optional] The name of the HTML attribute that contains the value.
/// The default is "val".</param>
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
/// of adapterName will be used instead.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, [attribute || "val"], function (options) {
setValidationValues(options, ruleName || adapterName, options.params[attribute]);
});
};
$jQval.addMethod("__dummy__", function (value, element, params) {
return true;
});
$jQval.addMethod("regex", function (value, element, params) {
var match;
if (this.optional(element)) {
return true;
}
match = new RegExp(params).exec(value);
return (match && (match.index === 0) && (match[0].length === value.length));
});
$jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
var match;
if (nonalphamin) {
match = value.match(/\W/g);
match = match && match.length >= nonalphamin;
}
return match;
});
if ($jQval.methods.extension) {
adapters.addSingleVal("accept", "mimtype");
adapters.addSingleVal("extension", "extension");
} else {
// for backward compatibility, when the 'extension' validation method does not exist, such as with versions
// of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
// validating the extension, and ignore mime-type validations as they are not supported.
adapters.addSingleVal("extension", "extension", "accept");
}
adapters.addSingleVal("regex", "pattern");
adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
adapters.add("equalto", ["other"], function (options) {
var prefix = getModelPrefix(options.element.name),
other = options.params.other,
fullOtherName = appendModelPrefix(other, prefix),
element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
setValidationValues(options, "equalTo", element);
});
adapters.add("required", function (options) {
// jQuery Validate equates "required" with "mandatory" for checkbox elements
if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
setValidationValues(options, "required", true);
}
});
adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
var value = {
url: options.params.url,
type: options.params.type || "GET",
data: {}
},
prefix = getModelPrefix(options.element.name);
$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
var paramName = appendModelPrefix(fieldName, prefix);
value.data[paramName] = function () {
return $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']").val();
};
});
setValidationValues(options, "remote", value);
});
adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
if (options.params.min) {
setValidationValues(options, "minlength", options.params.min);
}
if (options.params.nonalphamin) {
setValidationValues(options, "nonalphamin", options.params.nonalphamin);
}
if (options.params.regex) {
setValidationValues(options, "regex", options.params.regex);
}
});
$(function () {
$jQval.unobtrusive.parse(document);
});
}(jQuery));
var $jQval = $.validator,
adapters,
data_validation = "unobtrusiveValidation";
function setValidationValues(options, ruleName, value) {
options.rules[ruleName] = value;
if (options.message) {
options.messages[ruleName] = options.message;
}
}
function splitAndTrim(value) {
return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
}
function escapeAttributeValue(value) {
// As mentioned on http://api.jquery.com/category/selectors/
return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
}
function getModelPrefix(fieldName) {
return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
}
function appendModelPrefix(value, prefix) {
if (value.indexOf("*.") === 0) {
value = value.replace("*.", prefix);
}
return value;
}
function onError(error, inputElement) { // 'this' is the form element
var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
replaceAttrValue = container.attr("data-valmsg-replace"),
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
container.removeClass("field-validation-valid").addClass("field-validation-error");
error.data("unobtrusiveContainer", container);
if (replace) {
container.empty();
error.removeClass("input-validation-error").appendTo(container);
}
else {
error.hide();
}
}
function onErrors(event, validator) { // 'this' is the form element
var container = $(this).find("[data-valmsg-summary=true]"),
list = container.find("ul");
if (list && list.length && validator.errorList.length) {
list.empty();
container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
$.each(validator.errorList, function () {
$("<li />").html(this.message).appendTo(list);
});
}
}
function onSuccess(error) { // 'this' is the form element
var container = error.data("unobtrusiveContainer"),
replaceAttrValue = container.attr("data-valmsg-replace"),
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
if (container) {
container.addClass("field-validation-valid").removeClass("field-validation-error");
error.removeData("unobtrusiveContainer");
if (replace) {
container.empty();
}
}
}
function onReset(event) { // 'this' is the form element
var $form = $(this);
$form.data("validator").resetForm();
$form.find(".validation-summary-errors")
.addClass("validation-summary-valid")
.removeClass("validation-summary-errors");
$form.find(".field-validation-error")
.addClass("field-validation-valid")
.removeClass("field-validation-error")
.removeData("unobtrusiveContainer")
.find(">*") // If we were using valmsg-replace, get the underlying error
.removeData("unobtrusiveContainer");
}
function validationInfo(form) {
var $form = $(form),
result = $form.data(data_validation),
onResetProxy = $.proxy(onReset, form);
if (!result) {
result = {
options: { // options structure passed to jQuery Validate's validate() method
errorClass: "input-validation-error",
errorElement: "span",
errorPlacement: $.proxy(onError, form),
invalidHandler: $.proxy(onErrors, form),
messages: {},
rules: {},
success: $.proxy(onSuccess, form)
},
attachValidation: function () {
$form
.unbind("reset." + data_validation, onResetProxy)
.bind("reset." + data_validation, onResetProxy)
.validate(this.options);
},
validate: function () { // a validation function that is called by unobtrusive Ajax
$form.validate();
return $form.valid();
}
};
$form.data(data_validation, result);
}
return result;
}
$jQval.unobtrusive = {
adapters: [],
parseElement: function (element, skipAttach) {
/// <summary>
/// Parses a single HTML element for unobtrusive validation attributes.
/// </summary>
/// <param name="element" domElement="true">The HTML element to be parsed.</param>
/// <param name="skipAttach" type="Boolean">[Optional] true to skip attaching the
/// validation to the form. If parsing just this single element, you should specify true.
/// If parsing several elements, you should specify false, and manually attach the validation
/// to the form when you are finished. The default is false.</param>
var $element = $(element),
form = $element.parents("form")[0],
valInfo, rules, messages;
if (!form) { // Cannot do client-side validation without a form
return;
}
valInfo = validationInfo(form);
valInfo.options.rules[element.name] = rules = {};
valInfo.options.messages[element.name] = messages = {};
$.each(this.adapters, function () {
var prefix = "data-val-" + this.name,
message = $element.attr(prefix),
paramValues = {};
if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
prefix += "-";
$.each(this.params, function () {
paramValues[this] = $element.attr(prefix + this);
});
this.adapt({
element: element,
form: form,
message: message,
params: paramValues,
rules: rules,
messages: messages
});
}
});
$.extend(rules, { "__dummy__": true });
if (!skipAttach) {
valInfo.attachValidation();
}
},
parse: function (selector) {
/// <summary>
/// Parses all the HTML elements in the specified selector. It looks for input elements decorated
/// with the [data-val=true] attribute value and enables validation according to the data-val-*
/// attribute values.
/// </summary>
/// <param name="selector" type="String">Any valid jQuery selector.</param>
var $forms = $(selector)
.parents("form")
.andSelf()
.add($(selector).find("form"))
.filter("form");
// :input is a psuedoselector provided by jQuery which selects input and input-like elements
// combining :input with other selectors significantly decreases performance.
$(selector).find(":input").filter("[data-val=true]").each(function () {
$jQval.unobtrusive.parseElement(this, true);
});
$forms.each(function () {
var info = validationInfo(this);
if (info) {
info.attachValidation();
}
});
}
};
adapters = $jQval.unobtrusive.adapters;
adapters.add = function (adapterName, params, fn) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
/// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
/// mmmm is the parameter name).</param>
/// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
/// attributes into jQuery Validate rules and/or messages.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
if (!fn) { // Called with no params, just a function
fn = params;
params = [];
}
this.push({ name: adapterName, params: params, adapt: fn });
return this;
};
adapters.addBool = function (adapterName, ruleName) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation rule has no parameter values.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
/// of adapterName will be used instead.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, function (options) {
setValidationValues(options, ruleName || adapterName, true);
});
};
adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
/// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="minRuleName" type="String">The name of the jQuery Validate rule to be used when you only
/// have a minimum value.</param>
/// <param name="maxRuleName" type="String">The name of the jQuery Validate rule to be used when you only
/// have a maximum value.</param>
/// <param name="minMaxRuleName" type="String">The name of the jQuery Validate rule to be used when you
/// have both a minimum and maximum value.</param>
/// <param name="minAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
/// contains the minimum value. The default is "min".</param>
/// <param name="maxAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
/// contains the maximum value. The default is "max".</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
var min = options.params.min,
max = options.params.max;
if (min && max) {
setValidationValues(options, minMaxRuleName, [min, max]);
}
else if (min) {
setValidationValues(options, minRuleName, min);
}
else if (max) {
setValidationValues(options, maxRuleName, max);
}
});
};
adapters.addSingleVal = function (adapterName, attribute, ruleName) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation rule has a single value.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>
/// <param name="attribute" type="String">[Optional] The name of the HTML attribute that contains the value.
/// The default is "val".</param>
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
/// of adapterName will be used instead.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, [attribute || "val"], function (options) {
setValidationValues(options, ruleName || adapterName, options.params[attribute]);
});
};
$jQval.addMethod("__dummy__", function (value, element, params) {
return true;
});
$jQval.addMethod("regex", function (value, element, params) {
var match;
if (this.optional(element)) {
return true;
}
match = new RegExp(params).exec(value);
return (match && (match.index === 0) && (match[0].length === value.length));
});
$jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
var match;
if (nonalphamin) {
match = value.match(/\W/g);
match = match && match.length >= nonalphamin;
}
return match;
});
if ($jQval.methods.extension) {
adapters.addSingleVal("accept", "mimtype");
adapters.addSingleVal("extension", "extension");
} else {
// for backward compatibility, when the 'extension' validation method does not exist, such as with versions
// of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
// validating the extension, and ignore mime-type validations as they are not supported.
adapters.addSingleVal("extension", "extension", "accept");
}
adapters.addSingleVal("regex", "pattern");
adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength");
adapters.add("equalto", ["other"], function (options) {
var prefix = getModelPrefix(options.element.name),
other = options.params.other,
fullOtherName = appendModelPrefix(other, prefix),
element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
setValidationValues(options, "equalTo", element);
});
adapters.add("required", function (options) {
// jQuery Validate equates "required" with "mandatory" for checkbox elements
if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
setValidationValues(options, "required", true);
}
});
adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
var value = {
url: options.params.url,
type: options.params.type || "GET",
data: {}
},
prefix = getModelPrefix(options.element.name);
$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
var paramName = appendModelPrefix(fieldName, prefix);
value.data[paramName] = function () {
return $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']").val();
};
});
setValidationValues(options, "remote", value);
});
adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
if (options.params.min) {
setValidationValues(options, "minlength", options.params.min);
}
if (options.params.nonalphamin) {
setValidationValues(options, "nonalphamin", options.params.nonalphamin);
}
if (options.params.regex) {
setValidationValues(options, "regex", options.params.regex);
}
});
$(function () {
$jQval.unobtrusive.parse(document);
});
}(jQuery));
+3 -3
View File
@@ -1496,8 +1496,6 @@
<LastGenOutput>CommonHelpers.generated.cs</LastGenOutput>
</None>
<None Include="Properties\PublishProfiles\HADES3.pubxml" />
<None Include="ClientSource\Scripts\Core\jquery.validate.js" />
<None Include="ClientSource\Scripts\Core\jquery.validate.unobtrusive.js" />
<None Include="ClientSource\Scripts\Modules\Highcharts\highcharts.src.js" />
<None Include="ClientSource\Scripts\Modules\jQuery-SignalR\jquery.signalR-1.1.2.js" />
<None Include="ClientSource\Scripts\Core\jquery-2.0.3.js" />
@@ -1964,6 +1962,8 @@
<Content Include="ClientSource\Scripts\Modules\tinymce\skins\lightgray\skin.min.css" />
<None Include="ClientSource\Scripts\Modules\tinymce\themes\modern\theme.js" />
<None Include="ClientSource\Scripts\Modules\tinymce\tinymce.js" />
<None Include="ClientSource\Scripts\Core\jquery.validate.js" />
<None Include="ClientSource\Scripts\Core\jquery.validate.unobtrusive.js" />
<Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
@@ -2053,7 +2053,7 @@
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
<UserProperties BuildVersion_StartDate="2011/7/1" BuildVersion_BuildAction="Both" BuildVersion_UseGlobalSettings="False" BuildVersion_DetectChanges="False" BuildVersion_BuildVersioningStyle="None.DeltaBaseYear.MonthAndDayStamp.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_UpdateFileVersion="True" />
<UserProperties BuildVersion_UpdateFileVersion="True" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.DeltaBaseYear.MonthAndDayStamp.TimeStamp" BuildVersion_DetectChanges="False" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildAction="Both" BuildVersion_StartDate="2011/7/1" />
</VisualStudio>
</ProjectExtensions>
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+2 -2
View File
@@ -7,7 +7,7 @@
<package id="jQuery" version="2.0.3" targetFramework="net45" />
<package id="jQuery.UI.Combined" version="1.10.3" targetFramework="net45" />
<package id="jQuery.UI.Themes.lightness" version="1.8.22" targetFramework="net45" />
<package id="jQuery.Validation" version="1.11.1" targetFramework="net45" />
<package id="jQuery.Validation" version="1.12.0" targetFramework="net45" />
<package id="knockoutjs" version="2.3.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net45" />
@@ -23,7 +23,7 @@
<package id="Microsoft.AspNet.WebPages" version="2.0.30506.0" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.3" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="net45" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.0.0" targetFramework="net45" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.1.2" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.15" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="1.0.1" targetFramework="net45" />
<package id="Microsoft.SqlServer.Compact" version="4.0.8876.1" targetFramework="net45" />