prometheus-net
1288 строк · 41.6 Кб
1/*
2* This file has been commented to support Visual Studio Intellisense.
3* You should not use this file at runtime inside the browser--it is only
4* intended to be used only for design-time IntelliSense. Please use the
5* standard jQuery library for all production use.
6*
7* Comment version: 1.17.0
8*/
9
10/*
11* Note: While Microsoft is not the author of this file, Microsoft is
12* offering you a license subject to the terms of the Microsoft Software
13* License Terms for Microsoft ASP.NET Model View Controller 3.
14* Microsoft reserves all other rights. The notices below are provided
15* for informational purposes only and are not the license terms under
16* which Microsoft distributed this file.
17*
18* jQuery Validation Plugin - v1.17.0 - 12/5/2016
19* https://github.com/jzaefferer/jquery-validation
20* Copyright (c) 2013 Jörn Zaefferer; Licensed MIT
21*
22*/
23
24(function($) {25
26$.extend($.fn, {27// http://docs.jquery.com/Plugins/Validation/validate28validate: function( options ) {29/// <summary>30/// Validates the selected form. This method sets up event handlers for submit, focus,31/// keyup, blur and click to trigger validation of the entire form or individual32/// elements. Each one can be disabled, see the onxxx options (onsubmit, onfocusout,33/// onkeyup, onclick). focusInvalid focuses elements when submitting a invalid form.34/// </summary>35/// <param name="options" type="Object">36/// A set of key/value pairs that configure the validate. All options are optional.37/// </param>38
39// if nothing is selected, return nothing; can't chain anyway40if (!this.length) {41options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );42return;43}44
45// check if a validator for this form was already created46var validator = $.data(this[0], 'validator');47if ( validator ) {48return validator;49}50
51validator = new $.validator( options, this[0] );52$.data(this[0], 'validator', validator);53
54if ( validator.settings.onsubmit ) {55
56// allow suppresing validation by adding a cancel class to the submit button57this.find("input, button").filter(".cancel").click(function() {58validator.cancelSubmit = true;59});60
61// when a submitHandler is used, capture the submitting button62if (validator.settings.submitHandler) {63this.find("input, button").filter(":submit").click(function() {64validator.submitButton = this;65});66}67
68// validate the form on submit69this.submit( function( event ) {70if ( validator.settings.debug )71// prevent form submit to be able to see console output72event.preventDefault();73
74function handle() {75if ( validator.settings.submitHandler ) {76if (validator.submitButton) {77// insert a hidden input as a replacement for the missing submit button78var hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);79}80validator.settings.submitHandler.call( validator, validator.currentForm );81if (validator.submitButton) {82// and clean up afterwards; thanks to no-block-scope, hidden can be referenced83hidden.remove();84}85return false;86}87return true;88}89
90// prevent submit for invalid forms or custom submit handlers91if ( validator.cancelSubmit ) {92validator.cancelSubmit = false;93return handle();94}95if ( validator.form() ) {96if ( validator.pendingRequest ) {97validator.formSubmitted = true;98return false;99}100return handle();101} else {102validator.focusInvalid();103return false;104}105});106}107
108return validator;109},110// http://docs.jquery.com/Plugins/Validation/valid111valid: function() {112/// <summary>113/// Checks if the selected form is valid or if all selected elements are valid.114/// validate() needs to be called on the form before checking it using this method.115/// </summary>116/// <returns type="Boolean" />117
118if ( $(this[0]).is('form')) {119return this.validate().form();120} else {121var valid = true;122var validator = $(this[0].form).validate();123this.each(function() {124valid &= validator.element(this);125});126return valid;127}128},129// attributes: space seperated list of attributes to retrieve and remove130removeAttrs: function(attributes) {131/// <summary>132/// Remove the specified attributes from the first matched element and return them.133/// </summary>134/// <param name="attributes" type="String">135/// A space-seperated list of attribute names to remove.136/// </param>137
138var result = {},139$element = this;140$.each(attributes.split(/\s/), function(index, value) {141result[value] = $element.attr(value);142$element.removeAttr(value);143});144return result;145},146// http://docs.jquery.com/Plugins/Validation/rules147rules: function(command, argument) {148/// <summary>149/// Return the validations rules for the first selected element.150/// </summary>151/// <param name="command" type="String">152/// Can be either "add" or "remove".153/// </param>154/// <param name="argument" type="">155/// A list of rules to add or remove.156/// </param>157
158var element = this[0];159
160if (command) {161var settings = $.data(element.form, 'validator').settings;162var staticRules = settings.rules;163var existingRules = $.validator.staticRules(element);164switch(command) {165case "add":166$.extend(existingRules, $.validator.normalizeRule(argument));167staticRules[element.name] = existingRules;168if (argument.messages)169settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );170break;171case "remove":172if (!argument) {173delete staticRules[element.name];174return existingRules;175}176var filtered = {};177$.each(argument.split(/\s/), function(index, method) {178filtered[method] = existingRules[method];179delete existingRules[method];180});181return filtered;182}183}184
185var data = $.validator.normalizeRules(186$.extend(187{},188$.validator.metadataRules(element),189$.validator.classRules(element),190$.validator.attributeRules(element),191$.validator.staticRules(element)192), element);193
194// make sure required is at front195if (data.required) {196var param = data.required;197delete data.required;198data = $.extend({required: param}, data);199}200
201return data;202}203});204
205// Custom selectors
206$.extend($.expr[":"], {207// http://docs.jquery.com/Plugins/Validation/blank208blank: function(a) {return !$.trim("" + a.value);},209// http://docs.jquery.com/Plugins/Validation/filled210filled: function(a) {return !!$.trim("" + a.value);},211// http://docs.jquery.com/Plugins/Validation/unchecked212unchecked: function(a) {return !a.checked;}213});214
215// constructor for validator
216$.validator = function( options, form ) {217this.settings = $.extend( true, {}, $.validator.defaults, options );218this.currentForm = form;219this.init();220};221
222$.validator.format = function(source, params) {223/// <summary>224/// Replaces {n} placeholders with arguments.225/// One or more arguments can be passed, in addition to the string template itself, to insert226/// into the string.227/// </summary>228/// <param name="source" type="String">229/// The string to format.230/// </param>231/// <param name="params" type="String">232/// The first argument to insert, or an array of Strings to insert233/// </param>234/// <returns type="String" />235
236if ( arguments.length == 1 )237return function() {238var args = $.makeArray(arguments);239args.unshift(source);240return $.validator.format.apply( this, args );241};242if ( arguments.length > 2 && params.constructor != Array ) {243params = $.makeArray(arguments).slice(1);244}245if ( params.constructor != Array ) {246params = [ params ];247}248$.each(params, function(i, n) {249source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);250});251return source;252};253
254$.extend($.validator, {255
256defaults: {257messages: {},258groups: {},259rules: {},260errorClass: "error",261validClass: "valid",262errorElement: "label",263focusInvalid: true,264errorContainer: $( [] ),265errorLabelContainer: $( [] ),266onsubmit: true,267ignore: [],268ignoreTitle: false,269onfocusin: function(element) {270this.lastActive = element;271
272// hide error label and remove error class on focus if enabled273if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {274this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );275this.addWrapper(this.errorsFor(element)).hide();276}277},278onfocusout: function(element) {279if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {280this.element(element);281}282},283onkeyup: function(element) {284if ( element.name in this.submitted || element == this.lastElement ) {285this.element(element);286}287},288onclick: function(element) {289// click on selects, radiobuttons and checkboxes290if ( element.name in this.submitted )291this.element(element);292// or option elements, check parent select in that case293else if (element.parentNode.name in this.submitted)294this.element(element.parentNode);295},296highlight: function( element, errorClass, validClass ) {297$(element).addClass(errorClass).removeClass(validClass);298},299unhighlight: function( element, errorClass, validClass ) {300$(element).removeClass(errorClass).addClass(validClass);301}302},303
304// http://docs.jquery.com/Plugins/Validation/Validator/setDefaults305setDefaults: function(settings) {306/// <summary>307/// Modify default settings for validation.308/// Accepts everything that Plugins/Validation/validate accepts.309/// </summary>310/// <param name="settings" type="Options">311/// Options to set as default.312/// </param>313
314$.extend( $.validator.defaults, settings );315},316
317messages: {318required: "This field is required.",319remote: "Please fix this field.",320email: "Please enter a valid email address.",321url: "Please enter a valid URL.",322date: "Please enter a valid date.",323dateISO: "Please enter a valid date (ISO).",324number: "Please enter a valid number.",325digits: "Please enter only digits.",326creditcard: "Please enter a valid credit card number.",327equalTo: "Please enter the same value again.",328accept: "Please enter a value with a valid extension.",329maxlength: $.validator.format("Please enter no more than {0} characters."),330minlength: $.validator.format("Please enter at least {0} characters."),331rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),332range: $.validator.format("Please enter a value between {0} and {1}."),333max: $.validator.format("Please enter a value less than or equal to {0}."),334min: $.validator.format("Please enter a value greater than or equal to {0}.")335},336
337autoCreateRanges: false,338
339prototype: {340
341init: function() {342this.labelContainer = $(this.settings.errorLabelContainer);343this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);344this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );345this.submitted = {};346this.valueCache = {};347this.pendingRequest = 0;348this.pending = {};349this.invalid = {};350this.reset();351
352var groups = (this.groups = {});353$.each(this.settings.groups, function(key, value) {354$.each(value.split(/\s/), function(index, name) {355groups[name] = key;356});357});358var rules = this.settings.rules;359$.each(rules, function(key, value) {360rules[key] = $.validator.normalizeRule(value);361});362
363function delegate(event) {364var validator = $.data(this[0].form, "validator"),365eventType = "on" + event.type.replace(/^validate/, "");366validator.settings[eventType] && validator.settings[eventType].call(validator, this[0] );367}368$(this.currentForm)369.validateDelegate(":text, :password, :file, select, textarea", "focusin focusout keyup", delegate)370.validateDelegate(":radio, :checkbox, select, option", "click", delegate);371
372if (this.settings.invalidHandler)373$(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);374},375
376// http://docs.jquery.com/Plugins/Validation/Validator/form377form: function() {378/// <summary>379/// Validates the form, returns true if it is valid, false otherwise.380/// This behaves as a normal submit event, but returns the result.381/// </summary>382/// <returns type="Boolean" />383
384this.checkForm();385$.extend(this.submitted, this.errorMap);386this.invalid = $.extend({}, this.errorMap);387if (!this.valid())388$(this.currentForm).triggerHandler("invalid-form", [this]);389this.showErrors();390return this.valid();391},392
393checkForm: function() {394this.prepareForm();395for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {396this.check( elements[i] );397}398return this.valid();399},400
401// http://docs.jquery.com/Plugins/Validation/Validator/element402element: function( element ) {403/// <summary>404/// Validates a single element, returns true if it is valid, false otherwise.405/// This behaves as validation on blur or keyup, but returns the result.406/// </summary>407/// <param name="element" type="Selector">408/// An element to validate, must be inside the validated form.409/// </param>410/// <returns type="Boolean" />411
412element = this.clean( element );413this.lastElement = element;414this.prepareElement( element );415this.currentElements = $(element);416var result = this.check( element );417if ( result ) {418delete this.invalid[element.name];419} else {420this.invalid[element.name] = true;421}422if ( !this.numberOfInvalids() ) {423// Hide error containers on last error424this.toHide = this.toHide.add( this.containers );425}426this.showErrors();427return result;428},429
430// http://docs.jquery.com/Plugins/Validation/Validator/showErrors431showErrors: function(errors) {432/// <summary>433/// Show the specified messages.434/// Keys have to refer to the names of elements, values are displayed for those elements, using the configured error placement.435/// </summary>436/// <param name="errors" type="Object">437/// One or more key/value pairs of input names and messages.438/// </param>439
440if(errors) {441// add items to error list and map442$.extend( this.errorMap, errors );443this.errorList = [];444for ( var name in errors ) {445this.errorList.push({446message: errors[name],447element: this.findByName(name)[0]448});449}450// remove items from success list451this.successList = $.grep( this.successList, function(element) {452return !(element.name in errors);453});454}455this.settings.showErrors456? this.settings.showErrors.call( this, this.errorMap, this.errorList )457: this.defaultShowErrors();458},459
460// http://docs.jquery.com/Plugins/Validation/Validator/resetForm461resetForm: function() {462/// <summary>463/// Resets the controlled form.464/// Resets input fields to their original value (requires form plugin), removes classes465/// indicating invalid elements and hides error messages.466/// </summary>467
468if ( $.fn.resetForm )469$( this.currentForm ).resetForm();470this.submitted = {};471this.prepareForm();472this.hideErrors();473this.elements().removeClass( this.settings.errorClass );474},475
476numberOfInvalids: function() {477/// <summary>478/// Returns the number of invalid fields.479/// This depends on the internal validator state. It covers all fields only after480/// validating the complete form (on submit or via $("form").valid()). After validating481/// a single element, only that element is counted. Most useful in combination with the482/// invalidHandler-option.483/// </summary>484/// <returns type="Number" />485
486return this.objectLength(this.invalid);487},488
489objectLength: function( obj ) {490var count = 0;491for ( var i in obj )492count++;493return count;494},495
496hideErrors: function() {497this.addWrapper( this.toHide ).hide();498},499
500valid: function() {501return this.size() == 0;502},503
504size: function() {505return this.errorList.length;506},507
508focusInvalid: function() {509if( this.settings.focusInvalid ) {510try {511$(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])512.filter(":visible")513.focus()514// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find515.trigger("focusin");516} catch(e) {517// ignore IE throwing errors when focusing hidden elements518}519}520},521
522findLastActive: function() {523var lastActive = this.lastActive;524return lastActive && $.grep(this.errorList, function(n) {525return n.element.name == lastActive.name;526}).length == 1 && lastActive;527},528
529elements: function() {530var validator = this,531rulesCache = {};532
533// select all valid inputs inside the form (no submit or reset buttons)534// workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved535return $([]).add(this.currentForm.elements)536.filter(":input")537.not(":submit, :reset, :image, [disabled]")538.not( this.settings.ignore )539.filter(function() {540!this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);541
542// select only the first element for each name, and only those with rules specified543if ( this.name in rulesCache || !validator.objectLength($(this).rules()) )544return false;545
546rulesCache[this.name] = true;547return true;548});549},550
551clean: function( selector ) {552return $( selector )[0];553},554
555errors: function() {556return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );557},558
559reset: function() {560this.successList = [];561this.errorList = [];562this.errorMap = {};563this.toShow = $([]);564this.toHide = $([]);565this.currentElements = $([]);566},567
568prepareForm: function() {569this.reset();570this.toHide = this.errors().add( this.containers );571},572
573prepareElement: function( element ) {574this.reset();575this.toHide = this.errorsFor(element);576},577
578check: function( element ) {579element = this.clean( element );580
581// if radio/checkbox, validate first element in group instead582if (this.checkable(element)) {583element = this.findByName(element.name).not(this.settings.ignore)[0];584}585
586var rules = $(element).rules();587var dependencyMismatch = false;588for (var method in rules) {589var rule = { method: method, parameters: rules[method] };590try {591var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters );592
593// if a method indicates that the field is optional and therefore valid,594// don't mark it as valid when there are no other rules595if ( result == "dependency-mismatch" ) {596dependencyMismatch = true;597continue;598}599dependencyMismatch = false;600
601if ( result == "pending" ) {602this.toHide = this.toHide.not( this.errorsFor(element) );603return;604}605
606if( !result ) {607this.formatAndAdd( element, rule );608return false;609}610} catch(e) {611this.settings.debug && window.console && console.log("exception occured when checking element " + element.id612+ ", check the '" + rule.method + "' method", e);613throw e;614}615}616if (dependencyMismatch)617return;618if ( this.objectLength(rules) )619this.successList.push(element);620return true;621},622
623// return the custom message for the given element and validation method624// specified in the element's "messages" metadata625customMetaMessage: function(element, method) {626if (!$.metadata)627return;628
629var meta = this.settings.meta630? $(element).metadata()[this.settings.meta]631: $(element).metadata();632
633return meta && meta.messages && meta.messages[method];634},635
636// return the custom message for the given element name and validation method637customMessage: function( name, method ) {638var m = this.settings.messages[name];639return m && (m.constructor == String640? m641: m[method]);642},643
644// return the first defined argument, allowing empty strings645findDefined: function() {646for(var i = 0; i < arguments.length; i++) {647if (arguments[i] !== undefined)648return arguments[i];649}650return undefined;651},652
653defaultMessage: function( element, method) {654return this.findDefined(655this.customMessage( element.name, method ),656this.customMetaMessage( element, method ),657// title is never undefined, so handle empty string as undefined658!this.settings.ignoreTitle && element.title || undefined,659$.validator.messages[method],660"<strong>Warning: No message defined for " + element.name + "</strong>"661);662},663
664formatAndAdd: function( element, rule ) {665var message = this.defaultMessage( element, rule.method ),666theregex = /\$?\{(\d+)\}/g;667if ( typeof message == "function" ) {668message = message.call(this, rule.parameters, element);669} else if (theregex.test(message)) {670message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters);671}672this.errorList.push({673message: message,674element: element675});676
677this.errorMap[element.name] = message;678this.submitted[element.name] = message;679},680
681addWrapper: function(toToggle) {682if ( this.settings.wrapper )683toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );684return toToggle;685},686
687defaultShowErrors: function() {688for ( var i = 0; this.errorList[i]; i++ ) {689var error = this.errorList[i];690this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );691this.showLabel( error.element, error.message );692}693if( this.errorList.length ) {694this.toShow = this.toShow.add( this.containers );695}696if (this.settings.success) {697for ( var i = 0; this.successList[i]; i++ ) {698this.showLabel( this.successList[i] );699}700}701if (this.settings.unhighlight) {702for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {703this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );704}705}706this.toHide = this.toHide.not( this.toShow );707this.hideErrors();708this.addWrapper( this.toShow ).show();709},710
711validElements: function() {712return this.currentElements.not(this.invalidElements());713},714
715invalidElements: function() {716return $(this.errorList).map(function() {717return this.element;718});719},720
721showLabel: function(element, message) {722var label = this.errorsFor( element );723if ( label.length ) {724// refresh error/success class725label.removeClass().addClass( this.settings.errorClass );726
727// check if we have a generated label, replace the message then728label.attr("generated") && label.html(message);729} else {730// create label731label = $("<" + this.settings.errorElement + "/>")732.attr({"for": this.idOrName(element), generated: true})733.addClass(this.settings.errorClass)734.html(message || "");735if ( this.settings.wrapper ) {736// make sure the element is visible, even in IE737// actually showing the wrapped element is handled elsewhere738label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();739}740if ( !this.labelContainer.append(label).length )741this.settings.errorPlacement742? this.settings.errorPlacement(label, $(element) )743: label.insertAfter(element);744}745if ( !message && this.settings.success ) {746label.text("");747typeof this.settings.success == "string"748? label.addClass( this.settings.success )749: this.settings.success( label );750}751this.toShow = this.toShow.add(label);752},753
754errorsFor: function(element) {755var name = this.idOrName(element);756return this.errors().filter(function() {757return $(this).attr('for') == name;758});759},760
761idOrName: function(element) {762return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);763},764
765checkable: function( element ) {766return /radio|checkbox/i.test(element.type);767},768
769findByName: function( name ) {770// select by name and filter by form for performance over form.find("[name=...]")771var form = this.currentForm;772return $(document.getElementsByName(name)).map(function(index, element) {773return element.form == form && element.name == name && element || null;774});775},776
777getLength: function(value, element) {778switch( element.nodeName.toLowerCase() ) {779case 'select':780return $("option:selected", element).length;781case 'input':782if( this.checkable( element) )783return this.findByName(element.name).filter(':checked').length;784}785return value.length;786},787
788depend: function(param, element) {789return this.dependTypes[typeof param]790? this.dependTypes[typeof param](param, element)791: true;792},793
794dependTypes: {795"boolean": function(param, element) {796return param;797},798"string": function(param, element) {799return !!$(param, element.form).length;800},801"function": function(param, element) {802return param(element);803}804},805
806optional: function(element) {807return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";808},809
810startRequest: function(element) {811if (!this.pending[element.name]) {812this.pendingRequest++;813this.pending[element.name] = true;814}815},816
817stopRequest: function(element, valid) {818this.pendingRequest--;819// sometimes synchronization fails, make sure pendingRequest is never < 0820if (this.pendingRequest < 0)821this.pendingRequest = 0;822delete this.pending[element.name];823if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {824$(this.currentForm).submit();825this.formSubmitted = false;826} else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {827$(this.currentForm).triggerHandler("invalid-form", [this]);828this.formSubmitted = false;829}830},831
832previousValue: function(element) {833return $.data(element, "previousValue") || $.data(element, "previousValue", {834old: null,835valid: true,836message: this.defaultMessage( element, "remote" )837});838}839
840},841
842classRuleSettings: {843required: {required: true},844email: {email: true},845url: {url: true},846date: {date: true},847dateISO: {dateISO: true},848dateDE: {dateDE: true},849number: {number: true},850numberDE: {numberDE: true},851digits: {digits: true},852creditcard: {creditcard: true}853},854
855addClassRules: function(className, rules) {856/// <summary>857/// Add a compound class method - useful to refactor common combinations of rules into a single858/// class.859/// </summary>860/// <param name="name" type="String">861/// The name of the class rule to add862/// </param>863/// <param name="rules" type="Options">864/// The compound rules865/// </param>866
867className.constructor == String ?868this.classRuleSettings[className] = rules :869$.extend(this.classRuleSettings, className);870},871
872classRules: function(element) {873var rules = {};874var classes = $(element).attr('class');875classes && $.each(classes.split(' '), function() {876if (this in $.validator.classRuleSettings) {877$.extend(rules, $.validator.classRuleSettings[this]);878}879});880return rules;881},882
883attributeRules: function(element) {884var rules = {};885var $element = $(element);886
887for (var method in $.validator.methods) {888var value = $element.attr(method);889if (value) {890rules[method] = value;891}892}893
894// maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs895if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {896delete rules.maxlength;897}898
899return rules;900},901
902metadataRules: function(element) {903if (!$.metadata) return {};904
905var meta = $.data(element.form, 'validator').settings.meta;906return meta ?907$(element).metadata()[meta] :908$(element).metadata();909},910
911staticRules: function(element) {912var rules = {};913var validator = $.data(element.form, 'validator');914if (validator.settings.rules) {915rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};916}917return rules;918},919
920normalizeRules: function(rules, element) {921// handle dependency check922$.each(rules, function(prop, val) {923// ignore rule when param is explicitly false, eg. required:false924if (val === false) {925delete rules[prop];926return;927}928if (val.param || val.depends) {929var keepRule = true;930switch (typeof val.depends) {931case "string":932keepRule = !!$(val.depends, element.form).length;933break;934case "function":935keepRule = val.depends.call(element, element);936break;937}938if (keepRule) {939rules[prop] = val.param !== undefined ? val.param : true;940} else {941delete rules[prop];942}943}944});945
946// evaluate parameters947$.each(rules, function(rule, parameter) {948rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;949});950
951// clean number parameters952$.each(['minlength', 'maxlength', 'min', 'max'], function() {953if (rules[this]) {954rules[this] = Number(rules[this]);955}956});957$.each(['rangelength', 'range'], function() {958if (rules[this]) {959rules[this] = [Number(rules[this][0]), Number(rules[this][1])];960}961});962
963if ($.validator.autoCreateRanges) {964// auto-create ranges965if (rules.min && rules.max) {966rules.range = [rules.min, rules.max];967delete rules.min;968delete rules.max;969}970if (rules.minlength && rules.maxlength) {971rules.rangelength = [rules.minlength, rules.maxlength];972delete rules.minlength;973delete rules.maxlength;974}975}976
977// To support custom messages in metadata ignore rule methods titled "messages"978if (rules.messages) {979delete rules.messages;980}981
982return rules;983},984
985// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}986normalizeRule: function(data) {987if( typeof data == "string" ) {988var transformed = {};989$.each(data.split(/\s/), function() {990transformed[this] = true;991});992data = transformed;993}994return data;995},996
997// http://docs.jquery.com/Plugins/Validation/Validator/addMethod998addMethod: function(name, method, message) {999/// <summary>1000/// Add a custom validation method. It must consist of a name (must be a legal javascript1001/// identifier), a javascript based function and a default string message.1002/// </summary>1003/// <param name="name" type="String">1004/// The name of the method, used to identify and referencing it, must be a valid javascript1005/// identifier1006/// </param>1007/// <param name="method" type="Function">1008/// The actual method implementation, returning true if an element is valid1009/// </param>1010/// <param name="message" type="String" optional="true">1011/// (Optional) The default message to display for this method. Can be a function created by1012/// jQuery.validator.format(value). When undefined, an already existing message is used1013/// (handy for localization), otherwise the field-specific messages have to be defined.1014/// </param>1015
1016$.validator.methods[name] = method;1017$.validator.messages[name] = message != undefined ? message : $.validator.messages[name];1018if (method.length < 3) {1019$.validator.addClassRules(name, $.validator.normalizeRule(name));1020}1021},1022
1023methods: {1024
1025// http://docs.jquery.com/Plugins/Validation/Methods/required1026required: function(value, element, param) {1027// check if dependency is met1028if ( !this.depend(param, element) )1029return "dependency-mismatch";1030switch( element.nodeName.toLowerCase() ) {1031case 'select':1032// could be an array for select-multiple or a string, both are fine this way1033var val = $(element).val();1034return val && val.length > 0;1035case 'input':1036if ( this.checkable(element) )1037return this.getLength(value, element) > 0;1038default:1039return $.trim(value).length > 0;1040}1041},1042
1043// http://docs.jquery.com/Plugins/Validation/Methods/remote1044remote: function(value, element, param) {1045if ( this.optional(element) )1046return "dependency-mismatch";1047
1048var previous = this.previousValue(element);1049if (!this.settings.messages[element.name] )1050this.settings.messages[element.name] = {};1051previous.originalMessage = this.settings.messages[element.name].remote;1052this.settings.messages[element.name].remote = previous.message;1053
1054param = typeof param == "string" && {url:param} || param;1055
1056if ( this.pending[element.name] ) {1057return "pending";1058}1059if ( previous.old === value ) {1060return previous.valid;1061}1062
1063previous.old = value;1064var validator = this;1065this.startRequest(element);1066var data = {};1067data[element.name] = value;1068$.ajax($.extend(true, {1069url: param,1070mode: "abort",1071port: "validate" + element.name,1072dataType: "json",1073data: data,1074success: function(response) {1075validator.settings.messages[element.name].remote = previous.originalMessage;1076var valid = response === true;1077if ( valid ) {1078var submitted = validator.formSubmitted;1079validator.prepareElement(element);1080validator.formSubmitted = submitted;1081validator.successList.push(element);1082validator.showErrors();1083} else {1084var errors = {};1085var message = response || validator.defaultMessage(element, "remote");1086errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;1087validator.showErrors(errors);1088}1089previous.valid = valid;1090validator.stopRequest(element, valid);1091}1092}, param));1093return "pending";1094},1095
1096// http://docs.jquery.com/Plugins/Validation/Methods/minlength1097minlength: function(value, element, param) {1098return this.optional(element) || this.getLength($.trim(value), element) >= param;1099},1100
1101// http://docs.jquery.com/Plugins/Validation/Methods/maxlength1102maxlength: function(value, element, param) {1103return this.optional(element) || this.getLength($.trim(value), element) <= param;1104},1105
1106// http://docs.jquery.com/Plugins/Validation/Methods/rangelength1107rangelength: function(value, element, param) {1108var length = this.getLength($.trim(value), element);1109return this.optional(element) || ( length >= param[0] && length <= param[1] );1110},1111
1112// http://docs.jquery.com/Plugins/Validation/Methods/min1113min: function( value, element, param ) {1114return this.optional(element) || value >= param;1115},1116
1117// http://docs.jquery.com/Plugins/Validation/Methods/max1118max: function( value, element, param ) {1119return this.optional(element) || value <= param;1120},1121
1122// http://docs.jquery.com/Plugins/Validation/Methods/range1123range: function( value, element, param ) {1124return this.optional(element) || ( value >= param[0] && value <= param[1] );1125},1126
1127// http://docs.jquery.com/Plugins/Validation/Methods/email1128email: function(value, element) {1129// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/1130return 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);1131},1132
1133// http://docs.jquery.com/Plugins/Validation/Methods/url1134url: function(value, element) {1135// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/1136return this.optional(element) || /^(https?|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);1137},1138
1139// http://docs.jquery.com/Plugins/Validation/Methods/date1140date: function(value, element) {1141return this.optional(element) || !/Invalid|NaN/.test(new Date(value));1142},1143
1144// http://docs.jquery.com/Plugins/Validation/Methods/dateISO1145dateISO: function(value, element) {1146return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);1147},1148
1149// http://docs.jquery.com/Plugins/Validation/Methods/number1150number: function(value, element) {1151return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);1152},1153
1154// http://docs.jquery.com/Plugins/Validation/Methods/digits1155digits: function(value, element) {1156return this.optional(element) || /^\d+$/.test(value);1157},1158
1159// http://docs.jquery.com/Plugins/Validation/Methods/creditcard1160// based on http://en.wikipedia.org/wiki/Luhn1161creditcard: function(value, element) {1162if ( this.optional(element) )1163return "dependency-mismatch";1164// accept only digits and dashes1165if (/[^0-9-]+/.test(value))1166return false;1167var nCheck = 0,1168nDigit = 0,1169bEven = false;1170
1171value = value.replace(/\D/g, "");1172
1173for (var n = value.length - 1; n >= 0; n--) {1174var cDigit = value.charAt(n);1175var nDigit = parseInt(cDigit, 10);1176if (bEven) {1177if ((nDigit *= 2) > 9)1178nDigit -= 9;1179}1180nCheck += nDigit;1181bEven = !bEven;1182}1183
1184return (nCheck % 10) == 0;1185},1186
1187// http://docs.jquery.com/Plugins/Validation/Methods/accept1188accept: function(value, element, param) {1189param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";1190return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));1191},1192
1193// http://docs.jquery.com/Plugins/Validation/Methods/equalTo1194equalTo: function(value, element, param) {1195// bind to the blur event of the target in order to revalidate whenever the target field is updated1196// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead1197var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {1198$(element).valid();1199});1200return value == target.val();1201}1202
1203}1204
1205});1206
1207// deprecated, use $.validator.format instead
1208$.format = $.validator.format;1209
1210})(jQuery);1211
1212// ajax mode: abort
1213// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1214// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1215;(function($) {1216var pendingRequests = {};1217// Use a prefilter if available (1.5+)1218if ( $.ajaxPrefilter ) {1219$.ajaxPrefilter(function(settings, _, xhr) {1220var port = settings.port;1221if (settings.mode == "abort") {1222if ( pendingRequests[port] ) {1223pendingRequests[port].abort();1224} pendingRequests[port] = xhr;1225}1226});1227} else {1228// Proxy ajax1229var ajax = $.ajax;1230$.ajax = function(settings) {1231var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,1232port = ( "port" in settings ? settings : $.ajaxSettings ).port;1233if (mode == "abort") {1234if ( pendingRequests[port] ) {1235pendingRequests[port].abort();1236}1237
1238return (pendingRequests[port] = ajax.apply(this, arguments));1239}1240return ajax.apply(this, arguments);1241};1242}1243})(jQuery);1244
1245// provides cross-browser focusin and focusout events
1246// IE has native support, in other browsers, use event caputuring (neither bubbles)
1247
1248// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1249// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1250;(function($) {1251// only implement if not provided by jQuery core (since 1.4)1252// TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs1253if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) {1254$.each({1255focus: 'focusin',1256blur: 'focusout'1257}, function( original, fix ){1258$.event.special[fix] = {1259setup:function() {1260this.addEventListener( original, handler, true );1261},1262teardown:function() {1263this.removeEventListener( original, handler, true );1264},1265handler: function(e) {1266arguments[0] = $.event.fix(e);1267arguments[0].type = fix;1268return $.event.handle.apply(this, arguments);1269}1270};1271function handler(e) {1272e = $.event.fix(e);1273e.type = fix;1274return $.event.handle.call(this, e);1275}1276});1277};1278$.extend($.fn, {1279validateDelegate: function(delegate, type, handler) {1280return this.bind(type, function(event) {1281var target = $(event.target);1282if (target.is(delegate)) {1283return handler.apply(target, arguments);1284}1285});1286}1287});1288})(jQuery);1289