我有一个简单的请求范围实体/ pojo,它有一个Enum和一个String作为属性。
public Enum Type
{
None,
Email,
Fax;
}
@ManagedBean(name = "testEntity")
@RequestScoped
public class TestEntity
{
private Type type; //Default = None
private String address;
//getter and setter
}
此Enum有一个“电子邮件”字段,用于标识具有相关地址的电子邮件地址 在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调用正常,因为我可以在其他字段中看到更改值。
答案 0 :(得分: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。
答案 1 :(得分: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:repeat组件中工作,例如p:datatable。