2013-04-29 68 views
1

我以爲我有一個非常適合MVC web應用程序使用jQuery Unobtrusive驗證的防彈設置,但最近的一個bug讓我非常困惑。jQuery Unobtrusive驗證 - 遠程驗證提供誤報和設置被忽略?

我希望所有的驗證都是一致的,所以使用遠程驗證屬性和控制器方法來涵蓋獨特的電子郵件/用戶名檢查等內容。我很早就發現,在你的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。

請讓我知道,如果我可以更清楚或添加任何幫助。

回答

0

好吧,可能是隨機黑客歷史上最黑客的黑客攻擊,但我最終在對話框中追加了一個覆蓋div來停止字段和按鈕交互,並重置輸入值,如下所示,以強制表單通過驗證重新評估在隨後點擊:

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

這實際上並不重置價值,但它似乎消除任何驗證程序使用標記字段有效。我不會將此標記爲'''的答案,但它肯定是完成它的一種方法!