topical media & game development

talk show tell print

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



  
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 ) {
  
                  // 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() {
          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) {
                  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) {
                  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) {
          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) {
                  .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() {
                          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 ) {
                          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) {
                          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() {
                          if ( .fn.resetForm )
                                  $( this.currentForm ).resetForm();
                          this.submitted = {};
                          this.prepareForm();
                          this.hideErrors();
                          this.elements().removeClass( this.settings.errorClass );
                  },
  
                  numberOfInvalids: function() {
                          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) {
                  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) {
                  .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.