jQuery 验证不会清除 KeyUp 上服务器插入的错误消息

jQuery Validate won't clear server-inserted error messages on KeyUp

我们正在使用 JQuery 验证插件来进行简单的字段验证。使用默认的客户端验证时,一切都按预期工作。

但是,其中一些字段需要服务器端验证。在 HTML 中的服务器上手动创建错误标签时会出现此问题。这样做时,错误标签按预期显示,但行为是错误的。

本质上,错误标签一旦显示,就不会在该字段的KeyUp事件中被移除。它只会在您按下提交按钮时被删除,并且第一次按下提交按钮只会隐藏错误标签并将输入字段设置为有效。您必须再次按下提交按钮才能真正提交表单。看来 JQuery validate 知道错误标签及其连接的输入字段,否则在按下提交按钮时它不会被隐藏。

我尝试过的事情:

这是一个带有服务器返回错误标签的示例表单(使用 Thymeleaf):

    <div class="form-group">
    <label for="password" class="ex-label" th:text="#    {common.password}">Password</label>
    <input id="password" name="password" type="password" class="form-control ex-input-modal required" /> 
    <label th:if="${passFail}" for="password" class="error"> Wrong password     </label>
    </div>

Title: jQuery Validate won't clear server-inserted error messages on KeyUp

它不是为此而设计的,因为它是 客户端 端脚本。

jQuery 验证插件通过 JavaScript 在客户端生成并切换自己的验证错误消息。由于在满足 jQuery 验证之前,您无法将表单提交到服务器,因此您不会首先看到任何服务器生成的验证消息。

与客户端验证一起使用时,在正常情况下永远不会看到服务器端验证消息...服务器端验证只会在 JavaScript 被禁用、损坏时保护您, 或绕过。


编辑:

如果您要评估电子邮件地址、用户帐户或任何已存在于您的系统中的内容,那么您可以使用插件的内置 remote 方法。此规则将使用 ajax() 调用服务器端脚本,如果您的服务器端脚本 returns true,则规则通过验证。如果您的脚本 returns false 或 JSON 编码字符串,则规则验证失败。如果您使用 false,则使用默认错误消息。如果您 return 一个 JSON 字符串,例如 "john smith is already in use",那么插件将使用该字符串作为错误消息。

参见:jqueryvalidation.org/remote-method/

当我自定义从服务器获取标记后显示的错误消息时,它对我有效。

注意:错误字段有data-error-messages属性,有错误信息,用“;”分割:

this.showErrorMessages = function($root) {
    var handlerInstance = this;
    var validator = $(handlerInstance.instance.form).validate();
    var originalErrorMap = validator.errorMap;
    var originalErrorList = validator.errorList;
    var errorMap = {};
    var errorList = [];
    $root.find('[data-error-messages]').each(function() {
        var errorMessages = $(this).attr('data-error-messages').split(';');
        var propertyName = $(this).attr('name');
        for (var i = 0; i < errorMessages.length; i++) {
            errorMap[propertyName] = errorMessages[i];
            errorList.push({ message: errorMessages[i], element: $(this).get(0) });
        }
    });
    validator.errorMap = errorMap;
    validator.errorList = errorList;
    validator.showErrors();
    validator.errorMap = originalErrorMap;
    validator.errorList = originalErrorList;
};

为什么我必须手动分配 errorList - 因为否则如果我有其他具有相同名称的元素 - 默认验证方法将自行找出 errorList,采用具有该名称的第一个元素并突出显示它。 $root 包含搜索区域,在该区域查找错误元素,因此如果具有相同的名称,外部的其他元素将不会被突出显示为错误。