2012-05-20 62 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内工作:重复部件,如对:数据表。