原创js表单验证类(转贴)

来源:互联网 发布:通用软件 编辑:程序博客网 时间:2024/05/10 11:53
js类:
/***************************************************************
* 作者:mousecat,
mousecat4444@126.com
* 版本:v1.3
* 修改记录:
* (1)增加默认验证提示信息。
* (2)修改电话号码验证规则,使之符合086-010-87654321
* (3)简化类调用方式
* (4)简化描述符字符个数
* (5)增加相关验证符(小数验证,整数验证)
* (6)更新帮助说明
* (7)去掉收尾两边空格
* (8)没有rq标识符验证的控件,当为空时可以正确提交,当不为空时根据添加的验证符进行判断
* (9)没有自定义函数对象可以正常运行
* (10)修改程序容错信息
*
* 特点:
* (1)描述符(validation descrīptor)实现验证
* (2)允许添加自定义函数
* (3)面向对象(the oriented_object)
* (4)验证方式包括:onSubmit,onBlur,AJAX。
* (5)应用div形式显示提示信息
* (6)对提示信息应用css样式
* (7)对于程序级错误给予提示
* (8)正确识别中文、英文字符长度
* (9)实现表单控件验证、表单集合验证
* (10)对于大型表单验证更加方便容易
* (11)支持 ie6、firefox2.0 浏览器
* (12)方便调用方式
* (13)设置缺省提示信息
*
* 使用说明:
* (1)包含js验证类
* <head>
*   <scrīpt language="Javascrīpt" src="gen_validator.js" type="text/javascrīpt"></scrīpt>
* </head>
* (2)定义验证对象集合
* var a_fields = {
* 'username':{'rq':'必填项', 'mx=5':'', 'aa':'字母'},
* 'Email':{'mx=20':'', 'rq':'', 'el':''},
* 'Phone':{'te':''},
* 'introduce':{'mx=20':''},
* 'address':{'ds=0':'必须选择地区!'}
* }
* 其中,
* 'username':代表需要验证的表单控件
* 'rq':验证标识符(参见标识符说明)
* '必填项':验证提示信息
* (3)调用验证主函数
* html_form(a_fields, 'myform', 'testCustom');
* 参数1:验证对象集合
* 参数2:表单名称
* 参数3:自定义函数名称
* (4)备注:
* testCustom:自定义验证函数
*
* 注意事项:
* (1)验证提示div的id需要按照验证控件id值+"txt"形式表示
* 如:验证控件id为username,那么显示提示信息的位置id为txtusername。
* (2)当使用控件验证时,需要增加控件的自定义属性(详见使用范例)
* descrīptor:验证描述符列表,中间用"|"分隔(可采用默认提示信息)
* errormsg:错误信息列表,中间用"|"分隔,对应顺序应该和descrīptor顺序一致,最后一项应为正确时(默认)的提示信息
*     如果某一提示信息采用默认形式"|"不能省略
* (3)js验证类对象声明必须在html form之后
* (4)验证标识符必须保持一致
* (5)验证提示信息必须保持一致
* (6)控件验证标识符(descrīptor)和定义的验证标识符对象必须相同。
*
* 标识符说明(括号内标识为略写模式):
* (1)required(rq):必填项
* (2)maxlength=???(mx=???):最大长度,例:maxlen=25
* (3)minlength=???(mi=???):最小长度,例:minlen=5
* (4)alphanumeric(an):验证字符和数字
* (5)numeric(nc):验证数字
* (6)alpha(aa):验证字符
* (7)email(el):验证邮箱
* (8)lessthan=???(lt):验证对象要小于某值,例:lt=1000
* (9)greaterthan=???(gt):验证对象要大于某值,例:gt=10
* (10)regexp=???(rg=???):正则表达式验证,例:regexp=^[A-Za-z]{1,20}$
* (11)doselect=0(ds=0):验证select控件是否被选择
* (12)alnumhyphen(ay):验证字符、数字、-
* (13)telephone(te):验证电话格式,例:086-010-58022633
* (14)real(rl):验证实数格式,例:12.34
* (15)http(hp):验证url地址格式,例:
http://www.baidu.com/aa.index?flag=1&fadsf=2
*
****************************************************************/

/////////////////参数初始化////////////////////////////
//缺省样式规则
//格式:错误样式|正确样式
var defaultStyle = "style2|style1";
//缺省错误提示
var ōbjDescTips = {
required : "请输入必填项",
maxlength : "输入项最大长度不能超过",
minlength : "输入项最小长度不能小于",
alphanumeric : "输入项必须为字母和数字",
numeric : "输入项必须为数字",
alpha : "输入项必须为字母",
alnumhyphen : "输入项必须为字母、数字、横线、下划线",
email : "输入项必须为电子邮件格式",
lessthan : "输入项必须为数字",
lessthan_two : "输入项必须小于",
greaterthan : "输入项必须为数字",
greaterthan_two : "输入项必须大于",
regexp : "输入项必须符合自定义格式",
doselect : "请选择下拉选项",
telephone : "固定电话格式错误",
real : "实数格式错误",
http : "网址格式错误"
}
//缺省正确提示信息
var defaultTip = {
username : "请输入用户名",
Email : "请输入邮箱地址",
Phone : "请输入电话号码",
introduce : "请输入个人描述",
Lovers : "请选择个人爱好",
address : "请选择地区"
};

///////////////////////功能函数//////////////////////////////////
window.onerror = function() {return true};
String.prototype.trueLen = function() {return this.replace(/[^/x00-/xff]/g,"**").length;}
String.prototype.trim = function() {return this.replace(/(^/s*)|(/s*$)/g, "");};
//快捷方式
function $() {
   return document.getElementById(arguments[0]);
}

//信息提示
function dispInfo(msgObj, msgInfo, msgClass) {
var ōbjName = msgObj.name
var msgItem = $("txt" + objName);

if (!msgItem) {
   alert("Bug: " + objName + "缺少信息显示区域!");
   return false;
}

msgItem.style.display = "block";
msgItem.className = msgClass;
msgItem.innerHTML = msgInfo;
}

//////////////////////////////核心类//////////////////////////////
//控件验证
function unitCheck(evt) {
var evt = evt ? evt : window.event;
var srcEle = (evt.target) ? evt.target : evt.srcElement;
var strDescrīptor = srcEle.getAttribute("descrīptor");
var arrDescrīptor = strDescrīptor.split('|');
var arrStyle = defaultStyle.split('|');

if (srcEle.getAttribute("errormsg") == null) {
   var arrErrorMsg = new Array();
} else {
   var strErrorMsg = srcEle.getAttribute("errormsg");
   var arrErrorMsg = strErrorMsg.split('|');
}

if (strDescrīptor.search(/rq|required|ds/gi) == -1) {
   if (srcEle.value.length == 0) {
dispInfo(srcEle, defaultTip[srcEle.id], arrStyle[1]);
return true;
   }
}

for (var iteDes = 0; iteDes < arrDescrīptor.length; iteDes++) {
   if (!V2validateData(arrDescrīptor[iteDes], srcEle, arrErrorMsg[iteDes])) return false;
}

disName = srcEle.name;
dispInfo(srcEle, defaultTip[disName], arrStyle[1]);
return true;
}

function Validator(frmname) {
this.formobj = document.forms[frmname];
this.strForm = frmname;
if(!this.formobj) {
   alert("BUG: 不能得到表单对象" + frmname);
   return false;
}
if(this.formobj.onsubmit) {
   this.formobj.old_onsubmit = this.formobj.onsubmit;
   this.formobj.onsubmit = null;
} else {
   this.formobj.old_onsubmit = null;
}
this.formobj.onsubmit = form_submit_handler;
this.addValidation = add_validation;
this.setAddnlValidationFunction = set_addnl_vfunction;
this.clearAllValidations = clear_all_validations;
}
function set_addnl_vfunction(functionname) {
   this.formobj.addnlvalidation = functionname;
}
function clear_all_validations() {
for(var itr = 0;itr < this.formobj.elements.length;itr++) {
   this.formobj.elements[itr].validationset = null;
}
}
function form_submit_handler() {
for(var itr = 0;itr < this.elements.length;itr++) {
   if(this.elements[itr].validationset && !this.elements[itr].validationset.validate()) {
return false;
   }
}
if(this.addnlvalidation) {
   str =" var ret = "+this.addnlvalidation+"()";
   eval(str);
   if(!ret) return ret;
}
return true;
}
function add_validation(itemname, descrīptor, errstr) {
if(!this.formobj) {
   alert("BUG: 不能得到表单对象!");
   return;
}
var itemobj = this.formobj[itemname];
if(!itemobj) {
   alert("BUG: 不能得到被验证对象: "+itemname);
   return false;
}
if(!itemobj.validationset) {
   itemobj.validationset = new ValidationSet(itemobj);
}
itemobj.validationset.add(descrīptor, errstr);
}

function ValidationSet(inputitem) {
this.vSet = new Array();
this.add = add_validationdesc;
this.validate = vset_validate;
this.itemobj = inputitem;
}
function add_validationdesc(desc, error) {
   this.vSet[this.vSet.length] = new ValidationDesc(this.itemobj, desc, error);
}
function vset_validate() {
for(var itr=0;itr<this.vSet.length;itr++) {
   if(!this.vSet[itr].validate()) {
return false;
   }
}
return true;
}

function ValidationDesc(inputitem, desc, error) {
this.desc=desc;
this.error=error;
this.itemobj = inputitem;
this.validate=vdesc_validate;
}
function vdesc_validate() {
var arrStyle = defaultStyle.split('|');

if (!this.itemobj.getAttribute("descrīptor")) {
   alert('Bug:缺少' + this.itemobj.id + '验证标识符descrīptor');
   return false;
}
if (this.itemobj.getAttribute("descrīptor").search(/rq|required|ds/gi) == -1) {
   if (this.itemobj.value.length == 0) {
dispInfo(this.itemobj, defaultTip[this.itemobj.id], arrStyle[1]);
return true;
   }
}

if(!V2validateData(this.desc, this.itemobj, this.error)) {
   this.itemobj.focus();
   return false;
}
return true;
}

function V2validateData(strValidateStr, objValue, strError) {
var epos = strValidateStr.search("=");
var command   = "";
var cmdvalue = "";
var arrStyle = defaultStyle.split('|');

if(epos >= 0) {
   command   = strValidateStr.substring(0,epos);
   cmdvalue = strValidateStr.substr(epos+1);
} else {
   command = strValidateStr;
}
var _value = objValue.value.trim();
switch(command) {
   case "required":
   case "rq":
   {
if(eval(_value.trueLen()) == 0) {
if (!strError || strError.length == 0) {
    strError = objDescTips.required;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;
}
break;         
   }
   case "maxlength":
   case "mx":
   {
if(eval(_value.trueLen()) >   eval(cmdvalue)) {
if (!strError || strError.length == 0) {
    strError = objDescTips.maxlength + cmdvalue;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;
}
break;
   }
   case "minlength":
   case "mi":
   {
if(eval(_value.trueLen()) <   eval(cmdvalue)) {
if (!strError || strError.length == 0) {
    strError = objDesTip.minlength + cmdvalue;
    return false;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;                
}
break;
   }
   case "alphanumeric":
   case "an":
   {
var charpos = _value.search("[^A-Za-z0-9]");
if(_value.trueLen() > 0 &&   charpos >= 0) {
if (!strError || strError.length == 0) {
    strError = objDescTips.alphanumeric;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;
}
break;
   }
   case "numeric":
   case "nc":
   {
var charpos = _value.search("[^0-9]");
if(_value.trueLen() > 0 &&   charpos >= 0) {
if (!strError || strError.length == 0) {
    strError = objDescTips.numeric;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;
}
break;            
   }
   case "alpha":
   case "aa":
   {
var charpos = _value.search("[^A-Za-z]");
if(_value.trueLen() > 0 &&   charpos >= 0) {
if (!strError || strError.length == 0) {
    strError = objDescTips.alpha;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;
}
break;
   }
   case "alnumhyphen":
   case "ay":
   {
var charpos = _value.search("[^A-Za-z0-9/-_]");
if(_value.trueLen() > 0 &&   charpos >= 0) {   
if (!strError || strError.length == 0) {
    strError = objDescTips.alnumhyphen;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;
}
break;
   }
   case "email":
   case "el":
   {
var pattern = /^[/w-/.]+/@[/w/.-]+/.[a-z]{2,4}$/;
if (!pattern.test(_value)) {
if (!strError || strError.length == 0) {
    strError = objDescTips.email;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;
}
break;
   }
   case "lessthan":
   case "lt":
   {
if(isNaN(_value)) {
if (!strError || strError.length == 0) {
    strError = objDescTips.lessthan;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;
}
if(eval(_value) >=   eval(cmdvalue)) {
if (!strError || strError.length == 0) {
    strError = objDescTips.lessthan_two + cmdvalue;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;                
}      
break;
   }
   case "greaterthan":
   case "gt":
   {
if(isNaN(_value))   {
if (!strError || strError.length == 0) {
    strError = objDescTips.greaterthan;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;
}
if(eval(_value) <=   eval(cmdvalue)) {  
if (!strError || strError.length == 0) {
    strError = objDescTips.greaterthan_two + cmdvalue;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;                
}          
break;
   }
   case "regexp":
   case "rg":
   {
if(_value.trueLen() > 0) {
if(!_value.match(cmdvalue)) {  
    if (!strError || strError.length == 0) {
   strError = objDescTips.regexp;
    }
    dispInfo(objValue, strError, arrStyle[0]);
    return false;               
}
}
break;
   }
   case "doselect":
   case "ds":
   {
if(objValue.selectedIndex == null) {
alert("BUG: 不能找到select对象");
return false;
}
if(objValue.selectedIndex == eval(cmdvalue)) {  
if (!strError || strError.length == 0) {
    strError = objDescTips.doselect;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;                                  
}
break;
   }
   case "telephone":
   case "te":
   {
var pattern = /^0?/d{2}/-?/d{3}/-?/d{8}$/;
if (!pattern.test(_value)) {
if (!strError || strError.length == 0) {
    strError = objDescTips.telephone;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;
}
break;
   }
   case "real":
   case "rl":
   {
var pattern = /^[/+/-]?/d*/.?/d*$/;
if (!pattern.test(_value)) {
if (!strError || strError.length == 0) {
    strError = objDescTips.real;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;
}
break;
   }
   case "http":
   case "hp":
   {
var pattern = /^http:////([/w-]+/.)+[/w-]+(//[/w- .//?%&=]*)?$/;
if (!pattern.test(_value)) {
if (!strError || strError.length == 0) {
    strError = objDescTips.http;
}
dispInfo(objValue, strError, arrStyle[0]);
return false;
}
break;
   }
}
return true;
}

/////////////////////////用户调用接口////////////////////////////
function html_form(objSet, frmName) {
var frmvalidator   = new Validator(frmName);
for (var objSingle in objSet) {
   for (var descSets in objSet[objSingle]) {
if (objSet[objSingle][descSets] == '') {
frmvalidator.addValidation(objSingle, descSets);
} else {
frmvalidator.addValidation(objSingle, descSets, objSet[objSingle][descSets]);
}
   }
}
//自定义函数
frmvalidator.setAddnlValidationFunction(arguments[2]);
}

html调用
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Example for Validator</title>
<scrīpt language="Javascrīpt" src="gen_validator.js" type="text/javascrīpt"></scrīpt>
<style type="text/css">
<!--
.STYLE1 {color: #0000ff;font-size:10pt}
.STYLE2 {color: #FF0000;font-size:10pt}
-->
</style>
</head>
<body>
<form action="" name="myform" >
<table cellspacing="2" cellpadding="2" border="0">
<tr>
<td align="right">用户名</td>
<td><input type="text" name="username" id="username" ōnBlur="javascrīpt:unitCheck(event)" descrīptor='rq|mx=5|aa' errormsg='必填项||字母'><font size=2pt color=red>*</font>
   <div id="txtusername" class='STYLE1'>请输入用户名</div>   </td>
</tr>
<tr>
<td align="right">邮箱</td>
<td><input type="text" name="Email" id="Email" ōnBlur="javascrīpt:unitCheck(event)" descrīptor='mx=20|rq|el'><font size=2pt color=red>*</font>
   <div id="txtEmail" class='STYLE1'>请输入邮箱地址</div>   </td>
</tr>
<tr>
<td align="right">电话</td>
<td><input type="text" name="Phone" id="Phone" ōnBlur="javascrīpt:unitCheck(event)" descrīptor="te">
   <div id="txtPhone" class='STYLE1'>请输入电话号码</div>   </td>
</tr>
<tr>
<td align="right">描述</td>
<td><textarea cols="20" rows="5" name="introduce" id="introduce" ōnBlur="javascrīpt:unitCheck(event)" descrīptor="mx=20"></textarea>
   <div id="txtintroduce" class='STYLE1'>请输入个人描述</div>   </td>
</tr>
<tr>
   <td align="right">爱好</td>
   <td><input type="checkbox" name="Lovers[]" value="football" >
足球
   <input type="checkbox" name="Lovers[]" value="basketball" >
   篮球
   <input type="checkbox" name="Lovers[]" value="badminton" >
   羽毛球
<div id="txtLovers" class='STYLE1'>请选择个人爱好</div>   </td>
</tr>
<tr>
<td align="right">地区</td>
<td>
<SELECT name="address" id="address" ōnBlur="javascrīpt:unitCheck(event)" descrīptor="ds=0" errormsg="必须选择地区!">
   <option value="" selected>[choose yours]
   <option value="010">北京
   <option value="0335">秦皇岛
   <option value="0315">唐山
   <option value="0795">山东
</SELECT><font size=2pt color=red>*</font>
<div id="txtaddress" class='STYLE1'>请选择地区</div> </td>
</tr>
<tr>
<td align="right"></td>
<td><input type="submit" value="Submit"></td>
</tr>
</table>
</form>
<scrīpt language="Javascrīpt" type="text/javascrīpt">
//验证用户名
function testName() {
var v = document.getElementById('username');
if (v.value.trim() != 'lb') {
   return false;
} else {
   return true;
}
}
//验证复选框
function testCheckBox() {
var ōbjWorkPattern = document.getElementsByName("Lovers[]");
var temp = "";
for (i = 0; i < objWorkPattern.length; i++) {
   if (objWorkPattern.checked) {
temp += objWorkPattern.value.trim();
   }
}
if (temp.length == 0) {
   return false;
} else {
   return true;
}
}
//用户添加的自定义验证函数
function testCustom() {
var v1 = document.getElementById('txtusername');
var v2 = document.getElementById("txtLovers");
if (testName() == false) {
   v1.className = 'STYLE2';
   v1.innerHTML = '用户名填写不正确!';
   document.getElementById("username").focus();
   return false;
} else {
   v1.className = 'STYLE1';
   v1.innerHTML = '请输入用户名';
}
if (testCheckBox() == false) {
   v2.innerHTML = "<div class='STYLE2'>个人爱好不能为空!</div>";
   return false;
} else {
   v2.innerHTML = "<div class='STYLE1'>请选择个人爱好</div>";
}
return true;
}

//定义验证类
var a_fields = {
'username':{'rq':'必填项', 'mx=5':'', 'aa':'字母'},
'Email':{'mx=20':'', 'rq':'', 'el':''},
'Phone':{'te':''},
'introduce':{'mx=20':''},
'address':{'ds=0':'必须选择地区!'}
}
html_form(a_fields, 'myform', 'testCustom');
</scrīpt>
</body>
</html>

以上代码是我通过3周的时间不断完善最终形成的(中间并不是全做这个,可能还有别的其它事情)。贴出源码的主要目的是希望php、javascrīpt高手给予批评,使这个小生命能够茁壮成长。
附件: