Wednesday, November 17, 2010

Richfaces : ReThink Before ReRender

Sometimes when you go deeper into a framework or a tool , you tend to take beginner stuff for granted. That bit me today for a while before I could get my head around it.  ;-)

When using Ajax, it's a well known fact that for you to manipulate a DOM element, that element needs to be present. Same rule applies when you are using reRender in Richfaces as well. Let's take a look at following code snippet:

<rich:panel header="Add New Application">
   <h:outputText value="App Name " />
   <h:inputText size="20" id="appNameInput" value="#{appConfigBean.currentApp.appName}" />
   <a4j:commandButton id="new_app_submit" action="#{appConfigBean.addNewApp}"     
    value="Add" reRender="appDetails" />
</rich:panel>


<h:panelGrid columns="2" id="appDetails" 
                rendered="#{appConfigBean.renderDetail}">
      <h:outputText value="Some stuff"/>
</h:panelGrid>


The addNewApp method in backing bean sets renderDetail to true which initially was false. So when you click Add button, you would expect reRender to kick in and show the panelGrid with id appDetails. Nope. It does not happen. From second paragraph you might have understood the reason already. But here is a more detailed explanation.

Since initially, renderDetail boolean is set to false, when the page is first loaded, the html for panelGrid never gets rendered hence there does not exist a DOM element with id appDetails and reRender does not know what to update.

To fix this, the easiest and probably the best solution is to surround panelGrid with a4j:outputPanel and you would put this output panel's id for reRender to do its magic.  Here is the updated code:

<a4j:commandbutton id="new_app_submit">
                      action="#{appConfigBean.addNewApp}" value="Add"
                      reRender="appDetailOutputPanel" /&gt; 

<a4j:outputpanel id="appDetailOutputPanel"> 
     <h:panelgrid columns="2" id="appDetails">
                     rendered="#{appConfigBean.renderDetail}"&gt;
          <h:outputtext value="Some stuff"></h:outputtext>
     </h:panelgrid>
</a4j:outputpanel>

No comments: