8 Replies Latest reply on Feb 13, 2009 12:42 AM by joe.marques

    self-rerendering regions

      I see plenty of examples and ample documentation for how to get one area to execute an action and reRender some other element on the page, but I was wondering if it's possible to reRender the region that the action occurred in. Basically, I have some boolean state that I want to be able to toggle as follows:

      <a4j:outputPanel id="statePanel">
       <a4j:form id="stateForm">
       <a4j:commandButton
       id="stateButton"
       reRender="statePanel"
       image="#{Bean.state ? '/turnOff.png' : '/turnOn.png'}"
       action="#{Bean.toggleState}">
       </a4j:commandButton>
       <rich:toolTip for="favoritesPanel">
       <h:outputText value="State On"
       rendered="#{ResourceUIBean.state}"/>
       <h:outputText value="State Off"
       rendered="#{!ResourceUIBean.state}"/>
       </rich:toolTip>
       </a4j:form>
      </a4j:outputPanel>
      


      This works the first time, and I can click the image and the state will toggle properly. However, after the region reRenders things seem to stop working. The toggleState method stops being called, and thus the toggle doesn't work properly. I've found that if I extract these out into two separate forms, as shown below, then things work as expected, and I can toggle as many times as I want:

      <a4j:form>
       <a4j:commandButton
       reRender="statePanel"
       value="Toggle Me"
       action="#{Bean.toggleState}">
       </a4j:commandButton>
      </a4j:form>
      <a4j:outputPanel id="statePanel">
       <a4j:form id="stateForm">
       <h:graphicImage
       value="#{Bean.state ? '/turnOff.png' : '/turnOn.png'}"/>
       <rich:toolTip for="favoritesPanel">
       <h:outputText value="State On"
       rendered="#{ResourceUIBean.state}"/>
       <h:outputText value="State Off"
       rendered="#{!ResourceUIBean.state}"/>
       </rich:toolTip>
       </a4j:form>
      </a4j:outputPanel>
      


      So, is there something I'm missing? Is there a way to get the self-reRendering region in the first code example to work, or is this not supported by the framework?

        • 1. Re: self-rerendering regions

          FYI, I made a typo when simplifying my code for purposes of this post. Obviously, "ResourceUIBean" should just be "Bean".

          • 2. Re: self-rerendering regions

            Your first code should work also if ResourceUIBean scope is longer than request. I hope it is longer in your code. Are you sure you did not "simplify" something important?

            • 3. Re: self-rerendering regions

              I moved the Bean to session scope, it still fails in exactly the same way -- the page rendered, I click the image the first time and it toggles successfully, I click the image again and it does nothing. I have an a4j:status tag on the page, so I know some request is being sent. Breakpoints in the Bean tell me the isState() method is still being called, but the toggleState() method is not.

              • 4. Re: self-rerendering regions
                ilya_shaikovsky

                please post non-simplified code.

                • 5. Re: self-rerendering regions

                  facelet:

                   <h:panelGroup>
                   <a4j:outputPanel id="favoritesPanel">
                   <a4j:form id="favoritesForm">
                   <a4j:commandButton id="favoritesButton"
                   reRender="favoritesPanel" status="commonStatus"
                   image="#{FavoritesUIBean.favorite ? '/images/star_on_24.png' : '/images/star_off_24.png'}"
                   action="#{FavoritesUIBean.toggleFavorite}">
                   <f:param name="id" value="#{FavoritesUIBean.id}"/>
                   </a4j:commandButton>
                   <rich:toolTip for="favoritesPanel">
                   <h:outputText value="Add resource to favorites list" rendered="#{!FavoritesUIBean.favorite}"/>
                   <h:outputText value="Remove resource from favorites list" rendered="#{FavoritesUIBean.favorite}"/>
                   </rich:toolTip>
                   </a4j:form>
                   </a4j:outputPanel>
                   </h:panelGroup>
                  


                  managed bean:

                  public class FavoritesUIBean {
                  
                   private int id;
                  
                  
                   public boolean isFavorite() {
                   id = WebUtility.getResourceId(FacesContextUtility.getRequest());
                   return QuickFavoritesUtil.determineIfFavoriteResource(FacesContextUtility.getRequest());
                   }
                  
                   public int getId() {
                   return id;
                   }
                  
                   public String toggleFavorite() {
                   WebUser user = EnterpriseFacesContextUtility.getWebUser();
                   WebUserPreferences preferences = user.getWebPreferences();
                   WebUserPreferences.FavoriteResourcePortletPreferences favoriteResourcePreferences = preferences
                   .getFavoriteResourcePortletPreferences();
                  
                   int resourceId = WebUtility.getResourceId(FacesContextUtility.getRequest());
                  
                   boolean isFav = favoriteResourcePreferences.isFavorite(resourceId);
                   if (isFav) {
                   favoriteResourcePreferences.removeFavorite(resourceId);
                   } else {
                   favoriteResourcePreferences.addFavorite(resourceId);
                   }
                  
                   preferences.setFavoriteResourcePortletPreferences(favoriteResourcePreferences);
                   preferences.persistPreferences();
                  
                   return null;
                   }
                  }
                  


                  • 6. Re: self-rerendering regions

                    the bulk of the non-simplified code is posted. anything else you need from me. has this been reproduced on your end?

                    • 7. Re: self-rerendering regions

                      There is no problem with self-rerendering region for sure. I created the sample application based on your fist "simplify" code and it worked perfect. Of course, the been has no so complicated. Just getter, setter and toggle.
                      So, I suggest the problem is in your java code.

                      What I have working is:

                      ....
                      <f:view>
                      <a4j:outputPanel id="statePanel">
                       <a4j:form id="stateForm">
                       <a4j:commandButton
                       id="stateButton"
                       reRender="statePanel"
                       image="#{resourceUIBean.state ? '/turnOff.png' : '/turnOn.png'}"
                       action="#{resourceUIBean.toggleState}">
                       </a4j:commandButton>
                      
                       <h:outputText value="State On"
                       rendered="#{resourceUIBean.state}"/>
                       <h:outputText value="State Off"
                       rendered="#{!resourceUIBean.state}"/>
                      
                       </a4j:form>
                      </a4j:outputPanel>
                      </f:view>


                      <managed-bean>
                       <managed-bean-name>resourceUIBean</managed-bean-name>
                       <managed-bean-class>org.richfaces.ResourceUIBean</managed-bean-class>
                       <managed-bean-scope>session</managed-bean-scope>
                       </managed-bean>
                      


                      package org.richfaces;
                      
                      /**
                       * @author $Autor$
                       *
                       */
                      public class ResourceUIBean {
                      
                       public boolean state = false;
                      
                      
                       public void toggleState() {
                       this.state = !this.state;
                       System.out.println("It is toogled to "+ this.state);
                       }
                      
                       public void setState(boolean state) {
                       this.state = state;
                       }
                      
                       public boolean getState() {
                       return this.state;
                       }
                       public boolean isState() {
                       return this.state;
                       }
                      }



                      • 8. Re: self-rerendering regions

                        ok, i finally got it. as it turns out, the a4j:form i had in the example code was nested inside some other h:form, which for some reason only made the first toggle work. as soon as i moved the a4j:form alongside the h:form, things started working. thanks for your time and the complete example. it helped me debug and resolve my issue.