2012-05-20 89 views
2

我有一個簡單的請求範圍實體/ pojo,它具有一個枚舉和一個字符串作爲屬性。通過ajax禁用驗證程序

public Enum Type 
{ 
    None, 
    Email, 
    Fax; 
} 

@ManagedBean(name = "testEntity") 
@RequestScoped 
public class TestEntity 
{ 
    private Type type; //Default = None 
    private String address; 

    //getter and setter 
} 

此枚舉有一個字段'電子郵件',它標識與相關地址的電子郵件地址。
在JSF中,我現在想要啓用/禁用關於SelectOneMenu中當前所選類型的地址InputText字段的驗證器。

<h:form id="formId"> 
    <p:selectOneMenu id="type" value="#{testEntity.type}> 
     <p:ajax event="change" update=":formId:address"/> 
     <f:selectItem itemLabel="E-mail" itemValue="Email"/> 
     <f:selectItem itemLabel="Fax" itemValue="Fax"/> 
    </p:selectOneMenu> 
    <p:inputText id="address" value="#{testEntity.address}"> 
     <f:validator validatorId="emailValidator" disabled="#{testEntity.type != 'Email'}"/> 
    </p:inputText> 
    <!-- button to call bean method with testEntity as param --> 
</h:form> 

它是不工作的驗證是從來沒有主動但AJAX調用工作,因爲我可以看到在其他領域的變化值。

+1

這就是OmniFaces的一個有趣想法。這不是一個不常見的要求。 – BalusC

+0

不錯的項目,稍後會看看它的展示。 – djmj

回答

2

這不幸的是不可能的。 <f:xxx>標記是標記處理程序(不是UI組件),它在視圖構建時運行,而不是在視圖渲染時間期間運行。因此,如果在構建視圖期間它被禁用,它將始終被禁用,直到重新創建視圖(例如,通過新請求或非空導航)。

您需要有一個「全局」驗證程序,該驗證程序根據type屬性進一步委託給所需驗證程序。

E.g.

<p:inputText ... validator="#{testEntity.validateAddress}" /> 

public void validateAddress(FacesContext context, UIComponent component, Object value) throws ValidatorException { 
    if (type == Email) { 
     context.getApplication().createValidator("emailValidator").validate(context, component, value); 
    } 
} 

更新OmniFaces最近增加了新的<o:validator>標籤,該標籤如下應該解決的正是這種問題:

<o:validator validatorId="emailValidator" disabled="#{testEntity.type != 'Email'}"/> 

見陳列櫃例如here

+0

它是一個共享的遠程實體,我不想在其中任何jsf。 (註解也在faces-config中)我沒有看到任何其他方式來搜索文本字段驗證器中的類型組件/將其id作爲屬性進行傳遞,或者在bean提交方法中對其進行驗證。 – djmj

+0

爲什麼不叫「新的EmailValidator()。validate(...)? – djmj

+0

這是緊密耦合。 – BalusC

0

感謝BalusC的幫助,也許有人對我如何解決它感興趣。

將類型組件clientId傳遞給自定義轉換器。

<f:attribute name="typeComponentId" value=":formId:type"/> 

驗證:

public class TestEntity implements Validator 
{ 
    @Override 
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException 
    { 
     final String typeComponentId = (String)component.getAttributes().get("typeComponentId"); 

     final UIInput compType = (UIInput)context.getViewRoot().findComponent(typeComponentId); 

     if(compType != null) 
     { 
      final Type type = (Type)compType.getValue(); 

      if(type == Type.Email) 
       new EmailValidator().validate(context, component, value); 
     } 
    } 
} 

編輯:

不是UI內工作:重複部件,如對:數據表。