Search code examples
javaajaxjsfjsf-2richfaces

JSF 2: page not rerendered on AJAX request (@all and explicit IDs)


I'm trying to implement a simple RichFaces 4 skin switcher, so all the code does is set a new String property on a bean and rerender the whole view. Here's the JSF:

  <rich:panel styleClass="shadow">
    ...
    <h:form style="float: right;">
      <h:outputText value="Skin:&#160;" />
      <h:selectOneMenu value="#{skinBean.skin}" id="skin-selector">
        <f:ajax event="change" execute="@form" render="@all" listener="#{skinBean.listener}" />
        <f:selectItem itemValue="DEFAULT" itemLabel="Default" />
        <f:selectItem itemValue="classic" itemLabel="Classic" />
        <f:selectItem itemValue="blueSky" itemLabel="Blue Sky" />
        <f:selectItem itemValue="deepMarine" itemLabel="Deep Marine" />
        <f:selectItem itemValue="emeraldTown" itemLabel="Emerald Town" />
        <f:selectItem itemValue="japanCherry" itemLabel="Japan Cherry" />
        <f:selectItem itemValue="ruby" itemLabel="Ruby" />
        <f:selectItem itemValue="wine" itemLabel="Wine" />
      </h:selectOneMenu>
    </h:form>
  </rich:panel>

Here's the skin bean:

@Named
@SessionScoped
public class SkinBean implements Serializable
{
    private static final long serialVersionUID = 7477768262527797286L;

    private static final Logger log = Logger.getLogger(SkinBean.class);

    private String skin;

    @PostConstruct
    public void init()
    {
        log.info("Initializing skin bean!");

        // default
        this.skin = "wine";
    }

    @PreDestroy
    public void remove()
    {
        log.info("Removing skin bean!");
    }

    public String getSkin()
    {
        return skin;
    }

    public void setSkin(String skinName)
    {
        log.info("Setting skin to " + skinName);

        this.skin = skinName;
    }

    public void listener(AjaxBehaviorEvent abe)
    {
//      log.info("Skinning event!" + abe);
    }
}

Log on selection change:

07:34:49,869 INFO  [com.company.project.util.PhaseTracker] (http--127.0.0.1-8080-5) After RESTORE_VIEW 1
07:34:49,870 INFO  [com.company.project.util.PhaseTracker] (http--127.0.0.1-8080-5) Before APPLY_REQUEST_VALUES 2
07:34:49,871 INFO  [com.company.project.util.PhaseTracker] (http--127.0.0.1-8080-5) After APPLY_REQUEST_VALUES 2
07:34:49,871 INFO  [com.company.project.util.PhaseTracker] (http--127.0.0.1-8080-5) Before PROCESS_VALIDATIONS 3
07:34:49,871 INFO  [com.company.project.util.PhaseTracker] (http--127.0.0.1-8080-5) After PROCESS_VALIDATIONS 3
07:34:49,871 INFO  [com.company.project.util.PhaseTracker] (http--127.0.0.1-8080-5) Before UPDATE_MODEL_VALUES 4
07:34:49,872 INFO  [com.company.project.skin.SkinBean] (http--127.0.0.1-8080-5) Setting skin to classic
07:34:49,872 INFO  [com.company.project.util.PhaseTracker] (http--127.0.0.1-8080-5) After UPDATE_MODEL_VALUES 4
07:34:49,872 INFO  [com.company.project.util.PhaseTracker] (http--127.0.0.1-8080-5) Before INVOKE_APPLICATION 5
07:34:49,872 INFO  [com.company.project.util.PhaseTracker] (http--127.0.0.1-8080-5) After INVOKE_APPLICATION 5
07:34:49,872 INFO  [com.company.project.util.PhaseTracker] (http--127.0.0.1-8080-5) Before RENDER_RESPONSE 6
07:34:50,226 INFO  [com.company.project.util.PhaseTracker] (http--127.0.0.1-8080-5) After RENDER_RESPONSE 6

My logs clearly show the new value is set correctly, but it doesn't update the view. It only updates when reloading the whole page (which is kinda pointless).

Does anybody know why the view isn't updated? I've also tried a few IDs instead of render="@all", e.g. render=":repo-form" (external to the switcher's form), but nothing happens. Looking for bugs also didn't reveal anything useful. Not being able to update even an explicit ID makes me think it's something different...?

Note: I'm using Mojarra 2.0.4 on JBoss AS 7.0.1.

Thanks


Solution

  • try setting the skin using full request, not Ajax:

    <rich:panel styleClass="shadow">
        ...
        <h:form style="float: right;">
          <h:outputText value="Skin:&#160;" />
          <h:selectOneMenu value="#{skinBean.skin}" id="skin-selector" onchange="submit()">
            <f:selectItem itemValue="DEFAULT" itemLabel="Default" />
            <f:selectItem itemValue="classic" itemLabel="Classic" />
            <f:selectItem itemValue="blueSky" itemLabel="Blue Sky" />
            <f:selectItem itemValue="deepMarine" itemLabel="Deep Marine" />
            <f:selectItem itemValue="emeraldTown" itemLabel="Emerald Town" />
            <f:selectItem itemValue="japanCherry" itemLabel="Japan Cherry" />
            <f:selectItem itemValue="ruby" itemLabel="Ruby" />
            <f:selectItem itemValue="wine" itemLabel="Wine" />
          </h:selectOneMenu>
        </h:form>
    </rich:panel>
    

    Regards, Palo