topical media & game development

talk show tell print

mobile-application-03-MVCDerbyService-MVCDerbyService-Scripts-jquery.validate-vsdoc.js / js



  /*
  * This file has been commented to support Visual Studio Intellisense.
  * You should not use this file at runtime inside the browser--it is only
  * intended to be used only for design-time IntelliSense.  Please use the
  * standard jQuery library for all production use.
  *
  * Comment version: 1.8
  */
  
  /*
  * Note: While Microsoft is not the author of this file, Microsoft is
  * offering you a license subject to the terms of the Microsoft Software
  * License Terms for Microsoft ASP.NET Model View Controller 3.
  * Microsoft reserves all other rights. The notices below are provided
  * for informational purposes only and are not the license terms under
  * which Microsoft distributed this file.
  *
  * jQuery validation plugin 1.8.0
  *
  * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
  * http://docs.jquery.com/Plugins/Validation
  *
  * Copyright (c) 2006 - 2011 Jörn Zaefferer
  *
  */
  
  (function() {
  
  .extend(.fn, {
          // http://docs.jquery.com/Plugins/Validation/validate
  	validate: function( options ) {
  
<summary> Validates the selected form. This method sets up event handlers for submit, focus, keyup, blur and click to trigger validation of the entire form or individual elements. Each one can be disabled, see the onxxx options (onsubmit, onfocusout, onkeyup, onclick). focusInvalid focuses elements when submitting a invalid form. </summary> <param name="options" type="Options"> A set of key/value pairs that configure the validate. All options are optional. </param> <returns type="Validator" />

                  // if nothing is selected, return nothing; can't chain anyway
                  if (!this.length) {
                          options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );
                          return;
                  }
  
                  // check if a validator for this form was already created
                  var validator = .data(this[0], 'validator');
                  if ( validator ) {
                          return validator;
                  }
                  
                  validator = new .validator( options, this[0] );
                  .data(this[0], 'validator', validator); 
                  
                  if ( validator.settings.onsubmit ) {
                  
                          // allow suppresing validation by adding a cancel class to the submit button
                          this.find("input, button").filter(".cancel").click(function() {
                                  validator.cancelSubmit = true;
                          });
                          
                          // when a submitHandler is used, capture the submitting button
                          if (validator.settings.submitHandler) {
                                  this.find("input, button").filter(":submit").click(function() {
                                          validator.submitButton = this;
                                  });
                          }
                  
                          // validate the form on submit
                          this.submit( function( event ) {
                                  if ( validator.settings.debug )
                                          // prevent form submit to be able to see console output
                                          event.preventDefault();
                                          
                                  function handle() {
                                          if ( validator.settings.submitHandler ) {
                                                  if (validator.submitButton) {
                                                          // insert a hidden input as a replacement for the missing submit button
                                                          var hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
                                                  }
                                                  validator.settings.submitHandler.call( validator, validator.currentForm );
                                                  if (validator.submitButton) {
                                                          // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
                                                          hidden.remove();
                                                  }
                                                  return false;
                                          }
                                          return true;
                                  }
                                          
                                  // prevent submit for invalid forms or custom submit handlers
                                  if ( validator.cancelSubmit ) {
                                          validator.cancelSubmit = false;
                                          return handle();
                                  }
                                  if ( validator.form() ) {
                                          if ( validator.pendingRequest ) {
                                                  validator.formSubmitted = true;
                                                  return false;
                                          }
                                          return handle();
                                  } else {
                                          validator.focusInvalid();
                                          return false;
                                  }
                          });
                  }
                  
                  return validator;
          },
          // http://docs.jquery.com/Plugins/Validation/valid
  	valid: function() {
  
<summary> Checks if the selected form is valid or if all selected elements are valid. validate() needs to be called on the form before checking it using this method. </summary> <returns type="Boolean" />

          if ( $(this[0]).is('form')) {
              return this.validate().form();
          } else {
              var valid = true;
              var validator = $(this[0].form).validate();
              this.each(function() {
                                  valid &= validator.element(this);
              });
              return valid;
          }
      },
          // attributes: space seperated list of attributes to retrieve and remove
          removeAttrs: function(attributes) {
  
<summary> Remove the specified attributes from the first matched element and return them. </summary> <param name="attributes" type="String"> A space-seperated list of attribute names to remove. </param> <returns type="" />

                  var result = {},
                          element = this;
                  .each(attributes.split(/\s/), function(index, value) {
                          result[value] = element.attr(value);
                          element.removeAttr(value);
                  });
                  return result;
          },
          // http://docs.jquery.com/Plugins/Validation/rules
  	rules: function(command, argument) {
  
<summary> Return the validations rules for the first selected element. </summary> <param name="command" type="String"> Can be either "add" or "remove". </param> <param name="argument" type=""> A list of rules to add or remove. </param> <returns type="" />

                  var element = this[0];
                  
                  if (command) {
                          var settings = .data(element.form, 'validator').settings;
                          var staticRules = settings.rules;
                          var existingRules = .validator.staticRules(element);
                          switch(command) {
                          case "add":
                                  .extend(existingRules, .validator.normalizeRule(argument));
                                  staticRules[element.name] = existingRules;
                                  if (argument.messages)
                                          settings.messages[element.name] = .extend( settings.messages[element.name], argument.messages );
                                  break;
                          case "remove":
                                  if (!argument) {
                                          delete staticRules[element.name];
                                          return existingRules;
                                  }
                                  var filtered = {};
                                  .each(argument.split(/\s/), function(index, method) {
                                          filtered[method] = existingRules[method];
                                          delete existingRules[method];
                                  });
                                  return filtered;
                          }
                  }
                  
                  var data = .validator.normalizeRules(
                  .extend(
                          {},
                          .validator.metadataRules(element),
                          .validator.classRules(element),
                          .validator.attributeRules(element),
                          .validator.staticRules(element)
                  ), element);
                  
                  // make sure required is at front
                  if (data.required) {
                          var param = data.required;
                          delete data.required;
                          data = .extend({required: param}, data);
                  }
                  
                  return data;
          }
  });
  
  // Custom selectors
  .extend(.expr[":"], {
          // http://docs.jquery.com/Plugins/Validation/blank
  	blank: function(a) {return !.trim("" + a.value);},
          // http://docs.jquery.com/Plugins/Validation/filled
  	filled: function(a) {return !!.trim("" + a.value);},
          // http://docs.jquery.com/Plugins/Validation/unchecked
  	unchecked: function(a) {return !a.checked;}
  });
  
  // constructor for validator
  .validator = function( options, form ) {
          this.settings = .extend( true, {}, .validator.defaults, options );
          this.currentForm = form;
          this.init();
  };
  
  .validator.format = function(source, params) {
  
<summary> Replaces {n} placeholders with arguments. One or more arguments can be passed, in addition to the string template itself, to insert into the string. </summary> <param name="source" type="String"> The string to format. </param> <param name="params" type="String"> The first argument to insert, or an array of Strings to insert </param> <returns type="String" />

          if ( arguments.length == 1 ) 
                  return function() {
                          var args = .makeArray(arguments);
                          args.unshift(source);
                          return .validator.format.apply( this, args );
                  };
          if ( arguments.length > 2 && params.constructor != Array  ) {
                  params = .makeArray(arguments).slice(1);
          }
          if ( params.constructor != Array ) {
                  params = [ params ];
          }
          .each(params, function(i, n) {
                  source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
          });
          return source;
  };
  
  .extend(.validator, {
          
          defaults: {
                  messages: {},
                  groups: {},
                  rules: {},
                  errorClass: "error",
                  validClass: "valid",
                  errorElement: "label",
                  focusInvalid: true,
                  errorContainer: $( [] ),
                  errorLabelContainer: $( [] ),
                  onsubmit: true,
                  ignore: [],
                  ignoreTitle: false,
                  onfocusin: function(element) {
                          this.lastActive = element;
                                  
                          // hide error label and remove error class on focus if enabled
                          if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
                                  this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
                                  this.addWrapper(this.errorsFor(element)).hide();
                          }
                  },
                  onfocusout: function(element) {
                          if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
                                  this.element(element);
                          }
                  },
                  onkeyup: function(element) {
                          if ( element.name in this.submitted || element == this.lastElement ) {
                                  this.element(element);
                          }
                  },
                  onclick: function(element) {
                          // click on selects, radiobuttons and checkboxes
                          if ( element.name in this.submitted )
                                  this.element(element);
                          // or option elements, check parent select in that case
                          else if (element.parentNode.name in this.submitted)
                                  this.element(element.parentNode);
                  },
                  highlight: function( element, errorClass, validClass ) {
                          element.addClass(errorClass).removeClass(validClass);
                  },
                  unhighlight: function( element, errorClass, validClass ) {
                          element.removeClass(errorClass).addClass(validClass);
                  }
          },
  
          // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
  	setDefaults: function(settings) {
  
<summary> Modify default settings for validation. Accepts everything that Plugins/Validation/validate accepts. </summary> <param name="settings" type="Options"> Options to set as default. </param> <returns type="undefined" />

                  .extend( .validator.defaults, settings );
          },
  
          messages: {
                  required: "This field is required.",
                  remote: "Please fix this field.",
                  email: "Please enter a valid email address.",
                  url: "Please enter a valid URL.",
                  date: "Please enter a valid date.",
                  dateISO: "Please enter a valid date (ISO).",
                  number: "Please enter a valid number.",
                  digits: "Please enter only digits.",
                  creditcard: "Please enter a valid credit card number.",
                  equalTo: "Please enter the same value again.",
                  accept: "Please enter a value with a valid extension.",
                  maxlength: .validator.format("Please enter no more than {0} characters."),
                  minlength: .validator.format("Please enter at least {0} characters."),
                  rangelength: .validator.format("Please enter a value between {0} and {1} characters long."),
                  range: .validator.format("Please enter a value between {0} and {1}."),
                  max: .validator.format("Please enter a value less than or equal to {0}."),
                  min: .validator.format("Please enter a value greater than or equal to {0}.")
          },
          
          autoCreateRanges: false,
          
          prototype: {
                  
                  init: function() {
                          this.labelContainer = $(this.settings.errorLabelContainer);
                          this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
                          this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
                          this.submitted = {};
                          this.valueCache = {};
                          this.pendingRequest = 0;
                          this.pending = {};
                          this.invalid = {};
                          this.reset();
                          
                          var groups = (this.groups = {});
                          .each(this.settings.groups, function(key, value) {
                                  .each(value.split(/\s/), function(index, name) {
                                          groups[name] = key;
                                  });
                          });
                          var rules = this.settings.rules;
                          .each(rules, function(key, value) {
                                  rules[key] = .validator.normalizeRule(value);
                          });
                          
                          function delegate(event) {
                                  var validator = .data(this[0].form, "validator"),
                                          eventType = "on" + event.type.replace(/^validate/, "");
                                  validator.settings[eventType] && validator.settings[eventType].call(validator, this[0] );
                          }
                          $(this.currentForm)
                                  .validateDelegate(":text, :password, :file, select, textarea", "focusin focusout keyup", delegate)
                                  .validateDelegate(":radio, :checkbox, select, option", "click", delegate);
  
                          if (this.settings.invalidHandler)
                                  $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
                  },
  
                  // http://docs.jquery.com/Plugins/Validation/Validator/form
  		form: function() {
  
<summary> Validates the form, returns true if it is valid, false otherwise. This behaves as a normal submit event, but returns the result. </summary> <returns type="Boolean" />

                          this.checkForm();
                          .extend(this.submitted, this.errorMap);
                          this.invalid = .extend({}, this.errorMap);
                          if (!this.valid())
                                  $(this.currentForm).triggerHandler("invalid-form", [this]);
                          this.showErrors();
                          return this.valid();
                  },
                  
                  checkForm: function() {
                          this.prepareForm();
                          for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
                                  this.check( elements[i] );
                          }
                          return this.valid(); 
                  },
                  
                  // http://docs.jquery.com/Plugins/Validation/Validator/element
  		element: function( element ) {
  
<summary> Validates a single element, returns true if it is valid, false otherwise. This behaves as validation on blur or keyup, but returns the result. </summary> <param name="element" type="Selector"> An element to validate, must be inside the validated form. </param> <returns type="Boolean" />

                          element = this.clean( element );
                          this.lastElement = element;
                          this.prepareElement( element );
                          this.currentElements = element;
                          var result = this.check( element );
                          if ( result ) {
                                  delete this.invalid[element.name];
                          } else {
                                  this.invalid[element.name] = true;
                          }
                          if ( !this.numberOfInvalids() ) {
                                  // Hide error containers on last error
                                  this.toHide = this.toHide.add( this.containers );
                          }
                          this.showErrors();
                          return result;
                  },
  
                  // http://docs.jquery.com/Plugins/Validation/Validator/showErrors
  		showErrors: function(errors) {
  
<summary> Show the specified messages. Keys have to refer to the names of elements, values are displayed for those elements, using the configured error placement. </summary> <param name="errors" type="Object"> One or more key/value pairs of input names and messages. </param> <returns type="undefined" />

                          if(errors) {
                                  // add items to error list and map
                                  .extend( this.errorMap, errors );
                                  this.errorList = [];
                                  for ( var name in errors ) {
                                          this.errorList.push({
                                                  message: errors[name],
                                                  element: this.findByName(name)[0]
                                          });
                                  }
                                  // remove items from success list
                                  this.successList = .grep( this.successList, function(element) {
                                          return !(element.name in errors);
                                  });
                          }
                          this.settings.showErrors
                                  ? this.settings.showErrors.call( this, this.errorMap, this.errorList )
                                  : this.defaultShowErrors();
                  },
                  
                  // http://docs.jquery.com/Plugins/Validation/Validator/resetForm
  		resetForm: function() {
  
<summary> Resets the controlled form. Resets input fields to their original value (requires form plugin), removes classes indicating invalid elements and hides error messages. </summary> <returns type="undefined" />

                          if ( .fn.resetForm )
                                  $( this.currentForm ).resetForm();
                          this.submitted = {};
                          this.prepareForm();
                          this.hideErrors();
                          this.elements().removeClass( this.settings.errorClass );
                  },
                  
                  numberOfInvalids: function() {
  
<summary> Returns the number of invalid fields. This depends on the internal validator state. It covers all fields only after validating the complete form (on submit or via $("form").valid()). After validating a single element, only that element is counted. Most useful in combination with the invalidHandler-option. </summary> <returns type="Number" />

                          return this.objectLength(this.invalid);
                  },
                  
                  objectLength: function( obj ) {
                          var count = 0;
                          for ( var i in obj )
                                  count++;
                          return count;
                  },
                  
                  hideErrors: function() {
                          this.addWrapper( this.toHide ).hide();
                  },
                  
                  valid: function() {
                          return this.size() == 0;
                  },
                  
                  size: function() {
                          return this.errorList.length;
                  },
                  
                  focusInvalid: function() {
                          if( this.settings.focusInvalid ) {
                                  try {
                                          $(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
                                          .filter(":visible")
                                          .focus()
                                          // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
                                          .trigger("focusin");
                                  } catch(e) {
                                          // ignore IE throwing errors when focusing hidden elements
                                  }
                          }
                  },
                  
                  findLastActive: function() {
                          var lastActive = this.lastActive;
                          return lastActive && .grep(this.errorList, function(n) {
                                  return n.element.name == lastActive.name;
                          }).length == 1 && lastActive;
                  },
                  
                  elements: function() {
                          var validator = this,
                                  rulesCache = {};
                          
                          // select all valid inputs inside the form (no submit or reset buttons)
                          // workaround Query([]).add until http://dev.jquery.com/ticket/2114 is solved
                          return $([]).add(this.currentForm.elements)
                          .filter(":input")
                          .not(":submit, :reset, :image, [disabled]")
                          .not( this.settings.ignore )
                          .filter(function() {
                                  !this.name && validator.settings.debug && window.console && console.error( "\%o has no name assigned", this);
                          
                                  // select only the first element for each name, and only those with rules specified
                                  if ( this.name in rulesCache || !validator.objectLength(this.rules()) )
                                          return false;
                                  
                                  rulesCache[this.name] = true;
                                  return true;
                          });
                  },
                  
                  clean: function( selector ) {
                          return $( selector )[0];
                  },
                  
                  errors: function() {
                          return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );
                  },
                  
                  reset: function() {
                          this.successList = [];
                          this.errorList = [];
                          this.errorMap = {};
                          this.toShow = $([]);
                          this.toHide = $([]);
                          this.currentElements = $([]);
                  },
                  
                  prepareForm: function() {
                          this.reset();
                          this.toHide = this.errors().add( this.containers );
                  },
                  
                  prepareElement: function( element ) {
                          this.reset();
                          this.toHide = this.errorsFor(element);
                  },
          
                  check: function( element ) {
                          element = this.clean( element );
                          
                          // if radio/checkbox, validate first element in group instead
                          if (this.checkable(element)) {
                              element = this.findByName(element.name).not(this.settings.ignore)[0];
                          }
                          
                          var rules = element.rules();
                          var dependencyMismatch = false;
                          for (var method in rules) {
                                  var rule = { method: method, parameters: rules[method] };
                                  try {
                                          var result = .validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters );
                                          
                                          // if a method indicates that the field is optional and therefore valid,
                                          // don't mark it as valid when there are no other rules
                                          if ( result == "dependency-mismatch" ) {
                                                  dependencyMismatch = true;
                                                  continue;
                                          }
                                          dependencyMismatch = false;
                                          
                                          if ( result == "pending" ) {
                                                  this.toHide = this.toHide.not( this.errorsFor(element) );
                                                  return;
                                          }
                                          
                                          if( !result ) {
                                                  this.formatAndAdd( element, rule );
                                                  return false;
                                          }
                                  } catch(e) {
                                          this.settings.debug && window.console && console.log("exception occured when checking element " + element.id
                                                   + ", check the '" + rule.method + "' method", e);
                                          throw e;
                                  }
                          }
                          if (dependencyMismatch)
                                  return;
                          if ( this.objectLength(rules) )
                                  this.successList.push(element);
                          return true;
                  },
                  
                  // return the custom message for the given element and validation method
                  // specified in the element's "messages" metadata
                  customMetaMessage: function(element, method) {
                          if (!.metadata)
                                  return;
                          
                          var meta = this.settings.meta
                                  ? element.metadata()[this.settings.meta]
                                  : element.metadata();
                          
                          return meta && meta.messages && meta.messages[method];
                  },
                  
                  // return the custom message for the given element name and validation method
                  customMessage: function( name, method ) {
                          var m = this.settings.messages[name];
                          return m && (m.constructor == String
                                  ? m
                                  : m[method]);
                  },
                  
                  // return the first defined argument, allowing empty strings
                  findDefined: function() {
                          for(var i = 0; i < arguments.length; i++) {
                                  if (arguments[i] !== undefined)
                                          return arguments[i];
                          }
                          return undefined;
                  },
                  
                  defaultMessage: function( element, method) {
                          return this.findDefined(
                                  this.customMessage( element.name, method ),
                                  this.customMetaMessage( element, method ),
                                  // title is never undefined, so handle empty string as undefined
                                  !this.settings.ignoreTitle && element.title || undefined,
                                  .validator.messages[method],
                                  "<strong>Warning: No message defined for " + element.name + "</strong>"
                          );
                  },
                  
                  formatAndAdd: function( element, rule ) {
                          var message = this.defaultMessage( element, rule.method ),
                                  theregex = /$?\{(\d+)\}/g;
                          if ( typeof message == "function" ) {
                                  message = message.call(this, rule.parameters, element);
                          } else if (theregex.test(message)) {
                                  message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters);
                          }                        
                          this.errorList.push({
                                  message: message,
                                  element: element
                          });
                          
                          this.errorMap[element.name] = message;
                          this.submitted[element.name] = message;
                  },
                  
                  addWrapper: function(toToggle) {
                          if ( this.settings.wrapper )
                                  toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
                          return toToggle;
                  },
                  
                  defaultShowErrors: function() {
                          for ( var i = 0; this.errorList[i]; i++ ) {
                                  var error = this.errorList[i];
                                  this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
                                  this.showLabel( error.element, error.message );
                          }
                          if( this.errorList.length ) {
                                  this.toShow = this.toShow.add( this.containers );
                          }
                          if (this.settings.success) {
                                  for ( var i = 0; this.successList[i]; i++ ) {
                                          this.showLabel( this.successList[i] );
                                  }
                          }
                          if (this.settings.unhighlight) {
                                  for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
                                          this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
                                  }
                          }
                          this.toHide = this.toHide.not( this.toShow );
                          this.hideErrors();
                          this.addWrapper( this.toShow ).show();
                  },
                  
                  validElements: function() {
                          return this.currentElements.not(this.invalidElements());
                  },
                  
                  invalidElements: function() {
                          return $(this.errorList).map(function() {
                                  return this.element;
                          });
                  },
                  
                  showLabel: function(element, message) {
                          var label = this.errorsFor( element );
                          if ( label.length ) {
                                  // refresh error/success class
                                  label.removeClass().addClass( this.settings.errorClass );
                          
                                  // check if we have a generated label, replace the message then
                                  label.attr("generated") && label.html(message);
                          } else {
                                  // create label
                                  label = $("<" + this.settings.errorElement + "/>")
                                          .attr({"for":  this.idOrName(element), generated: true})
                                          .addClass(this.settings.errorClass)
                                          .html(message || "");
                                  if ( this.settings.wrapper ) {
                                          // make sure the element is visible, even in IE
                                          // actually showing the wrapped element is handled elsewhere
                                          label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
                                  }
                                  if ( !this.labelContainer.append(label).length )
                                          this.settings.errorPlacement
                                                  ? this.settings.errorPlacement(label, element )
                                                  : label.insertAfter(element);
                          }
                          if ( !message && this.settings.success ) {
                                  label.text("");
                                  typeof this.settings.success == "string"
                                          ? label.addClass( this.settings.success )
                                          : this.settings.success( label );
                          }
                          this.toShow = this.toShow.add(label);
                  },
                  
                  errorsFor: function(element) {
                          var name = this.idOrName(element);
                      return this.errors().filter(function() {
                                  return this.attr('for') == name;
                          });
                  },
                  
                  idOrName: function(element) {
                          return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
                  },
  
                  checkable: function( element ) {
                          return /radio|checkbox/i.test(element.type);
                  },
                  
                  findByName: function( name ) {
                          // select by name and filter by form for performance over form.find("[name=...]")
                          var form = this.currentForm;
                          return $(document.getElementsByName(name)).map(function(index, element) {
                                  return element.form == form && element.name == name && element  || null;
                          });
                  },
                  
                  getLength: function(value, element) {
                          switch( element.nodeName.toLowerCase() ) {
                          case 'select':
                                  return $("option:selected", element).length;
                          case 'input':
                                  if( this.checkable( element) )
                                          return this.findByName(element.name).filter(':checked').length;
                          }
                          return value.length;
                  },
          
                  depend: function(param, element) {
                          return this.dependTypes[typeof param]
                                  ? this.dependTypes[typeof param](param, element)
                                  : true;
                  },
          
                  dependTypes: {
                          "boolean": function(param, element) {
                                  return param;
                          },
                          "string": function(param, element) {
                                  return !!$(param, element.form).length;
                          },
                          "function": function(param, element) {
                                  return param(element);
                          }
                  },
                  
                  optional: function(element) {
                          return !.validator.methods.required.call(this, .trim(element.value), element) && "dependency-mismatch";
                  },
                  
                  startRequest: function(element) {
                          if (!this.pending[element.name]) {
                                  this.pendingRequest++;
                                  this.pending[element.name] = true;
                          }
                  },
                  
                  stopRequest: function(element, valid) {
                          this.pendingRequest--;
                          // sometimes synchronization fails, make sure pendingRequest is never < 0
                          if (this.pendingRequest < 0)
                                  this.pendingRequest = 0;
                          delete this.pending[element.name];
                          if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {
                                  $(this.currentForm).submit();
                                  this.formSubmitted = false;
                          } else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
                                  $(this.currentForm).triggerHandler("invalid-form", [this]);
                                  this.formSubmitted = false;
                          }
                  },
                  
                  previousValue: function(element) {
                          return .data(element, "previousValue") || .data(element, "previousValue", {
                                  old: null,
                                  valid: true,
                                  message: this.defaultMessage( element, "remote" )
                          });
                  }
                  
          },
          
          classRuleSettings: {
                  required: {required: true},
                  email: {email: true},
                  url: {url: true},
                  date: {date: true},
                  dateISO: {dateISO: true},
                  dateDE: {dateDE: true},
                  number: {number: true},
                  numberDE: {numberDE: true},
                  digits: {digits: true},
                  creditcard: {creditcard: true}
          },
          
          addClassRules: function(className, rules) {
  
<summary> Add a compound class method - useful to refactor common combinations of rules into a single class. </summary> <param name="name" type="String"> The name of the class rule to add </param> <param name="rules" type="Options"> The compound rules </param> <returns type="undefined" />

                  className.constructor == String ?
                          this.classRuleSettings[className] = rules :
                          .extend(this.classRuleSettings, className);
          },
          
          classRules: function(element) {
                  var rules = {};
                  var classes = element.attr('class');
                  classes && .each(classes.split(' '), function() {
                          if (this in .validator.classRuleSettings) {
                                  .extend(rules, .validator.classRuleSettings[this]);
                          }
                  });
                  return rules;
          },
          
          attributeRules: function(element) {
                  var rules = {};
                  var element = element;
  
                  for (var method in .validator.methods) {
                          var value = element.attr(method);
                          if (value) {
                                  rules[method] = value;
                          }
                  }
                  
                  // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
                  if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
                          delete rules.maxlength;
                  }
                  
                  return rules;
          },
          
          metadataRules: function(element) {
                  if (!.metadata) return {};
                  
                  var meta = .data(element.form, 'validator').settings.meta;
                  return meta ?
                          element.metadata()[meta] :
                          element.metadata();
          },
          
          staticRules: function(element) {
                  var rules = {};
                  var validator = .data(element.form, 'validator');
                  if (validator.settings.rules) {
                          rules = .validator.normalizeRule(validator.settings.rules[element.name]) || {};
                  }
                  return rules;
          },
          
          normalizeRules: function(rules, element) {
                  // handle dependency check
                  .each(rules, function(prop, val) {
                          // ignore rule when param is explicitly false, eg. required:false
                          if (val === false) {
                                  delete rules[prop];
                                  return;
                          }
                          if (val.param || val.depends) {
                                  var keepRule = true;
                                  switch (typeof val.depends) {
                                          case "string":
                                                  keepRule = !!$(val.depends, element.form).length;
                                                  break;
                                          case "function":
                                                  keepRule = val.depends.call(element, element);
                                                  break;
                                  }
                                  if (keepRule) {
                                          rules[prop] = val.param !== undefined ? val.param : true;
                                  } else {
                                          delete rules[prop];
                                  }
                          }
                  });
                  
                  // evaluate parameters
                  .each(rules, function(rule, parameter) {
                          rules[rule] = .isFunction(parameter) ? parameter(element) : parameter;
                  });
                  
                  // clean number parameters
                  .each(['minlength', 'maxlength', 'min', 'max'], function() {
                          if (rules[this]) {
                                  rules[this] = Number(rules[this]);
                          }
                  });
                  .each(['rangelength', 'range'], function() {
                          if (rules[this]) {
                                  rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
                          }
                  });
                  
                  if (.validator.autoCreateRanges) {
                          // auto-create ranges
                          if (rules.min && rules.max) {
                                  rules.range = [rules.min, rules.max];
                                  delete rules.min;
                                  delete rules.max;
                          }
                          if (rules.minlength && rules.maxlength) {
                                  rules.rangelength = [rules.minlength, rules.maxlength];
                                  delete rules.minlength;
                                  delete rules.maxlength;
                          }
                  }
                  
                  // To support custom messages in metadata ignore rule methods titled "messages"
                  if (rules.messages) {
                          delete rules.messages;
                  }
                  
                  return rules;
          },
          
          // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
          normalizeRule: function(data) {
                  if( typeof data == "string" ) {
                          var transformed = {};
                          .each(data.split(/\s/), function() {
                                  transformed[this] = true;
                          });
                          data = transformed;
                  }
                  return data;
          },
          
          // http://docs.jquery.com/Plugins/Validation/Validator/addMethod
  	addMethod: function(name, method, message) {
  
<summary> Add a custom validation method. It must consist of a name (must be a legal javascript identifier), a javascript based function and a default string message. </summary> <param name="name" type="String"> The name of the method, used to identify and referencing it, must be a valid javascript identifier </param> <param name="method" type="Function"> The actual method implementation, returning true if an element is valid </param> <param name="message" type="String" optional="true"> (Optional) The default message to display for this method. Can be a function created by jQuery.validator.format(value). When undefined, an already existing message is used (handy for localization), otherwise the field-specific messages have to be defined. </param> <returns type="undefined" />

                  .validator.methods[name] = method;
                  .validator.messages[name] = message != undefined ? message : .validator.messages[name];
                  if (method.length < 3) {
                          .validator.addClassRules(name, .validator.normalizeRule(name));
                  }
          },
  
          methods: {
  
                  // http://docs.jquery.com/Plugins/Validation/Methods/required
  		required: function(value, element, param) {
                          // check if dependency is met
                          if ( !this.depend(param, element) )
                                  return "dependency-mismatch";
                          switch( element.nodeName.toLowerCase() ) {
                          case 'select':
                                  // could be an array for select-multiple or a string, both are fine this way
                                  var val = element.val();
                                  return val && val.length > 0;
                          case 'input':
                                  if ( this.checkable(element) )
                                          return this.getLength(value, element) > 0;
                          default:
                                  return .trim(value).length > 0;
                          }
                  },
                  
                  // http://docs.jquery.com/Plugins/Validation/Methods/remote
  		remote: function(value, element, param) {
                          if ( this.optional(element) )
                                  return "dependency-mismatch";
                          
                          var previous = this.previousValue(element);
                          if (!this.settings.messages[element.name] )
                                  this.settings.messages[element.name] = {};
                          previous.originalMessage = this.settings.messages[element.name].remote;
                          this.settings.messages[element.name].remote = previous.message;
                          
                          param = typeof param == "string" && {url:param} || param; 
                          
                          if ( this.pending[element.name] ) {
                                  return "pending";
                          }
                          if ( previous.old === value ) {
                                  return previous.valid;
                          }
  
                          previous.old = value;
                          var validator = this;
                          this.startRequest(element);
                          var data = {};
                          data[element.name] = value;
                          .ajax(.extend(true, {
                                  url: param,
                                  mode: "abort",
                                  port: "validate" + element.name,
                                  dataType: "json",
                                  data: data,
                                  success: function(response) {
                                          validator.settings.messages[element.name].remote = previous.originalMessage;
                                          var valid = response === true;
                                          if ( valid ) {
                                                  var submitted = validator.formSubmitted;
                                                  validator.prepareElement(element);
                                                  validator.formSubmitted = submitted;
                                                  validator.successList.push(element);
                                                  validator.showErrors();
                                          } else {
                                                  var errors = {};
                                                  var message = response || validator.defaultMessage(element, "remote");
                                                  errors[element.name] = previous.message = .isFunction(message) ? message(value) : message;
                                                  validator.showErrors(errors);
                                          }
                                          previous.valid = valid;
                                          validator.stopRequest(element, valid);
                                  }
                          }, param));
                          return "pending";
                  },
  
                  // http://docs.jquery.com/Plugins/Validation/Methods/minlength
  		minlength: function(value, element, param) {
                          return this.optional(element) || this.getLength(.trim(value), element) >= param;
                  },
                  
                  // http://docs.jquery.com/Plugins/Validation/Methods/maxlength
  		maxlength: function(value, element, param) {
                          return this.optional(element) || this.getLength(.trim(value), element) <= param;
                  },
                  
                  // http://docs.jquery.com/Plugins/Validation/Methods/rangelength
  		rangelength: function(value, element, param) {
                          var length = this.getLength(.trim(value), element);
                          return this.optional(element) || ( length >= param[0] && length <= param[1] );
                  },
                  
                  // http://docs.jquery.com/Plugins/Validation/Methods/min
  		min: function( value, element, param ) {
                          return this.optional(element) || value >= param;
                  },
                  
                  // http://docs.jquery.com/Plugins/Validation/Methods/max
  		max: function( value, element, param ) {
                          return this.optional(element) || value <= param;
                  },
                  
                  // http://docs.jquery.com/Plugins/Validation/Methods/range
  		range: function( value, element, param ) {
                          return this.optional(element) || ( value >= param[0] && value <= param[1] );
                  },
                  
                  // http://docs.jquery.com/Plugins/Validation/Methods/email
  		email: function(value, element) {
                          // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
  			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);
                  },
          
                  // http://docs.jquery.com/Plugins/Validation/Methods/url
  		url: function(value, element) {
                          // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
  			return this.optional(element) || /^(https?|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);
                  },
          
                  // http://docs.jquery.com/Plugins/Validation/Methods/date
  		date: function(value, element) {
                          return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
                  },
          
                  // http://docs.jquery.com/Plugins/Validation/Methods/dateISO
  		dateISO: function(value, element) {
                          return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}/.test(value);
                  },
          
                  // http://docs.jquery.com/Plugins/Validation/Methods/number
  		number: function(value, element) {
                          return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?/.test(value);
                  },
          
                  // http://docs.jquery.com/Plugins/Validation/Methods/digits
  		digits: function(value, element) {
                          return this.optional(element) || /^\d+/.test(value);
                  },
                  
                  // http://docs.jquery.com/Plugins/Validation/Methods/creditcard
  		// based on http://en.wikipedia.org/wiki/Luhn
  		creditcard: function(value, element) {
                          if ( this.optional(element) )
                                  return "dependency-mismatch";
                          // accept only digits and dashes
                          if (/[^0-9-]+/.test(value))
                                  return false;
                          var nCheck = 0,
                                  nDigit = 0,
                                  bEven = false;
  
                          value = value.replace(/\D/g, "");
  
                          for (var n = value.length - 1; n >= 0; n--) {
                                  var cDigit = value.charAt(n);
                                  var nDigit = parseInt(cDigit, 10);
                                  if (bEven) {
                                          if ((nDigit *= 2) > 9)
                                                  nDigit -= 9;
                                  }
                                  nCheck += nDigit;
                                  bEven = !bEven;
                          }
  
                          return (nCheck % 10) == 0;
                  },
                  
                  // http://docs.jquery.com/Plugins/Validation/Methods/accept
  		accept: function(value, element, param) {
                          param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";
                          return this.optional(element) || value.match(new RegExp(".(" + param + ")", "i")); 
                  },
                  
                  // http://docs.jquery.com/Plugins/Validation/Methods/equalTo
  		equalTo: function(value, element, param) {
                          // bind to the blur event of the target in order to revalidate whenever the target field is updated
                          // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
                          var target = param.unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
                                  element.valid();
                          });
                          return value == target.val();
                  }
                  
          }
          
  });
  
  // deprecated, use .validator.format instead
  .format = .validator.format;
  
  })(jQuery);
  
  // ajax mode: abort
  // usage: .ajax({ mode: "abort"[, port: "uniqueport"]});
  // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() 
  ;(function() {
          var pendingRequests = {};
                  // Use a prefilter if available (1.5+)
          if ( .ajaxPrefilter ) {
                  .ajaxPrefilter(function(settings, _, xhr) {
                      var port = settings.port;
                      if (settings.mode == "abort") {
                              if ( pendingRequests[port] ) {
                                      pendingRequests[port].abort();
                              }                                pendingRequests[port] = xhr;
                      }
              });
          } else {
                  // Proxy ajax
                  var ajax = .ajax;
                  .ajax = function(settings) {
                          var mode = ( "mode" in settings ? settings : .ajaxSettings ).mode,
                                  port = ( "port" in settings ? settings : .ajaxSettings ).port;
                          if (mode == "abort") {
                                  if ( pendingRequests[port] ) {
                                          pendingRequests[port].abort();
                                  }
  
                              return (pendingRequests[port] = ajax.apply(this, arguments));
                      }
                      return ajax.apply(this, arguments);
              };
      }
  })(jQuery);
  
  // provides cross-browser focusin and focusout events
  // IE has native support, in other browsers, use event caputuring (neither bubbles)
  
  // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
  // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target 
  ;(function() {
          // only implement if not provided by jQuery core (since 1.4)
          // TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs
          if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) {
                  .each({
                          focus: 'focusin',
                          blur: 'focusout'        
                  }, function( original, fix ){
                          .event.special[fix] = {
                                  setup:function() {
                                          this.addEventListener( original, handler, true );
                                  },
                                  teardown:function() {
                                          this.removeEventListener( original, handler, true );
                                  },
                                  handler: function(e) {
                                          arguments[0] = .event.fix(e);
                                          arguments[0].type = fix;
                                          return .event.handle.apply(this, arguments);
                                  }
                          };
                          function handler(e) {
                                  e = .event.fix(e);
                                  e.type = fix;
                                  return .event.handle.call(this, e);
                          }
                  });
          };
          .extend(.fn, {
                  validateDelegate: function(delegate, type, handler) {
                          return this.bind(type, function(event) {
                                  var target = $(event.target);
                                  if (target.is(delegate)) {
                                          return handler.apply(target, arguments);
                                  }
                          });
                  }
          });
  })(jQuery);
  


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.