3 Replies Latest reply on Apr 16, 2008 1:11 AM by jmoreira

    rich:tree with recursiveTreeNodesAdaptor

    jmoreira

      hi,


      i'm trying to implement a rich:tree with recursiveTreeNodesAdaptor and i've read through all of the examples and cant figure what's wrong.
      Environment is Seam 2.0.2CR1, JBoss 4.2 and RichFaces 3.1.4 I have seen examples where there was no need for writing TreeModel/Node adaptor.
      The control is for selecting a category from a simple adjacency list object tree (parent, children) to assign to a item.
      The model is correct as i have testng tests and the seam components get initialized correctly, all the controls appear except the tree itself.


      Do i miss anything?



      <ui:composition     xmlns="http://www.w3.org/1999/xhtml"
                          xmlns:s="http://jboss.com/products/seam/taglib"
                          xmlns:ui="http://java.sun.com/jsf/facelets"
                          xmlns:f="http://java.sun.com/jsf/core"
                          xmlns:h="http://java.sun.com/jsf/html"
                          xmlns:rich="http://richfaces.org/rich"
                          xmlns:a4j="http://richfaces.org/a4j"
                          xmlns:a="https://ajax4jsf.dev.java.net/ajax"
                          template="layout/template.xhtml" >
      
      
      <rich:tree style="width:300px; height: 200px; border: 1px solid red;" switchType="ajax">
           <rich:recursiveTreeNodesAdaptor roots="#{rootCategories}" var="cat" nodes="#{cat.children}">
                <rich:treeNode>#{cat.name}</rich:treeNode>
           </rich:recursiveTreeNodesAdaptor>
      </rich:tree>
      
      </ui:composition>
      




      @Entity
      @Table(name = "T_CATEGORY")
      public class Category extends BaseBean implements Serializable {
      
           /**
            * 
            */
           private static final long serialVersionUID = 1L;
      
           /**
            * 
            */
           private Long id;
      
           /**
            * 
            */
           private String name;
      
           /**
            * 
            */
           private Category parent;
      
           /**
            * 
            */
           private Set<Category> children = new HashSet<Category>();
      
           /**
            * 
            */
           private Set<Item> items = new HashSet<Item>();
      
           /**
            * 
            * @return
            */
           @Id
           @GeneratedValue
           @Column(name = "CATEGORY_ID")
           public Long getId() {
                return id;
           }
      
           /**
            * 
            * @param id
            */
           public void setId(Long id) {
                this.id = id;
           }
      
           /**
            * 
            * @return
            */
           @Column(name = "CATEGORY_NAME", length = 255, nullable = false)
           @NotNull
           public String getName() {
                return name;
           }
      
           /**
            * 
            * @param name
            */
           public void setName(String name) {
                this.name = name;
           }
      
           /**
            * 
            * @return
            */
           @ManyToOne
           @JoinColumn(name = "FK_PARENT_CATEGORY_ID", nullable = true)
           public Category getParent() {
                return parent;
           }
      
           /**
            * 
            * @param parent
            */
           public void setParent(Category parent) {
                this.parent = parent;
           }
      
           /**
            * 
            * @return
            */
           @OneToMany(mappedBy = "category", fetch = FetchType.LAZY)
           public Set<Item> getItems() {
                return items;
           }
      
           /**
            * 
            * @param items
            */
           public void setItems(Set<Item> items) {
                this.items = items;
           }
      
           /**
            * @return the children
            */
           @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
           public Set<Category> getChildren() {
                return children;
           }
      
           /**
            * @param children
            *            the children to set
            */
           public void setChildren(Set<Category> children) {
                this.children = children;
           }
           
      }
      



      /**
       * @author josemoreira
       * 
       */
      @Name("categoryHome")
      public class CategoryHome extends EntityHome<Category> {
      
           @In
           CategoryDAO categoryDAO;
      
           private List<Category> rootCategories;
      
           @Factory("rootCategories")
           public void initRootCategories() {
                rootCategories = categoryDAO.getRootCategories();
           }     
      }
      


        • 1. Re: rich:tree with recursiveTreeNodesAdaptor
          andygibson.contact.andygibson.net

          I have some very similar code that works the same way (recursive categories), and it is almost identical.


          Try displaying the content of the data as text, i.e adding to the page :


          <h:outputText value="#{rootCategories}"/>
          <h:outputText value="#{rootCategories.children}"/>
          



          and see what kind of output you get.


          Next, try increasing the scope of your data just in case it is something along those lines. I know in my code I use a conversation scope on the factory:


          @Factory(value="securityCategories",scope=ScopeType.CONVERSATION)
          public List<SecurityCategory> getSecurityCategories() {
          



          I have found that the trees can be somewhat problematic at times when they don't behave as they should, and I think they just did a bit of an overhaul on them. What version of Richfaces are you using?

          • 2. Re: rich:tree with recursiveTreeNodesAdaptor
            jmoreira

            thanks for replying.


            Environment is Seam 2.0.2CR1, JBoss 4.2 and RichFaces 3.1.4, i upgraded yesterday after first atempts at this.


            Meanwhile i tried using a selectOneMenu with a flat category tree list that worked. will try your solution later as Eclipse is hanging on a long commit.


            cheers

            • 3. Re: rich:tree with recursiveTreeNodesAdaptor
              jmoreira

              i've changed the Factory and nothing again. Using debug.seam i can see all the data in the conversation.


              i've added above the rich:tree:


              <h:selectOneMenu value="#{item.category}" id="category1">
                  <s:selectItems value="#{categoryHome.rootCategories}" var="category1" label="#{category1.name}" />
                  <s:convertEntity />
              </h:selectOneMenu>
              
              <h:selectOneMenu value="#{item.category}" id="category">
                  <s:selectItems value="#{allCategories}" var="category" label="#{category.getMaterializedPath('::')}" />
                  <s:convertEntity />
              </h:selectOneMenu>
              



              and it worked flawlessly. If i look at the source, there is javascript/html code for the tree component but there are 2 empty (java)script tags.


              The allCategories is in CategorySelector.java (work in progress, don't laugh :):


              /**
               * @author josemoreira
               * 
               */
              @Name("categorySelector")
              @AutoCreate
              @Scope(ScopeType.CONVERSATION)
              public class CategorySelector {
              
                   @In
                   CategoryDAO categoryDAO;
              
                   @Name("allCategories")
                   @Scope(ScopeType.CONVERSATION)
                   @AutoCreate
                   public static class AllCategoriesList implements Serializable {
              
                        @In
                        protected CategoryDAO categoryDAO;
              
                        protected List<Category> categories;
              
                        @Unwrap
                        @SuppressWarnings( { "unchecked" })
                        public List<Category> getCategories() {
                             categories = categoryDAO.getAllCategories();
                             return categories;
                        }
              
                   }
              
              }
              



              so i dunno, i'm out of ideas. Perhaps it's a configuration thing or jar problems. My headers are as follows:


              <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
                                    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
              <ui:composition     xmlns="http://www.w3.org/1999/xhtml"
                                  xmlns:s="http://jboss.com/products/seam/taglib"
                                  xmlns:ui="http://java.sun.com/jsf/facelets"
                                  xmlns:f="http://java.sun.com/jsf/core"
                                  xmlns:h="http://java.sun.com/jsf/html"
                                  xmlns:rich="http://richfaces.org/rich"
                                  xmlns:a4j="http://richfaces.org/a4j"
                                  xmlns:a="https://ajax4jsf.dev.java.net/ajax"
                                  template="layout/template.xhtml" >
              




              Either way i'm moving out of rich:tree. This is all about selecting the Item category, a tree would be appropriate but i'm gonna go for a selectOne with an ajax filtering textbox :/ i need to see how ebay does it :)