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