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