论坛首页 Web前端技术论坛

用prototype实现的form表单验证(进行了改进和内容的扩充)

浏览 7906 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-07-27  
validate.js(我已经改进了很多,这是新的)
   var Validator = Class.create();
    Object.extend(Validator.prototype,{ 
		initialize : function(form,className,options){
			this.form = $(form);
            this.options = Object.extend({
                onlyNum : 'num',
                required : 'required',
                url : 'url',
	       maxLength : 'maxLength'     
            },options || {});
            this.className = className;
	   this.fireType = null;
            this.checked();//动态添加的元素可以再次执行checked方法以加载验证
        },
        checked : function () {
            this.form.getElements().each(function(obj,index){
                if(this._isExistAttribute(obj,this.options.onlyNum)){
                    this._onlyNum(obj);
                };
                if(this._isExistAttribute(obj,this.options.required)){
                    obj.setStyle({
                        background : 'url(/images/required1.gif) no-repeat right top'
                    })
					setInterval(function(){if(!obj.value.blank())
								obj.style.background = 'url(/images/required.gif) no-repeat right top';
							else
								obj.style.background = 'url(/images/required1.gif) no-repeat right top';
					}.bind(this),10)
					
                };
				if(obj[this.options.maxLength]){
					Event.observe(obj,'keydown',function(){
						if(obj.value.length>parseInt(obj[this.options.maxLength]))
							event.returnValue = false;	
					}.bind(this,obj))
				}
                if(obj[this.options.url]){
                    Event.observe(obj,'change',function(){
                        new Ajax.Request(obj[this.options.url],{
                            parameters : {value : obj.value},
                            onComplete : function(transport){
								if(transport.responseText == 'true'){
                                   	if(!$(obj.id+'Div'))
										this._createMsgDiv(obj,obj.urlMsg);
                                    obj.focus();
                                   	obj.value = '';
                                }else
									if($(obj.id+'Div'))
                                    	this._destoryMsgDiv(obj.id+'Div');
                            }.bind(this)
                        })
                    }.bind(this,obj))
                }
            }.bind(this))
        },
        //sumbit validate
        fireSubmit : function (){
          if(!this.fireType)  this.fireType = event.srcElement;
		  var _needArr =  this.form.getElements()
                            .findAll(function(obj){return this._isExistAttribute(obj,this.options.required)&& obj.value.blank()}.bind(this));
           if(event.srcElement == this.fireType && _needArr.length == 0) this.form.submit();
           else 
                _needArr.each(function(o){
					Event.observe(o,'blur',function(){
                          if(!o.value.blank()){
                               if($(o.id+'Div')) this._destoryMsgDiv(o.id+'Div');
								o.setStyle({
                        			background : 'url(/images/required.gif) no-repeat right top'
                    			})
                                this.fireSubmit();
                          }else{
                                o.focus();
                          }
                    }.bind(this,o));
                    o.focus();
                    var msg = o.msg || 'the element can not empty';
                    this._createMsgDiv(o,msg);
                    throw $break;
            }.bind(this));
                
        },
        //create show message div
        _createMsgDiv : function(el,msg){
                //IE6 select fix
                if(!this.underlay){//ie select fix
                    this.underlay = document.body.appendChild(Builder.node('iframe',{id:'iframe'}));
                    Element.setStyle(this.underlay, {
                        position: 'absolute',
                        display: 'none',
                        border: 0,
                        margin: 0,
                        opacity: 0.01,
                        padding: 0,
                        background: 'none'
                    });
                }
                var _nDiv = document.body.appendChild(Builder.node('div',{id:el.id+'Div',className:this.className}));
				_nDiv.innerText = msg.replace(/(^\s*)|(\s*$)/g, "");
                _nDiv.style.height = el.offsetHeight;
                switch (el.position){
					case 'left' :
						_nDiv.style.left = Position.cumulativeOffset(el)[0] - _nDiv.offsetWidth - 3 +'px';
                		_nDiv.style.top = Position.cumulativeOffset(el)[1] + 'px';
                        break;
					case 'up' :
						_nDiv.style.top = Position.cumulativeOffset(el)[1]- el.offsetHeight - 3+ 'px';
						_nDiv.style.left = Position.cumulativeOffset(el)[0] + 'px';
						break;
					case 'down' :
						_nDiv.style.top = Position.cumulativeOffset(el)[1]+ el.offsetHeight + 3+ 'px';
						_nDiv.style.left = Position.cumulativeOffset(el)[0] + 'px';
						break;
					default :
						_nDiv.style.top = Position.cumulativeOffset(el)[1] + 'px';
						_nDiv.style.left = Position.cumulativeOffset(el)[0] + el.offsetWidth + 3 + 'px';
				}
				this.underlay.style.height = _nDiv.offsetHeight;
				this.underlay.style.left = _nDiv.style.left;
				this.underlay.style.top = _nDiv.style.top;
                this.underlay.style.width = _nDiv.offsetWidth;
		        $('iframe').show();
                _nDiv.style.display = 'none'; 
		        _nDiv.style.zIndex = '1200';
                Effect.Appear(_nDiv); 
        },
        //destory message div
        _destoryMsgDiv : function (id){
			if(!$(id)) return;
            this.underlay.hide();
			Effect.Fade(id,{afterFinish : function(){ document.body.removeChild($(id))}});
        },
        _isExistAttribute : function(el,attr){
            return el.readAttribute(attr)!=null ? true : false;
        },
        //only input number
        _onlyNum : function(obj){
            Event.observe(obj,'keydown',function(e){
                var e1 = event || e;
                   	if(!((e1.keyCode>=48&&e1.keyCode<=57)||(e1.keyCode>=96&&e1.keyCode<=105)||(e1.keyCode==8)||(e1.keyCode==190)))
				        if(e1.keyCode==13)
					       e1.keyCode=9
				    else 
					   e1.returnValue=false; 
            });
        }
    })

使用时的页面
<html>

<head>
<style type="text/css">
    .msg {
    position : absolute;
    background:#85BBEF;
    padding : 2px 5px 2px 5px;
    font : 12px #FFFFFF 新宋体;
    border : 1px solid black;
	
    }
</style>
<script src='prototype.js'></script>
<script src='effects.js'></script>
<script src='builder.js'></script>
<script src='validator.js'></script>
<script language="javascript" type="text/javascript">
    Event.observe(window,'load',function(){
       validator = new Validator('form1','msg');
    })
</script>
<title></title>

</head>

<body>
    <form id='form1' action='ajaxsubmit'>
        <input type='text' num id='tx1' required msg=' o k '  maxLength='2'  />
        <select>
            <option>asfasdfasdf</option>
        </select>
		<input type='text' id='tx3' required msg='用户名不能为空' position="left"/>
        <input type='text'  id='tx2'  />
        <input type='button' onclick='validator.fireSubmit()' />
    </form> 
</body>

</html>

希望大家指出不足,一起讨论,一起进步
  • validator.rar (33.4 KB)
  • 描述: 这是所有的图和源码
  • 下载次数: 314
   发表时间:2007-07-27  
...看看这里
http://wiki.javascud.org/display/si/Javascript_EasyValidation
0 请登录后投票
   发表时间:2007-07-27  
谢谢Ivan Li,我会好好学习你写的源码,做成你那样是我的目标
0 请登录后投票
   发表时间:2007-07-27  
Ivan, EasyValidation看上去很不错啊,这么好的东西怎么不多多宣传呢?

如果可以和webwork的服务器端验证集成到一起就更好了
0 请登录后投票
   发表时间:2007-07-28  
Ivan Li 写道
...看看这里
http://wiki.javascud.org/display/si/Javascript_EasyValidation


to:Ivan Li.

引用

1. 我的网站现在使用的是UTF-8编码,怎么使用validation_cn.js显示中文会乱码?
答: validation_cn.js默认是使用GBK编码,使用可以改变文件编码的编辑器以UTF-8编码方式再保存,如保存为validation_cn_UTF-8.js


建议通过转义字符去解决这个问题。
比如: 将“中文” 编码成: “\u4e2d\u6587”

这样部署的时候就不会有中文乱码。

写一个简单的程序就可以转换过来,用JSA压缩后,也会自动处理这种问题。


仍外,代码注释中有中文也是危险的,编码不匹配的时候,有可能导致无法准确找到注释的结尾。
0 请登录后投票
   发表时间:2007-08-21  
badqiu才是最大的功臣,这个主要是badqiu搞的!我只是跟着瞎参合了一下。
0 请登录后投票
   发表时间:2007-08-21  

呵呵,我目前的做法比较简单。直接用的Event.observe,把回调函数直接写出来。比较直接。但是重用性不好。正好可以学学楼主的这个!

0 请登录后投票
   发表时间:2007-08-23  

var Validator = Class.create();
    Object.extend(Validator.prototype,{ 
		initialize : function(form,className,options){
			this.form = $(form);
            this.options = Object.extend({
                onlyNum : 'num',
                required : 'required',
                url : 'url',
				maxLength : 'maxLength'     
            },options || {});
            this.className = className;
	   this.fireType = null;//作用在后面说明
            this.checked();
        },
        checked : function () {
            this.form.getElements().each(function(obj,index){
                if(this._isExistAttribute(obj,this.options.onlyNum)){
                    this._onlyNum(obj);
                };
                if(this._isExistAttribute(obj,this.options.required)){
                    obj.setStyle({
                        background : 'url(required1.gif) no-repeat right top'
                    })
					setInterval(function(){if(!obj.value.blank())
								obj.style.background = 'url(required.gif) no-repeat right top';
							else
								obj.style.background = 'url(required1.gif) no-repeat right top';
					}.bind(this),10)
					
                };
				if(obj[this.options.maxLength]){
					Event.observe(obj,'keydown',function(){
						if(obj.value.length>parseInt(obj[this.options.maxLength]))
							event.returnValue = false;	
					}.bind(this,obj))
				}
                if(obj[this.options.url]){
                    Event.observe(obj,'change',function(){
                        new Ajax.Request(obj[this.options.url],{
                            parameters : {value : obj.value},
                            onComplete : function(transport){
								if(transport.responseText == 'true'){
                                   	if(!$(obj.id+'Div'))
										this._createMsgDiv(obj,obj.urlMsg);
                                    obj.focus();
                                   	obj.value = '';
                                }else
									if($(obj.id+'Div'))
                                    	this._destoryMsgDiv(obj.id+'Div');
                            }.bind(this)
                        })
                    }.bind(this,obj))
                }
            }.bind(this))
        },
        //sumbit validate
        fireSubmit : function (){
          if(!this.fireType)  this.fireType = event.srcElement;
		  var _needArr =  this.form.getElements()
                            .findAll(function(obj){return this._isExistAttribute(obj,this.options.required)&& obj.value.blank()}.bind(this));
           if(event.srcElement == this.fireType && _needArr.length == 0) this.form.submit();
           else 
                _needArr.each(function(o){
					Event.observe(o,'blur',function(){
                          if(!o.value.blank()){
                               if($(o.id+'Div')) this._destoryMsgDiv(o.id+'Div');
								o.setStyle({
                        			background : 'url(required.gif) no-repeat right top'
                    			})
                                this.fireSubmit();
                          }else{
                                o.focus();
                          }
                    }.bind(this,o));
                    o.focus();
                    var msg = o.msg || 'the element can not empty';
                    this._createMsgDiv(o,msg);
                    throw $break;
            }.bind(this));
                
        },
        //create show message div
        _createMsgDiv : function(el,msg){
                //IE6 select fix
                if(!this.underlay){//ie select fix
                    this.underlay = document.body.appendChild(Builder.node('iframe',{id:'iframe'}));
                    Element.setStyle(this.underlay, {
                        position: 'absolute',
                        display: 'none',
                        border: 0,
                        margin: 0,
                        opacity: 0.01,
                        padding: 0,
                        background: 'none'
                    });
                }
                var _nDiv = document.body.appendChild(Builder.node('div',{id:el.id+'Div',className:this.className}));
				_nDiv.innerText = msg.replace(/(^\s*)|(\s*$)/g, "");
                _nDiv.style.height = el.offsetHeight;
                switch (el.position){
					case 'left' :
						_nDiv.style.left = Position.cumulativeOffset(el)[0] - _nDiv.offsetWidth - 3 +'px';
                		_nDiv.style.top = Position.cumulativeOffset(el)[1] + 'px';
                        break;
					case 'up' :
						_nDiv.style.top = Position.cumulativeOffset(el)[1]- el.offsetHeight - 3+ 'px';
						_nDiv.style.left = Position.cumulativeOffset(el)[0] + 'px';
						break;
					case 'down' :
						_nDiv.style.top = Position.cumulativeOffset(el)[1]+ el.offsetHeight + 3+ 'px';
						_nDiv.style.left = Position.cumulativeOffset(el)[0] + 'px';
						break;
					default :
						_nDiv.style.top = Position.cumulativeOffset(el)[1] + 'px';
						_nDiv.style.left = Position.cumulativeOffset(el)[0] + el.offsetWidth + 3 + 'px';
				}
				this.underlay.style.height = _nDiv.offsetHeight;
				this.underlay.style.left = _nDiv.style.left;
				this.underlay.style.top = _nDiv.style.top;
                this.underlay.style.width = _nDiv.offsetWidth;
		        $('iframe').show();
                _nDiv.style.display = 'none'; 
		        _nDiv.style.zIndex = '1200';
                Effect.Appear(_nDiv); 
        },
        //destory message div
        _destoryMsgDiv : function (id){
			if(!$(id)) return;
            this.underlay.hide();
			Effect.Fade(id,{afterFinish : function(){ document.body.removeChild($(id))}});
        },
        _isExistAttribute : function(el,attr){
            return el.readAttribute(attr)!=null ? true : false;
        },
        //only input number
        _onlyNum : function(obj){
            Event.observe(obj,'keydown',function(e){
                var e1 = event || e;
                   	if(!((e1.keyCode>=48&&e1.keyCode<=57)||(e1.keyCode>=96&&e1.keyCode<=105)||(e1.keyCode==8)||(e1.keyCode==190)))
				        if(e1.keyCode==13)
					       e1.keyCode=9
				    else 
					   e1.returnValue=false; 
            });
        }
    })

我的目的是当你,用fireSubmit提交时,会挨着遍历每个要添值却没有添的,但自己不会在都验证通过后,自动提交,而是当你在触发提交时才提交的,fireType记录的是你用那个元素出发fireSubmit,不一定是按钮,我们使用的就是图标
这是改进后的
我把整个源码和图都放在正文了,望大家多提意见,我会不断改进,程序就跟写作文一样,要不断的改进
0 请登录后投票
   发表时间:2007-08-23  
和楼主一样我在学习prototype的时候也参考已有的各个实现写了表单验证easyvalidation, 后来才看到baidqiu的在也取了名字,竟然和我的一样,够郁闷的,呵呵。
你可以对比着看看,大家都是初学,呵呵 。http://jianfeng008cn.iteye.com/admin/show/38717 欢迎意见建议,我计划是从小的东西入手 能写点好用js控件
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics