0

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?

flyasfish
  • 119
  • 2
  • 3
  • 11

2 Answers2

1

Actually updated currentEnvName value should be present in the

public void envChange(AjaxBehaviorEvent event) {
    System.out.println(currentEnvName );
}

You don't have to set it like you do...

And instead of all those ValueExpression stuff you better use managed properties Inside your GCSelectionBean add the following:

@ManagedProperty(value = "#{envMenuBean }")
private EnvMenuBean envMenuBean ; //add getter and setter

than access the currentEnvName from envMenuBean obejct...

That's all ?

Daniel
  • 36,833
  • 10
  • 119
  • 200
  • I have tried your suggestions but no luck. The behaviour is the same. Only after refresh the table will show the new values. Is there a way to force refresh after the page is loaded? – flyasfish Oct 22 '12 at 22:22
0

This seems to be issue with primefaces, after upgrade primefaces from primefaces-3.4-SNAPSHOT to primefaces-3.4.1, the problem is resolved.

flyasfish
  • 119
  • 2
  • 3
  • 11