5 Replies Latest reply on Jul 19, 2013 4:41 AM by Ifta Khirul

    tree expandAll collapse issue

    Smitha Ramaswamy Newbie

      I had a similar post earlier but I don’t find the link to post anymore. Hence I am reposting this question. Please help me. I have a tree that displays large number of nodes. It’s working fine. Each time in order to navigate the nodes it’s tedious to expand each node. Hence in my design I have a button Expand All and Collapse All that must expand all the nodes on click of the button and collapse the tree nodes on click of collapse button.

      I am struggling to get this work for long time, can anyone please help me, else we may have to forgo the rich tree. I have tried all the suggestion on the discussion forum. Help will be greatly appreciated.

      In the code the component State is bound. How do we get the instance of the tree in order for the expand all collapse all function to work. Any time configUITree is always null when it comes to expandall function. Anywhere I can find the detail documentation apart from richfaces live demo site where I can dig in deeper to understand the behaviour of tree on how it is implemented.

      Here is the code,


      
      
       <rich:panel id="configtree" bodyClass="leftmenu_body_config">
       <h:form>
      
       <div class="actionButtons" style="padding-bottom:10px">
       <h:commandButton id="expand"
       styleClass="button"
       value="Expand"
       action="#{configTreeComponentState.expandAll}"/>
      
      
       <h:commandButton id="close"
       styleClass="button"
       value="Collapse"
       action="#{configTreeComponentState.collapseAll}" />
       </div>
      
      
       <rich:tree switchType="ajax" stateAdvisor="#{treeStateAdvisor}" componentState="#{treeComponentState.componentState}">
       <rich:recursiveTreeNodesAdaptor id="config" roots="#{configuration.rootNodes}"
       var="config"
       nodes="#{config.childrenNodes}" >
       <rich:treeNode>
       <h:outputText rendered="#{config.screen == null}" value="#{config.evalNodeText}"/>
       <s:link view="/#{config.screen.screenName}" rendered="#{config.screen != null}" propagation="none"/>
       </rich:treeNode>
       </rich:recursiveTreeNodesAdaptor>
      
       </rich:tree>
      
       </h:form>
      
       </rich:panel>
      </ui:composition>
      
      
      
      @Scope(ScopeType.SESSION)
      @Name("configTreeComponentState")
      public class ConfigTreeComponentState {
      
       private static Logger logger = Logger
       .getLogger(ConfigTreeComponentState.class);
      
      
       UITree configUITree;
      
       public final UITree getConfigUITree() {
       return configUITree;
       }
      
       public final void setConfigUITree(final UITree configUITree) {
       this.configUITree = configUITree;
       }
      
       public void expandAll() {
       try {
       //this.getConfigUITree();
       configUITree..queueExpandAll();
       } catch (final Exception ex) {
       ex.printStackTrace();
       if (logger.isDebugEnabled()) {
       logger.debug("IOException in Expand all Tree");
       }
       }
       }
      
      
       public void collapseAll() {
       try {
       //this.getConfigUITree();
       configUITree.queueCollapseAll();
       } catch (final Exception ex) {
       ex.printStackTrace();
       if (logger.isDebugEnabled()) {
       logger.debug("IOException in Collapse all Tree");
       }
       }
       }
      }
      


        • 1. Re: tree expandAll collapse issue
          Nick Belaevski Master

          Hello,

          Use "binding" attribute to bind tree to bean property - note that you shouldn't use session or application scoped beans to bind component.

          Also you can use http://java.sun.com/javaee/javaserverfaces/1.2_MR1/docs/api/javax/faces/component/UIComponent.html#findComponent(java.lang.String) to find tree component by id; if you replace "action" with "actionListener", you'll get ActionEvent passed into method and you can take command button component instance from this event, to invoke findComponent() on it.

          • 2. Re: tree expandAll collapse issue
            Smitha Ramaswamy Newbie

            Thankyou very much for your response,

            I tried to do the following

            1. Tried to bind the tree
            2. Had actionalListener to the buttons,

            When Expandall button is clicked it enters the bean twice and sets the UItree and then when it enters the processAction method the UITree is lost.

            Hence I tried the second approach to get the tree instance by findComponent() way in processAction, but it never recognizes the component id.

            Why is this?

            <rich:panel bodyClass="leftmenu_body_config">
             <h:form>
            
             <div class="actionButtons" style="padding-bottom:10px">
             <h:commandButton id="expand"
             styleClass="button"
             value="Expand"
             >
             <f:actionListener type="com.harasoftware.eem.util.ConfigTreeComponentState"/>
             </h:commandButton>
            
            
             </div>
            
            
             <rich:tree id="tree" switchType="ajax" componentState="#{treeComponentState.componentState}" binding="#{configTreeComponentState.configUITree}">
             <rich:recursiveTreeNodesAdaptor id="config" roots="#{configurationManager.rootNodes}"
             var="config"
             nodes="#{config.childrenNodes}" >
             <rich:treeNode>
             <h:outputText rendered="#{config.screen == null}" value="#{config.evalNodeText}"/>
             ------MORE CODE--------
             </rich:treeNode>
             </rich:recursiveTreeNodesAdaptor>
            
             </rich:tree>
            
             </h:form>
            
             </rich:panel>
            


            @Name("configTreeComponentState")
            public class ConfigTreeComponentState implements ActionListener {
            
             private static Logger logger = Logger
             .getLogger(ConfigTreeComponentState.class);
            
             UITree configUITree;
            
             public final UITree getConfigUITree() {
             return configUITree;
             }
            
             public final void setConfigUITree(final UITree configUITree) {
             this.configUITree = configUITree;
             }
            
            
             public void processAction(final ActionEvent e)
             throws AbortProcessingException {
             System.out.println("+++++++++++++++++++++++++++++++++++++++++++++"
             + e.getComponent());
            
             // tree instance is getting lost. Hence need to find the tree by
             // component id.
             // expandAll();
             configUITree = (UITree) FacesContext.getCurrentInstance().getViewRoot()
             .findComponent("tree");
            
             }
            }


            • 3. Re: tree expandAll collapse issue
              Nick Belaevski Master

              That's because you are using listener in the wrong way - two different instances of ConfigTreeComponentState class are created: one as Seam component, another - as listener type instance. Change it in the following way:

              <h:commandButton id="expand"
               styleClass="button"
               value="Expand"
               actionListener="#{configTreeComponentState.processAction}">
               </h:commandButton>
              and ActionListener interface won't be necessary anymore, cause component will call it by reflection.

              Also do the following change and try:
              public void processAction(final ActionEvent e)
               throws AbortProcessingException {
               System.out.println("+++++++++++++++++++++++++++++++++++++++++++++"
               + e.getComponent());
              
               // tree instance is getting lost. Hence need to find the tree by
               // component id.
               // expandAll();
               configUITree = (UITree) e.getComponent().findComponent("tree");
              
               }


              • 4. Re: tree expandAll collapse issue
                Smitha Ramaswamy Newbie

                Thankyou...... sooo... much, it works! So it's the reflection, But I still have another issue. Earlier in order to maintain the state of the tree I was using the Scope session, but you mention that it's not a good idea to use session or application scope. what is the reason for not using session or application scope?

                In order to maintain the state I am using componentState attribute

                with DataComponentState componentState. But it never remembers the state.

                Can you please guide to some resource where I can get more knowledge about this.

                Thanks.

                • 5. Re: tree expandAll collapse issue
                  Ifta Khirul Newbie

                  Hi,

                   

                  I know it's an old post. But I have a requirement similar to you.

                   

                  But there is an extension. Suppose my tree is 4 level deep. I want 4 buttons. So that when the user will click button1 then the tree will be expanded upto level 1, when clicking button 2 then the tree will be expanded upto level 2 and so on.

                   

                  So, can you please tell me how can I achieve that ?