当前位置: 代码迷 >> Web前端 >> jQuery插件开发示范:表单验证
  详细解决方案

jQuery插件开发示范:表单验证

热度:213   发布时间:2012-09-19 13:43:54.0
jQuery插件开发示例:表单验证

上周写了一个页面,里面有一个很大的form,一个一个写验证太麻烦了,于是写了一个jQuery的表单验证插件。我希望达到这样的效果:

?

  1. 调用应该是链式的,如:
$('#form').required('input1Name').maxlength('input1Name',7).required('input2Name').email('input2Name').validate(userSpecifiedConfig);
? ? ? ? ? 以上语句达到的效果是name属性为input1Name的表单项必填,最长长度为7;name属性为input2Name的表单项必填,并符合email的格式。
? ? ?2. 插件应该是可配置的,通过上面的userSpecifiedConfig对象,修改或者部分修改默认配置

jQuery的官网上有一篇灰常强大的插件tutorial,解决了我所有的问题,地址,这篇文章实际上规定了写插件的一种范式,或者叫“最佳实践”,如下:

(function($){
  //overridable configuration
  var config = {
      validateOnBlur : true,

      showAllErrorOnSubmit : true,

      validateFailCallBack : function(rule){
          alert(rule.explain);
      }
      
  };

  //public method
  var methods = {
    validate : function(options) {
        return this.each(function() {        
            // If options exist, lets merge them
            // with our default settings
            if ( options ) { 
                $.extend( config, options );
            }

           //do other stuff

    });
    },

    required : function(inputName,explain){
        //Maintaining Chainability
        return this.each(function(){
               //do your thing
        });
    },

  };

  $.fn.validate = function( method ) {
    // Method calling logic
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.validate.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.validate' );
    }    
  
  };
})(jQuery);

  • 首先,所谓的闭包,整个插件代码用(function( $ ){ })( jQuery );包起来,这样,你就不用担心插件内部定义的函数名与外部冲突了,当然,你扩展的$.fn对象名字依然不能和$.fn中已有的对象冲突
  • 在插件的开头,定义你的config对象,写上你的配置项和默认值。那么,如何修改这些配置呢,请往下面看。
  • 现在该定义插件的公共方法了,由于几乎所有的插件都是在扩展$.fn,所以项目规模大的话,很容易会有命名冲突,官网的tutorial甚至要求一个插件只占用$.fn中的一个名字。现在我想定义很多公共方法,怎么办呢,解决方法是类似
$('#1').bind('focus',function(){});
?
? ? ? ? ? ?这种风格的API,将方法名字作为第一个参数传入。同时我在插件里定义一个methods对象,将各种方法的实现塞在里面
  • 下面具体看每个方法的实现,以代码中的methods.validate函数为例,首先,不加思索的,第一行写上return this.each(function(){}),这是为了返回this对象,从而实现链式的调用,有点诡异,看来each返回的是调用者本身?API上并没有提到这点。然后,如果你需要修改默认配置,得在函数参数里加上比如说option,option应该类似这样的
option={
    validateOnBlur :false
}
?
? ? ? ? ? 然后用一个很神奇的$.extend()方法来搞定参数的更新,好吧,我承认,要不是看了白纸黑字,我绝对想不到还有 这么个函数。。这样我就告诉插件,在文本框blur的时候不用验证了,最后submit时验证就可以了。
  • 写完公共方法后,下一个是重头戏,我们要在$.fn里加一个函数,这样插件才能被$对象调用,最牛叉的是,这个函数别人已经给写好了。。我们改个名字就可以了。这个函数就干一件事,根据第一个参数找到methods数组里对应的方法,然后把剩下的参数传给这个方法,一执行就完了。当然,你可能希望有一个函数是默认调用的,比如说,这里我希望调用validate()函数时不用再传'validate'参数了,我只需要修改else if里的语句就可以了。
介绍完范式以后,下面还是说说表单验证吧,为了防止命名冲突,我的插件的调用方法已经变了,先给大家看一段实际使用插件的代码:
    $('#infoform').validate('required','name','请填写公司名称')
    .validate('required','password','请填写密码')
    .validate('required','contactName','请填写联系人姓名')
    .validate('chineseName','contactName')
    .validate('required','province','请选择您所在的省')
    .validate('required','city','请选择您所在的城市')
    .validate('required','address','请填写您所在的地址')
    .validate('required','email','请填写您的电子邮箱地址')
    .validate('email','email','请填写有效的电子邮箱地址')
    .validate('custome','confirmPassword',function(){
        var p = $(':password[name=password]').attr('value');
        var confirm = $(':password[name=confirmPassword]').attr('value');
        if(p == confirm){
            return true;
        }
        return false;
    },'确认密码与密码不符')
    .validate({
        validateFailCallBack : function(rule){
            $(':input[name='+rule.name+']','#infoform').each(function(){
                 var parent = $(this).parent();
                 parent.addClass('fm-error');
                 $('.fm-explain',parent).html(rule.explain);
                 //reset when on focus again
                 $(this).bind('focus',function(){
                   //clear error style
                 });
            });  
        }
    });
?这样就搞定了一个表单的验证,很方便有木有!!
  1. ?可以看到,我定义了很多的公共方法,除了required,还有email、姓名之类的,用来对不同格式的文本做验证,如果插件里实在没有,还可以调用custome方法,向这个方法注册一个回调的验证函数就可以了,这里,我用custome方法实现了对确认密码栏的验证
  2. 使用时基本上是要重写config中的validateFailCallBack方法了,我提供的默认方法只是把错误信息alert出来。
就这么多了,很简单吧,jQuery用起来是舒坦啊,怪不得这么火了。

另外,我腆着脸把代码附在下面了,请给点意见哦,呵呵






?

  相关解决方案