此文件为当前路径下 js/vanadium.js
/*
@author Daniel Kwiecinski <[email protected]>
@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))
}, '邮箱格式不正确,请检查.正确格式例如[email protected]'],
//网址
['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>
<[email protected]统计代码,使用本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>