js 表单验证 感谢网友天牛!
一直想写一个属于自己的表单验证
但是对象的基础很差,在网上找了很多demo 看又看不懂;
后来网友 天涯 以其博客示之,便有了赶脚,
几番拼凑 几番调试
勉强算是写完了
写的不好 颇多霸割!.....现贴上代码。
再次感谢 涯桑
先看效果图
声明一个类 传一个数组(后面会讲到这是个神马数组)以及 内置验证函数的方法名:
function MyCheck(Arr){ // Arr 工厂模式出一个包含所有要验证对象的规则和id //说明 //能力有限 内部验证函数写的不多 可以自行添加 添加后需要把函数名加在this.findFn 里面 使用方法 见index.html /* * required --->必填选项 * symbol------>一般字符串:字母字符下划线 * IntNum------>自然数 *floatNum----->小数 * Email------->邮箱 * maxlength--->最大长度 * mixlength--->最小长度 *password----->密码常用格式 字母数字下划线 * chinese----->//校验中文 * * * */
}
默认属性 就是默认的内置函数错误提示
this.arr=Arr; this.allBl=true;//全部判断的时候需要一个bool存储是否所有都通过 this.requiredErr="该项不能为空"; this.intNumErr="请填写正整数"; this.floatNumErr="请填写正确的小数"; this.EmailErr="请填写正确的邮箱格式"; this.symbolErr="请填写字母数字或下划线"; this.passwordErr="对不起密码格式有误,为[6-16]个字母数字或下划线"; this.chineseErr="伙计,请使用天朝的文字"; this.dataTypesErr="伙计,你把日子搞错了";
第一个方法: 必填选项
this.required=function(obj,req_txt){ //必须填写的 接收dom对象 if(""==obj.value){ var errmsg=(req_txt==""||req_txt==undefined)? this.requiredErr:req_txt; //alert(errmsg); this.showErrMsg(obj,errmsg); return false; }else{ this.showPassMsg(obj); return true; } }
其中 obj 是element 对象 req_txt 是自己设置的 错误提示字符串
以下几个 都是一样
长度验证时我后来加上去的,发现其与的函数都只有两个参数 如果一个是obj 一个是错误str 而长度的话 就需要三个参数即 obj ,允许长度,
和提示字符串 只好去掉错误提示改为 允许长度 实在是 失败啊
//一般字符 字母 数字下划线 this.symbol=function(obj,req_txt){ var reg=/^[a-zA-Z0-9_]{4,20}$/; if(this.validating(reg,this.trim(obj.value))){ this.showPassMsg(obj); return true; }else{ var errmsg=(req_txt==""||req_txt==undefined)? this.symbolErr:req_txt; this.showErrMsg(obj,errmsg); return false; } } //正整数 this.IntNum=function(obj,intNum_txt){//正整数验证 var reg=/^[-\+]?\d+$/; if(this.validating(reg,this.trim(obj.value))){ this.showPassMsg(obj); return true; }else{ var errmsg=(intNum_txt==""||intNum_txt==undefined)? this.intNumErr:intNum_txt; this.showErrMsg(obj,errmsg); return false; } } this.floatNum=function(obj,floatNum_txt){ var reg=/^[-\+]?\d+(\.\d+)?$/; if(this.validating(reg,this.trim(obj.value))){ this.showPassMsg(obj); return true; }else{ var errmsg=(floatNum_txt==""||floatNum_txt==undefined)? this.intNumErr:floatNum_txt; this.showErrMsg(obj,errmsg); return false; } } //邮箱 this.Email=function(obj,Email_txt){ var reg=/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;//邮箱正则; if(this.validating(reg,this.trim(obj.value))){ this.showPassMsg(obj); return true; }else{ var errmsg=(Email_txt==""||Email_txt==undefined)? this.EmailErr:Email_txt; this.showErrMsg(obj,errmsg); return false; } } //最大长度 this.maxlength=function(obj,num){ var val_length=this.trim(obj.value).length; num=parseInt(num); if(val_length>num){ this.showErrMsg(obj,"最大长度为"+num); return false; }else{ this.showPassMsg(obj); return true; } } //最小长度 this.minlength=function(obj,num){ var val_length=this.trim(obj.value).length; num=parseInt(num); if(val_length<num){ this.showErrMsg(obj,"对不起长度最小为"+num); return false; }else{ this.showPassMsg(obj); return true; } } //密码常用格式 this.password=function(obj,padErr_txt){ var reg=/^[\w_]{6,16}$/; if(this.validating(reg,this.trim(obj.value))){ this.showPassMsg(obj); return true; }else{ var errmsg=(padErr_txt==""||padErr_txt==undefined)?this.passwordErr:padErr_txt; this.showErrMsg(obj,errmsg); return false; } } //校验中文 this.chinese=function(obj,chinese_){ var reg=/^[\u2E80-\u9FFF]+$/; if(this.validating(reg,this.trim(obj.value))){ this.showPassMsg(obj); return true; }else{ var errmsg=(chinese_==""||chinese_==undefined)?this.chineseErr:chinese_; this.showErrMsg(obj,errmsg); return false; } } //日期 格式(不管其有效性) this.dataTypes=function(obj,dataRee_txt){ var reg=/^((\d{4})|(\d{2}))[\-\.\/](\d{1,2})[\-\.\/](\d{1,2})/; if(this.validating(reg,this.trim(obj.value))){ this.showPassMsg(obj); return true; }else{ var errmsg=(dataRee_txt==""||dataRee_txt==undefined)?this.dataTypesErr:dataRee_txt; this.showErrMsg(obj,errmsg); return false; } }
下面一个是验证ing 那个函数 负责与正则匹配
//核心函数 接收正则和值 匹配 this.validating=function(reg,str){ //此函数是核心函数 接收数据与正则相计算 var ex=new RegExp(reg); if(ex.test(str)){ return true; }else{ return false; } }
下面则是一些后勤工作和准备工作的函数
挺简单的
//根据id取得对象 this.obj=function(idtxt){ return document.getElementById(idtxt); } //根据name取得对象组 this.objsByName=function(nametxt){ return document.getElementsByName(nametxt); } //去除空格 this.trim=function(str){//去除两端空格 return str.replace(/^\s*|\s*$/gi,""); } //显示错误提示 this.showErrMsg=function(obj,errmsg){ //清除已经提示的信息 包对的错的 this.removeTips(obj); //创建一个错误提示节点 var span=document.createElement("SPAN"); span.id=obj.id+"_err"; span.className="tips_err"; span.style.color="red"; obj.parentNode.appendChild(span); span.innerHTML=errmsg; } //显示正确提示 this.showPassMsg=function(obj){ //通过验证提示 //清除已经提示的信息 包对的错的 this.removeTips(obj); var span=document.createElement("SPAN"); span.id=obj.id+"_pass"; span.className="tips_pass"; span.style.color="#00ff00"; obj.parentNode.appendChild(span); span.innerHTML="正确"; } //移除提示元素 this.removeTips=function(obj){ //通过提示 和未通过提示在有提示之前全部删除 var ids=obj.id; if(document.getElementById(ids+"_err")!=null){ var o=document.getElementById(ids+"_err"); o.parentNode.removeChild(o); } if(document.getElementById(ids+"_pass")!=null){ var o=document.getElementById(ids+"_pass"); o.parentNode.removeChild(o); } }
通过传递来的参数名 查找并且执行函数
//寻找并执行验证函数 扩充 this.findFn=function(fnstr,obj,str){ switch(this.trim(fnstr)){ case "required":return this.required(obj,str); case "symbol":return this.symbol(obj,str); case "IntNum": return this.IntNum(obj,str); case "floatNum":return this.floatNum(obj,str); case "Email": return this.Email(obj,str); case "maxlength":return this.maxlength(obj,str); case "minlength":return this.minlength(obj,str); case "password":return this.password(obj,str); case "chinese":return this.chinese(obj,str); case "dataTypes":return this.dataTypes(obj,str); default : alert('没有'+fnstr+'函数请修改配置代码'); } }
所有需要检验的 表单控件(遍历对象) 其实我后来越写越觉得 checkbox 没什么好验证的
this.checking=function(){ //全部验证 this.allBl=true; var arr=this.arr; for(var i=0;i<arr.length;i++){ //这一层遍历对象 var ids=arr[i].id; if(ids==undefined){//验证checkbox //checkbox情况 始 var checkboxname=arr[i].name; var cb_min=arr[i].min[0]; var errTxt=arr[i].min[1]; if(!this.checkboxs(checkboxname,cb_min,errTxt)){ this.allBl=false; } continue; } //验证内部函数==> var obj=this.obj(ids); if(arr[i].fuc){ if(!this.forThisRule(obj,arr[i].fuc)){ continue; } } //验证内部函数<== //验证外部函数==> if(!arr[i].OtherRule){continue;} if(!this.forOtherRule(obj,arr[i].OtherRule)){ continue; } //外部函数<== } return this.allBl; }
由上一个遍历出来的分支 内部函数 的执行控制
this.forThisRule=function(objElement,objFucAr){ for(var i=0;i<objFucAr.length;i++){ for(var n in objFucAr[i]){ var fn=n; var part=objFucAr[i][n]; if(fn==undefined){ break; } if(!this.findFn(fn,objElement,part)){ this.allBl=false; return false; } } } return true; }
外加的规则函数 执行控制
this.forOtherRule=function(objElement,objOtherFucAr){ for(var i=0;i<objOtherFucAr.length;i++){ for(var n in objOtherFucAr[i]){ var fn=n; if(n==undefined){break;} var part=objOtherFucAr[i][n]; if(!eval(fn+"()")){ this.allBl=false; this.showErrMsg(objElement,part); return false; } } } this.showPassMsg(objElement); return true; }
给每一个控件添加事件 完成单个验证
//每个对象注册事件失去焦点的事件 this.addEvents=function(){ var that=this; for(var i=0;i<this.arr.length;i++){ if(!arr[i].id||arr[i].id==undefined){ continue; } var obj=this.obj(arr[i].id); obj.onblur=function(event){ that.checkEvent(event); } } }
具体如何实现 单个函数验证的逻辑
//如何去执行这一个的校验 this.checkOne=function(o){ var obj=this.obj(o.id); if(o.fuc){ if(!this.forThisRule(obj,o.fuc)){return;} } if(!o.OtherRule){ return;} if(!this.forOtherRule(obj,o.OtherRule)){return;}; }
最后自动执行一行代码 作为对象初始化
this.addEvents();
好 所有的 方法和属性都写完了。但是貌似没有接口~!
学识浅薄
只有再写一个函数作为 创造一个Arr 对象
该函数与mycheck 没有直接联系
//工厂模式出一个参数对象 function addObj(){ var o=[]; o.Add=function(obj){ this.push(obj); return this; } return o; }
好,看一个例子
就是图上那个
<form action="www.baidu.com" id="myform" onsubmit="return validates.checking()"> <div><span class="t">用户名:</span><input type="text" value="" name="u_name" id="u_name"/></div> <div><span class="t">邮箱:</span><input type="text" value="" name="email" id="email"/> </div> <div><span class="t">密码:</span><input type="password" value="" name="psd" id="password"/> </div> <div><span class="t">重复密码:</span><input type="password" value="" name="psd_" id="password_"/> </div> <div><span class="t">爱好:</span><input type="checkbox" value="w" name="hobby"/> 美女 <input type="checkbox" value="m" name="hobby"/> 帅哥 <input type="checkbox" value="fn" name="hobby"/> 腐女 <input type="checkbox" value="rh" name="hobby"/> 日韩 <input type="checkbox" value="om" name="hobby"/> 欧美 </div> <div><span class="t">工作:</span><input type="text" value="" name="work" id="work"/> </div> <div><span class="t">身高(cm):</span><input type="text" value="" name="h" maxlength="3" id="height"/></div> <div><span class="t">生日:</span><input type="text" value="" name="b" id="birthday"/>如:2012-11-21</div> <div><span class="t">真实姓名:</span><input type="text" value="" name="n" maxlength="3" id="name"/></div> <input type="submit" value="提交"/><input type="button" id="btn" value="验证"/> </form>
最后 贴上参数配置过程 和几个 自定义规则的 函数
//构建程序的参数 // 这是比较关键的一步操作 //逐个地添加 var arr=addObj().Add({ id:"u_name", //id fuc:[{"required":"用户名不能为空哦"},{"symbol":"只能是[4-20]长度字母数字和下划线"}], //验证函数以及其错误提示 以对象数组形式添加 OtherRule:[{"begin_":"必须是_开头"}] //额外限制函数 }).Add({ id:"email", fuc:[{"required":"邮箱不能为空"},{"Email":"邮箱格式有误"}] }).Add({ id:"password", fuc:[{"required":"密码不能为空哦"},{"password":""}] }).Add({ //这个比较特殊 是一个checkbox 其实我感觉checkbox不需要验证的 name:"hobby", min:[2,"对不起,为了您的身心健康最好有两个爱好"] }).Add({ id:"work", fuc:[{"required":"伙计描述一下你的工作状态"},{"maxlength":"10"}] //*注意长度验证的 错误提示其实就是 长度允许的值!这里写的不好* }).Add({ id:"height", fuc:[{"required":"童鞋身高要填哦"},{"IntNum":"身高填整数"},{"minlength":"2"}] }).Add({ id:"birthday", fuc:[{"required":"童鞋把生日填一下,有惊喜哦"},{"dataTypes":""}] }).Add({ id:"name", fuc:[{"required":""},{"chinese":""}] }).Add({ //这里是为了测试不写fuc的情况 其实应该要有一个 required 规则 应用于可填可不填的表单类型 其实应该要有一个 id:"password_", OtherRule:[{"compare_password":"两次输入不一样"}] }) //实例化验证器对象 var validates=new MyCheck(arr);
//给验证按钮添加事件 这个其实可以不需要的 是测试的时候用的 /* var ob=document.getElementById("btn"); ob.onclick=function(){ var b=validates.checking(); alert(b); } */
//额外的规则之校验用户名必须以下划线开头(不可带参) function begin_(){ var val=document.getElementById("u_name").value; var ex=/^_/; //alert(ex.test(val)); return ex.test(val); } //额外的规则之重复密码必须相同 function compare_password(){ var v1=document.getElementById("password").value; var v2=document.getElementById("password_").value; return (v1==v2); }