【问题标题】:jQuery Validation Plugin: Invoke errorPlacement function when onfocusout, keyup and clickjQuery Validation Plugin:onfocusout、keyup 和 click 时调用 errorPlacement 函数
【发布时间】:2011-01-24 22:18:24
【问题描述】:

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

当使用提交按钮提交表单但触发以下任何事件时,这非常有用: - 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"
});

【问题讨论】:

    标签: javascript jquery forms validation


    【解决方案1】:

    您的问题是插件只为每个经过验证的元素调用一次errorPlacement 函数。即在首次创建元素的错误标签时。之后插件只是重用已经存在的标签并替换里面的html(或者如果元素现在有效则隐藏错误标签)。这就是你的十字架被移除并显示实际错误消息的原因。

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

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

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

    你可以通过查看验证插件源代码来检查我所说的

    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();
        }
    ...
    });
    

    也许有一个更清洁的解决方案,但这应该可以让您有时间研究更好的解决方案。

    【讨论】:

      【解决方案2】:

      谢谢抖动

      我做了一些挖掘,发现了同样的问题。

      我设法通过“破解” jquery.validation.js 中的 showLabel 函数来使其工作。它不漂亮,但很有效。

      覆盖 showErrors 函数选项会阻止我更改插件代码,所以我会看看。

      这是我用于 showLabel 方法的代码:

           showLabel: function(element, message) {
      
                  // look for existing error message
                  var label = this.errorsFor( element );
                  // existing error exist?
                  if (label.length) {
                      // refresh error/success class
                      label.removeClass().addClass( this.settings.errorClass );
      
                      // check if we have a generated label, replace the message then
                      label.attr("generated");
      
                      // is message empty?
                      if(!message)
                      {
                          // add tick glyph
                          label.html("✔");
      
                          // wipe element title
                          $(element).attr('title', message)
                      }
                      else
                      {
                          // clear error html and add cross glyph
                          label.html("✘");
      
                          // update element title
                          $(element).attr('title', message)
                      }
      
                      // && label.html(message);
                  } 
                  else {
                      // create label
                      label = $("<" + this.settings.errorElement + "/>")
                          .attr({"for":  this.idOrName(element), generated: true})
                          .addClass(this.settings.errorClass)
                          .html(message || "");
                      if ( this.settings.wrapper ) {
                          // make sure the element is visible, even in IE
                          // actually showing the wrapped element is handled elsewhere
                          label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
                      }
                      if ( !this.labelContainer.append(label).length )
                          this.settings.errorPlacement
                              ? this.settings.errorPlacement(label, $(element) )
                              : label.insertAfter(element);
                  }
                  if ( !message && this.settings.success ) {
                      label.text("");
                      typeof this.settings.success == "string"
                          ? label.addClass( this.settings.success )
                          : this.settings.success( label );
                  }
                  this.toShow = this.toShow.add(label);
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-20
        • 1970-01-01
        • 1970-01-01
        • 2020-04-19
        • 2015-12-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多