Mootools之FormCheck的扩展

本文章对mootools formcheck插件进行改进,//注意,这里不对FormChekc源码做详细分析,仅仅简单介绍下怎么扩展的,且后面会付上扩展后的js文件和使用手册。

 

Mootools FormCheck 下载地址:http://mootools.floor.ch/en/download/

 

去年进公司的时候接触到了一种新的JS前端框架技术Mootools,它的语法与JQuery比较相似,个人觉得它与JQuery最大的区别在于Mootools提供面向对象的编程方式。作为应用系统基本上大部分页面都有表单,而对表单的较验则是用的FormCheck插件,我在用FormCheck插件的时候发现以下不爽的问题:

 

1、验证表达式的配置太难看了。validate['required'] 我觉得里面这个单引号多余.

2、在有的情况下想自定义一个Function来处理数据的验证,这个FormCheck冒似没有提供。因为FormCheck是使用正则表达式来验证的数据的,它无非就是调用正则的test方法来验证,也许你会想到用下面这种方式来变通:

//...省略了其它配置
regexp:{
	customValidate:{
		test:function(v){
			//do something...
			return true/false;
		}
	}
}
//...省略了其它配置
//这样配置验证表达式:class="validate['customValidate']"

 这样做确实可以,我一开始就是这样做的,但是后来发现有些需求需要根据输入的值做一些更人性化的提示,完蛋了,它彻底的不支持,没办法只好看源代码改咯....

 

 

第一步:去掉那讨厌的单引号。

找到register : function(el, position)方法//这个方法是给当前的输入框注册验证器的

在这个方法的下面添加如下方法代码:

/**
* 从这类字符串( "required",c{validatePassword} )中分割出表达式列表
* @param exps
* @param splitChar
* @returns {Array}
* @private
*/
_getExpressions:function(exps,splitChar){
        splitChar=splitChar||',';
        var expressions=new Array(),sb=new Array(),methodCount=0,blockCount=0,arrayCount=0,c;
        for(var i=0;i<exps.length;i++){
            c=exps.charAt(i);
            if(c=='('){
                methodCount++;
            }else if(c==')'){
                methodCount--;
            }else if(c=='{'){
                blockCount++;
            }else if(c=='}'){
                blockCount--;
            }else if(c=='['){
                arrayCount++;
            }else if(c==']'){
                arrayCount--;
            }else if(c==splitChar&&methodCount==0&&blockCount==0&&arrayCount==0){
                expressions.push(sb.join(''));
                sb.splice(0,sb.length);
                continue;
            }
            sb.push(c);
        }
        if(sb.length!=0){
            expressions.push(sb.join(''));
        }
        return expressions;
    },

 然后修改register : function(el, position)方法内的代码如下:

register : function(el, position) {
		el.validation = [];
		el.getProperty("class").split(' ').each(function(classX) {
			if (classX.match(/^validate(\[.+\])$/)) {
				var valid = true;

                /******************* Modify BEGIN*************************/
                //注掉下面这行代码
                //var validators = eval(classX.match(/^validate(\[.+\])$/)[1]);//正是因为这句话导致validate中的表达式一定得用引号括住
                 var validators=[];
                 var vStr = classX.match(/^validate\[(.+)\]$/)[1];
                this._getExpressions(vStr).each(function(item){
					if(item.charAt(0)=="'" || item.charAt(0)=='"'){//忽略引号 做兼容
						validators.push(item.substring(1,item.length-1));
					}else{
						validators.push(item);
					}
				});
                 delete vStr;
                 /*******************Modify END*************************/
//...这里省略了其余的代码

 

 

第二步:增加自定义验证方式

在类的options下面加入如下属性

customValidation:{
            _compare:function(v1,v2,exp){
                if(v1&&v1!=''&&v2&&v2!=''){
                    var numRgx=/^\d+$/;
                    if(numRgx.test(v1)&&numRgx.test(v2)){
                        if(eval([v1,exp,v2].join('')))return true;
                    }else{
                        if(eval(["'",v1,"'",exp,"'",v2,"'"].join('')))return true;
                    }
                    return false;
                }
                return true;
            },
            gt:{
                msg:"当前值必需大于 \"%{minValue}\".",
                fn:function(v,minValue,el){
                    if(!this.options.customValidation._compare(v,minValue,">=")){
                        return {minValue:minValue};
                    }
                    return true;
                }
            },
            ge:{
                msg:"当前值必需大于等于 \"%{minValue}\".",
                fn:function(v,minValue,el){
                    if(!this.options.customValidation._compare(v,minValue,">=")){
                        return {minValue:minValue};
                    }
                    return true;
                }
            },
            eq:{
                msg:"当前值必需是 \"%{value}\".",
                fn:function(v,newValue,el){
                    if(!this.options.customValidation._compare(v,newValue,"==")){
                        return {value:newValue};
                    }
                    return true;
                }
            },
            nq:{
                msg:"当前值不能等于 \"%{value}\".",
                fn:function(v,value,el){
                    if(!this.options.customValidation._compare(v,value,"!=")){
                        return {value:value};
                    }
                    return true;
                }
            },
            lt:{
                msg:"当前值必需小于 \"%{value}\".",
                fn:function(v,newValue,el){
                    if(!this.options.customValidation._compare(v,newValue,"<")){
                        return {value:newValue};
                    }
                    return true;
                }
            },
            le:{
                msg:"当前值必需小于等于 \"%{value}\".",
                fn:function(v,newValue,el){
                    if(!this.options.customValidation._compare(v,newValue,"<=")){
                        return {value:newValue};
                    }
                    return true;
                }
            },
            range:{
				msg:"当前值需在\"%{begin}\"至\"%{end}\"之间.",
				fn:function(v,begin,end){
					if(v!=''){
						if(v>=begin&&v<=end){
							return true;
						}else{
							return {begin:begin,end:end};
						}
					}
					return true;
				}
			},
            fileSuffix:{
				msg:"文件类型必需是 %{suffixes} 文件.",
				fn:function(v,suffix){
					suffix=$splat(suffix);
					var suf=v.lastIndexOf('.');
					if(suf!=-1){
						suf=v.substr(suf+1).toLowerCase();
						if(suffix.some(function(sf){
							return suf==sf.toLowerCase();
						})){
							return true;
						}
					}
					return {suffixes:suffix.join("、")};
				}
			}
        }

 

找到validate : function(el)方法//此方法在el需要被验证的时候触发

在此validate 方法下面加入以下方法:

 

/**
     * 这个Function负责执行验证函数里面的参数
     */
    _EXPRESSION_EXECUTE_FN:new Function("return eval(arguments[0])"),
    /**
     * 从表达式中获取结果
     * @param exp
     * @param scope
     * @returns {*}
     * @private
     */
    _getResultByExp:function(exp,scope){
        return this._EXPRESSION_EXECUTE_FN.call(scope||window,exp);
    },

 找到validate方法下的el.validation.each(function(rule) {代码段

 

在第一个else的最后面加入如下代码:

/************************** Modify Begin ****************************/
                var customExpRegx=/^c{(.+)}/i;
                var cExp=rule.match(customExpRegx),me=this;
                if(cExp){
                    var exp=cExp[1];
                    var exps=me._getExpressions(exp);
                    exps.each(function(e){
                        var v,vh,vr,args=[el.get('value')];
                        if(e.indexOf('(')!=-1){//处理传参的情况
                            exr=e.match(/^(\S+?)\((.+)\)/);
                            v=exr[1];
                            me._getExpressions(exr[2]).each(function(arg){
                                args.push(
                                    me._getResultByExp(arg,el)
                                );
                            },me);
                        }else{
                            v=e;
                        }
                        args.push(el);
                        vh=me.options.customValidation[v];//从配置中取得验证器方法
                        if(vh){
                            if($type(vh)=='function'){
                                vr=vh.apply(me,args);
                            }else{
                                vr=vh.fn.apply(me,args);
                            }
                            if(vr===true){
                                el.isOk=el.isOk&&true;
                            }else{
                                el.isOk=false;
                                if($type(vr)=='object'){//处理提示消息绑定值的情况
                                    el.errors.push(vh.msg.replace(/\%{(\w+)}/g,function(){
                                        var vm=vr[arguments[1]];
                                        if($type(vm)=='array'){
                                            return vm.join(',');
                                        }else{
                                            return vm;
                                        }
                                    }));
                                }else if($type(vr)=='string'){//返回字符串直接将其作为提示信息
                                    el.errors.push(vr);
                                }else{
                                    el.errors.push(vh.msg||'当前值不合法');
                                }
                            }
                        }
                    },this);
                }
                /************************** Modify End ****************************/

 完事...

 

示例:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>test</title>
    <script type="text/javascript" src="mootools-1.2.5-core-yc.js"></script>
    <script type="text/javascript" src="mootools-1.2.5.1-more.js"></script>
    <link media="screen" rel="stylesheet" href="theme/blue/formcheck.css" type="text/css">
    <script type="text/javascript" src="lang/en.js"></script>
    <script type="text/javascript" src="formcheck.js"></script>
    <script type="text/javascript">
        window.addEvent("domready",function(){
            new FormCheck('form', {
                submitReload:1,
                display : {
                    showErrors:1,
                    indicateErrors : 1,
                    fadeDuration : 1000
                },
                customValidation:{
                    validatePassword:function(v){
                        if(v==null||v=='')return true;
                        if(v.length<6){
                            return "密码长度要大于6位哦,亲";
                        }
                        var pl=0;
                        if(/\d/.test(v)){
                            pl++;
                        }
                        if(/[a-zA-Z]/.test(v)){
                            pl++;
                        }
                        if(/[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]/.test(v)){
                            pl++;
                        }
                        if(pl<=1){
                            return "密码再设复杂点吧,亲";
                        }
                        return true;
                    }
                }
            });
        });
    </script>
</head>
<body>
    <div style="position: absolute; left:30%;top:30%">
        <form id="form" action="http://www.baidu.com" method="POST">
            <lable>
                email:<input type="text" name="email" class="validate[required,email]"/></br>
                password:<input type="text" class='validate["required",c{validatePassword}]' name="password" id="password" /><br/>
                confirmation:<input type="text" class="validate[c{eq($('password').get('value'))}]" name="confirm" /> <br/>
                <input type="submit" value="submit"/>
            </lable>
        </form>
    </div>
</body>
</html>

 效果如下:

 
Mootools之FormCheck的扩展_第1张图片


Mootools之FormCheck的扩展_第2张图片

详细的使用示例请参看rar附件中的使用文档....

 

将FormCheck1.6.rar中的formcheck.js替换原来1.6版本下的forcheck.js(不用担心,完全兼容原来的)

你可能感兴趣的:(JavaScript,mootools,formcheck)