jQuery Validation插件remote驗證方式的Bug

 

jQuery插件很多,其中一個重要的插件便是jQuery Validation,它的作用是對錶單進行驗證,還上了jQuery官網。不過奇怪的是,最近用下來感覺有些古怪,因爲好像有些死板,已有功能的應變能力還不強,甚至還有個奇怪的Bug。任何項目有Bug其實也正常,但這個Bug其實是一個文檔上已經記載了,卻沒有實現的功能,這就有些說不過去了。這個問題便出在remote驗證方式上,還好修改起來非常容易,在此記錄一下,也方便以後的參考。

在表單驗證時,有時候會需要發一個AJAX請求去服務器上進行判斷,例如在用戶註冊時檢查用戶名是否存在。jQuery Validation插件提供了一種remote方式來實現這一點。例如我可以這樣驗證表單:

<form id="regForm">
    <input type="text" name="userName" />
</form>

<script language="javascript">
    $('#regForm').validate({
        'rules': {
            'userName': {
                'required': true,
                'remote': '/account/verify'
            }});
</script>

這樣,jQuery Validation便會請求“/account/verify?userName=jeffz”這樣的URL來獲取true/false。可惜的是,我們在使用ASP.NET MVC時,往往會將input的name寫爲特定的形式,目的是利用DefaultModelBinder的強大綁定功能。例如:

<form id="regForm">
    <input type="text" id="userName" name="user.Name" />
</form>

與此同時,我們用來進行驗證的Action方法,它的參數名可能也有所不同:

public ActionResult Verify(string name) { ... }

根據文檔描述,此時我們應該這樣寫:

$('#regForm').validate({
    'rules': {
        'user.Name': {
            'remote': {
                url: '/account/verify',
                data: {
                    name: function() { return $("#userName").val(); }
                }}}}});

可是,從實際效果來看,jQuery還是在請求“/account/verify?user.Name=jeffz”,百思不得其解。確認在三之後只得求助於jquery.validation.js源碼,看後差點暈過去:

remote: function(value, element, param) {
    if ( this.optional(element) )
        return "dependency-mismatch";
    
    ...
    
    param = typeof param == "string" && {url:param} || param; 
    
    if ( previous.old !== value ) {
        previous.old = value;
        var validator = this;
        this.startRequest(element);
        var data = {}; 
        data[element.name] = value; // data還是以element.name爲準?
        $.ajax($.extend(true, {
            url: param,
            mode: "abort",
            port: "validate" + element.name,
            dataType: "json",
            data: data,
            success: function(response) {
                ...

我很奇怪,不知道爲什麼會這樣做,這樣根本沒有起到指定參數名的作用。那麼,改吧:

remote: function(value, element, param) {
    if (this.optional(element))
        return "dependency-mismatch";

    ...

    param = typeof  param == "string" && {url:param} || param;

    if (previous.old !== value) {
        previous.old = value;
        var validator = this;
        this.startRequest(element);
        var data = {};
        data[element.name] = value;
        $.ajax($.extend(true, {
            // url: param,
            url: param.url,
            mode: "abort",
            port: "validate" + element.name,
            dataType: "json",
            // data: data,
            data: param.data || data,
            success: function(response) {
                ...

修改兩處即可,問題就此解決。只可惜,jquery.validate.min.js類似的文件只能自己進行壓縮了。

居然會出現這樣的問題,實在令人費解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章