Issue-id: OCS-9
[msb/apigateway.git] / msb-core / apiroute / apiroute-service / src / main / resources / iui-route / js / jquery-validation / jquery.validate.js
1 /*
2  * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  *     Author: Zhaoxing Meng
17  *     email: meng.zhaoxing1@zte.com.cn
18  */
19 (function( factory ) {
20         if ( typeof define === "function" && define.amd ) {
21                 define( ["jquery"], factory );
22         } else {
23                 factory( jQuery );
24         }
25 }(function( $ ) {
26
27 $.extend($.fn, {
28         // http://jqueryvalidation.org/validate/
29         validate: function( options ) {
30
31                 // if nothing is selected, return nothing; can't chain anyway
32                 if ( !this.length ) {
33                         if ( options && options.debug && window.console ) {
34                                 console.warn( "Nothing selected, can't validate, returning nothing." );
35                         }
36                         return;
37                 }
38
39                 // check if a validator for this form was already created
40                 var validator = $.data( this[ 0 ], "validator" );
41                 if ( validator ) {
42                         return validator;
43                 }
44
45                 // Add novalidate tag if HTML5.
46                 this.attr( "novalidate", "novalidate" );
47
48                 validator = new $.validator( options, this[ 0 ] );
49                 $.data( this[ 0 ], "validator", validator );
50
51                 if ( validator.settings.onsubmit ) {
52
53                         this.validateDelegate( ":submit", "click", function( event ) {
54                                 if ( validator.settings.submitHandler ) {
55                                         validator.submitButton = event.target;
56                                 }
57                                 // allow suppressing validation by adding a cancel class to the submit button
58                                 if ( $( event.target ).hasClass( "cancel" ) ) {
59                                         validator.cancelSubmit = true;
60                                 }
61
62                                 // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
63                                 if ( $( event.target ).attr( "formnovalidate" ) !== undefined ) {
64                                         validator.cancelSubmit = true;
65                                 }
66                         });
67
68                         // validate the form on submit
69                         this.submit( function( event ) {
70                                 if ( validator.settings.debug ) {
71                                         // prevent form submit to be able to see console output
72                                         event.preventDefault();
73                                 }
74                                 function handle() {
75                                         var hidden;
76                                         if ( validator.settings.submitHandler ) {
77                                                 if ( validator.submitButton ) {
78                                                         // insert a hidden input as a replacement for the missing submit button
79                                                         hidden = $( "<input type='hidden'/>" )
80                                                                 .attr( "name", validator.submitButton.name )
81                                                                 .val( $( validator.submitButton ).val() )
82                                                                 .appendTo( validator.currentForm );
83                                                 }
84                                                 validator.settings.submitHandler.call( validator, validator.currentForm, event );
85                                                 if ( validator.submitButton ) {
86                                                         // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
87                                                         hidden.remove();
88                                                 }
89                                                 return false;
90                                         }
91                                         return true;
92                                 }
93
94                                 // prevent submit for invalid forms or custom submit handlers
95                                 if ( validator.cancelSubmit ) {
96                                         validator.cancelSubmit = false;
97                                         return handle();
98                                 }
99                                 if ( validator.form() ) {
100                                         if ( validator.pendingRequest ) {
101                                                 validator.formSubmitted = true;
102                                                 return false;
103                                         }
104                                         return handle();
105                                 } else {
106                                         validator.focusInvalid();
107                                         return false;
108                                 }
109                         });
110                 }
111
112                 return validator;
113         },
114         // http://jqueryvalidation.org/valid/
115         valid: function() {
116                 var valid, validator;
117
118                 if ( $( this[ 0 ] ).is( "form" ) ) {
119                         valid = this.validate().form();
120                 } else {
121                         valid = true;
122                         validator = $( this[ 0 ].form ).validate();
123                         this.each( function() {
124                                 valid = validator.element( this ) && valid;
125                         });
126                 }
127                 return valid;
128         },
129         // attributes: space separated list of attributes to retrieve and remove
130         removeAttrs: function( attributes ) {
131                 var result = {},
132                         $element = this;
133                 $.each( attributes.split( /\s/ ), function( index, value ) {
134                         result[ value ] = $element.attr( value );
135                         $element.removeAttr( value );
136                 });
137                 return result;
138         },
139         // http://jqueryvalidation.org/rules/
140         rules: function( command, argument ) {
141                 var element = this[ 0 ],
142                         settings, staticRules, existingRules, data, param, filtered;
143
144                 if ( command ) {
145                         settings = $.data( element.form, "validator" ).settings;
146                         staticRules = settings.rules;
147                         existingRules = $.validator.staticRules( element );
148                         switch ( command ) {
149                         case "add":
150                                 $.extend( existingRules, $.validator.normalizeRule( argument ) );
151                                 // remove messages from rules, but allow them to be set separately
152                                 delete existingRules.messages;
153                                 staticRules[ element.name ] = existingRules;
154                                 if ( argument.messages ) {
155                                         settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );
156                                 }
157                                 break;
158                         case "remove":
159                                 if ( !argument ) {
160                                         delete staticRules[ element.name ];
161                                         return existingRules;
162                                 }
163                                 filtered = {};
164                                 $.each( argument.split( /\s/ ), function( index, method ) {
165                                         filtered[ method ] = existingRules[ method ];
166                                         delete existingRules[ method ];
167                                         if ( method === "required" ) {
168                                                 $( element ).removeAttr( "aria-required" );
169                                         }
170                                 });
171                                 return filtered;
172                         }
173                 }
174
175                 data = $.validator.normalizeRules(
176                 $.extend(
177                         {},
178                         $.validator.classRules( element ),
179                         $.validator.attributeRules( element ),
180                         $.validator.dataRules( element ),
181                         $.validator.staticRules( element )
182                 ), element );
183
184                 // make sure required is at front
185                 if ( data.required ) {
186                         param = data.required;
187                         delete data.required;
188                         data = $.extend( { required: param }, data );
189                         $( element ).attr( "aria-required", "true" );
190                 }
191
192                 // make sure remote is at back
193                 if ( data.remote ) {
194                         param = data.remote;
195                         delete data.remote;
196                         data = $.extend( data, { remote: param });
197                 }
198
199                 return data;
200         }
201 });
202
203 // Custom selectors
204 $.extend( $.expr[ ":" ], {
205         // http://jqueryvalidation.org/blank-selector/
206         blank: function( a ) {
207                 return !$.trim( "" + $( a ).val() );
208         },
209         // http://jqueryvalidation.org/filled-selector/
210         filled: function( a ) {
211                 return !!$.trim( "" + $( a ).val() );
212         },
213         // http://jqueryvalidation.org/unchecked-selector/
214         unchecked: function( a ) {
215                 return !$( a ).prop( "checked" );
216         }
217 });
218
219 // constructor for validator
220 $.validator = function( options, form ) {
221         this.settings = $.extend( true, {}, $.validator.defaults, options );
222         this.currentForm = form;
223         this.init();
224 };
225
226 // http://jqueryvalidation.org/jQuery.validator.format/
227 $.validator.format = function( source, params ) {
228         if ( arguments.length === 1 ) {
229                 return function() {
230                         var args = $.makeArray( arguments );
231                         args.unshift( source );
232                         return $.validator.format.apply( this, args );
233                 };
234         }
235         if ( arguments.length > 2 && params.constructor !== Array  ) {
236                 params = $.makeArray( arguments ).slice( 1 );
237         }
238         if ( params.constructor !== Array ) {
239                 params = [ params ];
240         }
241         $.each( params, function( i, n ) {
242                 source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
243                         return n;
244                 });
245         });
246         return source;
247 };
248
249 $.extend( $.validator, {
250
251         defaults: {
252                 messages: {},
253                 groups: {},
254                 rules: {},
255                 errorClass: "error",
256                 validClass: "valid",
257                 errorElement: "label",
258                 focusInvalid: true,
259                 errorContainer: $( [] ),
260                 errorLabelContainer: $( [] ),
261                 onsubmit: true,
262                 ignore: ":hidden",
263                 ignoreTitle: false,
264                 onfocusin: function( element ) {
265                         this.lastActive = element;
266
267                         // hide error label and remove error class on focus if enabled
268                         if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
269                                 if ( this.settings.unhighlight ) {
270                                         this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
271                                 }
272                                 this.hideThese( this.errorsFor( element ) );
273                         }
274                 },
275                 onfocusout: function( element ) {
276                         if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {
277                                 this.element( element );
278                         }
279                 },
280                 onkeyup: function( element, event ) {
281                         if ( event.which === 9 && this.elementValue( element ) === "" ) {
282                                 return;
283                         } else if ( element.name in this.submitted || element === this.lastElement ) {
284                                 this.element( element );
285                         }
286                 },
287                 onclick: function( element ) {
288                         // click on selects, radiobuttons and checkboxes
289                         if ( element.name in this.submitted ) {
290                                 this.element( element );
291
292                         // or option elements, check parent select in that case
293                         } else if ( element.parentNode.name in this.submitted ) {
294                                 this.element( element.parentNode );
295                         }
296                 },
297                 highlight: function( element, errorClass, validClass ) {
298                         if ( element.type === "radio" ) {
299                                 this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
300                         } else {
301                                 $( element ).addClass( errorClass ).removeClass( validClass );
302                         }
303                 },
304                 unhighlight: function( element, errorClass, validClass ) {
305                         if ( element.type === "radio" ) {
306                                 this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
307                         } else {
308                                 $( element ).removeClass( errorClass ).addClass( validClass );
309                         }
310                 }
311         },
312
313         // http://jqueryvalidation.org/jQuery.validator.setDefaults/
314         setDefaults: function( settings ) {
315                 $.extend( $.validator.defaults, settings );
316         },
317
318         messages: {
319                 required: "This field is required.",
320                 remote: "Please fix this field.",
321                 email: "Please enter a valid email address.",
322                 url: "Please enter a valid URL.",
323                 date: "Please enter a valid date.",
324                 dateISO: "Please enter a valid date ( ISO ).",
325                 number: "Please enter a valid number.",
326                 digits: "Please enter only digits.",
327                 creditcard: "Please enter a valid credit card number.",
328                 equalTo: "Please enter the same value again.",
329                 maxlength: $.validator.format( "Please enter no more than {0} characters." ),
330                 minlength: $.validator.format( "Please enter at least {0} characters." ),
331                 rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
332                 range: $.validator.format( "Please enter a value between {0} and {1}." ),
333                 max: $.validator.format( "Please enter a value less than or equal to {0}." ),
334                 min: $.validator.format( "Please enter a value greater than or equal to {0}." )
335         },
336
337         autoCreateRanges: false,
338
339         prototype: {
340
341                 init: function() {
342                         this.labelContainer = $( this.settings.errorLabelContainer );
343                         this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );
344                         this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );
345                         this.submitted = {};
346                         this.valueCache = {};
347                         this.pendingRequest = 0;
348                         this.pending = {};
349                         this.invalid = {};
350                         this.reset();
351
352                         var groups = ( this.groups = {} ),
353                                 rules;
354                         $.each( this.settings.groups, function( key, value ) {
355                                 if ( typeof value === "string" ) {
356                                         value = value.split( /\s/ );
357                                 }
358                                 $.each( value, function( index, name ) {
359                                         groups[ name ] = key;
360                                 });
361                         });
362                         rules = this.settings.rules;
363                         $.each( rules, function( key, value ) {
364                                 rules[ key ] = $.validator.normalizeRule( value );
365                         });
366
367                         function delegate( event ) {
368                                 var validator = $.data( this[ 0 ].form, "validator" ),
369                                         eventType = "on" + event.type.replace( /^validate/, "" ),
370                                         settings = validator.settings;
371                                 if ( settings[ eventType ] && !this.is( settings.ignore ) ) {
372                                         settings[ eventType ].call( validator, this[ 0 ], event );
373                                 }
374                         }
375                         $( this.currentForm )
376                                 .validateDelegate( ":text, [type='password'], [type='file'], select, textarea, " +
377                                         "[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
378                                         "[type='email'], [type='datetime'], [type='date'], [type='month'], " +
379                                         "[type='week'], [type='time'], [type='datetime-local'], " +
380                                         "[type='range'], [type='color'], [type='radio'], [type='checkbox']",
381                                         "focusin focusout keyup", delegate)
382                                 // Support: Chrome, oldIE
383                                 // "select" is provided as event.target when clicking a option
384                                 .validateDelegate("select, option, [type='radio'], [type='checkbox']", "click", delegate);
385
386                         if ( this.settings.invalidHandler ) {
387                                 $( this.currentForm ).bind( "invalid-form.validate", this.settings.invalidHandler );
388                         }
389
390                         // Add aria-required to any Static/Data/Class required fields before first validation
391                         // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
392                         $( this.currentForm ).find( "[required], [data-rule-required], .required" ).attr( "aria-required", "true" );
393                 },
394
395                 // http://jqueryvalidation.org/Validator.form/
396                 form: function() {
397                         this.checkForm();
398                         $.extend( this.submitted, this.errorMap );
399                         this.invalid = $.extend({}, this.errorMap );
400                         if ( !this.valid() ) {
401                                 $( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
402                         }
403                         this.showErrors();
404                         return this.valid();
405                 },
406
407                 checkForm: function() {
408                         this.prepareForm();
409                         for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
410                                 this.check( elements[ i ] );
411                         }
412                         return this.valid();
413                 },
414
415                 // http://jqueryvalidation.org/Validator.element/
416                 element: function( element ) {
417                         var cleanElement = this.clean( element ),
418                                 checkElement = this.validationTargetFor( cleanElement ),
419                                 result = true;
420
421                         this.lastElement = checkElement;
422
423                         if ( checkElement === undefined ) {
424                                 delete this.invalid[ cleanElement.name ];
425                         } else {
426                                 this.prepareElement( checkElement );
427                                 this.currentElements = $( checkElement );
428
429                                 result = this.check( checkElement ) !== false;
430                                 if ( result ) {
431                                         delete this.invalid[ checkElement.name ];
432                                 } else {
433                                         this.invalid[ checkElement.name ] = true;
434                                 }
435                         }
436                         // Add aria-invalid status for screen readers
437                         $( element ).attr( "aria-invalid", !result );
438
439                         if ( !this.numberOfInvalids() ) {
440                                 // Hide error containers on last error
441                                 this.toHide = this.toHide.add( this.containers );
442                         }
443                         this.showErrors();
444                         return result;
445                 },
446
447                 // http://jqueryvalidation.org/Validator.showErrors/
448                 showErrors: function( errors ) {
449                         if ( errors ) {
450                                 // add items to error list and map
451                                 $.extend( this.errorMap, errors );
452                                 this.errorList = [];
453                                 for ( var name in errors ) {
454                                         this.errorList.push({
455                                                 message: errors[ name ],
456                                                 element: this.findByName( name )[ 0 ]
457                                         });
458                                 }
459                                 // remove items from success list
460                                 this.successList = $.grep( this.successList, function( element ) {
461                                         return !( element.name in errors );
462                                 });
463                         }
464                         if ( this.settings.showErrors ) {
465                                 this.settings.showErrors.call( this, this.errorMap, this.errorList );
466                         } else {
467                                 this.defaultShowErrors();
468                         }
469                 },
470
471                 // http://jqueryvalidation.org/Validator.resetForm/
472                 resetForm: function() {
473                         if ( $.fn.resetForm ) {
474                                 $( this.currentForm ).resetForm();
475                         }
476                         this.submitted = {};
477                         this.lastElement = null;
478                         this.prepareForm();
479                         this.hideErrors();
480                         this.elements()
481                                         .removeClass( this.settings.errorClass )
482                                         .removeData( "previousValue" )
483                                         .removeAttr( "aria-invalid" );
484                 },
485
486                 numberOfInvalids: function() {
487                         return this.objectLength( this.invalid );
488                 },
489
490                 objectLength: function( obj ) {
491                         /* jshint unused: false */
492                         var count = 0,
493                                 i;
494                         for ( i in obj ) {
495                                 count++;
496                         }
497                         return count;
498                 },
499
500                 hideErrors: function() {
501                         this.hideThese( this.toHide );
502                 },
503
504                 hideThese: function( errors ) {
505                         errors.not( this.containers ).text( "" );
506                         this.addWrapper( errors ).hide();
507                 },
508
509                 valid: function() {
510                         return this.size() === 0;
511                 },
512
513                 size: function() {
514                         return this.errorList.length;
515                 },
516
517                 focusInvalid: function() {
518                         if ( this.settings.focusInvalid ) {
519                                 try {
520                                         $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [])
521                                         .filter( ":visible" )
522                                         .focus()
523                                         // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
524                                         .trigger( "focusin" );
525                                 } catch ( e ) {
526                                         // ignore IE throwing errors when focusing hidden elements
527                                 }
528                         }
529                 },
530
531                 findLastActive: function() {
532                         var lastActive = this.lastActive;
533                         return lastActive && $.grep( this.errorList, function( n ) {
534                                 return n.element.name === lastActive.name;
535                         }).length === 1 && lastActive;
536                 },
537
538                 elements: function() {
539                         var validator = this,
540                                 rulesCache = {};
541
542                         // select all valid inputs inside the form (no submit or reset buttons)
543                         return $( this.currentForm )
544                         .find( "input, select, textarea" )
545                         .not( ":submit, :reset, :image, [disabled]" )
546                         .not( this.settings.ignore )
547                         .filter( function() {
548                                 if ( !this.name && validator.settings.debug && window.console ) {
549                                         console.error( "%o has no name assigned", this );
550                                 }
551
552                                 // select only the first element for each name, and only those with rules specified
553                                 if ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
554                                         return false;
555                                 }
556
557                                 rulesCache[ this.name ] = true;
558                                 return true;
559                         });
560                 },
561
562                 clean: function( selector ) {
563                         return $( selector )[ 0 ];
564                 },
565
566                 errors: function() {
567                         var errorClass = this.settings.errorClass.split( " " ).join( "." );
568                         return $( this.settings.errorElement + "." + errorClass, this.errorContext );
569                 },
570
571                 reset: function() {
572                         this.successList = [];
573                         this.errorList = [];
574                         this.errorMap = {};
575                         this.toShow = $( [] );
576                         this.toHide = $( [] );
577                         this.currentElements = $( [] );
578                 },
579
580                 prepareForm: function() {
581                         this.reset();
582                         this.toHide = this.errors().add( this.containers );
583                 },
584
585                 prepareElement: function( element ) {
586                         this.reset();
587                         this.toHide = this.errorsFor( element );
588                 },
589
590                 elementValue: function( element ) {
591                         var val,
592                                 $element = $( element ),
593                                 type = element.type;
594
595                         if ( type === "radio" || type === "checkbox" ) {
596                                 return $( "input[name='" + element.name + "']:checked" ).val();
597                         } else if ( type === "number" && typeof element.validity !== "undefined" ) {
598                                 return element.validity.badInput ? false : $element.val();
599                         }
600
601                         val = $element.val();
602                         if ( typeof val === "string" ) {
603                                 return val.replace(/\r/g, "" );
604                         }
605                         return val;
606                 },
607
608                 check: function( element ) {
609                         element = this.validationTargetFor( this.clean( element ) );
610
611                         var rules = $( element ).rules(),
612                                 rulesCount = $.map( rules, function( n, i ) {
613                                         return i;
614                                 }).length,
615                                 dependencyMismatch = false,
616                                 val = this.elementValue( element ),
617                                 result, method, rule;
618
619                         for ( method in rules ) {
620                                 rule = { method: method, parameters: rules[ method ] };
621                                 try {
622
623                                         result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
624
625                                         // if a method indicates that the field is optional and therefore valid,
626                                         // don't mark it as valid when there are no other rules
627                                         if ( result === "dependency-mismatch" && rulesCount === 1 ) {
628                                                 dependencyMismatch = true;
629                                                 continue;
630                                         }
631                                         dependencyMismatch = false;
632
633                                         if ( result === "pending" ) {
634                                                 this.toHide = this.toHide.not( this.errorsFor( element ) );
635                                                 return;
636                                         }
637
638                                         if ( !result ) {
639                                                 this.formatAndAdd( element, rule );
640                                                 return false;
641                                         }
642                                 } catch ( e ) {
643                                         if ( this.settings.debug && window.console ) {
644                                                 console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
645                                         }
646                                         throw e;
647                                 }
648                         }
649                         if ( dependencyMismatch ) {
650                                 return;
651                         }
652                         if ( this.objectLength( rules ) ) {
653                                 this.successList.push( element );
654                         }
655                         return true;
656                 },
657
658                 // return the custom message for the given element and validation method
659                 // specified in the element's HTML5 data attribute
660                 // return the generic message if present and no method specific message is present
661                 customDataMessage: function( element, method ) {
662                         return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() +
663                                 method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
664                 },
665
666                 // return the custom message for the given element name and validation method
667                 customMessage: function( name, method ) {
668                         var m = this.settings.messages[ name ];
669                         return m && ( m.constructor === String ? m : m[ method ]);
670                 },
671
672                 // return the first defined argument, allowing empty strings
673                 findDefined: function() {
674                         for ( var i = 0; i < arguments.length; i++) {
675                                 if ( arguments[ i ] !== undefined ) {
676                                         return arguments[ i ];
677                                 }
678                         }
679                         return undefined;
680                 },
681
682                 defaultMessage: function( element, method ) {
683                         return this.findDefined(
684                                 this.customMessage( element.name, method ),
685                                 this.customDataMessage( element, method ),
686                                 // title is never undefined, so handle empty string as undefined
687                                 !this.settings.ignoreTitle && element.title || undefined,
688                                 $.validator.messages[ method ],
689                                 "<strong>Warning: No message defined for " + element.name + "</strong>"
690                         );
691                 },
692
693                 formatAndAdd: function( element, rule ) {
694                         var message = this.defaultMessage( element, rule.method ),
695                                 theregex = /\$?\{(\d+)\}/g;
696                         if ( typeof message === "function" ) {
697                                 message = message.call( this, rule.parameters, element );
698                         } else if ( theregex.test( message ) ) {
699                                 message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
700                         }
701                         this.errorList.push({
702                                 message: message,
703                                 element: element,
704                                 method: rule.method
705                         });
706
707                         this.errorMap[ element.name ] = message;
708                         this.submitted[ element.name ] = message;
709                 },
710
711                 addWrapper: function( toToggle ) {
712                         if ( this.settings.wrapper ) {
713                                 toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
714                         }
715                         return toToggle;
716                 },
717
718                 defaultShowErrors: function() {
719                         var i, elements, error;
720                         for ( i = 0; this.errorList[ i ]; i++ ) {
721                                 error = this.errorList[ i ];
722                                 if ( this.settings.highlight ) {
723                                         this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
724                                 }
725                                 this.showLabel( error.element, error.message );
726                         }
727                         if ( this.errorList.length ) {
728                                 this.toShow = this.toShow.add( this.containers );
729                         }
730                         if ( this.settings.success ) {
731                                 for ( i = 0; this.successList[ i ]; i++ ) {
732                                         this.showLabel( this.successList[ i ] );
733                                 }
734                         }
735                         if ( this.settings.unhighlight ) {
736                                 for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
737                                         this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );
738                                 }
739                         }
740                         this.toHide = this.toHide.not( this.toShow );
741                         this.hideErrors();
742                         this.addWrapper( this.toShow ).show();
743                 },
744
745                 validElements: function() {
746                         return this.currentElements.not( this.invalidElements() );
747                 },
748
749                 invalidElements: function() {
750                         return $( this.errorList ).map(function() {
751                                 return this.element;
752                         });
753                 },
754
755                 showLabel: function( element, message ) {
756                         var place, group, errorID,
757                                 error = this.errorsFor( element ),
758                                 elementID = this.idOrName( element ),
759                                 describedBy = $( element ).attr( "aria-describedby" );
760                         if ( error.length ) {
761                                 // refresh error/success class
762                                 error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
763                                 // replace message on existing label
764                                 error.html( message );
765                         } else {
766                                 // create error element
767                                 error = $( "<" + this.settings.errorElement + ">" )
768                                         .attr( "id", elementID + "-error" )
769                                         .addClass( this.settings.errorClass )
770                                         .html( message || "" );
771
772                                 // Maintain reference to the element to be placed into the DOM
773                                 place = error;
774                                 if ( this.settings.wrapper ) {
775                                         // make sure the element is visible, even in IE
776                                         // actually showing the wrapped element is handled elsewhere
777                                         place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
778                                 }
779                                 if ( this.labelContainer.length ) {
780                                         this.labelContainer.append( place );
781                                 } else if ( this.settings.errorPlacement ) {
782                                         this.settings.errorPlacement( place, $( element ) );
783                                 } else {
784                                         place.insertAfter( element );
785                                 }
786
787                                 // Link error back to the element
788                                 if ( error.is( "label" ) ) {
789                                         // If the error is a label, then associate using 'for'
790                                         error.attr( "for", elementID );
791                                 } else if ( error.parents( "label[for='" + elementID + "']" ).length === 0 ) {
792                                         // If the element is not a child of an associated label, then it's necessary
793                                         // to explicitly apply aria-describedby
794
795                                         errorID = error.attr( "id" );
796                                         // Respect existing non-error aria-describedby
797                                         if ( !describedBy ) {
798                                                 describedBy = errorID;
799                                         } else if ( !describedBy.match( new RegExp( "\b" + errorID + "\b" ) ) ) {
800                                                 // Add to end of list if not already present
801                                                 describedBy += " " + errorID;
802                                         }
803                                         $( element ).attr( "aria-describedby", describedBy );
804
805                                         // If this element is grouped, then assign to all elements in the same group
806                                         group = this.groups[ element.name ];
807                                         if ( group ) {
808                                                 $.each( this.groups, function( name, testgroup ) {
809                                                         if ( testgroup === group ) {
810                                                                 $( "[name='" + name + "']", this.currentForm )
811                                                                         .attr( "aria-describedby", error.attr( "id" ) );
812                                                         }
813                                                 });
814                                         }
815                                 }
816                         }
817                         if ( !message && this.settings.success ) {
818                                 error.text( "" );
819                                 if ( typeof this.settings.success === "string" ) {
820                                         error.addClass( this.settings.success );
821                                 } else {
822                                         this.settings.success( error, element );
823                                 }
824                         }
825                         this.toShow = this.toShow.add( error );
826                 },
827
828                 errorsFor: function( element ) {
829                         var name = this.idOrName( element ),
830                                 describer = $( element ).attr( "aria-describedby" ),
831                                 selector = "label[for='" + name + "'], label[for='" + name + "'] *";
832                         // aria-describedby should directly reference the error element
833                         if ( describer ) {
834                                 selector = selector + ", #" + describer.replace( /\s+/g, ", #" );
835                         }
836                         return this
837                                 .errors()
838                                 .filter( selector );
839                 },
840
841                 idOrName: function( element ) {
842                         return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );
843                 },
844
845                 validationTargetFor: function( element ) {
846                         // if radio/checkbox, validate first element in group instead
847                         if ( this.checkable( element ) ) {
848                                 element = this.findByName( element.name ).not( this.settings.ignore )[ 0 ];
849                         }
850                         return element;
851                 },
852
853                 checkable: function( element ) {
854                         return ( /radio|checkbox/i ).test( element.type );
855                 },
856
857                 findByName: function( name ) {
858                         return $( this.currentForm ).find( "[name='" + name + "']" );
859                 },
860
861                 getLength: function( value, element ) {
862                         switch ( element.nodeName.toLowerCase() ) {
863                         case "select":
864                                 return $( "option:selected", element ).length;
865                         case "input":
866                                 if ( this.checkable( element ) ) {
867                                         return this.findByName( element.name ).filter( ":checked" ).length;
868                                 }
869                         }
870                         return value.length;
871                 },
872
873                 depend: function( param, element ) {
874                         return this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true;
875                 },
876
877                 dependTypes: {
878                         "boolean": function( param ) {
879                                 return param;
880                         },
881                         "string": function( param, element ) {
882                                 return !!$( param, element.form ).length;
883                         },
884                         "function": function( param, element ) {
885                                 return param( element );
886                         }
887                 },
888
889                 optional: function( element ) {
890                         var val = this.elementValue( element );
891                         return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch";
892                 },
893
894                 startRequest: function( element ) {
895                         if ( !this.pending[ element.name ] ) {
896                                 this.pendingRequest++;
897                                 this.pending[ element.name ] = true;
898                         }
899                 },
900
901                 stopRequest: function( element, valid ) {
902                         this.pendingRequest--;
903                         // sometimes synchronization fails, make sure pendingRequest is never < 0
904                         if ( this.pendingRequest < 0 ) {
905                                 this.pendingRequest = 0;
906                         }
907                         delete this.pending[ element.name ];
908                         if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
909                                 $( this.currentForm ).submit();
910                                 this.formSubmitted = false;
911                         } else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) {
912                                 $( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
913                                 this.formSubmitted = false;
914                         }
915                 },
916
917                 previousValue: function( element ) {
918                         return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
919                                 old: null,
920                                 valid: true,
921                                 message: this.defaultMessage( element, "remote" )
922                         });
923                 }
924
925         },
926
927         classRuleSettings: {
928                 required: { required: true },
929                 email: { email: true },
930                 url: { url: true },
931                 date: { date: true },
932                 dateISO: { dateISO: true },
933                 number: { number: true },
934                 digits: { digits: true },
935                 creditcard: { creditcard: true }
936         },
937
938         addClassRules: function( className, rules ) {
939                 if ( className.constructor === String ) {
940                         this.classRuleSettings[ className ] = rules;
941                 } else {
942                         $.extend( this.classRuleSettings, className );
943                 }
944         },
945
946         classRules: function( element ) {
947                 var rules = {},
948                         classes = $( element ).attr( "class" );
949
950                 if ( classes ) {
951                         $.each( classes.split( " " ), function() {
952                                 if ( this in $.validator.classRuleSettings ) {
953                                         $.extend( rules, $.validator.classRuleSettings[ this ]);
954                                 }
955                         });
956                 }
957                 return rules;
958         },
959
960         attributeRules: function( element ) {
961                 var rules = {},
962                         $element = $( element ),
963                         type = element.getAttribute( "type" ),
964                         method, value;
965
966                 for ( method in $.validator.methods ) {
967
968                         // support for <input required> in both html5 and older browsers
969                         if ( method === "required" ) {
970                                 value = element.getAttribute( method );
971                                 // Some browsers return an empty string for the required attribute
972                                 // and non-HTML5 browsers might have required="" markup
973                                 if ( value === "" ) {
974                                         value = true;
975                                 }
976                                 // force non-HTML5 browsers to return bool
977                                 value = !!value;
978                         } else {
979                                 value = $element.attr( method );
980                         }
981
982                         // convert the value to a number for number inputs, and for text for backwards compability
983                         // allows type="date" and others to be compared as strings
984                         if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
985                                 value = Number( value );
986                         }
987
988                         if ( value || value === 0 ) {
989                                 rules[ method ] = value;
990                         } else if ( type === method && type !== "range" ) {
991                                 // exception: the jquery validate 'range' method
992                                 // does not test for the html5 'range' type
993                                 rules[ method ] = true;
994                         }
995                 }
996
997                 // maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
998                 if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
999                         delete rules.maxlength;
1000                 }
1001
1002                 return rules;
1003         },
1004
1005         dataRules: function( element ) {
1006                 var method, value,
1007                         rules = {}, $element = $( element );
1008                 for ( method in $.validator.methods ) {
1009                         value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
1010                         if ( value !== undefined ) {
1011                                 rules[ method ] = value;
1012                         }
1013                 }
1014                 return rules;
1015         },
1016
1017         staticRules: function( element ) {
1018                 var rules = {},
1019                         validator = $.data( element.form, "validator" );
1020
1021                 if ( validator.settings.rules ) {
1022                         rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};
1023                 }
1024                 return rules;
1025         },
1026
1027         normalizeRules: function( rules, element ) {
1028                 // handle dependency check
1029                 $.each( rules, function( prop, val ) {
1030                         // ignore rule when param is explicitly false, eg. required:false
1031                         if ( val === false ) {
1032                                 delete rules[ prop ];
1033                                 return;
1034                         }
1035                         if ( val.param || val.depends ) {
1036                                 var keepRule = true;
1037                                 switch ( typeof val.depends ) {
1038                                 case "string":
1039                                         keepRule = !!$( val.depends, element.form ).length;
1040                                         break;
1041                                 case "function":
1042                                         keepRule = val.depends.call( element, element );
1043                                         break;
1044                                 }
1045                                 if ( keepRule ) {
1046                                         rules[ prop ] = val.param !== undefined ? val.param : true;
1047                                 } else {
1048                                         delete rules[ prop ];
1049                                 }
1050                         }
1051                 });
1052
1053                 // evaluate parameters
1054                 $.each( rules, function( rule, parameter ) {
1055                         rules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter;
1056                 });
1057
1058                 // clean number parameters
1059                 $.each([ "minlength", "maxlength" ], function() {
1060                         if ( rules[ this ] ) {
1061                                 rules[ this ] = Number( rules[ this ] );
1062                         }
1063                 });
1064                 $.each([ "rangelength", "range" ], function() {
1065                         var parts;
1066                         if ( rules[ this ] ) {
1067                                 if ( $.isArray( rules[ this ] ) ) {
1068                                         rules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ];
1069                                 } else if ( typeof rules[ this ] === "string" ) {
1070                                         parts = rules[ this ].replace(/[\[\]]/g, "" ).split( /[\s,]+/ );
1071                                         rules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ];
1072                                 }
1073                         }
1074                 });
1075
1076                 if ( $.validator.autoCreateRanges ) {
1077                         // auto-create ranges
1078                         if ( rules.min && rules.max ) {
1079                                 rules.range = [ rules.min, rules.max ];
1080                                 delete rules.min;
1081                                 delete rules.max;
1082                         }
1083                         if ( rules.minlength && rules.maxlength ) {
1084                                 rules.rangelength = [ rules.minlength, rules.maxlength ];
1085                                 delete rules.minlength;
1086                                 delete rules.maxlength;
1087                         }
1088                 }
1089
1090                 return rules;
1091         },
1092
1093         // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
1094         normalizeRule: function( data ) {
1095                 if ( typeof data === "string" ) {
1096                         var transformed = {};
1097                         $.each( data.split( /\s/ ), function() {
1098                                 transformed[ this ] = true;
1099                         });
1100                         data = transformed;
1101                 }
1102                 return data;
1103         },
1104
1105         // http://jqueryvalidation.org/jQuery.validator.addMethod/
1106         addMethod: function( name, method, message ) {
1107                 $.validator.methods[ name ] = method;
1108                 $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
1109                 if ( method.length < 3 ) {
1110                         $.validator.addClassRules( name, $.validator.normalizeRule( name ) );
1111                 }
1112         },
1113
1114         methods: {
1115
1116                 // http://jqueryvalidation.org/required-method/
1117                 required: function( value, element, param ) {
1118                         // check if dependency is met
1119                         if ( !this.depend( param, element ) ) {
1120                                 return "dependency-mismatch";
1121                         }
1122                         if ( element.nodeName.toLowerCase() === "select" ) {
1123                                 // could be an array for select-multiple or a string, both are fine this way
1124                                 var val = $( element ).val();
1125                                 return val && val.length > 0;
1126                         }
1127                         if ( this.checkable( element ) ) {
1128                                 return this.getLength( value, element ) > 0;
1129                         }
1130                         return $.trim( value ).length > 0;
1131                 },
1132
1133                 // http://jqueryvalidation.org/email-method/
1134                 email: function( value, element ) {
1135                         // From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
1136                         // Retrieved 2014-01-14
1137                         // If you have a problem with this implementation, report a bug against the above spec
1138                         // Or use custom methods to implement your own email validation
1139                         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 );
1140                 },
1141
1142                 // http://jqueryvalidation.org/url-method/
1143                 url: function( value, element ) {
1144                         // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1145                         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 );
1146                 },
1147
1148                 // http://jqueryvalidation.org/date-method/
1149                 date: function( value, element ) {
1150                         return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
1151                 },
1152
1153                 // http://jqueryvalidation.org/dateISO-method/
1154                 dateISO: function( value, element ) {
1155                         return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
1156                 },
1157
1158                 // http://jqueryvalidation.org/number-method/
1159                 number: function( value, element ) {
1160                         return this.optional( element ) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
1161                 },
1162
1163                 // http://jqueryvalidation.org/digits-method/
1164                 digits: function( value, element ) {
1165                         return this.optional( element ) || /^\d+$/.test( value );
1166                 },
1167
1168                 // http://jqueryvalidation.org/creditcard-method/
1169                 // based on http://en.wikipedia.org/wiki/Luhn/
1170                 creditcard: function( value, element ) {
1171                         if ( this.optional( element ) ) {
1172                                 return "dependency-mismatch";
1173                         }
1174                         // accept only spaces, digits and dashes
1175                         if ( /[^0-9 \-]+/.test( value ) ) {
1176                                 return false;
1177                         }
1178                         var nCheck = 0,
1179                                 nDigit = 0,
1180                                 bEven = false,
1181                                 n, cDigit;
1182
1183                         value = value.replace( /\D/g, "" );
1184
1185                         // Basing min and max length on
1186                         // http://developer.ean.com/general_info/Valid_Credit_Card_Types
1187                         if ( value.length < 13 || value.length > 19 ) {
1188                                 return false;
1189                         }
1190
1191                         for ( n = value.length - 1; n >= 0; n--) {
1192                                 cDigit = value.charAt( n );
1193                                 nDigit = parseInt( cDigit, 10 );
1194                                 if ( bEven ) {
1195                                         if ( ( nDigit *= 2 ) > 9 ) {
1196                                                 nDigit -= 9;
1197                                         }
1198                                 }
1199                                 nCheck += nDigit;
1200                                 bEven = !bEven;
1201                         }
1202
1203                         return ( nCheck % 10 ) === 0;
1204                 },
1205
1206                 // http://jqueryvalidation.org/minlength-method/
1207                 minlength: function( value, element, param ) {
1208                         var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
1209                         return this.optional( element ) || length >= param;
1210                 },
1211
1212                 // http://jqueryvalidation.org/maxlength-method/
1213                 maxlength: function( value, element, param ) {
1214                         var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
1215                         return this.optional( element ) || length <= param;
1216                 },
1217
1218                 // http://jqueryvalidation.org/rangelength-method/
1219                 rangelength: function( value, element, param ) {
1220                         var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
1221                         return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
1222                 },
1223
1224                 // http://jqueryvalidation.org/min-method/
1225                 min: function( value, element, param ) {
1226                         return this.optional( element ) || value >= param;
1227                 },
1228
1229                 // http://jqueryvalidation.org/max-method/
1230                 max: function( value, element, param ) {
1231                         return this.optional( element ) || value <= param;
1232                 },
1233
1234                 // http://jqueryvalidation.org/range-method/
1235                 range: function( value, element, param ) {
1236                         return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
1237                 },
1238
1239                 // http://jqueryvalidation.org/equalTo-method/
1240                 equalTo: function( value, element, param ) {
1241                         // bind to the blur event of the target in order to revalidate whenever the target field is updated
1242                         // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1243                         var target = $( param );
1244                         if ( this.settings.onfocusout ) {
1245                                 target.unbind( ".validate-equalTo" ).bind( "blur.validate-equalTo", function() {
1246                                         $( element ).valid();
1247                                 });
1248                         }
1249                         return value === target.val();
1250                 },
1251
1252                 // http://jqueryvalidation.org/remote-method/
1253                 remote: function( value, element, param ) {
1254                         if ( this.optional( element ) ) {
1255                                 return "dependency-mismatch";
1256                         }
1257
1258                         var previous = this.previousValue( element ),
1259                                 validator, data;
1260
1261                         if (!this.settings.messages[ element.name ] ) {
1262                                 this.settings.messages[ element.name ] = {};
1263                         }
1264                         previous.originalMessage = this.settings.messages[ element.name ].remote;
1265                         this.settings.messages[ element.name ].remote = previous.message;
1266
1267                         param = typeof param === "string" && { url: param } || param;
1268
1269                         if ( previous.old === value ) {
1270                                 return previous.valid;
1271                         }
1272
1273                         previous.old = value;
1274                         validator = this;
1275                         this.startRequest( element );
1276                         data = {};
1277                         data[ element.name ] = value;
1278                         $.ajax( $.extend( true, {
1279                                 url: param,
1280                                 mode: "abort",
1281                                 port: "validate" + element.name,
1282                                 dataType: "json",
1283                                 data: data,
1284                                 context: validator.currentForm,
1285                                 success: function( response ) {
1286                                         var valid = response === true || response === "true",
1287                                                 errors, message, submitted;
1288
1289                                         validator.settings.messages[ element.name ].remote = previous.originalMessage;
1290                                         if ( valid ) {
1291                                                 submitted = validator.formSubmitted;
1292                                                 validator.prepareElement( element );
1293                                                 validator.formSubmitted = submitted;
1294                                                 validator.successList.push( element );
1295                                                 delete validator.invalid[ element.name ];
1296                                                 validator.showErrors();
1297                                         } else {
1298                                                 errors = {};
1299                                                 message = response || validator.defaultMessage( element, "remote" );
1300                                                 errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message;
1301                                                 validator.invalid[ element.name ] = true;
1302                                                 validator.showErrors( errors );
1303                                         }
1304                                         previous.valid = valid;
1305                                         validator.stopRequest( element, valid );
1306                                 }
1307                         }, param ) );
1308                         return "pending";
1309                 }
1310
1311         }
1312
1313 });
1314
1315 $.format = function deprecated() {
1316         throw "$.format has been deprecated. Please use $.validator.format instead.";
1317 };
1318
1319 // ajax mode: abort
1320 // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1321 // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1322
1323 var pendingRequests = {},
1324         ajax;
1325 // Use a prefilter if available (1.5+)
1326 if ( $.ajaxPrefilter ) {
1327         $.ajaxPrefilter(function( settings, _, xhr ) {
1328                 var port = settings.port;
1329                 if ( settings.mode === "abort" ) {
1330                         if ( pendingRequests[port] ) {
1331                                 pendingRequests[port].abort();
1332                         }
1333                         pendingRequests[port] = xhr;
1334                 }
1335         });
1336 } else {
1337         // Proxy ajax
1338         ajax = $.ajax;
1339         $.ajax = function( settings ) {
1340                 var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
1341                         port = ( "port" in settings ? settings : $.ajaxSettings ).port;
1342                 if ( mode === "abort" ) {
1343                         if ( pendingRequests[port] ) {
1344                                 pendingRequests[port].abort();
1345                         }
1346                         pendingRequests[port] = ajax.apply(this, arguments);
1347                         return pendingRequests[port];
1348                 }
1349                 return ajax.apply(this, arguments);
1350         };
1351 }
1352
1353 // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1354 // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1355
1356 $.extend($.fn, {
1357         validateDelegate: function( delegate, type, handler ) {
1358                 return this.bind(type, function( event ) {
1359                         var target = $(event.target);
1360                         if ( target.is(delegate) ) {
1361                                 return handler.apply(target, arguments);
1362                         }
1363                 });
1364         }
1365 });
1366
1367 }));