Ajax – Use single p:ajax to execute multiple actions

ajaxjsfprimefaces

I have a p:selectOneMenu in my application, and when the selection takes place I need to call multiple back-end methods from different managed beans in order to perform different actions.

XHTML code:

<p:selectOneMenu id="selectMenu" value="#{userBean.selectedSite}"
  converter="siteConverter" style="width:150px">
  <p:ajax event="change" listener="#{bean2.changeSite}"
    render="@form :comp1 :comp2 :comp3 :comp4" />
  <f:selectItems value="#{userBean.sites}" var="site"
    itemValue="#{site}" itemLabel="#{site.description}" />
  <p:ajax event="change" listener="#{bean1.reset}" 
    update="@form :comp1 :comp2 :comp3 :comp4" />
</p:selectOneMenu>

Managed bean 1:

@ManagedBean(name="bean1")
@ViewScoped
public class Bean1 implements Serializable {
  // ...
  public void reset() {
    loadEvents();
    resetEvent();
  }
}

Managed bean 2:

@ManagedBean(name="bean2")
@SessionScoped
public class Bean2 implements Serializable {
  // ...
  public void changeSite() {
    FacesContext context = FacesContext.getCurrentInstance();
    Bean1 bean = (Bean1) context.getApplication().evaluateExpressionGet(context, "#{bean1}", Bean1.class);
    reload();
    bean.loadEvents();
  }
}

If, instead of using two different p:ajax components, I use a single p:ajax that calls a single method from Bean1, the page components listed under "update" are not correctly updated.

XHTML:

<p:ajax event="change" listener="#{bean1.singleMethod}" 
  update="@form :comp1 :comp2 :comp3 :comp4" />

Managed bean 1:

@ManagedBean(name="bean1")
@ViewScoped
public class Bean1 implements Serializable {
  // ...
  public void () singleMethod() {
    FacesContext context = FacesContext.getCurrentInstance();
    Bean2 bean = (Bean2) context.getApplication().evaluateExpressionGet(context, "#{bean2}", Bean2.class);
    bean2.changeSite();
    reset();
  }
}

Changing the selected values updates the server side objects, but the page is not updated: if I press F5, the page shows the actual situation.

Best Answer

Moving the single global method to the session scoped bean (Bean2) does the job.

Related Topic