1 2 Previous Next 17 Replies Latest reply on Nov 16, 2007 5:14 PM by j-pro

    rich tree and a4j support onselected - how to?

    j-pro

      Good afternoon.

      My point is to make update a form on a page after user clicks on a tree node.

      I tried two ways, none of it worked:

      The first one:

      <rich:tree style="width:250px" id="structureTree" styleClass="tree" switchType="ajax"
       ajaxSubmitSelection="true" showConnectingLines="true"
       changeExpandListener="#{treeMan.onDepartmentTreeExpand}"
       nodeSelectListener="#{treeMan.onDepartmentTreeSelect}"
       stateAdvisor="#{departmentTreeStateAdvisor}">
       <rich:recursiveTreeNodesAdaptor roots="#{treeMan.departmentsTreeRoots}" var="item" nodes="#{item.nodes}" />
       <a4j:support event="onselected" actionListener="#{treeMan.onA4JDepartmentTreeSelect}" reRender="pretendersDataTable_Form"/>
      </rich:tree>
      


      public void onA4JDepartmentTreeSelect(ActionEvent event)
      {
       UITree tree = (UITree) event.getComponent();
      
       DepartmentTreeNode selectedNode = (DepartmentTreeNode)tree.getRowData();
      
       ...
      }


      And all I'm getting after clicking on a node, is this:
      actionListener="#{treeMan.onA4JDepartmentTreeSelect}": java.lang.ClassCastException: org.ajax4jsf.component.html.HtmlAjaxSupport


      This exception is caused by this line: "UITree tree = (UITree) event.getComponent();"


      Then I've tried the second way, like it was done with HtmlDataTable(using binding to UITree property):

      <rich:tree style="width:250px" id="structureTree" styleClass="tree" switchType="ajax"
       ajaxSubmitSelection="true" showConnectingLines="true"
       changeExpandListener="#{treeMan.onDepartmentTreeExpand}"
       nodeSelectListener="#{treeMan.onDepartmentTreeSelect}"
       stateAdvisor="#{departmentTreeStateAdvisor}
       binding="#{treeMan.tree}">
       <rich:recursiveTreeNodesAdaptor roots="#{treeMan.departmentsTreeRoots}" var="item" nodes="#{item.nodes}" />
       <a4j:support event="onselected" actionListener="#{treeMan.onA4JDepartmentTreeSelect}" reRender="pretendersDataTable_Form"/>
      </rich:tree>


      And my action listener method changed to:
      ...
      
      private UITree tree;
      
      ...
      
      public void onA4JDepartmentTreeSelect(ActionEvent event)
      {
       // commented because of private property UITree tree
       //UITree tree = (UITree) event.getComponent();
      
       DepartmentTreeNode selectedNode = (DepartmentTreeNode)tree.getRowData();
      
       ...
      }



      And this time I'm getting this:
      actionListener="#{treeMan.onA4JDepartmentTreeSelect}": java.lang.IllegalStateException: No tree element available or row key not set!


      This exception is caused by this line: "DepartmentTreeNode selectedNode = (DepartmentTreeNode)tree.getRowData();"


      Please, help me to understand what should be done to make this work? I already learned how to catch clicks on nodes using nodeSelectListener, but using it I can't reRender needed regions on the page. The one and only way for it is a4j:support with reRender attribute. But how make it work? I'm sure I'm doing something wrong, so please, point me to the right direction.

      Thanks in advance!

        • 1. Re: rich tree and a4j support onselected - how to?
          j-pro

          Updated to version 3.1.2 GA(it was 3.1.0 before) and:

          1st case: the same exception.

          2nd case: I'm getting a null pointer exception when invoking selectedNode.toString(); after "DepartmentTreeNode selectedNode = (DepartmentTreeNode)tree.getRowData();", so there is no more "IllegalStateException". But still doesn't work because of NP Exception.

          Does anybody knows what should I do?

          Thanks in advance.

          • 2. Re: rich tree and a4j support onselected - how to?
            j-pro

            Dear Rich Faces developers.

            I would greatly appreciate if you give me any advice on how to solve this problem... I'm sure you know better than me what could be a solution for that...

            Thank you very much in advance for your time.

            • 3. Re: rich tree and a4j support onselected - how to?
              j-pro

              Okay, I've tried to use the method which is in nodeSelectListener of rich:tree, but leaving a4j:support tag, without acion attribude, but with reRender attribute.

              So, I have now:

              <rich:tree style="width:250px" id="structureTree" styleClass="tree" switchType="client"
               ajaxSubmitSelection="true" showConnectingLines="true"
               changeExpandListener="#{treeMan.onDepartmentTreeExpand}"
               nodeSelectListener="#{treeMan.onDepartmentTreeSelect}"
               stateAdvisor="#{departmentTreeStateAdvisor}">
               <rich:recursiveTreeNodesAdaptor roots="#{treeMan.departmentsTreeRoots}" var="item" nodes="#{item.nodes}" />
               <a4j:support event="onselected" reRender="pretendersDataTable_Form"/>
              </rich:tree>



              It seems to work, BUT my onDepartmentTreeSelect method is invoked for two times. When I remove this "<a4j:support event="onselected" reRender="pretendersDataTable_Form"/>" - it's invoked only once. But when I add it again, the method is invoked twice.

              Here is onDepartmentTreeSelect:
              public void onDepartmentTreeSelectStaff(NodeSelectedEvent event)
              {
               if(event == null) { System.out.println("############### >>>>> Event IS NULL !!!"); return; }
              
               UITree tree = (UITree) event.getComponent();
              
               System.out.println("################# >>>>> Tree node selected");
              
               if(tree == null) { System.out.println("############### >>>>> Tree IS NULL !!!"); return; }
              
               DepartmentTreeNode selectedNode = (DepartmentTreeNode)tree.getRowData();
               System.out.println("name = " + selectedNode.toString());
              
               System.out.println("################# >>>>> Tree node selected FINISH");
              }


              And when I click on the tree node, I get:
              18:24:57,587 INFO [STDOUT] ################# >>>>> Tree node selected
              18:24:57,587 INFO [STDOUT] name = Anketa
              18:24:57,587 INFO [STDOUT] ################# >>>>> Tree node selected FINISH
              18:24:57,869 INFO [STDOUT] ################# >>>>> Tree node selected
              18:24:57,869 INFO [STDOUT] name = Anketa
              18:24:57,869 INFO [STDOUT] ################# >>>>> Tree node selected FINISH


              But when I remove a4j:support from rich:tree, I get logs for only once:
              18:27:46,487 INFO [STDOUT] ################# >>>>> Tree node selected
              18:27:46,487 INFO [STDOUT] name = Anketa
              18:27:46,487 INFO [STDOUT] ################# >>>>> Tree node selected FINISH



              I use RichFaces, version 3.1.0 RC6. Because using 3.1.2, I get the same, plus "TreeRendererBase.encodeAjaxChildren()[j__id34_:0]".


              Please, tell me if my solution is good and answer please, why my method is invoked twice?

              Thank you very much.

              • 4. Re: rich tree and a4j support onselected - how to?
                j-pro

                In previous post "public void onDepartmentTreeSelectStaff" = "public void onDepartmentTreeSelect", body is the same. Just mistyped.

                I've tested the situation with nodeSelectListener + a4j:support onselected for some more time and found out that nodeSelectListener is not always invoked twice. I can't find any regularity(rule), but it definitely can be invoked as twice, as once. Sometimes when I click on a node it's invoked once, sometimes - twice. I can't yet find a solution...

                Any help would be appreciated.

                • 5. Re: rich tree and a4j support onselected - how to?
                  nbelaevski

                  Hello!

                  Tree component with ajaxSubmitSelection="true" automatically submits new selection, so you should not need onselected a4j:support. Looks like you have 2 different AJAX requests (to check that see if id of FacesContext.getCurrentInstance() is the same for 2 event handlers invocation in debugger).

                  If that's the case then we should talk about incorrect selection handler work. It should react only on changes for current selection, and it seems to me that onselected handler is sometimes fired when it should not do it. We'll check that.

                  To solve the problem try switching off ajaxSubmitSelection or removing support. Tree obeys reRender attribute, so you can remove a4j:support safely.

                  P.S. ClassCastException in the first demo-code is caused by the fact that ActionEvent has been generated by a4j:support. To access the tree traverse parents of event component until you'll find UITree.

                  P.P.S. Code for the second case seems to be ok, so we'll check that problem too.

                  • 6. Re: rich tree and a4j support onselected - how to?
                    j-pro

                     

                    "nbelaevski" wrote:
                    Looks like you have 2 different AJAX requests (to check that see if id of FacesContext.getCurrentInstance() is the same for 2 event handlers invocation in debugger).

                    Yes, there are 2 AJAX requests. But not always, as I've described above. I see that because I have "Richfaces.showModalPanel" in a4j:status onstart. I write there something like "please wait". And when I click on a tree node, the panel shows for some time, disappears, then shows again and disappears again. Then I can see log output from the handler for two times. But, again - it's not the constant behaviour. Sometimes it can be 2 AJAX requests, sometimes - one, on the same nodes and I can't yet find a rule for it.

                    About to view FacesContext ID, I hope I've understood you right and added this string in my node select listener:
                    System.out.println("FacesContext toString = " + FacesContext.getCurrentInstance().toString());

                    After that the log looks like:
                    17:11:26,614 INFO [STDOUT] ################# >>>>> Tree node selected
                    17:11:26,629 INFO [STDOUT] name = Sklad 2
                    17:11:26,629 INFO [STDOUT] FacesContext toString = com.sun.faces.context.FacesContextImpl@43b884
                    17:11:26,629 INFO [STDOUT] ################# >>>>> Tree node selected FINISH
                    17:11:26,770 INFO [STDOUT] ################# >>>>> Tree node selected
                    17:11:26,770 INFO [STDOUT] name = Sklad 2
                    17:11:26,770 INFO [STDOUT] FacesContext toString = com.sun.faces.context.FacesContextImpl@1bf7a02
                    17:11:26,770 INFO [STDOUT] ################# >>>>> Tree node selected FINISH


                    "nbelaevski" wrote:
                    To solve the problem try switching off ajaxSubmitSelection or removing support.

                    Removing support and moving its reRender attribute to rich:tree helped(but as I've explained below, element is reRendered even if I expand/collapse the node).
                    But when I just changed ajaxSubmitSelection to "false", result wasn't so different:
                    17:23:45,248 INFO [STDOUT] ################# >>>>> Tree node selected
                    17:23:45,248 INFO [STDOUT] name = Sklad 1
                    17:23:45,248 INFO [STDOUT] FacesContext toString = com.sun.faces.context.FacesContextImpl@fedd8
                    17:23:45,248 INFO [STDOUT] ################# >>>>> Tree node selected FINISH
                    17:23:45,311 INFO [STDOUT] ################# >>>>> Tree node selected
                    17:23:45,311 INFO [STDOUT] name = Sklad 1
                    17:23:45,326 INFO [STDOUT] FacesContext toString = com.sun.faces.context.FacesContextImpl@1881c68
                    17:23:45,326 INFO [STDOUT] ################# >>>>> Tree node selected FINISH


                    "nbelaevski" wrote:
                    Tree obeys reRender attribute, so you can remove a4j:support safely.

                    Yes, but reRender of rich:tree works on every AJAX request. And if I use it - I can't reRender different regions while doing different actions(like node select, or node expand). I mean that my table(in example above) reRenders always, no matter if I select a node, or expand it. How to be in that case?

                    "nbelaevski" wrote:
                    P.S. ClassCastException in the first demo-code is caused by the fact that ActionEvent has been generated by a4j:support. To access the tree traverse parents of event component until you'll find UITree.

                    Could you please show me how to do it? It's interesting, but I don't know how to traverse parents of ActionEvent... Thanks in advance.

                    • 7. Re: rich tree and a4j support onselected - how to?
                      sergeyhalipov

                       

                      "J-Pro" wrote:

                      "nbelaevski" wrote:
                      P.S. ClassCastException in the first demo-code is caused by the fact that ActionEvent has been generated by a4j:support. To access the tree traverse parents of event component until you'll find UITree.

                      Could you please show me how to do it? It's interesting, but I don't know how to traverse parents of ActionEvent... Thanks in advance.


                      Action event is generated for a4j:suport, not for tree. So we have to search for UITree in components tree:
                      public void onA4JDepartmentTreeSelect(ActionEvent event)
                      {
                       UIComponent component = event.getComponent();
                       while (null != component && !(component instanceof UITree)) {
                       component = component.getParent();
                       }
                       if (null == component)
                       return;
                       UITree tree = component;
                      
                       DepartmentTreeNode selectedNode = (DepartmentTreeNode)tree.getRowData();
                      
                       ...
                      }
                      


                      • 8. Re: rich tree and a4j support onselected - how to?
                        j-pro

                        Thanks, Sergey, now I see.

                        • 9. Re: rich tree and a4j support onselected - how to?
                          nbelaevski

                           

                          "J-Pro" wrote:
                          "nbelaevski" wrote:
                          Tree obeys reRender attribute, so you can remove a4j:support safely.

                          Yes, but reRender of rich:tree works on every AJAX request. And if I use it - I can't reRender different regions while doing different actions(like node select, or node expand). I mean that my table(in example above) reRenders always, no matter if I select a node, or expand it. How to be in that case?


                          Here is the sample code allowing to control re-rendering programmatically that could serve as a workaround. It's not so convenient as re-render, but maybe helpful in some situations
                          FacesContext facesContext = FacesContext.getCurrentInstance();
                          AjaxContext ajaxContext = AjaxContext
                           .getCurrentInstance(facesContext);
                          
                          ajaxContext.addComponentToAjaxRender(concreteComponent);
                          ajaxContext.addComponentToAjaxRender(tree, anotherComponentId);
                          


                          • 10. Re: rich tree and a4j support onselected - how to?
                            nbelaevski

                             

                            "J-Pro" wrote:
                            "nbelaevski" wrote:
                            To solve the problem try switching off ajaxSubmitSelection or removing support.

                            Removing support and moving its reRender attribute to rich:tree helped(but as I've explained below, element is reRendered even if I expand/collapse the node).
                            But when I just changed ajaxSubmitSelection to "false", result wasn't so different:
                            17:23:45,248 INFO [STDOUT] ################# >>>>> Tree node selected
                            17:23:45,248 INFO [STDOUT] name = Sklad 1
                            17:23:45,248 INFO [STDOUT] FacesContext toString = com.sun.faces.context.FacesContextImpl@fedd8
                            17:23:45,248 INFO [STDOUT] ################# >>>>> Tree node selected FINISH
                            17:23:45,311 INFO [STDOUT] ################# >>>>> Tree node selected
                            17:23:45,311 INFO [STDOUT] name = Sklad 1
                            17:23:45,326 INFO [STDOUT] FacesContext toString = com.sun.faces.context.FacesContextImpl@1881c68
                            17:23:45,326 INFO [STDOUT] ################# >>>>> Tree node selected FINISH



                            Strange, we can still 2 different AJAX requests. Sergey have you reproduced this case?

                            • 11. Re: rich tree and a4j support onselected - how to?
                              sergeyhalipov

                              Hi, J-Pro! You wrote:

                              "J-Pro" wrote:

                              "nbelaevski" wrote:
                              To solve the problem try switching off ajaxSubmitSelection or removing support.

                              Removing support and moving its reRender attribute to rich:tree helped(but as I've explained below, element is reRendered even if I expand/collapse the node).
                              But when I just changed ajaxSubmitSelection to "false", result wasn't so different:
                              17:23:45,248 INFO [STDOUT] ################# >>>>> Tree node selected
                              17:23:45,248 INFO [STDOUT] name = Sklad 1
                              17:23:45,248 INFO [STDOUT] FacesContext toString = com.sun.faces.context.FacesContextImpl@fedd8
                              17:23:45,248 INFO [STDOUT] ################# >>>>> Tree node selected FINISH
                              17:23:45,311 INFO [STDOUT] ################# >>>>> Tree node selected
                              17:23:45,311 INFO [STDOUT] name = Sklad 1
                              17:23:45,326 INFO [STDOUT] FacesContext toString = com.sun.faces.context.FacesContextImpl@1881c68
                              17:23:45,326 INFO [STDOUT] ################# >>>>> Tree node selected FINISH


                              Tree is rerendered during expanding/collapsing node if switchType attribute is set to "ajax". Try to change its value to "client". This should help you to avoid unnecessary Ajax requests.

                              • 12. Re: rich tree and a4j support onselected - how to?
                                j-pro

                                Thanks for your replies.


                                "sergeyhalipov" wrote:

                                ...
                                Tree is rerendered during expanding/collapsing node if switchType attribute is set to "ajax". Try to change its value to "client". This should help you to avoid unnecessary Ajax requests.

                                Here comes another problem which I described here: http://www.jboss.com/index.html?module=bb&op=viewtopic&t=122489 - while switchType is set to client, my nodes doesn't "want" to collapse/expand. I can't yet understand the reason...


                                "nbelaevski" wrote:
                                FacesContext facesContext = FacesContext.getCurrentInstance();
                                AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
                                
                                ajaxContext.addComponentToAjaxRender(concreteComponent);
                                ajaxContext.addComponentToAjaxRender(tree, anotherComponentId);

                                I suppose that concreteComponent - can be for example rich:dataTable, binded as HTMLDataTable, right? And anotherComponentId should be id, like "pretendersDataTable_Form" ? Am I right here?

                                • 13. Re: rich tree and a4j support onselected - how to?
                                  sergeyhalipov

                                  I can't reproduce these problems with my environment. Could you send us your JSP file or entire *.war file with project? My E-mail is "hans at exadel dot com".
                                  BTW, which richfaces version are you using?

                                  • 14. Re: rich tree and a4j support onselected - how to?
                                    j-pro

                                    Thanks, I'll send you needed files, no problem.

                                    I use RF 3.1.3 snapshot (24.10).

                                    1 2 Previous Next