开发者

Rich faces tree problem

开发者 https://www.devze.com 2023-01-27 02:46 出处:网络
Please consider following rich faces tree example: <rich:tree switchType=\"ajax\"> <rich:treeNodesAdaptor id=\"officeNodeAdaptor\" nodes=\"#{officesBean.offices}\" var=\"office\" >

Please consider following rich faces tree example:

  <rich:tree switchType="ajax">
<rich:treeNodesAdaptor id="officeNodeAdaptor" nodes="#{officesBean.offices}" var="office" >
      <rich:treeNode changeExpandListener="#{office.loadEmplyeesIfNeeded}" >
          <h:outputText value="#{office.name}" />
     开发者_如何学C </rich:treeNode>
<rich:treeNodesAdaptor id="employeeNodeAdaptor" nodes="#{office.employees}" var="employee">
       <rich:treeNode>
           <h:outputText value="#{employee.name}" />
       </rich:treeNode>
</rich:treeNodesAdaptor>

This is sample tree for representing "Offices --> Employees" data structure. I want to have emplyees loaded in lazy way - so I introduced the loadEmplyeesIfNeeded expand listener. Everything works well except one thing. The employees are loaded after the office node is expanded.. So when the tree is rendered all offices don't have any employee and are rendered as leafs.. And of course leafs can not be expanded....

To make long store short. Is there any way to set that the node should be rendered as node (with possibility to expand) despite having no children? The best would be if rich:treeNode would have some attribut like isNode but it doesn't..

b.t.w. I could solve it by just adding to every office an fake employee at the initialization of offices.. But that's not very nice work around...

Thanks in advance for help.


A little late but. Who knows.

You can extend org.richfaces.model.TreeNodeImpl as I did.

   public class RichTreeNodeImpl extends org.richfaces.model.TreeNodeImpl {

       private boolean treatAsNode;

       public boolean getTreatAsNode() {
         return treatAsNode;
       }

       public void setTreatAsNode(boolean treatAsNode) {
         this.treatAsNode = treatAsNode;
       }

       @Override
       public boolean isLeaf() {
           if (this.treatAsNode)
              return false;
           else
              return super.isLeaf();
       }
   }


You can do this using OpenFaces TreeTable if you don't mind adding another library to your application. Lazy loading can be implemented just by adding the preloadedNodes="none" (or prelodedNodes="levelsPreloaded:1") to <o:treeTable> tag, and it will also automatically detect whether the node's expansion toggle should be displayed. OpenFaces TreeTable is quite customizable and it shouldn't necessarily look as a multi-column table, but it can be shown as a simple tree as well (e.g. see this page)

Here's how such a TreeTable can be declared (you might actually need more customizations, but this example shows the idea):

<o:treeTable var="node" preloadedNodes="none">
  <o:dynamicTreStructure nodeChildren="#{treeTableBean.nodeChildren}"/>
  <o:treeColumn>
    <h:outputText value="node.name"/>
  </o:treeColumn>
</o:treeTable>

The treeTableBean.nodeChildren method should take the value of the "node" variable, and return its child nodes (or return root nodes if its value is null). Here's how this method might look in your case:

public List getNodeChildren() {
  Object node = Faces.var("node");
  if (node == null) 
    return getOffices();
  else
    return ((Office) node).getEmployees();
}
0

精彩评论

暂无评论...
验证码 换一张
取 消