欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Mootools之FormCheck的扩展

程序员文章站 2022-06-08 18:53:25
...

本文章对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的扩展
            
    
    博客分类: javascript javascriptmootoolsformcheck 


Mootools之FormCheck的扩展
            
    
    博客分类: javascript javascriptmootoolsformcheck 

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

 

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

  • Mootools之FormCheck的扩展
            
    
    博客分类: javascript javascriptmootoolsformcheck 
  • 大小: 12.8 KB
  • Mootools之FormCheck的扩展
            
    
    博客分类: javascript javascriptmootoolsformcheck 
  • 大小: 13.1 KB