home *** CD-ROM | disk | FTP | other *** search
/ 61.19.244.139 / 61.19.244.139.zip / 61.19.244.139 / wsCompulTransfer / cp2013 / Scripts / jquery.validate.js < prev    next >
Text File  |  2013-06-07  |  38KB  |  1,208 lines

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