表单验证代码

 

 

此文件为当前路径下   js/vanadium.js

/*
 @author Daniel Kwiecinski <daniel.kwiecinski@lambder.com>
 @copyright 2009 Daniel Kwiecinski.
 本插件原作者Vanadium,原文请移步前往http://vanadiumjs.com/查看
 本插件由Mr.Think中文整理,Mr.Think的博客:http://MrThink.net/
 转载及使用请务必注明原作者.
*/
//********** vanadium-jquery.js **********
Vanadium = {};
Vanadium.Version = '0.1';
Vanadium.CompatibleWithJQuery = '1.3.2';
Vanadium.Type = "jquery";

if (jQuery().jquery.indexOf(Vanadium.CompatibleWithJQuery) != 0 && window.console && window.console.warn)
  console.warn("This version of Vanadium is tested with jQuery " + Vanadium.CompatibleWithJQuery +
               " it may not work as expected with this version (" + jQuery().jquery + ")");

Vanadium.each = jQuery.each;

Vanadium.all_elements = function() {
  return jQuery('*');
};

Vanadium.partition = function(elements, dyscriminator) {
  var left = [];
  var right = [];
  Vanadium.each(elements, function() {
    if (dyscriminator(this)) {
      left.push(this);
    } else {
      right.push(this);
    }
    ;
  });
  return [left, right];
};
//********** vanadium-hashmap.js **********
var HashMap = function() {
  this.initialize();
}
HashMap.hashmap_instance_id = 0;
HashMap.prototype = {
  hashkey_prefix: "<#HashMapHashkeyPerfix>",
  hashcode_field: "<#HashMapHashcodeField>",
  initialize: function() {
    this.backing_hash = {};
    this.code = 0;
    HashMap.hashmap_instance_id += 1;
    this.instance_id = HashMap.hashmap_instance_id;
  },
  hashcodeField: function() {
    return this.hashcode_field + this.instance_id;
  },
  /*
   maps value to key returning previous assocciation
   */
  put: function(key, value) {
    var prev;

    if (key && value) {
      var hashCode;
      if (typeof(key) === "number" || typeof(key) === "string") {
        hashCode = key;
      } else {
        hashCode = key[this.hashcodeField()];
      }
      if (hashCode) {
        prev = this.backing_hash[hashCode];
      } else {
        this.code += 1;
        hashCode = this.hashkey_prefix + this.code;
        key[this.hashcodeField()] = hashCode;
      }
      this.backing_hash[hashCode] = [key, value];
    }
    return prev === undefined ? undefined : prev[1];
  },
  /*
   returns value associated with given key
   */
  get: function(key) {
    var value;
    if (key) {
      var hashCode;
      if (typeof(key) === "number" || typeof(key) === "string") {
        hashCode = key;
      } else {
        hashCode = key[this.hashcodeField()];
      }
      if (hashCode) {
        value = this.backing_hash[hashCode];
      }
    }
    return value === undefined ? undefined : value[1];
  },
  /*
   deletes association by given key.
   Returns true if the assocciation existed, false otherwise
   */
  del: function(key) {
    var success = false;
    if (key) {
      var hashCode;
      if (typeof(key) === "number" || typeof(key) === "string") {
        hashCode = key;
      } else {
        hashCode = key[this.hashcodeField()];
      }
      if (hashCode) {
        var prev = this.backing_hash[hashCode];
        this.backing_hash[hashCode] = undefined;
        if (prev !== undefined){
          key[this.hashcodeField()] = undefined; //let's clean the key object
          success = true;
        }
      }
    }
    return success;
  },
  /*
   iterate over key-value pairs passing them to provided callback
   the iteration process is interrupted when the callback returns false.
   the execution context of the callback is the value of the key-value pair
   @ returns the HashMap (so we can chain)                                                                  (
   */
  each: function(callback, args) {
    var key;
    for (key in this.backing_hash){
      if (callback.call(this.backing_hash[key][1], this.backing_hash[key][0], this.backing_hash[key][1]) === false)
        break;
    }
    return this;
  },
  toString: function() {
    return "HashMapJS"
  }
}
//********** vanadium-container.js **********
Vanadium.containers = new HashMap();

var ContainerValidation = function(html_element) {
  this.initialize(html_element)
}
ContainerValidation.prototype = {
  initialize: function(html_element) {
    this.html_element = html_element;
    this.elements = [];
  },
  add_element: function(element) {
    this.elements.push(element);
  },
  decorate: function() {
    var valid = null;
    for (var id in this.elements) {
      if (this.elements[id].invalid === undefined) {
        valid = undefined;
      } else if (this.elements[id].invalid === true) {
        valid = false;
        break;
      } else if (this.elements[id].invalid === false && valid === null) {
        valid = true;
      }
    }
    if (valid === undefined) {
      jQuery(this.html_element).removeClass(Vanadium.config.invalid_class);
      jQuery(this.html_element).removeClass(Vanadium.config.valid_class);
    } else if (valid) {
      jQuery(this.html_element).removeClass(Vanadium.config.invalid_class);
      jQuery(this.html_element).addClass(Vanadium.config.valid_class);
    } else {
      jQuery(this.html_element).removeClass(Vanadium.config.valid_class);
      jQuery(this.html_element).addClass(Vanadium.config.invalid_class);
    }
  }
}
//********** vanadium-form.js **********
var VanadiumForm = function(element) {
    this.initialize(element);
}
Vanadium.forms = new HashMap();
VanadiumForm.add_element = function(validation_element) {
    var form = validation_element.element.form;
    if (form) {
        var vanadum_form = Vanadium.forms.get(form);
        if (vanadum_form) {
            vanadum_form.validation_elements.push(validation_element);
        } else {
            vanadum_form = new VanadiumForm(validation_element);
            Vanadium.forms.put(form, vanadum_form);
        }
    }
}
VanadiumForm.prototype = {
    initialize: function(validation_element) {
        this.validation_elements = [validation_element];
        this.form = validation_element.element.form;
        var self = this;
        var on_form_submit = function() {
            var validation_result = self.validate();

            var success = true;
            validation_result.each(function(_element, validation_results) {
                for (var r in validation_results) {
                    if (validation_results[r].success == false) {
                        success = false;
                        break;
                    }
                }
                if (success == false) {
                    return false;// break from hashmap iteration
                }
            });
            if (!success) {
                self.decorate();
                return false;
            }
            return success;
        };
        //jQuery(this.form).submit(on_form_submit);
        jQuery(this.form).find(':submit').click(function() {
            return on_form_submit();
        });

        this.form.decorate = function() {
            self.decorate();
        }
    },
    validate: function() {
        var validation = new HashMap();
        Vanadium.each(this.validation_elements,
                function() {
                    validation.put(this, this.validate());
                });
        return validation;
    },

    decorate: function(validation_results) {
        if (arguments.length == 0) {
            validation_results = this.validate();
        }
        validation_results.each(function(element, element_validation_results) {
            element.decorate(element_validation_results);
        });
    },

    validateAndDecorate: function() {
        this.decorate(this.validate())
    }
}
//********** vanadium-base.js **********
Vanadium.validators_types = {};
Vanadium.elements_validators_by_id = {};
Vanadium.all_elements_validators = [];
Vanadium.created_advices = [];
Vanadium.all_html_elements = new HashMap();
Vanadium.empty_advice_marker_class = '-vanadium-empty-advice-'
//validation rules
Vanadium.rules = {}
Vanadium.init = function() {
    this.setupValidatorTypes();
    this.scan_dom();
}
Vanadium.addValidatorType = function(className, validationFunction, error_message, message, init) {
    this.validators_types[className] = new Vanadium.Type(className, validationFunction, error_message, message, init);
};

Vanadium.addValidatorTypes = function(validators_args) {
    var self = this;
    Vanadium.each(validators_args,
            function() {
                Vanadium.addValidatorType.apply(self, this);
            }
            )
};
Vanadium.scan_dom = function() {
    Vanadium.each(Vanadium.all_elements(),
            function(_idx, child) {
                var class_names = child.className.split(' ');
                if (Vanadium.is_input_element(child)) {
                    var element_validation = new ElementValidation(child);
                    if (child.id)
                        Vanadium.elements_validators_by_id[child.id] = element_validation
                    Vanadium.all_elements_validators.push(element_validation)
                    Vanadium.all_html_elements.put(child, element_validation);
                    VanadiumForm.add_element(element_validation);
                    //create validation rules based on class markup
                    Vanadium.each(class_names,
                            function() {
                                var parameters = Vanadium.parse_class_name(this);
                                /*'this' is class_name*/
                                if (parameters) {
                                    Vanadium.add_validation_instance(element_validation, parameters);
                                    Vanadium.add_validation_modifier(element_validation, parameters);
                                }
                            });
                    //create validation rules based on json providen in VanadiumRules variable
                    Vanadium.each(Vanadium.get_rules(child.id),
                            function() {
                                var parameters = this;
                                if (parameters) {
                                    Vanadium.add_validation_instance(element_validation, parameters);
                                    Vanadium.add_validation_modifier(element_validation, parameters);
                                }
                            });
                    element_validation.setup();
                } else {
                    Vanadium.add_validation_container(child);
                }
            })
}
Vanadium.add_validation_container = function(element) {
    var class_names = element.className.split(' ');
    Vanadium.each(class_names,
            function() {
                var parameters = Vanadium.parse_class_name(this);
                if (parameters[0] == 'container') {
                    Vanadium.containers.put(element, new ContainerValidation(element));
                    return true
                }
            });
    Vanadium.each(Vanadium.get_rules(element.id),
            function() {
                var rule = this;
                if (rule == 'container') {
                    Vanadium.containers.put(element, new ContainerValidation(element));
                    return true
                }
            });
}
Vanadium.get_rules = function(element_id) {
    var rule_from_string_or_hash = function(r) {
        if (typeof r === "string") {
            return [r];
        } else if (Vanadium.isArray(r)) {
            return r;
        } else if (typeof(r) === "object") {
            return [r.validator, r.parameter, r.advice];
        } else {
            return undefined;
        }
    }
    //
    var rules = [];
    //
    var rs = Vanadium.rules[element_id];
    if (typeof rs === "undefined") {
        return [];
    } else if (typeof rs === "string") {
        rules.push(rs);
    } else if (Vanadium.isArray(rs)) {
        for (var r in rs) {
            rules.push(rule_from_string_or_hash(rs[r]));
        }
    } else if (typeof(rs) === "object") {
        rules.push(rule_from_string_or_hash(rs));
    }
    return rules;
}
Vanadium.parse_class_name = function(class_name) {
    if (class_name.indexOf(Vanadium.config.prefix) == 0) {
        var v_params = class_name.substr(Vanadium.config.prefix.length).split(Vanadium.config.separator)
        for (var key in v_params) {
            if (v_params[key] == "") {
                v_params[key] = undefined
            }
        }
        return v_params;
    } else {
        return [];
    }
}
Vanadium.add_validation_instance = function(element_validation, parameters) {
    var v_name = parameters[0];
    var v_param = parameters[1];
    var v_advice_id = parameters[2];
    var validator_type = Vanadium.validators_types[v_name]
    if (validator_type) {
        element_validation.add_validation_instance(validator_type, v_param, v_advice_id);
    }
}
Vanadium.add_validation_modifier = function(element_validation, parameters) {
    var m_name = parameters[0];
    var m_param = parameters[1];
    if (m_name == 'only_on_blur' || m_name == 'only_on_submit' || m_name == 'wait' || m_name == 'advice') {
        element_validation.add_validation_modifier(m_name, m_param);
    }
}
Vanadium.validate = function() {
    var validation = new HashMap();
    Vanadium.each(Vanadium.all_elements_validators,
            function() {
                validation.put(this, this.validate());
            });
    return validation;
}
Vanadium.validateAndDecorate = function(html_element) {
    if (typeof html_element === "undefined") {  // validate and decorate everything
        Vanadium.decorate(Vanadium.validate());
    } else if (html_element.nodeType == 1) {
        var element_validation = Vanadium.all_html_elements.get(html_element) || Vanadium.forms.get(html_element);
        if (element_validation) {
            element_validation.validateAndDecorate(false);
        }
    }
}
Vanadium.decorate = function(validation_results) {
    if (typeof validation_results === "object") {
        if (validation_results.toString() == "HashMapJS") {
            validation_results.each(function(element, element_validation_results) {
                element.decorate(element_validation_results);
            })
        } else {//this is probably json structure representing validation result
            var element_id;
            for (element_id in validation_results) {
                var element = Vanadium.elements_validators_by_id[element_id];
                if (element) {
                    element.decorate(validation_results[element_id]);
                }
            }
        }
    }
}
Vanadium.reset = function() {
    Vanadium.each(Vanadium.all_elements_validators,
            function() {
                this.reset();
            });
}
//********** vanadium-utils.js **********
Vanadium.isArray = function(object) {
  return object != null && typeof object == "object" &&
         'splice' in object && 'join' in object;
}
Vanadium.isFunction = function(object) {
  return object != null && object.toString() === "[object Function]";
}
Vanadium.extend = function(extension) {
  var args = [Vanadium];
  for (var idx = 0; idx < arguments.length; idx++) {
    args.push(arguments[idx]);
  }
  return jQuery.extend.apply(jQuery, args);
}
Vanadium.bind = function(fun, context) {
  return function() {
    return fun.apply(context, arguments);
  }
}
//********** vanadium-dom.js **********
Vanadium.extend(
{
  /**
   * gets the type of element, to check whether it is compatible
   */
  getElementType: function(element) {
    switch (true) {
      case (element.nodeName.toUpperCase() == 'TEXTAREA'):
        return Vanadium.TEXTAREA;
      case (element.nodeName.toUpperCase() == 'INPUT' && element.type.toUpperCase() == 'TEXT'):
        return Vanadium.TEXT;
      case (element.nodeName.toUpperCase() == 'INPUT' && element.type.toUpperCase() == 'PASSWORD'):
        return Vanadium.PASSWORD;
      case (element.nodeName.toUpperCase() == 'INPUT' && element.type.toUpperCase() == 'CHECKBOX'):
        return Vanadium.CHECKBOX;
      case (element.nodeName.toUpperCase() == 'INPUT' && element.type.toUpperCase() == 'FILE'):
        return Vanadium.FILE;
      case (element.nodeName.toUpperCase() == 'SELECT'):
        return Vanadium.SELECT;
      case (element.nodeName.toUpperCase() == 'INPUT'):
        throw new Error('Vanadium::getElementType - Cannot use Vanadium on an ' + element.type + ' input!');
      default:
        throw new Error('Vanadium::getElementType - Element must be an input, select, or textarea!');
    }
    ;
  },
  is_input_element : function(element) {
    return (element.nodeName.toUpperCase() == 'TEXTAREA') ||
           (element.nodeName.toUpperCase() == 'INPUT' && element.type.toUpperCase() == 'TEXT') ||
           (element.nodeName.toUpperCase() == 'INPUT' && element.type.toUpperCase() == 'PASSWORD') ||
           (element.nodeName.toUpperCase() == 'INPUT' && element.type.toUpperCase() == 'CHECKBOX') ||
           (element.nodeName.toUpperCase() == 'INPUT' && element.type.toUpperCase() == 'FILE') ||
           (element.nodeName.toUpperCase() == 'SELECT')
  },
  /**
   * makes a span containg the passed or failed advice
   *
   * @return {HTMLSpanObject} - a span element with the advice message in it
   */
  createAdvice: function(element, advice_id, message) {
    var advice = document.createElement('span');
    advice.id = advice_id;
    var textNode = document.createTextNode(message);
    advice.appendChild(textNode);
    element.parentNode.insertBefore(advice, element.nextSibling);
    this.created_advices.push(advice);
  },
  /**
   * adds the class of the element/advice/container to indicte if valid or not
   */
  addValidationClass: function(element, valid) {
    if (element) {
      this.removeValidationClass(element);
      if (valid) {
        element.className += ' ' + Vanadium.config.valid_class;
      } else {
        element.className += ' ' + Vanadium.config.invalid_class;
      }
      ;
    }
    ;
  },
  /**
   * removes the class that has been applied to the element/advice/container to indicte if valid or not
   */
  removeValidationClass: function(element) {
    if (element) {
      if (element.className.indexOf(Vanadium.config.invalid_class) != -1) element.className = element.className.split(Vanadium.config.invalid_class).join(' ');
      if (element.className.indexOf(Vanadium.config.valid_class) != -1) element.className = element.className.split(Vanadium.config.valid_class).join(' ');
    }
    ;
  },
  /** element types constants ****/
  TEXTAREA: 1,
  TEXT: 2,
  PASSWORD: 3,
  CHECKBOX: 4,
  SELECT: 5,
  FILE: 6
}
        );
//-------------------- vanadium-element.js -----------------------------
ElementValidation = function(element) {
  this.initialize(element)
};
ElementValidation.prototype = {
  initialize: function(element) {
    this.virgin = true;
    this.element = element;
    this.validations = [];
    this.only_on_blur = false;
    this.only_on_submit = false;
    this.wait = 100;
    this.created_advices = [];
    this.decorated = false;
    this.containers = null;
    this.invalid = undefined;
    this.advice_id = undefined; //this is general common advice for all validation instances having no specific advice defined
  },
  add_validation_instance: function(validator_type, param, advice_id) {
    this.validations.push(new Validation(this.element, validator_type, param, advice_id));
  },
  add_validation_modifier: function(modifier, param) {
    if (modifier == 'only_on_blur') {
      //  whether you want it to validate as you type or only on blur  (DEFAULT: false)
      this.only_on_blur = true
    } else if (modifier == 'only_on_submit') {
      //  whether should be validated only when the form it belongs to is submitted (DEFAULT: false)
      this.only_on_submit = true
    } else if (modifier == 'wait') {
      //  the time you want it to pause from the last keystroke before it validates (ms) (DEFAULT: 0)
      var milisesonds = parseInt(param);
      if (milisesonds != NaN && typeof(milisesonds) === "number") {
        this.wait = milisesonds;
      }
      ;
    } else if (modifier == 'advice') {
      var advice = document.getElementById(param);
      if (advice) {
        this.advice_id = param;
      }
    }
    ;
  },
  element_containers: function() {
    if (this.containers === null) {
      this.containers = new HashMap();
      var parent = this.element.parentNode;
      //search up the DOM tree
      while (parent != document) {
        var container = Vanadium.containers.get(parent);
        if (container) {
          container.add_element(this);
          this.containers.put(parent, container);
        }
        ;
        parent = parent.parentNode;
      }
      ;
    }
    ;
    return this.containers;
  },
  // context - the contect in which decoration_callback should be invoked
  // decoration_callback - the decoration used by asynchronous validation
  validate: function(decoration_context, decoration_callback) {
    var result = [];
    Vanadium.each(this.validations, function() {
      result.push(this.validate(decoration_context, decoration_callback));
    });
    return result;
  },
  decorate: function(element_validation_results, do_not_reset) {
    if (!do_not_reset) {
      this.reset();
    }
    this.decorated = true;
    var self = this;
    var passed_and_failed = Vanadium.partition(element_validation_results, function(validation_result) {
      return validation_result.success
    });
    var passed = passed_and_failed[0];
    var failed = passed_and_failed[1];
    // add apropirate CSS class to the validated element
    if (failed.length > 0) {
      this.invalid = true; //mark this validation element as invalid
      Vanadium.addValidationClass(this.element, false);
    } else if (passed.length > 0 && !this.invalid) { //when valid result comes but the previous was invalid and no reset was done, the invalid flag should stay unchanged
      this.invalid = false; //mark this validation element as valid
      Vanadium.addValidationClass(this.element, true);
    } else {
      this.invalid = undefined; //mark this validation element as undefined
    }
    ;
    // add apropirate CSS class to the validated element's containers
    this.element_containers().each(function(_element, container) {
      container.decorate();
    });
    //
    Vanadium.each(failed, function(_idx, validation_result) {
      var advice = undefined;
      if (self.advice_id) {
        advice = document.getElementById(self.advice_id);
      }
      if (advice || validation_result.advice_id) {
        advice = advice || document.getElementById(validation_result.advice_id);
        if (advice) {
          jQuery(advice).addClass(Vanadium.config.advice_class);
          var advice_is_empty = advice.childNodes.length == 0
          if (advice_is_empty || jQuery(advice).hasClass(Vanadium.empty_advice_marker_class)) {
            jQuery(advice).addClass(Vanadium.empty_advice_marker_class);
            jQuery(advice).append("<span>" + validation_result.message + "</span>");
          }
          ;
          jQuery(advice).show();
        } else {
          advice = self.create_advice(validation_result);
        }
        ;
      } else {
        advice = self.create_advice(validation_result);
      }
      ;
      Vanadium.addValidationClass(advice, false);
    });
  },
  validateAndDecorate : function(regard_virginity) {
    //That's tricky one ;)
    // 1. we are runing validate to get all validation results
    // 2. there could be possible some validations running asynchronous
    // so we won't get the result imediately. In that case the provided decoration callback
    // will be invoked on return from asynchronous callback
    // It is used by Ajax based server-side validation
    if(!regard_virginity || !this.virgin)
      this.decorate(this.validate(this, this.decorate));
  },
  create_advice: function(validation_result) {
    var span = document.createElement("span");
    this.created_advices.push(span);
    jQuery(span).addClass(Vanadium.config.advice_class);
    jQuery(span).html(validation_result.message);
    jQuery(this.element).after(span);
    return span;
  },
  reset: function() {
    this.invalid = undefined; //mark this validation element as undefined
    //    this.element_containers().each(function(_element, container) {
    //      container.decorate();
    //    });
    var element_advice = document.getElementById(this.advice_id);
    if (element_advice) {
      if (jQuery(element_advice).hasClass(Vanadium.empty_advice_marker_class)) {
        jQuery(element_advice).empty();
      }
      jQuery(element_advice).hide();
    }
    Vanadium.each(this.validations, function() {
      var advice = document.getElementById(this.adviceId);
      if (advice) {
        if (jQuery(advice).hasClass(Vanadium.empty_advice_marker_class)) {
          jQuery(advice).empty();
        }
        jQuery(advice).hide();
      }
      ;
    });

    var created_advice = this.created_advices.pop();
    while (!(created_advice === undefined)) {
      jQuery(created_advice).remove();
      created_advice = this.created_advices.pop();
    }
    ;
    Vanadium.removeValidationClass(this.element);
  },
  //
  //
  //
  /**
   * makes the validation wait the alotted time from the last keystroke
   */
  deferValidation: function() {
    if (this.wait >= 300) this.reset();
    var self = this;
    if (self.timeout) clearTimeout(self.timeout);
    self.timeout = setTimeout(function() {
      jQuery(self.element).trigger('validate');
    }, self.wait);
  },
  deferReset: function() {
    var self = this;
    if (self.reset_timeout) clearTimeout(self.reset_timeout);
    self.reset_timeout = setTimeout(function() {
      self.reset();
    }, Vanadium.config.reset_defer_timeout);
  },
  setup: function() {
    var self = this;
    this.elementType = Vanadium.getElementType(this.element);

    this.form = this.element.form;

    this.element_containers();

    if (!this.only_on_submit) {
      this.observe();
      jQuery(self.element).bind('validate', function() {
        self.validateAndDecorate.call(self, true)
      });
      jQuery(self.element).bind('defer_validation', function() {
        self.deferValidation.call(self)
      });
      jQuery(self.element).bind('reset', function() {
        self.reset.call(self)
      });
    }
  },
  observe: function() {
    var element = this.element;
    var elementType = Vanadium.getElementType(element);
    var self = this;
    jQuery(element).focus(function() {
      self.virgin = false;
    });
    switch (elementType) {
      case Vanadium.CHECKBOX:
        jQuery(element).click(function() {
          //TODO check db click !!!
          self.virgin = false; //this is here 'cos safari do not focus on checkboxes
          jQuery(self.element).trigger('validate');
        });
        break;
      //TODO check if checkboxes support on-change too. and if yes handle it!
      // let it run into the next to add a change event too
      case Vanadium.SELECT:
      case Vanadium.FILE:
        jQuery(element).change(function() {
          jQuery(element).trigger('validate');
        });
        break;
      default:
        jQuery(element).keydown(function(e) {
          if (e.keyCode != 9) {//no tabulation as it changes focus
            jQuery(element).trigger('reset');
          }
          ;
        });

        if (!this.only_on_blur) {
          jQuery(element).keyup(function(e) {
            if (e.keyCode != 9) {//no tabulation as it changes focus
              jQuery(element).trigger('defer_validation');
            }
            ;
          });
        };
        jQuery(element).blur(function() {
          jQuery(element).trigger('validate');
        });
    }
  }
};
//********** vanadium-instance.js **********
var Validation = function(element, validation_type, param, advice_id) {
  this.initialize(element, validation_type, param, advice_id)
}
Validation.prototype = {
  initialize: function(element, validation_type, param, advice_id) {
    this.element = element;
    this.validation_type = validation_type;
    this.param = param;
    //
    this.adviceId = advice_id;
    var advice = document.getElementById(advice_id);
    if (advice) {
      jQuery(advice).addClass(Vanadium.config.advice_class);
    }
    if(this.validation_type.init){//Vanadium.isFunction(this.validation_type.init)){
      this.validation_type.init(this); //this give us oportunity to define in validation_type scope activity which will be performed on its instance initialisation
    }
  },
  emmit_message: function(message) {
    if (typeof(message) === "string") {
      return message;
    } else if (typeof(message) === "function") {
      return message.call(this, jQuery(this.element).val(), this.param);
    }
  },
  validMessage: function() {
    return this.emmit_message(this.validation_type.validMessage()) || 'ok'
  },
  invalidMessage: function() {
    return this.emmit_message(this.validation_type.invalidMessage()) || 'error'
  },
  test: function(decoration_context, decoration_callback) {
    return this.validation_type.validationFunction.call(this, jQuery(this.element).val(), this.param, this, decoration_context, decoration_callback);
  },
  // decoration_context - the contect in which decoration_callback should be invoked
  // decoration_callback - the decoration used by asynchronous validation
  validate: function(decoration_context, decoration_callback) {
    var return_value = {
      success: false,
      message: "Received invalid return value."
    }
    var validation_result = this.test(decoration_context, decoration_callback);
    if (typeof validation_result === "boolean") {
      return {
        success: validation_result,
        advice_id: this.adviceId,
        message: (validation_result ? this.validMessage() : this.invalidMessage())
      }
    } else if (typeof validation_result === "object") {
      jQuery.extend.apply(return_value, validation_result);
    }
    return return_value;
  }
}
//********** vanadium-init.js **********
jQuery(document).ready(function () {
  if (typeof(VanadiumConfig) === "object" && VanadiumConfig) {
    Vanadium.each(VanadiumConfig, function(k, v) {
      Vanadium.config[k] = v;
    })
  }
  if (typeof(VanadiumRules) === "object" && VanadiumRules) {
    Vanadium.each(VanadiumRules, function(k, v) {
      Vanadium.rules[k] = v;
    })
  }
  Vanadium.init();
});

 

 

 

 

 

 

 

//..................................此文件为demo.htm............................................................///

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="author" content="Mr.Think青鸟" />
<meta name="keywords" content="Mr.Think,青鸟,前端开发,前端技术,网站策划,网站优化,javascript,css,Mr.Think的博客,青鸟的博客,PHP爱好者,Bluebirdsky" />
<meta name="description" content="Mr.Think的个人博客,中文网名青鸟,现专注于WEB前端开发,同时也是一位PHP的爱好者.爱思考,有点代码洁癖,生吃过螃蟹腿,喜好肉食.这里是我记录知识与生活琐事的地方." />
<title>实用齐全的表单验证程序@原作者Vanadium,由@Mr.Think中文整理@www.MrThink.net</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script src="js/vanadium.js"></script>
<style>
body{font-size:0.8em;letter-spacing:1px;font-family:"微软雅黑"; line-height:1.2}
a{color:#047;text-decoration:none}
a:hover{color:#a40000;text-decoration:none}
h1{font-size:1em; font-weight:normal; line-height:1.8em}
h1 a{background:#CFF; padding:2px 3px; text-decoration:none}
h1 a:hover{background:#eee; text-decoration:underline}
h2,h3{font-size:1em; font-weight:normal; color:#a40000; margin:1em auto; position:relative}
h3{color:#888; font-weight:bold}
h2 span{position:absolute; right:2%; background:#cff; padding:3px}
form *{padding:0; margin:0}
form{margin:20px; background:#eee; padding:5px 10px;}
input{margin:0 8px 0 15px; height:20px; line-height:20px;width:200px;}
input[type="submit"]{widows:100px;}
fieldset{padding:10px; border:1px solid #000;}
table{width:100%; border:0; border-collapse:collapse; line-height:30px; margin:10px 0;}
table th{text-align:right; width:20%; font-weight:normal;}
table td span{color:#a40000}
input.rightformcss,select.rightformcss,textarea.rightformcss{border:1px solid green;padding:1px;}
.failmsg{color:#a40000;}
.msgvaluecss{font-style:italic;}
input.failformcss,select.failformcss,textarea.failformcss{border:1px solid #a40000;padding:1px;}
</style>
<script>
/*
 *本插件原作者Vanadium,原文请移步前往http://vanadiumjs.com/查看
 *本插件由Mr.Think中文整理,Mr.Think的博客:http://MrThink.net/
 *转载及使用请务必注明原作者.
*/
$(function(){
 //必填项加红*,Mr.Think添加,原插件无
    $("input[class*=:required]").after("<span> *</span>")
});
 //弹出信息样式设置
Vanadium.config = {
    valid_class: 'rightformcss',//验证正确时表单样式
    invalid_class: 'failformcss',//验证失败时该表单样式
    message_value_class: 'msgvaluecss',//这个样式是弹出信息中调用值的样式
    advice_class: 'failmsg',//验证失败时文字信息的样式
    prefix: ':',
    separator: ';',
    reset_defer_timeout: 100
}
//验证类型及弹出信息设置
Vanadium.Type = function(className, validationFunction, error_message, message, init) {
  this.initialize(className, validationFunction, error_message, message, init);
};
Vanadium.Type.prototype = {
  initialize: function(className, validationFunction, error_message, message, init) {
    this.className = className;
    this.message = message;
    this.error_message = error_message;
    this.validationFunction = validationFunction;
    this.init = init;
  },
  test: function(value) {
    return this.validationFunction.call(this, value);
  },
  validMessage: function() {
    return this.message;
  },
  invalidMessage: function() {
    return this.error_message;
  },
  toString: function() {
    return "className:" + this.className + " message:" + this.message + " error_message:" + this.error_message
  },
  init: function(parameter) {
    if (this.init) {
      this.init(parameter);
    }
  }
};
Vanadium.setupValidatorTypes = function() {
Vanadium.addValidatorType('empty', function(v) {
    return  ((v == null) || (v.length == 0));
  });
//***************************************以下为验证方法,使用时可仅保留用到的判断
Vanadium.addValidatorTypes([
 //匹配大小写的等值
    ['equal', function(v, p) {
      return v == p;
    }, function (_v, p) {
      return '输入的值必须与<span class="' + Vanadium.config.message_value_class + '">' + p + '相符\(区分大小写\)</span>.'
    }],
    //不匹配大小写的等值
    ['equal_ignore_case', function(v, p) {
      return v.toLowerCase() == p.toLowerCase();
    }, function (_v, p) {
      return '输入的值必须与<span class="' + Vanadium.config.message_value_class + '">' + p + '相符\(不区分大小写\)</span>.'
    }],
    //是否为空
    ['required', function(v) {
      return !Vanadium.validators_types['empty'].test(v);
    }, '此项不可为空!'],
    //强制选中
    ['accept', function(v, _p, e) {
      return e.element.checked;
    }, '必须接受!'],
    //
    ['integer', function(v) {
      if (Vanadium.validators_types['empty'].test(v)) return true;
      var f = parseFloat(v);
      return (!isNaN(f) && f.toString() == v && Math.round(f) == f);
    }, '请输入一个正确的整数值.'],
    //数字
    ['number', function(v) {
      return Vanadium.validators_types['empty'].test(v) || (!isNaN(v) && !/^\s+$/.test(v));
    }, '请输入一个正确的数字.'],
    //
    ['digits', function(v) {
      return Vanadium.validators_types['empty'].test(v) || !/[^\d]/.test(v);
    }, '请输入一个非负整数,含0.'],
    //只能输入英文字母
    ['alpha', function (v) {
      return Vanadium.validators_types['empty'].test(v) || /^[a-zA-Z\u00C0-\u00FF\u0100-\u017E\u0391-\u03D6]+$/.test(v)   //% C0 - FF (� - �); 100 - 17E (? - ?); 391 - 3D6 (? - ?)
    }, '请输入英文字母.'],
    //仅限ASCII编码模式下输入英文字母
    ['asciialpha', function (v) {
      return Vanadium.validators_types['empty'].test(v) || /^[a-zA-Z]+$/.test(v)   //% C0 - FF (� - �); 100 - 17E (? - ?); 391 - 3D6 (? - ?)
    }, '请在ASCII下输入英文字母.'],
 //英文字母或正数
    ['alphanum', function(v) {
      return Vanadium.validators_types['empty'].test(v) || !/\W/.test(v)
    }, '请输入英文字母或正数.'],
 //邮箱验证
    ['email', function (v) {
      return (Vanadium.validators_types['empty'].test(v) || /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(v))
    }, '邮箱格式不正确,请检查.正确格式例如mrthink@gmail.com'],
    //网址
    ['url', function (v) {
      return Vanadium.validators_types['empty'].test(v) || /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i.test(v)
    }, '请输入正确的网址,比如:http://www.mrthink.net'],
    //日期格式
    ['date_au', function(v) {
      if (Vanadium.validators_types['empty'].test(v)) return true;
      var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/;
      if (!regex.test(v)) return false;
      var d = new Date(v.replace(regex, '$2/$1/$3'));
      return ( parseInt(RegExp.$2, 10) == (1 + d.getMonth()) ) && (parseInt(RegExp.$1, 10) == d.getDate()) && (parseInt(RegExp.$3, 10) == d.getFullYear() );
    }, '请输入正确的日期格式,比如:28/05/2010.'],
    //输入固定长度字符串
    ['length',
      function (v, p) {
        if (p === undefined) {
          return true
        } else {
          return v.length == parseInt(p)
        }
        ;
      },
      function (_v, p) {
        return '输入字符长度等于<span class="' + Vanadium.config.message_value_class + '">' + p + '</span>个.'
      }
    ],
    //
    ['min_length',
      function (v, p) {
        if (p === undefined) {
          return true
        } else {
          return v.length >= parseInt(p)
        }
        ;
      },
      function (_v, p) {
        return '输入字符长度不低于<span class="' + Vanadium.config.message_value_class + '">' + p + '</span>个.'
      }
    ],
    ['max_length',
      function (v, p) {
        if (p === undefined) {
          return true
        } else {
          return v.length <= parseInt(p)
        }
        ;
      },
      function (_v, p) {
        return '输入字符长度不大于<span class="' + Vanadium.config.message_value_class + '">' + p + '</span>个.'
      }
    ],
 //判断密码是相同
    ['same_as',
      function (v, p) {
        if (p === undefined) {
          return true
        } else {
          var exemplar = document.getElementById(p);
          if (exemplar)
            return v == exemplar.value;
          else
            return false;
        }
        ;
      },
      function (_v, p) {
        var exemplar = document.getElementById(p);
        if (exemplar)
          return '两次密码输入不相同.';
        else
          return '没有可参考值!'
      },
      "",
      function(validation_instance) {
        var exemplar = document.getElementById(validation_instance.param);
        if (exemplar){
          jQuery(exemplar).bind('validate', function(){
            jQuery(validation_instance.element).trigger('validate');
          });
        }
      }
    ],
 //ajax判断是否存在值
    ['ajax',
      function (v, p, validation_instance, decoration_context, decoration_callback) {
        if (Vanadium.validators_types['empty'].test(v)) return true;
        if (decoration_context && decoration_callback) {
          jQuery.getJSON(p, {value: v, id: validation_instance.element.id}, function(data) {
            decoration_callback.apply(decoration_context, [[data], true]);
          });
        }
        return true;
      }]
    ,
 //正则匹配,此用法不甚理解
    ['format',
      function(v, p) {
        var params = p.match(/^\/(((\\\/)|[^\/])*)\/(((\\\/)|[^\/])*)$/);       
        if (params.length == 7) {
          var pattern = params[1];
          var attributes = params[4];
          try
          {
            var exp = new RegExp(pattern, attributes);
            return exp.test(v);
          }
          catch(err)
          {
            return false
          }
        } else {
          return false
        }
      },
      function (_v, p) {
        var params = p.split('/');
        if (params.length == 3 && params[0] == "") {
          return '输入的值必须与 <span class="' + Vanadium.config.message_value_class + '">' + p.toString() + '</span> 相匹配.';
        } else {
          return '提供的值与<span class="' + Vanadium.config.message_value_class + '">' + p.toString() + '</span>不匹配.';
        }
      }
    ]
  ])
  if (typeof(VanadiumCustomValidationTypes) !== "undefined" && VanadiumCustomValidationTypes) Vanadium.addValidatorTypes(VanadiumCustomValidationTypes);
};
</script>
</head>
<body>
<h1><a href="http://mrthink.net/">Mr.Think的个人博客</a><br />@专注前端技术,热爱PHP,崇尚简单生活.</h1>
<h2>实用齐全的表单验证程序@原作者Vanadium,由@Mr.Think中文整理@www.MrThink.net<span><a href="/demo/download/VanadiuFormValidationModifiedforMrThink.7z">点此下载本页DEMO</a></span></h2>
<h3>返回文章页:<a href="http://mrthink.net/jquery-form-validation-plugin/">http://mrthink.net/jquery-form-validation-plugin/</a></h3>
</body>
<form id="iform" name="iform" method="post" action="#">
<fieldset>
<legend>基于JQUERY的表单验证插件.原作者<a href="http://vanadiumjs.com/" target="_blank" title="前往原作者网站">@Vanadium</a>,由<a href="http://mrthink.net/" target="_blank" title="前往Mr.Think的博客">Mr.Think</a>进行中文整理</legend>
<table>
<tr><th><label for="checkempty">请输入Mr.Think(区分大小写):</label></td><td align="left"><input id="checkempty" class=":equal;Mr.Think" /></td></tr>
<tr><th><label for="checkempty">请输入Mr.Think(不区分大小写):</label></td><td align="left"><input id="checkempty" class=":equal_ignore_case;Mr.Think" /></td></tr>
<tr><th><label for="checkempty">输入不能为空:</label></td><td><input id="checkempty" class=":required" /></td></tr>
<tr><th><label for="checkinteger">输入整数(含负):</label></td><td><input id="checkinteger" class=":integer" /></td></tr>
<tr><th><label for="checknum">输入数字:</label></td><td><input id="checknum" class=":number" /></td></tr>
<tr><th><label for="checkfloat">输入正数值:</label></td><td><input id="checkfloat" class=":digits :required" /></td></tr>
<tr><th><label for="checkletter">输入字母:</label></td><td><input id="checkletter" class=":alpha" /></td></tr>
<tr><th><label for="checkletterasc">请在ASC编码下输入字母:</label></td><td><input id="checkletterasc" class=":asciialpha" /></td></tr><tr><th><label for="checkletternum">请输入英文字母或正数:</label></td><td><input id="checkletternum" class=":alphanum" /></td></tr>
<tr><th><label for="checkmail">请输入邮箱:</label></td><td><input id="checkmail" class=":email :required" /></td></tr>
<tr><th><label for="checkurl">请输入网址:</label></td><td><input id="checkurl" class=":url" /></td></tr>
</tr><tr><th><label for="checkdate">请输入日期:</label></td><td><input id="checkdate" class=":date_au" /></td></tr>
</tr><tr><th><label for="checklength">请输入4个字符:</label></td><td><input id="checklength" class=":length;4" /></td></tr>
<tr><th><label for="checkminlength">最少输入4个字符:</label></td><td><input id="checkminlength"  class=":min_length;4 :required" /></td></tr>
<tr><th><label for="checkmaxlength">最多输入4个字符:</label></td><td><input id="checkmaxlength"  class=":max_length;4" /></td></tr>
<tr><th><label for="checkmaxmin">最多输入4到8个字符:</label></td><td><input id="checkmaxmin"  class=":min_length;4 :max_length;8" /></td></tr>
<tr><th><label for="checkpsw">请输入密码:</label></th><td><input id="checkpsw" class=":required" type="password" /></td></tr>
<tr><th><label for="checkpswrepeat">请再次输入密码:</label></th><td><input id="checkpswrepeat" class=":same_as;checkpsw" type="password" /></td></tr>
<tr><th><label for="checkvalue">正则匹配:</label></td><td><input id="checkvalue" class=":format;/^(Mr.Think)+$/i" /></td></tr>
<tr><th><label for="checkpass">账号验证:</label></td><td><input id="checkpass" class=":ajax;/mrthink.php" /><em>此项须连接服务器测试才有效</em></td></tr>
<tr><th><label for="checkaccept">必须接受:</label></td><td><input type="checkbox" id="checkaccept" class=":accept" /></td></tr>
<tr><th></th><td><input type="submit" value="提交表单" style="width:80px; padding:0.2em; height:30px;" /></td></tr>
</table>
</fieldset>
</form>
<!--@Mr.Think统计代码,使用本DEMO请勿复制:)-->
<script>
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script>
try {
var pageTracker = _gat._getTracker("UA-15924173-1");
pageTracker._trackPageview();
} catch(err) {}
</script>
<!--@end-->
</html>


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值