2010-05-06 46 views
11

我有一個非常複雜的表單,包含大量的輸入和驗證器。對於用戶來說,花費相當長的時間(甚至一個小時)才能完成該操作,所以他們希望能夠保存草稿數據,即使它違反了像未輸入強制字段的規則。JSF如何臨時禁用驗證器來保存草稿

我相信這個問題對許多Web應用程序來說都很常見,但是找不到任何可以被實現的模式。你可以請建議如何實現這一目標?

現在我可以看到以下選項:

  1. 使用立即=「保存草稿」按鈕不起作用真的如UI數據不會被存儲在豆,所以我將無法訪問它。從技術上講,我可以在UI組件樹中找到數據,但遍歷這似乎不是一個好主意。
  2. 從頁面中刪除所有字段驗證,並在爲窗體定義的操作偵聽器中驗證數據programmaticaly。同樣,不是一個好主意,表單非常複雜,有很多字段,所以驗證以這種方式實現將非常麻煩。
  3. 實現自己的驗證,會被一些請求屬性,這將標準表單提交設置(與全面驗證預期)進行控制,將取消設置「保存爲草稿」提交(在驗證應跳過)。再次,不是一個好的解決方案,我需要爲我使用的所有驗證器提供自己的包裝器。

但是正如你所看到的,沒有人真的很合理。這個問題真的沒有簡單的解決方案嗎?

回答

7

事實並非如此簡單。在JSF生命週期中驗證非常緊密。

我會親自去選擇1.真正的,骯髒的工作,但你可以隱藏在實用程序課程等。只需從視圖中抓取<h:form>,遞歸地遍歷其子級,由此測試component instanceof EditableValueHolder是否爲真,將找到的id-值對存儲在Map類中並最終保存它。

作爲第四種替代方案,您可以使用阿賈克斯冪來獨立保存所有數據。 jQuery在這方面很有幫助。

$.post('/savedraft', $('#formid').serialize()); 

它只在客戶端需要Javascript支持。


更新:JSF的工具庫OmniFaces<o:ignoreValidationFailed> taghandler的確切目的。這確實不是一個簡單的解決方案,因爲它也需要定製<h:form>。它通過在驗證和更新模型值階段提供自定義FacesContext實例來完成工作,該階段在validationFailed()renderResponse()方法中執行NOOP。所以組件仍然無效,並且消息仍然附加,但它仍然會繼續執行更新模型值並調用應用程序階段。

+0

謝謝Balus。我喜歡你的想法選擇1,可能我應該能夠做相反的事情,當數據被階段監聽器加載並重新初始化EditableValueHolders時。 關於你的第二個建議,我在jQuery中找不到任何unserialize()函數,你將如何加載草稿數據? – Swiety 2010-05-06 17:10:14

+0

通過相應地設置服務器端的託管bean屬性。 – BalusC 2010-05-06 18:16:25

1

我有同樣的問題,我不喜歡跳過所有驗證的想法。經過很多思考後,我最終只想跳過必需的字段驗證。這背後的邏輯是用戶要麼正確填寫,要麼完全不填寫。這對我來說非常重要,因爲一切都以數據庫結尾,當然,我不想溢出數據庫字段或最終將String值保存到INT數據庫字段中。

根據我的經驗,跳過必填字段允許有足夠的迴旋餘量來保存草稿。爲了達到這個目的,我寫了一個requiredWarnValidator,顯示一條警告消息。

public void validate(FacesContext context, UIComponent component, Object value) 
    throws ValidatorException { 

    if (value == null) { 
    FacesMessage message = new FacesMessage(); 
    message.setSeverity(FacesMessage.SEVERITY_WARN); 
    message.setSummary("This field is required."); 
    context.addMessage(component.getClientId(), message); 
    context.validationFailed(); 
    } 
} 

在這種驗證,因爲我想通過驗證階段,但我打電話validationFailed(),因爲我想知道,如果一個必填字段沒有填充我不扔一個ValidatorException()

我在用於保存表單的實體中有一個標誌(completed)。保存表格時,我檢查了isValidationFailed()

  • 如果true至少一個必填字段未填寫:我取消了標誌completed。 (這是一個草案)
  • 如果false所有表格都完成了:我檢查了國旗completed。 (這不是草稿)

這也讓我有一個「保存」按鈕,而不是兩個按鈕(「保存」和「另存爲草稿」)。

說明和已知缺陷:

  • 如果要保存草稿到數據庫中,那麼你必須確保沒有NOT NULL約束。
  • 使用轉換器和驗證器時,您必須確保它們可以處理NULL值。
  • 對於您的字段,您將在outputLabel中丟失必填字段星號。