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