2010-03-08 26 views
10

我使用jQuery驗證插件,並希望使用errorPlacement功能錯誤信息添加到字段標題屬性,顯示只是一個✘該字段旁邊。jQuery的驗證插件:調用errorPlacement功能時onfocusout在,KEYUP並單擊

當表單被提交按鈕提交,但出現以下任一事件被觸發這個偉大的工程: - 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" 
}); 

回答

16

你的問題是,該插件僅適用於被驗證的每個元素調用errorPlacement函數一次。 Namly當第一次創建該元素的錯誤標籤。此後該插件只會重複使用已存在的標籤,只是替換裏面的HTML(或隱藏錯誤標籤如果元素是現在有效)。這就是爲什麼你的十字架被移除,顯示實際的錯誤信息。

只是爲了確保該插件的流程清晰。

  1. 元(不errorlabel還)
  2. 元素在某些時候
  3. 插件創建錯誤的標籤,並呼籲errorPlacement功能
  4. 元素「跨界」(標題中的錯誤消息)
  5. 元素獲得得到確認重點和你改變的東西
  6. 插件重新驗證元素
  7. 看到錯誤標籤已被創建(並放置)
  8. 插件只是調用的label.html(message)不是刪除舊標籤和readding它

所以你看,你的問題是一種優化的插件不保存錯誤標籤的一些不必要的,插入/移除。這也是有道理的。

您可以檢查我說在功能查看確認,插件,源代碼

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

線條也許有一個更清潔的解決方案,這一點,但這個應該這樣做,給你時間去調查一個更好的解決方案。

+0

幫助........ :) – 2015-05-29 13:05:56

1

感謝抖動

我做了一些挖了一圈,發現了同樣的問題。

我設法通過「hacking」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); 
     }