jQuery Validation Plugin:在onfocusout,keyup和click时调用errorPlacement函数

th3*_*ler 10 javascript forms validation jquery

我正在使用jquery验证插件,并希望使用errorPlacement函数将错误消息添加到字段title属性,并在字段旁边显示一个✘.

当使用提交按钮提交表单但触发以下任何事件时,这非常有用: - onfocusout - 单击 - onkeyup

运行验证检查但跳过errorPlacement函数并在字段后添加完整的错误消息,如默认行为.

我使用以下代码:

$("#send-mail").validate({
    debug: true,
    // set this class to error-labels to indicate valid fields 
    success: function(label) {
        // set text as tick
        label.html("✔").addClass("valid"); 
    }, 
     // the errorPlacement has to take the table layout into account 
    errorPlacement: function(error, element) {
        console.log("errorPlacement called for "+element.attr("name")+" field");
        // check for blank/success error
        if(error.text() == "")
        { 
            // remove field title/error message from element
            element.attr("title", "");
            console.log("error check passed");
        }
        else
        {
            // get error message
            var message = error.text();

            // set as element title
            element.attr("title", message);

            // clear error html and add cross glyph
            error.html("✘"); 

            console.log("error check failed: "+message);
        }
        // add error label after form element
        error.insertAfter(element);
    },
    ignoreTitle: true,
    errorClass: "invalid"
});
Run Code Online (Sandbox Code Playgroud)

jit*_*ter 17

您的问题是该插件仅为errorPlacement每个经过验证的元素调用该函数一次.Namly首次创建元素的错误标签时.之后,插件只重用已存在的标签,只是替换内部的html(如果元素现在有效,则隐藏错误标签).这就是为什么你的十字架被删除,并显示实际的错误信息.

只是为了确保插件的流程清晰.

  1. 元素(还没有错误标签)
  2. 元素在某些时候得到验证
  3. 插件创建错误标签和调用errorPlacement功能
  4. 元素"cross"(标题中的错误消息)
  5. 元素获得焦点,你改变了一些东西
  6. 插件重新验证元素
  7. 看到错误标签已经创建(并放置)
  8. 插件只是调用label.html(message) 而不是删除旧标签并读取它

所以你看到你的问题是插件为保存一些不必要的插入/删除错误标签而做的一种优化.这也是有道理的.

您可以通过查看validation-plugin-sourcecode来查看我说的内容

jquery.validate.js v1.6检查showLabel相关部分的功能行617-625.


一个可能的解决方案可能是额外提供一个自定义showErrors回调,用蛮力解决问题.

有点像

$("#send-mail").validate({
...
    showErrors: function(errorMap, errorList) {
        for (var i = 0; errorList[i]; i++) {
            var element = this.errorList[i].element;
            //solves the problem with brute force
            //remove existing error label and thus force plugin to recreate it
            //recreation == call to errorplacement function
            this.errorsFor(element).remove();
        }
        this.defaultShowErrors();
    }
...
});
Run Code Online (Sandbox Code Playgroud)

也许有一个更清洁的解决方案,但这应该做,并给你时间来研究更好的解决方案.