I have a selectOneMenu which controls what should be shown in the datatable. The code is as below (I have removed all unnecessary staff):
<ui:composition template="/WEB-INF/templates/BasicTemplate.xhtml">
<ui:define name="content">
<br />
<h:form id="menuform">
<p:selectOneMenu value="#{envMenuBean.currentEnvName}">
<f:selectItems value="#{envMenuBean.envs}" var="env" itemLabel="#{env.name}" itemValue="#{env.name}" />
<p:ajax event="change" update="currentEnvoutput,contentpanel" listener="#{envMenuBean.envChange}" />
</p:selectOneMenu>
<h:outputLabel value="Current Selection: " />
<h:outputText id="currentEnvoutput" style="font-weight:bold" value="#{envMenuBean.currentEnvName}"></h:outputText>
<br />
<p:panel id="contentpanel">
<div id="contentdiv">
<p:dataTable id="gcfiletable" var="row" value="#{gCSelectionBean.dataTableDTO.serverListRows}">
<p:column>
<f:facet name="header">
<h:outputText value="Server Names" />
</f:facet>
<h:outputText value="#{row.serverName}" />
</p:column>
<p:columns value="#{gCSelectionBean.dataTableDTO.machineNamesList}" var="columnName" columnIndexVar="colIndex">
<f:facet name="header">
#{columnName}
</f:facet>
</p:columns>
</p:dataTable>
</div>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
The envMenuBean.envChange code is very simple:
@ManagedBean
@SessionScoped
public class EnvMenuBean {
private String currentEnvName;
public void envChange(AjaxBehaviorEvent event) {
String newValue = (String)((UIOutput)event.getSource()).getValue();
currentEnvName = newValue;
}
}
The datatable content is generated in the gCSelectionBean class:
@ManagedBean
@SessionScoped
public class GCSelectionBean {
private GCInstanceDataTableDTO dataTableDTO;
String currentEnvName;
public GCInstanceDataTableDTO getDataTableDTO() {
FacesContext fc = FacesContext.getCurrentInstance();
Application app = fc.getApplication();
ExpressionFactory exp = app.getExpressionFactory();
ValueExpression currEnvNameMenuBeanEL = exp.createValueExpression(fc.getELContext(), "#{envMenuBean.currentEnvName}", String.class);
String currEnvNameMenuBean = (String) currEnvNameMenuBeanEL.getValue(fc.getELContext());
ApplicationConfigs gcReportConfigs = GetAppConfigs.getInstance().getAppConfigs();
for (Environment env : gcReportConfigs.getEnvs()) {
if (env.getName().equalsIgnoreCase(currEnvNameMenuBean)) {
dataTableDTO = new GCInstanceDataTableDTO(env);
currentEnvName = currEnvNameMenuBean;
break;
}
}
return dataTableDTO;
}
}
However the code
ValueExpression currEnvNameMenuBeanEL = exp.createValueExpression(fc.getELContext(), "#{envMenuBean.currentEnvName}", String.class);
String currEnvNameMenuBean = (String) currEnvNameMenuBeanEL.getValue(fc.getELContext());
gives me the old selectOneMenu value before the change, which makes my datatable still shows the old table values. But the
<h:outputText id="currentEnvoutput" style="font-weight:bold" value="#{envMenuBean.currentEnvName}"></h:outputText>
can show the correct new value.
This makes me believe myfaces renders the table first before processing the ajax change event. When I change JSF2.0 implementation from myfaces to Glassfish, the same codes worked fine.
Has anyone faced the same problem? How to resolve this?