设计表单验证插件

课后整理 2020-12-14

在Web应用中,正则表达式的应用比较广泛,具体说明如下。

表单验证在网页设计中经常用到,为了方便读者学习和开发需要,本节通过一个综合实例演示如何使用正则表达式设计一个表单验证工具Validator。本节实例会涉及到后面几章有关面向对象的知识,读者可根据实际情况有选择的学习。

Validator是基于JavaScript的伪静态类和对象的自定义属性,可以对网页中的表单项输入进行相应的验证,允许同一页面中同时验证多个表单,熟悉接口代码之后也可以对特定的表单项,甚至仅仅是某个字符串进行验证。因为是伪静态类,所以在调用时不需要实例化,直接以“类名+.语法+属性或方法名”来调用。此外,Validator还提供3种不同的错误提示模式,以满足不同的需要。

预览效果

【操作步骤】

第1步,新建文档,保存为index.html。在页面中新建一个表格,设计一个表单框,其中包含多个输入文本框,如图1所示。

 

图1  设计表单

第2步,在<body>标签底部插入一个<script type="text/javascript">标签,在其中设计Validator类表单验证脚本。

第3步,在脚本中新建全局对象Validator,在其中定义多个属性值为正则表达式的成员。

Validator = {
    Require : /.+/,                //是否为空
    Email :  /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,    //Email地址
    Phone :  /^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$/,  //电话号码
    Mobile : /^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$/,    //手机号码
    Url :  /^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$/,// 使用HTTP协议的网址
    Currency : /^\d+(\.\d+)?$/,    //货币
    Number : /^\d+$/,    //数字
    Zip : /^[1-9]\d{5}$/,    //邮政编码
    QQ : /^[1-9]\d{4,8}$/,    //QQ号码
    Integer : /^[-\+]?\d+$/,    //整数
    Double : /^[-\+]?\d+(\.\d+)?$/,    //实数
    English : /^[A-Za-z]+$/,     //英文
    Chinese : /^[\u0391-\uFFE5]+$/,     //中文
    Username : /^[a-z]\w{3,}$/i,     //用户名
    UnSafe : /^(([A-Z]*|[a-z]*|\d*|[-_\~!@#\$%\^&\*\.\(\)\[\]\{\}<>\?\\\/\'\"]*)|.{0,5})$|\s/符合安全规则的密码
}

第4步,为Validator对象定义一个Validate()方法,该方法根据参数theForm指定的表单form,通过for循环语句获取表单中所有包含dataType属性的文本框。然后根据dataType属性值不同,分别调用上一步定义的正则表达式执行表单验证。如果通过验证,说明输入值合法,否则获取该文本框的msg属性值,并显示错误信息。

//表单验证对象
Validator = {
    //表单验证方法,参数theForm为需要验证的表单对象,mode指定验证错误提示方式
    Validate : function(theForm, mode) {
        var obj = theForm || event.srcElement;    //如果没有指定表单对象,则使用当前元素
        var count = obj.elements.length;    //获取表单项的个数
        this.ErrorMessage.length = 1;        //初始错误信息个数为1
        this.ErrorItem.length = 1;            //初始错误项目个数为1
        this.ErrorItem[0] = obj;            //把表单传递给错误信息对象
        for (var i = 0; i < count; i++) {    //遍历所有表单项
            with (obj.elements[i]) {        //操作当前表单项
                //获取当前表单项dataType属性值
                var _dataType =  getAttribute("dataType"); 
                //如果dataType属性值非法,则跳过
                if ( typeof (_dataType) ==  "object" || typeof (this[_dataType]) == "undefined")
                    continue;
                this.ClearState(obj.elements[i]);  //清除当前表单项的错误提示信息
                //如果require属性值为false,或者输入框为空,则跳过
                if  (getAttribute("require") == "false" && value ==  "")
                    continue;
                //如果dataType属性值为下列值之一时,则调用验证函数执行验证
                switch(_dataType) {
                case "IdCard" :        //身份证
                case "Date" :        //日期
                case "Repeat" :        //某项的重复值
                case "Range" :        //范围
                case "Compare" :    //两数的关系比较
                case "Custom" :        //自定义的正则表达式验证
                case "Group" :        //判断输入值是否在(n, m)区间
                case "Limit" :        //对于具有相同名称的单选按钮的选中判断
                case "LimitB" :        //输入字符长度限制(可按字节比较)
                case "SafeString" :// 符合安全规则的密码
                case "Filter" :        //文件上传格式过滤
                    if (!eval(this[_dataType]))  {
                        this.AddError(i,  getAttribute("msg"));
                    }
                    break;
                //对于非上面所列dataType属性值,则直接使用正则表达式进行验证
                default :
                    if  (!this[_dataType].test(value)) {
                        //验证失败后,则调用AddError()函数显示错误信息
                        //获取表单项的msg属性值,并把它作为错误信息源
                        this.AddError(i,  getAttribute("msg"));
                    }
                    break;
                }
            }
        }
        //根据错误信息,以及指定的模式,显示错误信息
        if (this.ErrorMessage.length > 1) {
            mode = mode || 1;
            var errCount =  this.ErrorItem.length;
            switch(mode) {
            case 2 :     //本模式是把错误项目的字体颜色设置为红色显示
                for (var i = 1; i <  errCount; i++)
                    this.ErrorItem[i].style.color  = "red";
                break;
            case 1 :     //本模式是通过弹出提示框提示错误信息
                console.log(this.ErrorMessage.join("\n"));
                this.ErrorItem[1].focus();
                break;
            case 3 :    //本模式是创建一个span元素,把错误信息显示在文本框后面
                for (var i = 1; i < errCount;  i++) {
                    try {
                        var span =  document.createElement("SPAN");
                        span.id =  "__ErrorMessagePanel";
                        span.style.color =  "red";
                        this.ErrorItem[i].parentNode.appendChild(span);
                        span.innerHTML =  this.ErrorMessage[i].replace(/\d+:/, "*");
                    } catch(e) {
                        console.log(e.description);
                    }
                }
                this.ErrorItem[1].focus();
                break;
            default :
                console.log(this.ErrorMessage.join("\n"));
                break;
            }
            return false;
        }
        return true;
    }
}

第5步,使用自定义属性dataType定义表单项(文本框)验证类型。在表单结构中,为每个文本框设置如下自定义属性:

<input  name="Nick" dataType="English" require="false"  msg="英文名只允许英文字母">

其中自定义属性dataType用于设定表单项的输入数据验证类型,值为字符串,必填项目。该属性可选值如下:

dataType="Require |  Chinese | English | Number | Integer | Double | Email | Url | Phone | Mobile |  Currency | Zip | IdCard | QQ | Date | SafeString | Repeat | Compare | Range |  Limit | LimitB | Group | Custom | Filter "

可选值的验证功能说明如下:

【提示】

另外,还可以通过如下自定义属性为文本框设置特定验证需求。

各选值所对应的关系操作符:

第6步,调用Validate()方法进行验证。在提交按钮中绑定Validate()方法,代码如下:

<input  onClick="Validator.Validate(document.getElementById('demo'))"  value="检验模式1"  type="button">
<input  onClick="Validator.Validate(document.getElementById('demo'),2)"  value="检验模式2"  type="button">
<input  onClick="Validator.Validate(document.getElementById('demo'),3)"  value="检验模式3"  type="button">

在调用Validate()方法中,第一个参数为需要验证的表单对象,第二个参数为模式。这个模式指定要显示错误信息的方式,效果如图2所示。

预览效果

 

模式一

 

模式二

 

模式三

图2  表单错误提示信息