Subversion Repositories Integrator Subversion

Rev

Details | Last modification | View Log | RSS feed

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