I have a field that is rendered conditionally, based on a dropdown. All of that goes without problem, but when I submit the form of which the newly rendered component should be part of, it doesn't get submitted.
The code is fairly straightforward:
<h:form id="form">
<p:layout id="layout">
...
<p:layoutUnit id="layoutUnit">
...
<p:panel id="panel">
<p:outputPanel id="container1">
<p:selectOneMenu id="value1" value="#{bean.value1}">
<f:selectItem itemValue="1"/>
<f:selectItem itemValue="2"/>
<f:selectItem itemValue="3"/>
<f:selectItem itemValue="18"/>
<p:ajax event="change" update="container2"/>
</p:selectOneMenu>
</p:outputPanel>
<p:outputPanel id="container2">
<p:inputText id="value2"
value="#{bean.value2}"
rendered="#{bean.value1 eq 18}"
>
</p:inputText>
</p:outputPanel>
</panel>
<div id="buttons">
<p:commandButton id="commandButton" action="#{bean.save}" value="save" />
</div>
</layoutUnit>
</layout>
</form>
Tried possible solutions:
I can think of a few scenarios causing this behaviour:
Option 1 seems to be the most likely one, but could anyone point me in the right direction?
I work with WAS8.5 (so JSF2.0), Primefaces and CDI.
Using CDI's @ConversationScoped in addition to @Named is a solution. That scope works comparable to the @ViewScoped from JSF.
To get it working I've simply added code from the example here. So in short:
Bean.java
@Named
@ConversationScoped
public class Bean implements Serializable{
@Inject
private Conversation conversation;
Bean values, getters & setters
public void initConversation(){
if (!FacesContext.getCurrentInstance().isPostback() && conversation.isTransient()) {
conversation.begin();
}
}
public String endConversation(){
if(!conversation.isTransient()){
conversation.end();
}
}
public String navigateAwayFromScreen(){
endConversation();
}
}
beanOutput.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:event listener="#{bean.initConversation}" type="preRenderView"/>
<h:form id="form">
<p:layout id="layout">
...
<p:layoutUnit id="layoutUnit">
...
<p:panel id="panel">
<p:outputPanel id="container1">
<p:selectOneMenu id="value1" value="#{bean.value1}">
<f:selectItem itemValue="1"/>
<f:selectItem itemValue="2"/>
<f:selectItem itemValue="3"/>
<f:selectItem itemValue="18"/>
<p:ajax event="change" update="container2"/>
</p:selectOneMenu>
</p:outputPanel>
<p:outputPanel id="container2">
<p:inputText id="value2"
value="#{bean.value2}"
rendered="#{bean.value1 eq 18}"
>
</p:inputText>
</p:outputPanel>
</panel>
<div id="buttons">
<p:commandButton id="commandButton" action="#{bean.navigateAwayFromScreen}" value="Go away!" />
</div>
</layoutUnit>
</layout>
</form>
</html>
Now, a conversation gets started when you open the page (due to the initConversation being called from the top of beanOutput.xhtml), and ended when you click the button navigateAwayFromScreen.
(However, if you are able to work with JSF2.2, it should be possible to use the @ViewScoped in combination with CDI. (I say 'should': I am not in the situation to upgrade. But it may be useful to others to examine)).