打造可复用可扩展javascript验证表单脚本
如果需要从用户那里收集信息,就需要使用表单。
表单包含大多数常见的图形界面元素,例如文本框,单选按钮,复选框,下拉菜单等等。
填写完表单,点击Submit按钮将表单发送给web服务器,尽管可以通过服务器CGI程序完成验证,但在客户端用javascript验证要快得多,而且用户操作的效率也高。
这篇博客,主要是把我写的一个用于验证表单的可复用,可扩展的javascript脚本(版本1.0)分享给大家.
先来看看实现效果:
1、初始表单
2、提交,
如果Email为空,则:
3、如果Email不符合规范,则:
5、如果没有选择单选按钮中的一个,则:
6、根据已选字段,自动选择其他字段:选择NormalUser会自动选择2G
验证两个至少选一个:如果没有输入地址,也没有选择地址,则:
7、验证邮编:如果输入错误的邮编则:
8、验证文件:如果输入错误的Image格式,则:
javascript脚本(ValidForm1.js):
// JavaScript Document window.onload=initForms; function initForms(){ for (var i=0;i<document.forms.length;i++){ //遍历所有表单,执行验证 document.forms[i].onsubmit=function(){return validForm();} }; //为复选框NormalUser注册事件 document.getElementById("NormalUser").onclick=spaceSet; }; function validForm(){ var allGood=true; //获得所有标签 var allTags=document.getElementsByTagName("*"); for (var i=0;i<allTags.length;i++){ //检验所有标签 if(!validTag(allTags[i])){ allGood=false; }; }; return allGood; //检验标签是否有效 function validTag(thisTag){ var outClass=""; //获得该标签的class属性 var allClasses=thisTag.className.split(" "); for (var j=0;j<allClasses.length;j++){ //验证该标签,通过改变class标识无效标签 outClass += validBasedOnClass(allClasses[j])+" "; }; thisTag.className=outClass; if(outClass.indexOf("invalid")>-1){ //标识出无效的输入值前的标签 invalidLabel(thisTag.parentNode); //无效输入标签获得焦点 thisTag.focus(); //如果是输入标签,则选中其中的文本 if(thisTag.nodeName=="INPUT"){ thisTag.select(); }; return false; }; return true; //标识无效的字段,添加类名invalid function validBasedOnClass(thisClass){ var classBack=""; //验证,在这里可以扩展验证 switch(thisClass){ case "": case "invalid": break; case "reqd": //判断空 if (allGood && thisTag.value=="") //invalid后有空格 {classBack="invalid ";}; classBack += thisClass; break; case "radio": //检查是否已选单选框 if(allGood && !radioPicked(thisTag.name)){classBack="invalid ";}; classBack += thisClass; break; case "isNum": //检查是否是数字 if(allGood && !isNum(thisTag.value)){classBack="invalid ";}; classBack += thisClass; break; case "isEmail": //检查是否是Email if(allGood && !isEmail(thisTag.value)){classBack="invalid ";}; classBack += thisClass; break; case "isImage": //检查是否是图片,可以演化为检查文件名 if(allGood && !isImg(thisTag.value)){classBack="invalid ";}; classBack += thisClass; break; case "isPostcode": //检查邮政编码 if(allGood && !isPostcode(thisTag.value)){classBack="invalid ";}; classBack += thisClass; break; case "isAddress": classBack += thisClass; break; default: //invalid后有空格 //检查是否至少已经设置了两个字段之一 if(allGood && !crossCheck(thisTag,thisClass)){classBack="invalid ";}; classBack += thisClass; }; return classBack; }; //检查是否至少已经设置了两个字段之一 //这是为邮政编码字段和地址列表元素准备的 function crossCheck(inTag,otherFieldID){ if(!document.getElementById(otherFieldID)){return false;}; return (inTag.value!="" || document.getElementById(otherFieldID).value!="") }; //标识出有问题的字段的标签 function invalidLabel(parentTag){ if(parentTag.nodeName=="LABEL"){ //invalid前有空格 parentTag.className += " invalid"; }; }; //确保用户选择了一个单选按钮 function radioPicked(radioName){ var radioSet=""; //循环遍历表单,如果找到要找单选按钮组,radio就会包含一个值 for (var k=0;k<document.forms.length;k++){ //将radioSet设置为正在查看的表单中单选按钮组的名称 if(!radioSet){ radioSet=document.forms[k][radioName]; }; }; //如果不能找到单选按钮组,则返回false,不能选择单选按钮 if(!radioSet){return false;} //检查每个单选按钮,如果有一个被选中,则返回true for(k=0;k<radioSet.length;k++){ if(radioSet[k].checked){ return true; }; }; //没有发现被选中单选按钮,则返回false return false; }; //验证是否是数字 function isNum(passedVal){ //如果字段是空的,那么肯定不是数组,直接返回False就可以了 if (passedVal==""){return false;} for(var k=0; k<passedVal.length;k++) { //charAt函数返回字段位置K上的字符,检查是否为数字 if(passedVal.charAt(k)<"0"){return false;} if (passedVal.charAt(k)>"9"){return false;} }; return true }; //纯javascript检查邮箱(不使用正则表达式),只是检验输入的内容符合Email的正确形式,无法确认是否存在。 function validEmail(email){ //验证是否存在空格,斜杠,冒号,都好分号等无效字符 var invalidChars=" /:,;"; if (email==""){return false;}; for (var k=0;k<invalidChars.length;k++){ var badChar=invalidChars.charAt(k); if(email.indexOf(badChar)>-1){return false;}; }; //验证是否存在@ var atPos=email.indexOf("@",1); if(atPos==-1){return false;}; //验证@是否重复存在 if(email.indexOf("@",atPos+1)!=-1){return false;}; //验证是否存在点 var periodPos=email.indexOf(".",atPos); if(periodPos==-1){return false;}; //验证点号后是否至少有两个字符 if(periodPos+3>email.length){return false;}; return true; }; //用正则表达式检验电子邮件地址(推荐使用) function isEmail(email){ var reEmail=/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/; return reEmail.test(email); }; //用正则表达式检验文件后缀是否为gif或jpg function isImg(newURL){ var reImg=/^(file|http):\/\/\S+\/\S+\.(gif|jpg)$/i; return reImg.test(newURL); }; //验证邮政编码 function isPostcode(postcode){ var rePostcode=/^[0-9]{6}$/; return rePostcode.test(postcode); } //可以在这里继续扩展验证内容,例如 //验证座机号码 //验证手机 }; }; //根据用户做出的选择自动设置字段输入 function spaceSet(){ if(this.checked){ document.getElementById("Space2").checked=true; }else { document.getElementById("Space2").checked=false; }; };
注释,我尽量写得详细些,大家应该能看明白。
可复用:
基本上囊括了表单上最常用的几个控件的验证方法.
可扩展,方法:
只要在这个位置
加入你需要验证的标签的class属性,
然后在这里,
添加你的验证方法即可.
Html文档:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> <script type="text/javascript" src="ValidForm1.js"></script> <link rel="stylesheet" type="text/css" href="ValidForm.css"> </head> <body> <h2 >Valid Form</h2> <form action="#"> <p><label for="emailAddr">Email Address: <input id="emailAddr" type="text" size="30" class="reqd isEmail" /> </label></p> <p><label for="color">Colors: <select id="color" class="reqd"> <option value="" selected="selected">Choose a color</option> <option value="Red">Red</option> <option value="Green">Green</option> <option value="Blue">Blue</option> </select> </label></p> <p>Options: <label for="NormalUser"><input type="checkbox" id="NormalUser" value="Yes" />NormalUser(2G only) </label> <label for="AdvancedUser"><input type="checkbox" id="AdvancedUser" value="Yes" />AdvancedUser</label></p> <p><label for="Space">Space: <input type="radio" id="Space2" name="Space" value="2G" class="radio" />2G <input type="radio" id="Space4" name="Space" value="4G" class="radio" />4G </label></p> <p><label for="address">Enter your Address or pick the Address<br />Address: <input type="text" id="address" size="30" maxlength="30" class="isAddress addressList"/> <select id="addressList" size="4" class="address"> <option value="cangzhou">Cangzhou</option> <option value="langfang">Langfang</option> <option value="handan">Handan</option> <option value="baoding">Baoding</option> <option value="zhangjiakou">Zhangjiakou</option> </select> </label></p> <p><label for="postcode">Postcode: <input id="postcode" type="text" size="6" maxlength="6" class="isPostcode" /></label></p> <p><label for="image">Image URL:<input id="image" type="text" size="30" maxlength="30" class="isImage" /></label></p> <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p> </form> </body> </html>
CSS样式表(ValidForm.css):
@charset "utf-8"; /* CSS Document */ body{ color:#000; background-color:#FFF; } input.invalid{ /*当输入无效时,使用该样式*/ background-color:#FF9; border:2px red inset; } label.invalid{ /*当输入无效时,使用该样式*/ color:#F00; }
欢迎拍砖!
会把改进放到版本2.0里!