views:

412

answers:

3

I have a tree of categories and courses in my SEAM application. Courses may be active and inactive. I want to be able to show only active or all courses in my tree.

I've decided to always build complete tree in my PAGE scope component since building this tree is quite expensive operation. I have boolean flag courseActive in the data wrapped by TreeNode<T>. Now I can't find the way to show courses node only if this flag is true.

The best result I've achieved with the following code:

<h:outputLabel for="showInactiveCheckbox" value="show all courses: "/>
<h:selectBooleanCheckbox id="showInactiveCheckbox" value="#{categoryTreeEditorModel.showAllCoursesInTree}">
   <a4j:support event="onchange" reRender="categoryTree"/>
</h:selectBooleanCheckbox>

<rich:tree id="categoryTree" value="#{categoryTree}" var="item" switchType="ajax"
           ajaxSubmitSelection="true" reRender="categoryTree,controls"
           adviseNodeOpened="#{categoryTreeActions.adviseRootOpened}"
           nodeSelectListener="#{categoryTreeActions.processSelection}"
           nodeFace="#{item.typeName}">

   <rich:treeNode type="Category" icon="..." iconLeaf="...">
      <h:outputText value="#{item.title}"/>
   </rich:treeNode>

   <rich:treeNode type="Course" icon="..." iconLeaf="..."
                  rendered="#{item.courseActive or categoryTreeEditorModel.showAllCoursesInTree}">
      <h:outputText rendered="#{item.courseActive}" value="#{item.title}"/>
      <h:outputText rendered="#{not item.courseActive}" value="#{item.title}" style="color:#{a4jSkin.inactiveTextColor}"/>
   </rich:treeNode>

</rich:tree>

the only problem is if some node is not listed in any rich:treeNode it just still shown with title obtained by Object.toString() method insted of being hidden.

Does anybody know how to not show some nodes in the Richfases tree according to some condition?

Update

For better understanding what I'm trying to do I can provide simple example:

Imagune that I have a filesystem with files and directories and there are normal and hidden files (in my case I have no hidden directories but it's not important).

I want to read files and directories once and store the tree in the model (org.richfaces.model.TreeNode) and then be able to show only directories on one page and only directories and not hidden files by default on another page with possibility to show all files and directories using checkbox on this page.

There is not enough to hede(/not render) rish:treeNode element in facelet since if there is a node which is not mentioned in any of rendered rich:treeNode this node is rendered using default icons and title. One may think about rich:treeNode like about an elemnt only to add custom visual style to nodes of some types but not as an element responsible for rendering of a node.

A: 

I'm really not sure, but maybe you could try to use a Facelets . Would the EL would be evaluated correctly, since c:if is a build-time tag?

See: http://wiki.java.net/bin/view/Projects/FaceletsFAQ#Why_doesn_t_my_c_if_ui_repeat_ui

ciaron
It doesn't works and it's clear why. If there is a node it the tree model it will be rendered in a view generated by rich:tree even if there is no rich:treeNode element for it. Results with the c:if is completely the same as obtained by the code I've posted. I'm searching for the way how to avoid rendering of some nodes I don't need. Actually I want to use the same backing bean model on three or four different views and in each view there will be different conditions which nodes to render and which to skip.
VestniK
A: 

Have you tried the <s:fragment>?

<s:fragment rendered="#{item.flag == 'true'}">
    Show some stuff here when flag returns true
</s:fragment>

<s:fragment rendered="#{not item.flag}">
    Show some stuff here when flag is NOT true
</s:fragment>

Update

I am not sure what your question really is, however I am guessing you want to hide a treenode In your example it would look like this:

<s:fragment rendered="#{item.courseActive}">
   <rich:treeNode type="Category" icon="..." iconLeaf="...">
      <h:outputText value="#{item.title}"/>
   </rich:treeNode>
</s:fragment>

<s:fragment rendered="#{not item.courseActive}">
  <rich:treeNode type="Course" icon="..." iconLeaf="...">
     <h:outputText value="#{item.title}"/>
  </rich:treeNode>
</s:fragment>
Shervin
It will not work as expected since your code will hide treeNode element while this element doesn't really renders node on the view. It only allows to specify custom style parameters for certain types of nodes. If there is a node in the model and no rendered treeNode element for it, this node will be rendered with default styles.
VestniK
A: 

It looks like there are two ways to solve my problem.

First one: I can use rich:recursiveTreeNodesAdaptor and in my recursive getter function I can skip some nodes. This aproach may be hard to use with drag and drop for moving items in the tree.

Second one: Attach detach some nodes on the server side. Disadvantage of this approach is a lot of Java code for recursive iterations through the tree.

I think I'll use the second way since I need drag and drop tree editor.

The same question was discussed in the JBoss comunity forum one year ago: http://community.jboss.org/message/64929 and the second way was also advised

VestniK