代码改变世界

Fancy Validate 与 jQuery.validate 对比(下):进阶篇

2012-02-22 22:31 by 囧月, ... 阅读, ... 评论, 收藏, 编辑

上一篇对比了Fancy ValidatejQuery.validate的使用,本篇将进一步介绍两者在使用上的异同。

自定义验证规则

当默认的验证规则无法满足使用需求的时候,就需要自定义验证规则了。

先特别说明一下,Fancy ValidatejQuery.validate都提供了一个optional方法,用于表单元素值不为空时才触发验证。

jQuery.validate自定义验证规则:

jQuery.validator.addMethod("division", function(value, element) {
    return this.optional(element) || value % 2 == 0 && value % 3 == 0;
}, "必须能被2和3整除");

Fancy Validate的定义方式也一样:

$f.addMethod("division", function(value, element) {
  return this.optional(element) || value % 2 == 0 && value % 3 == 0;
}, "必须能被2和3整除");

如果要在元素值为空时也触发验证,把optional方法移除即可:

$f.addMethod("division", function(value, element) {
  return value % 2 == 0 && value % 3 == 0;
}, "必须能被2和3整除");

此外,Fancy ValidatejQuery.validate都支持为规则指定参数,但只支持一个参数,如下:

$f.addMethod("method2", function(value, element, param) {
  return value == param;
}, "必须相等");

如果需要指定多个参数,只能把param作为Array/Object(JSON)类型。

Fancy Validate还支持添加正则表达式规则:

$f.addPattern("re1", /^abc.*$/i, "必须abc开头(不区分大小写)");

需要注意的是,因为添加的正则表达式规则会被保存起来,所以不能"g"(全局)参数,否则会导致这个RegExp规则的lastIndex累加,从而导致验证结果不正确。

以上自定义规则使用方法与内置的规则一样:

$f("fancyform", {
  rules: {
    inputxxx: {
      division: 1,
      method2: "囧月",
      re1: 1
    }
  }
  //...其他参数
});

自定义默认提示信息

Fancy ValidatejQuery.validate都内置了一些规则的默认提示信息,定义的方式也一样:

jQuery.validator.messages = {
  required: "必填"
  // 其他...
}

// fancy validate
$f.messages = {
  required: "必填"
  // 其他...
}

// 或者仅重定义单个
$f.messages.required = "必填"

另外也可以通过extend方法来重定义:

jQuery.extend(jQuery.validator.messages, {
  required: "必填"
  // 其他...
});

// fancy validate
$f.core.extend($f.messages, {
  required: "必填"
  // 其他...
});

提示信息的呈现

Fancy ValidatejQuery.validate默认都是把提示信息添加到表单元素的(nextSibling)下一个节点之前,如果需要添加到其他地方,则Fancy Validate需要通过自定义appendLabel函数,jQuery.validate需要通过自定义errorPlacement函数来实现。

有区别的是,Fancy Validate在容器中显示($f.appendContainer)也是使用这种方法,而jQuery.validate是通过设置errorContainer参数,具体上一篇已介绍过。

Fancy Validate除了默认的$f.appendNext,还提供了作为父元素的最后一个子节点

$f("fancyform", {
  //...各种规则
  , appendLabel: $f.appendLast
});

此外,在容器中显示的$f.appendContainer函数默认为提示信息设置了top/left值,所以可以用于实现绝对定位:

$f("fancyform", {
  //...各种规则
  , errorCls: "error ab"
  , container: document.body
  , appendLabel: $f.appendContainer
});

当然,默认的$f.appendNext$f.appendLast也可以实现绝对定位,没有top/left值倒也没影响。

完全自定义提示

Fancy ValidatejQuery.validate都可以通过自定义showErrors函数来实现完全自定义提示信息的呈现,仅演示fancy validate:

$f("fancyform", {
  //...各种规则
  , showErrors: function() {
    var msg = [];
    this.errors.each(function(err) {
      msg.push(err.message);
    });
    if (msg.length) alert(msg.join("\r\n"));
  }
});

提示效果

jQuery.validate仅提供了一个简单的提示效果,如果需要更丰富的则需要自定义css样式。

Fancy Validate除了默认的提示效果,还提供了以下提示效果:

气泡提示效果,需要设置以下选项:

$f("fancyform", {
  // rules 及 messages等其他选项……
  , validCls: ""
  , errorCls: "bblue m4l3"
  , errorElement: "div"
  , container: document.body
  , appendLabel: $f.bubbleTip
  , labelText: $f.tipText
});

主要样式为errorCls,"m4l3"用于位置偏移,相应的色彩风格有:bblue,bblue2,bblue3,bgreen,bgreen2,bred,borange,bcream,bdark,bblack

箭头提示效果,需要设置以下选项:

$f("fancyform", {
  // rules 及 messages等其他选项……
  , validCls: ""
  , errorCls: "aorange m40"
  , errorElement: "div"
  , container: document.body
  , appendLabel: $f.arrowTip
  , labelText: $f.tipText
});

主要样式为errorCls,"m40"用于位置偏移,相应的色彩风格有:ablue,ablue2,ablue3,agreen,agreen2,ared,aorange,acream,adark,ablack

以上2种提示都是通过自定义appendLabel和labelText函数来实现提示效果,其中appendLabel用于创建提示的html标记,labelText用于设置呈现提示信息,如以上的2种效果具体的实现如下:

    bubbleTip: function(label, element) {
      dom.addClass(label, "b-b e-bubble");
      $f.appendContainer.call(this, label, element);
      label.innerHTML = '<span class="b-cor b-cor10 e-b-bot"></span><span class="b-cor b-cor10 e-b-top"></span><p class="b-con"></p>';
      label.textNode = label.childNodes[2];
    },

    arrowTip: function(label, element) {
      dom.addClass(label, "b-b e-arrow");
      $f.appendContainer.call(this, label, element);
      label.innerHTML = '<span class="b-cor b-cor15"></span><p class="b-con"></p>';
      label.textNode = label.childNodes[1];
    },

    tipText: function(label, message) {
      label.textNode.innerHTML = message;
    }

更多丰富的提示效果都可以通过自定义appendLabel和labelText函数来实现,而jQuery.validate也提供errorPlacement可以用来实现类似的效果:

errorPlacement: function(error, element) {
   error.html("提示效果的html");
   error.appendTo("#container");
}
这里不再作具体演示。

默认的事件

默认不触发验证

Fancy ValidatejQuery.validate默认会在表单提交时触发验证,可以通过设置参数(fancy validate设置interceptSubmit参数为false,jQuery.validate的参数为onsubmit),以实现只让指定的按钮来触发验证:

var val = $f("fancyform", {
  //...各种规则
  , interceptSubmit: false
});

xxx.onclick = function() {
  val.onSubmit();
}

不在输入时触发验证

Fancy Validate监听了表单元素的focusin,focusout,input,keyup,click事件,关闭事件监听很简单:

$f("fancyform", {
  //...各种规则
  , interceptInput: false
});

jQuery.validate监听了表单元素的onfocusin,onfocusout,onkeyup,onclick事件,关闭监听需要把这4个参数设置为空:

$("#fancyform").validate({
  //...各种规则
  , onfocusin: null
  , onfocusout: null
  , onkeyup: null
  , onclick: null
});

Ajax验证

Fancy Validate内置的ajax验证很简单,使用POST方式提交表单元素的值,再判断返回值是否与"1"相等:

$f("fancyform", {
  username: { required: 1, ajax: "ajax.ashx" }
});

或者自定义判断:

$f("fancyform", {
  username: { required: 1, ajax: {
      url: "ajax.ashx"
      , callback: function(text) {
        return text == "true";
      }
    }
  }
});

服务器端ajax.ashx的实现如下:

    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";
        context.Response.Write(context.Request.Form[0] == "12345" ? "1" : string.Empty);
    }

而jQuery.validate默认则是验证返回的值是否等于"true":

    $("#fancyform").validate({   
       rules: {   
         username: {   
           required: true,   
           remote: "ajax.ashx"  
         }   
       }   
    });  

结尾

本文就介绍到这里,更详细请看我的Fancy Validate相关文章,或者访问:http://code.google.com/p/fancyvalidate/下载相关DEMO。