如何将jQuery Validation插件与元数据、jQuery Forms和xVal一起使用?

21

我一直在使用.NET的xVal框架,结合jQuery验证插件jQuery表单插件来连接服务器端模型的某些验证规则以及客户端验证。

然而,我遇到了将它们全部连接起来的问题。

我想要实现以下目标:

  1. 允许客户端使用通过调用jQuery验证插件的rules("add", options")方法定义的基本验证(这就是xVal使用的获取在服务器端上定义在模型上的规则的方式)。

  2. 如果客户端验证成功,则进行调用向服务器输入表单数据并再次执行验证(对于在客户端验证的项,以及任何无法在客户端执行的其他验证)。

  3. 使服务器返回一个JSON对象,指示可能具有特定字段的任何错误,然后设置这些字段的错误显示。

通过对xVal进行调用,我已经通过ASP.NET MVC页面为插件设置了元数据,如下所示:

<%= Html.ClientSideValidation<Model>("model") %>

这将在客户端转化为以下内容:

<script type="text/javascript">
xVal.AttachValidator("model", 
{
    "Fields": 
    [ 
        {
            "FieldName":"title",
            "FieldRules": 
            [
                {
                    "RuleName":"Required",
                    "RuleParameters":{}
                },
                {
                    "RuleName":"StringLength",
                    "RuleParameters":
                    {
                        "MaxLength":"250"
                    }
                }
            ]
        },
        {
            "FieldName":"body",
            "FieldRules":
            [
                {
                    "RuleName":"Required",
                    "RuleParameters":{}
                }
            ]
        }
    ]
}, {})
</script>

上面的代码实际上只是一系列调用 rules("add", options) 的操作,然后由 jQuery 验证插件进行处理。

但是,当尝试通过 jQuery 表单提交时,验证不会对表单值进行验证。表单会被提交,但值根本没有经过验证。

如何在使用 jQuery Form 插件提交表单时,通过调用 ajax 进行 jQuery 验证插件的验证?

1个回答

5
当把所有内容组合在一起时,最重要的是要注意文档中的一个小细节(xVal文档中并不明显,它将rules("add", options)的调用抽象为xVal.AttachValidator的调用),即rules("add", options)的文档(强调我的部分):
添加指定规则并返回第一个匹配元素的所有规则。需要验证父表单,也就是首先调用$("form").validate()。
当使用jQuery Form插件并且想要通过AJAX提交表单时,这一点尤其重要,因为你必须在调用validate(options)时设置submitHandler选项,如下所示:
<script type="text/javascript">
    $(document).ready(function() {
        // Initialize the form.  Store the validator.
        var validator = $("form").validate({

            // Called when the form is valid.
            submitHandler: function(form) {

                // Submit the form via ajax.
                $(form).ajaxSubmit({

                    // The return data type is json.
                    dataType: "json",

                    // The callback on a successful form
                    // submission.
                    success: function(data, statusText) {

                        // If the new location is not null, then
                        // redirect to that location.
                        if (data.data.newLocation) {
                            // Go to the new location.
                            document.location.href = data.data.newLocation;

                            // Get out.
                            return;
                        }

                        // There are errors, pass them to the validator
                        // for display.
                        validator.showErrors(data.data.errors);
                    }
                });
            }
        });
    });
</script>

由于上述有关调用rules("add", options)的文档,因此必须在调用rules("add", options)之前调用validate(options)
如果不这样做,则submitHandler将被忽略,永远不会被调用。
最终,这意味着当将所有内容组合在一起时,您的客户端代码必须如下所示:
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="jquery.validate.min.js"></script>
<script type="text/javascript" src="jquery.form.js"></script>
<!-- Note this is only needed if using xVal. -->
<script type="text/javascript" src="xVal.jquery.validate.js"></script>
<!-- The call to validate the form must come first. -->
<script type="text/javascript">
    $(document).ready(function() {
        // Initialize the form.
        $("form").validate({

            // Called when the form is valid.
            submitHandler: function(form) {

                // Submit the form via ajax.
                $(form).ajaxSubmit({

                    // The return data type is json.
                    dataType: "json",

                    // The callback.
                    success: function(data, statusText) {

                        // Alert the users to the message.
                        window.alert(statusText);
                    }
                });
            }
        });
    });
</script>

<!-- Now make the calls to rules("add", options), AFTER the call to -->
<!-- validate (options). It's separated into another block for      -->
<!-- emphasis, but could be done in the block above.                -->
<script type="text/javascript">
    // Make calls to rules("add", options).
</script>

<!-- Or, if you are using xVal, make the following call in the ASP.NET -->
<!-- page but again, note it must come AFTER the call to               -->
<!-- validate(options).                                                -->
<%= Html.ClientSideValidation<Model>("model") %>

最后,当服务器端方法返回时,需要做的最后一件事情就是如何处理。
你希望这些调用返回的JSON格式类似于标准化视图模型外壳,其中响应特定内容包装在更标准化的部分中,跨同类调用暴露所需信息,类似于这样:
{
    // An integer, non-zero indicates faulure, with predefined ranges
    // for standard errors across all operations, with other ranges for custom
    // errors which are operation-specific.  Examples of shared errors
    // are not authenticated, not authorized, etc, etc.
    resultCode: 0,

    // A string, which is to be displayed to the user (usually in the
    // form of a jQuery dialog, usually used for the common ranges of
    // errors defined above.
    message: null,

    // An object with operation-specific results.
    data: null
}

对于服务器上的错误,请返回与上述相同的内容,但附带一个位置,其中包含用户在成功时应重定向到的URL(如果不成功,则为null),以及一个映射表,如果字段存在错误,则可以直接传递给showErrors(errors)方法。
{
    resultCode: 0,

    message: null,

    data:
    {
        // Returned as a string.  If not null, then this is the url
        // that the client should be redirected to, as the server-side
        // operation was successful.
        newLocation: null,

        // If not-null, then this is a map which has the names of the
        // fields with the errors, along with the errors for the fields.
        errors:
        {
            "model.title": "The title already exists in the system.",
            "model.body": "The body cannot have malicious HTML code in it."
        }
    }
}

鉴于此,传递给 ajaxSubmitoptions 参数中的 success 字段 应该是清晰明了的:

// The callback on a successful form
// submission.
success: function(data, statusText) {

    // If the new location is not null, then
    // redirect to that location.
    if (data.data.newLocation) {
        // Go to the new location.
        document.location.href = data.data.newLocation;

        // Get out.
        return;
    }

    // There are errors, pass them to the validator
    // for display.
    validator.showErrors(data.data.errors);
}

它所做的只是检查newLocation属性是否已定义。如果已定义,则将当前文档重定向到该位置(通常是新保存资源的URL)。

如果未定义,则将地图传递给validate(options)调用返回的验证器中的showErrors,并使用调用validate(options)指定的定位和样式设置错误消息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接