JSF action never triggered on h:commandButton (with f:ajax)

Loric- picture Loric- · Jun 12, 2013 · Viewed 8.2k times · Source

I read a lot about f:ajax working with other jsf or html tags but it doesn't seem to be enough!

I have a commandButton with a (necessary?) f:ajax tag in my page and the action is never triggered. Here is the code.

<html>
  <h:head>
  </h:head>

  <h:body>
    <h:form>
      <h:commandButton action="#{bean.myFirstFunction}" value="Submit">
        <f:ajax render=":wrap" />
      </h:commandButton>
    </h:form>

    <h:panelGroup id="wrap">
      <h:panelGroup id="content" rendered="#{bean.myVariable != null}">

       <h:form>
         <h:commandButton action="#{bean.mySecondFunction}" value="Submit">
           <f:ajax render=":wrap" />
         </h:commandButton>
       </h:form>

      </h:panelGroup>
    </panelGroup>
  <h:body>
</html>

So like above I got two button, the first one out of the wrap works and it must show the wrap panel which is hidden at the beginning. The second one is in the wrap and must launch a completely different action. (the wrap must stay showed)

Here is the bean.

@ManagedBean(name = "bean")
@ViewScoped
public class myBean {
  private Object myVariable;

  public void setMyVariable(Object o) { ... }
  public Object getMyVariable() { ... }

  @PostConstruct
  public void init() {
    this.myVariable = null;
  }

  public void myFirstFonction() {
    this.myVariable = new Object();
  }

  public void mySecondAction() {
    System.out.println("here");
  }
}

When I launch, I see the first button. I click it and the second appears. (so the first function is called, the object is instantiated and with the ajax tag the wrap is rendered. However, when the second button is clicked, nothing happens.

I have written just a part of my code I hope the mistake is here.

I think it's about the rendered option of the panel group but I can't locate it precisely.

Thanks

Answer

BalusC picture BalusC · Jun 12, 2013

As per point 9 of commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated, you're victim of JSF spec issue 790. When you ajax-update some content which in turn contains a form, it would lose its view state. As a quick workaround, just give the to-be-updated form an ID and explicitly reference it in <f:ajax render> as well.

  <h:body>
    <h:form>
      <h:commandButton action="#{bean.myFirstFunction}" value="Submit">
        <f:ajax render=":wrap :wrapForm" />
      </h:commandButton>
    </h:form>

    <h:panelGroup id="wrap">
      <h:panelGroup id="content" rendered="#{bean.myVariable != null}">

       <h:form id="wrapForm">
         <h:commandButton action="#{bean.mySecondFunction}" value="Submit">
           <f:ajax render=":wrap" />
         </h:commandButton>
       </h:form>

      </h:panelGroup>
    </panelGroup>
  <h:body>