jQuery Unobtrusive Validation - 远程验证会忽略误报和设置吗?

时间:2013-04-29 08:39:55

标签: asp.net-mvc-3 jquery jquery-validate

我认为我为MVC网络应用程序使用jQuery Unobtrusive Validation设置了一个漂亮的防弹设置,但是最近的一个错误令我非常困惑。

我希望所有验证都保持一致,因此请使用远程验证属性和控制器方法来涵盖独特的电子邮件/用户名检查等内容。我很早就开始研究,在form.valid()调用中导致错误肯定不会导致服务器端延迟,因此黑客会挂起一个挂起的验证检查,并等待一段时间等到验证完成后再输出错误消息或提交表单。

下面的代码绑定onclick函数并关闭表单的onkeyup验证:

$(document).ready(function () {

            // Bind events to buttons so they can be removed later
            $('#btnSave').click(function () {
                SaveEntry();
            });

            $('#btnCancel').click(function () {
                $('#dialog-Timesheet').dialog('close');
            });

            var $form = $("#btnSave").closest("form");

            // Just something I was trying..
            $.validator.unobtrusive.parse($form); 

            // Find the validator and turn temporarily turn of onkeyup validation to prevent user making the form valid before the remote validation is complete
            var validator = $form.data("validator");

            // Seems to work with the below on its own but keyup still fires validation later
            validator.settings.onkeyup = false;

        });

然后我有先前绑定的SaveEntry()方法找到表单,找到它的验证器,并使用间隔,在最终检查表单并输出错误消息或提交ajax之前检查是否有任何挂起的验证请求请求:

function SaveEntry() {

        var $form = $("#btnSave").closest("form");
        var validator = $form.data("validator");

        var closeButton = "<br/><input type='button' value='OK' style='font-size:small; font-weight:bold; float:right;' onclick=\"$('#dialog-Timesheet').dialog('close');\" class='greenbutton' />";
        var errorMessage = "";
        var successMessage = "";

        // Starts the remote validation checks
        if ($form.valid()) {
        }

        // Call function every 30 milliseconds
        interval = setInterval(pendingValidationComplete, 30);

        // Saves or validates as long as no validation pending
        function pendingValidationComplete() {

            // This only runs once remote validation is finished
            if (validator.pendingRequest === 0) {

                clearInterval(interval);

                //Force validation to present to user (this will not retrigger remote validation)
                if ($form.valid()) {
                    // If is valid then submit
                    if ($('#TimeSheetEntryID').val() > 0) {
                        $.ajax(
                        {
                            type: "POST",
                            url: "/Timesheet/EditEntry",
                            data: "id=" + $('#Id').val() + "&" + $form.serialize(),
                            success: function (result) {
                                ShowData("fromCookie", "current");
                                successMessage = "<div style='text-align:center; margin-top: 10px;'>" + result + "<div>";
                                $openDialog.html(successMessage + closeButton);
                            },
                            error: function (jqXhr, textStatus, errorThrown) {
                                // Populate dialog with error message and button
                                errorMessage = "<div style='text-align:center'>Error '" + jqXhr.status + "' (Status: '" + textStatus + "', errorThrown: '" + errorThrown + "')<div>";
                                $openDialog.html(errorMessage + closeButton);
                            }
                        });
                    } else {
                        $.ajax(
                        {
                            type: "POST",
                            url: "/Timesheet/CreateEntry",
                            data: $form.serialize(),
                            success: function (result) {
                                ShowData("fromCookie", "current");
                                successMessage = "<div style='text-align:center; margin-top: 10px;'>" + result + "<div>";
                                $openDialog.html(successMessage + closeButton);
                            },
                            error: function (jqXhr, textStatus, errorThrown) {
                                // Populate dialog with error message and button
                                errorMessage = "<div style='text-align:center'>Error '" + jqXhr.status + "' (Status: '" + textStatus + "', errorThrown: '" + errorThrown + "')<div>";
                                $openDialog.html(errorMessage + closeButton);
                            }
                        });
                    }
                }

                //else { alert("invalid"); }
            }

            //else { alert("NOT YET"); }
        };
    }

所以,所有这些都很有效,除了在测试不同的问题时我发现如果你提交表单,它将按预期使所需的字段无效,但是如果你那么足够快地纠正所需的字段(大概是在它的时候)正在循环进行挂起验证,虽然我一直在努力测试这个,因为调试导致延迟)它将提交请求,即使你没有点击,因为你看到了原始的错误消息。所以我认为onkeyup必须重置验证器(及其挂起的验证值)或其他东西,所以间隔中的下一次检查是有效的并且它提交了吗?但是我在文档或我看过的各种帖子中找不到任何确认内容。

作为临时解决方法,我想停止表单的onkeyup,但在同一场景中 - 快速将有效数据输入到无效字段中 - onkeyup触发并且表单提交!我想这是相关的,但验证器设置总是显示onkeyup = false,所以我无法理解验证和提交的原因。

欢迎任何想法。在向控制器方法返回部分的ajax请求之后,表单在jQuery对话框中显示。没有什么特别的HTML。

如果我能更清楚或添加任何帮助,请告诉我。

1 个答案:

答案 0 :(得分:0)

好吧,可能是随机黑客历史上最黑客的黑客攻击但是我最终在对话框中添加了一个覆盖div以停止字段和按钮交互并重置输入值,如下所示强制通过验证重新评估表单后续点击:

// Force validation to reevaluate next time
var inputs = $form.find(":input");
inputs.removeData("previousValue");

这实际上并没有重置值,但它似乎删除了验证器用于将字段标记为有效或无效的任何内容。我不会将此标记为“答案”,但它肯定是完成任务的一种方法!