2015-10-07 36 views
0

我在facelet上有一個自定義轉換器(對於其他任何對象,只是我的示例中的另一個字符串)以及自定義驗證器( 「需要」的價值,以及其他支票)。這裏有一個用例描述預期的和有問題的實際步驟:如何清除所需的字段值 - 恢復回最後一個有效值

  1. 輸入一個有效值和模糊字段(標籤輸出或點擊其他元素)。
    • 轉換器將字段值更改爲對象的標準化字符串表示形式。 與預期的一樣
  2. 返回並輸入一個無效值,再次模糊。
    • 驗證消息顯示錯誤。 與預期的一樣
    • 字段值保持無效值。 與預期的一樣
  3. 返回並刪除值,再次模糊。
    • 驗證消息顯示錯誤。 與預期的一樣
    • 字段值變回到最後一個有效(標準化)值。 未如預期,希望它留空

這是一個有點反直覺如果驗證消息顯示值應該提供,而舊的有效值節目。任何想法,即使驗證失敗,我可以做些什麼來保持領域清晰?

我或許需要強調以下關於交換器:

  • 空/空字符串轉換爲空對象。 (但驗證器需要一個有效的非空值。)
  • 使用blur上的ajax調用來在完成鍵入值時始終運行轉換器 - 意圖是將提供的值轉換爲後備對象bean成員,然後轉換回對象的(「規範化」)字符串表示形式。 (「規範化」示例:符合枚舉常數名稱的情況下,或處於某個日期格式。)

我在GlassFish 4.1上使用JSF 2.2(Mojarra 2.2.7)。

示例代碼(修剪回顯到只顯示一個測試用例,但包含的重要組成部分 - 我認爲):

支持bean:

@ManagedBean 
@ViewScoped 
public class TestBean implements Serializable { 
    : 
    private String test; // plus g/setters 
    : 
} 

JSF視圖頁面:

<h:form> 
    : 
    <h:inputText id="test" binding="#{test}" value="#{testBean.test}"> 
     <cp:uppercaseConverter /> 
     <f:validator binding="${testValidator}" /> 
     <f:ajax event="blur" render="@this msg_test" /><!-- @this forces converter on blur --> 
    </h:inputText> 
    <h:messages id="msg_test" for="test" /> 
    : 
</h:form> 

定製轉換器:(請記住,爲了進行測試有點做作)

/** 
* The "object" as used in the backing bean is simply the uppercase version of 
* the input value in the field. 
*/ 
@FacesConverter("UppercaseConverter") 
public class UppercaseConverter implements Converter, Serializable { 
    private static final long serialVersionUID = 1L; 

    @Override 
    public Object getAsObject(
     FacesContext ctx, UIComponent component, String newValue 
    ) throws ConverterException { 
     if (newValue == null || newValue.trim().equals("")) 
      return null; 
     return newValue.toUpperCase(); 
    } 

    @Override 
    public String getAsString(
     FacesContext ctx, UIComponent component, Object value 
    ) throws ConverterException { 
     if (value == null) return ""; 
     return value.toString(); 
    } 
} 

自定義的驗證:(記住,用於測試目的有點做作)

/** 
* Values are valid only if they start with an "A" (not case sensitive). 
* Thus, null or empty values are also invalid implicitly. 
*/ 
@ManagedBean 
@FacesValidator 
public class TestValidator implements Validator { 

    @Override 
    public void validate(
     FacesContext context, UIComponent component, Object value 
    ) throws ValidatorException { 
     if (value == null || !value.toString().trim().toLowerCase().startsWith("a")) 
      throw new ValidatorException(new FacesMessage("A value starting with A or a is required")); 
    } 
} 

回答

0

的問題顯然是由<f:ajax>調用也render造成s @this,連同消息元素。

渲染@this導致運行並顯示在字段(但是這不能被做了一個無效的值或空值,很明顯)轉換值的轉換器。

我認爲現在最簡單的解決方法是從render屬性中刪除@this。結果只會有一點美學上的缺陷,而不是世界末日 - 在我看來,嚴重(令使用者感到困惑)的是,顯示有效並且以前輸入並被覆蓋的值的「這是無效的」消息。

相關問題