2 Replies Latest reply on Apr 26, 2016 9:34 AM by Jordan Koidahl

    Richfaces 4 Dynamic Tree creation

    Jordan Koidahl Newbie

      I'm migrating a project from richfaces 3 to 4. I'm wondering what the correct way to dynamically add children to a richfaces4 tree? My  current issue is that the rendering of newly added child nodes to a tree during a "toggleListener" action is not correctly identifying a given node as colapsed when it should be. I believe the problem is happening in the TreeEncoderBase class. So the sequence of events is the user clicks on a colapsed node, toggleListener action is triggered on the backing bean. The current node (which extends org.richfaces.model.TreeNodeImpl) gets a child node added to it ( who return false when isLeaf is called). The EncodeTree method is triggered to update the html. Which eventually gets to the walkModelChildren method inside AbstractTree. My new node gets added to a queuedDataList and is given "visited" state in the beforeChildrenVisit() method. Because this new node is "visited", The associated TreeNodeState is set to "expandedNoChildren" instead of "collapsed" which ultimately drives the behavior assigned to my new node. This same logic works in richfaces3 so I'm wondering what is incorrect about my approach?

       

      Some of my markup:

       

      <rich:tree toggleType="ajax" id="myTree" value="#{treeBean.dyanamicTree}" var="treeNode" nodeType="#{treeNode.level}">
          <rich:treeNode expanded="#{treeBean.treeState}" type="root" status="waitStatus" eventsQueue="globalQueue">
              <h:outputText value="#{treeNode.level}"/>
          </rich:treeNode>
          <rich:treeNode expanded="#{treeBean.treeState}" type="0" toggleListener="#{treeBean.loadFirstChildNodes(treeNode)}" status="waitStatus" eventsQueue="globalQueue" styleClass="rvgRowOne" highlightedClass="rvgRowTwo">
              <h:panelGrid id="toplvlTedId" columns="1" cellspacing="10px" columnClasses="columnWidth1">
                  <h:outputText value="Name:#{treeNode.name}"/>
              </h:panelGrid>
          </rich:treeNode>
          <rich:treeNode expanded="#{treeBean.treeState}" type="1" toggleListener="#{treeBean.loadSecondChildNodes(treeNode)}" status="waitStatus" eventsQueue="globalQueue" styleClass="rvgRowOne" highlightedClass="rvgRowTwo">
              <h:panelGrid id="firstlvlTedId" columns="1" cellspacing="10px" columnClasses="columnWidth1">
                  <h:outputText value="Name:#{treeNode.name}"/>
              </h:panelGrid>
          </rich:treeNode>
          <rich:treeNode expanded="#{treeBean.treeState}" type="2" status="waitStatus" eventsQueue="globalQueue" styleClass="rvgRowOne" highlightedClass="rvgRowTwo">
              <h:panelGrid id="secondlvlTedId" columns="1" cellspacing="10px" columnClasses="columnWidth1">
                  <h:outputText value="Name:#{treeNode.name}"/>
              </h:panelGrid>
          </rich:treeNode>
      </rich:tree>
      
      

       

      Example child node loading code:

       

       

          public void loadFirstChildNodes(org.richfaces.model.TreeNode root) {
              MyTreeNode node = (MyTreeNode) root;
              List<TreeNode> tempNodes = loader.findChildren(node);
              int i = 0;
              for (Iterator<TreeNode> iterator = tempNodes.iterator(); iterator.hasNext(); ) {
                  TreeNode tempNode = iterator.next();
                  root.addChild(Integer.toString(i), tempNode);
                  i++;
              }
          }