Using JSF2 (MyFaces 2.1) and CDI (Weld) I use a selectOneMenu filled with an enum to conditionally render a second selectOneMenu (doublemenu in the code). There are several other fields in the form which are validated using bean validation.
The problem:
If there are validation errors after clicking on the commandButton and error messages are shown, the doublemenu will not reappear. It appears that bean.type ==’double’ is not true. But why? The selectOneMenu itself shows the option double as the selected item.
@javax.inject.Named
@javax.enterprise.context.RequestScoped
public class Bean {
private enum MyEnum {
Single, Double
}
private MyEnum type;
public MyEnum getType() {
return type;
}
public void setType(MyEnum type) {
this.type = type;
}
public MyEnum [] getTypes() {
return MyEnum.values();
}
<h:form>
<h:selectOneMenu value="#{bean.type}">
<f:selectItems value="#{bean.types}" />
<f:ajax render="doublemenu" />
</h:selectOneMenu>
<h:panelGroup id="doublemenu">
<h:panelGroup rendered="#{bean.type == 'double'}">
<h:selectOneMenu ...>
</h:selectOneMenu>
</h:panelGroup>
</h:panelGroup>
<h:inputText id="VALIDATED"/>
<h:commandButtonaction="#{bean.save}"
</h:form>
BTW: bean.save is not executed
It’s because your bean is request scoped. Request scoped beans are garbaged by end of every request and newly created on begin of every request. This also applies to individual ajax requests on the same view.
The
renderedattribute is also evaluated during collecting submitted values (the apply request values phase). However, at the point the submitted values are to be collected, the#{bean.type}is obviously not been set yet (it has still to be set based on the collected submitted value during update model values phase). As your bean is request scoped, it would return the default value, not the submitted value from a previous request.There are basically 2 ways to fix this.
Put the bean in a bit broader scope. JSF offers the
@ViewScopedfor exactly this purpose. This is in the current JSF 2.1 version only not compatible with CDI. If switching to JSF@ManagedBeanis not an option, then you’d need MyFaces CODI to bridge the JSF@ViewScopedtransparently to CDI, or to wait for JSF 2.2 to get a CDI compatible@ViewScopedout the box.Check a request parameter instead of a bean property.
Please note that this all is completely unrelated to enums. You’d have had exactly the same problem when using e.g. a
String. Also please note that I fixed a typo in your code example, an enum value ofDoubleis definitely not the same asdouble.See also: