You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Enrico Triolo <tr...@itc.it> on 2005/10/12 12:06:26 UTC

Tree2 with checkboxes problem

Hi all, I'm experimenting with the tree2 component, but I'm facing a problem: I
added a checkbox for each node, trying to follow the same method I would use for
a datatable. I then added a commandButton for submitting page data.

The problem is, when the commandButton action is performed on the server side, I
can't extract any node from the tree component.

Here is the code:

The backing bean:

public class MyBean {

     private UITreeData tree = null;
     private UISelectBoolean checkbox = null;

     //Creates the TreeModel to feed the tree
     public TreeModel getTreeData() {
         TreeNode root = this.addNode(new MyTreeNode("0", "root"), 0);
         return new TreeModelBase(root);
     }

     //Adds some fake nodes to the tree
     private TreeNode addNode(MyTreeNode node, int level) {

         TreeNodeBase node1 = null;

         if(level == 0)
             node1 = new TreeNodeBase("root",  node.getName(), node.getId(), false);
         else
             node1 = new TreeNodeBase("central-node", node.getName(),
node.getId(), false);

         Vector children = new Vector();

         if(level < 3) {
             children.add( new MyTreeNode(level + ".1", "node" + level + ".1") );
             children.add( new MyTreeNode(level + ".2", "node" + level + ".2") );
             children.add( new MyTreeNode(level + ".3", "node" + level + ".3") );

             for(int i = 0; i < children.size(); i++) {
                 TreeNode child =
this.addNode((MyTreeNode)children.elementAt(i), level + 1);
                 node1.getChildren().add(child);
             }
         }

         return node1;
     }

     public UITreeData getTree() {
         return tree;
     }

     public void setTree(UITreeData tree) {
         this.tree = tree;
     }

     public UISelectBoolean getCheckbox() {
         return checkbox;
     }

     public void setCheckbox(UISelectBoolean checkbox) {
         this.checkbox = checkbox;
     }

     public void submitTree(ActionEvent e) {

         TreeNode root = this.tree.getNode();

         if(root != null) {
            ...   //   *** ROOT IS ALWAYS NULL. THIS BLOCK IS NEVER EXECUTED ***
         }
     }
}

MyTreeNode is a simple bean:

class MyTreeNode {

    private String name;
    private String id;

    public MyTreeNode(String id, String name) {
         this.id = id;
         this.name = name;
    }

    public String getId() { return id; }
    public String getName() { return name; }
    public void setId(String id) { this.id = id; }
    public void setName(String name) { this.name = name; }
}

And here's the view:

<%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>
<%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%>

<f:view>
     <h:form>
     <t:tree2 binding="#{myBean.tree}"
              value="#{myBean.treeData}"
              var="node"
              varNodeToggler="t"
              clientSideToggle="false"
              showLines="true"
              showRootNode="true"
              preserveToggle="true"
              id="tree">
         <f:facet name="root">
             <h:panelGroup>
                     <h:outputText value="<strong>root</strong>"
styleClass="nodeFolder" escape="false"/>
             </h:panelGroup>
         </f:facet>
         <f:facet name="central-node">
             <h:panelGroup>
                 <h:selectBooleanCheckbox id="relation"
binding="#{myBean.checkbox}" />
                 <h:commandLink immediate="true" action="#{t.toggleExpanded}">
                     <h:outputText value="<strong>#{node.description}</strong>"
styleClass="nodeFolder" escape="false" />
                 </h:commandLink>
             </h:panelGroup>
         </f:facet>
     </t:tree2>				

     <h:commandButton value="do something" action="#{myBean.submitTree}" />

     </h:form>
</f:view>


The problem is in the submitTree() method: in fact the root node is always null!


Re: Tree2 with checkboxes problem

Posted by Ennio Tosi <en...@gmail.com>.
2005/10/18, Sean Schofield <se...@gmail.com>:
>
> A few thoughts ...
>
> I'm not sure the binding attribute on tree2 works properly although I
> could be wrong since I haven't worked closely on it in a few months
> now.
>
> I don't think you need to have refs to the tree data, etc. in your
> backing bean. Try using ActionEvent.getComponent() instead.


I tried myself the example and had the same problems.
I don't think ActionEvent.getComponent() would work, because in this case
the component would be the commandbutton, not the tree. Am I missing
something?

I had the same problem, and I solved it in a slightly different way, but I'm
not really sure it is the "best practice";
taking as example the code posted before I modified the submitTree() method
this way:

public void submitTree(ActionEvent e) {
TreeModelBase model = (TreeModelBase)tree.getValue();
this.handleSelected(model, "0");
}

I then added the handleSelected() method that makes recursion into the tree
nodes starting from the root (id = "0"):

private void handleSelected(TreeModel model, String nodeId) {

//Set the current node id
model.setNodeId(nodeId);
TreeNode node = model.getNode();

if(node != null) {
//Build the checkox id by concatenating formId, tree id, nodeId and checkbox
id...
String checkboxId = "formId:tree:" + nodeId + ":relation";

//Extract the checkbox parameter from the request
Object chk = FacesContext.getCurrentInstance
().getExternalContext().getRequestParameterMap().get(checkboxId);
if(chk != null) {
//Checkbox selected!
}

//If the node isn't a leaf continue recursion
if(node.getChildCount() > 0) {
List children = node.getChildren();

if(children != null) {
Iterator it = children.iterator();
int i = -1;
while(it.hasNext()) {
i++;
//Creates the child node's id
String childNodeId = nodeId + ":" + i;
model.setNodeId(childNodeId);
TreeNode childNode = (TreeNode)it.next();
//Recursion
this.handleSelected(model, childNodeId);
}
}
}
}
}

As I said before, I'm not sure this is the correct way of doing this; my
perplexity comes from the way I used to evaluate the actual checkbox id, i.e.
concatenating the form id, the tree id, the current node id and the checkbox
id.

Does someone have a better solution?

ennio

sean
>
> On 10/12/05, Enrico Triolo <tr...@itc.it> wrote:
> > Hi all, I'm experimenting with the tree2 component, but I'm facing a
> problem: I
> > added a checkbox for each node, trying to follow the same method I would
> use for
> > a datatable. I then added a commandButton for submitting page data.
> >
> > The problem is, when the commandButton action is performed on the server
> side, I
> > can't extract any node from the tree component.
> >
> > Here is the code:
> >
> > The backing bean:
> >
> > public class MyBean {
> >
> > private UITreeData tree = null;
> > private UISelectBoolean checkbox = null;
> >
> > //Creates the TreeModel to feed the tree
> > public TreeModel getTreeData() {
> > TreeNode root = this.addNode(new MyTreeNode("0", "root"), 0);
> > return new TreeModelBase(root);
> > }
> >
> > //Adds some fake nodes to the tree
> > private TreeNode addNode(MyTreeNode node, int level) {
> >
> > TreeNodeBase node1 = null;
> >
> > if(level == 0)
> > node1 = new TreeNodeBase("root", node.getName(), node.getId(), false);
> > else
> > node1 = new TreeNodeBase("central-node", node.getName(),
> > node.getId(), false);
> >
> > Vector children = new Vector();
> >
> > if(level < 3) {
> > children.add( new MyTreeNode(level + ".1", "node" + level + ".1") );
> > children.add( new MyTreeNode(level + ".2", "node" + level + ".2") );
> > children.add( new MyTreeNode(level + ".3", "node" + level + ".3") );
> >
> > for(int i = 0; i < children.size(); i++) {
> > TreeNode child =
> > this.addNode((MyTreeNode)children.elementAt(i), level + 1);
> > node1.getChildren().add(child);
> > }
> > }
> >
> > return node1;
> > }
> >
> > public UITreeData getTree() {
> > return tree;
> > }
> >
> > public void setTree(UITreeData tree) {
> > this.tree = tree;
> > }
> >
> > public UISelectBoolean getCheckbox() {
> > return checkbox;
> > }
> >
> > public void setCheckbox(UISelectBoolean checkbox) {
> > this.checkbox = checkbox;
> > }
> >
> > public void submitTree(ActionEvent e) {
> >
> > TreeNode root = this.tree.getNode();
> >
> > if(root != null) {
> > ... // *** ROOT IS ALWAYS NULL. THIS BLOCK IS NEVER EXECUTED ***
> > }
> > }
> > }
> >
> > MyTreeNode is a simple bean:
> >
> > class MyTreeNode {
> >
> > private String name;
> > private String id;
> >
> > public MyTreeNode(String id, String name) {
> > this.id <http://this.id> = id;
> > this.name <http://this.name> = name;
> > }
> >
> > public String getId() { return id; }
> > public String getName() { return name; }
> > public void setId(String id) { this.id <http://this.id> = id; }
> > public void setName(String name) { this.name <http://this.name> = name;
> }
> > }
> >
> > And here's the view:
> >
> > <%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
> > <%@taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>
> > <%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
> >
> > <f:view>
> > <h:form>
> > <t:tree2 binding="#{myBean.tree}"
> > value="#{myBean.treeData}"
> > var="node"
> > varNodeToggler="t"
> > clientSideToggle="false"
> > showLines="true"
> > showRootNode="true"
> > preserveToggle="true"
> > id="tree">
> > <f:facet name="root">
> > <h:panelGroup>
> > <h:outputText value="<strong>root</strong>"
> > styleClass="nodeFolder" escape="false"/>
> > </h:panelGroup>
> > </f:facet>
> > <f:facet name="central-node">
> > <h:panelGroup>
> > <h:selectBooleanCheckbox id="relation"
> > binding="#{myBean.checkbox}" />
> > <h:commandLink immediate="true" action="#{t.toggleExpanded}">
> > <h:outputText value="<strong>#{node.description}</strong>"
> > styleClass="nodeFolder" escape="false" />
> > </h:commandLink>
> > </h:panelGroup>
> > </f:facet>
> > </t:tree2>
> >
> > <h:commandButton value="do something" action="#{myBean.submitTree}" />
> >
> > </h:form>
> > </f:view>
> >
> >
> > The problem is in the submitTree() method: in fact the root node is
> always null!
> >
> >
> >
> >
>

Re: Tree2 with checkboxes problem

Posted by Sean Schofield <se...@gmail.com>.
A few thoughts ...

I'm not sure the binding attribute on tree2 works properly although I
could be wrong since I haven't worked closely on it in a few months
now.

I don't think you need to have refs to the tree data, etc. in your
backing bean.  Try using ActionEvent.getComponent() instead.

sean

On 10/12/05, Enrico Triolo <tr...@itc.it> wrote:
> Hi all, I'm experimenting with the tree2 component, but I'm facing a problem: I
> added a checkbox for each node, trying to follow the same method I would use for
> a datatable. I then added a commandButton for submitting page data.
>
> The problem is, when the commandButton action is performed on the server side, I
> can't extract any node from the tree component.
>
> Here is the code:
>
> The backing bean:
>
> public class MyBean {
>
>      private UITreeData tree = null;
>      private UISelectBoolean checkbox = null;
>
>      //Creates the TreeModel to feed the tree
>      public TreeModel getTreeData() {
>          TreeNode root = this.addNode(new MyTreeNode("0", "root"), 0);
>          return new TreeModelBase(root);
>      }
>
>      //Adds some fake nodes to the tree
>      private TreeNode addNode(MyTreeNode node, int level) {
>
>          TreeNodeBase node1 = null;
>
>          if(level == 0)
>              node1 = new TreeNodeBase("root",  node.getName(), node.getId(), false);
>          else
>              node1 = new TreeNodeBase("central-node", node.getName(),
> node.getId(), false);
>
>          Vector children = new Vector();
>
>          if(level < 3) {
>              children.add( new MyTreeNode(level + ".1", "node" + level + ".1") );
>              children.add( new MyTreeNode(level + ".2", "node" + level + ".2") );
>              children.add( new MyTreeNode(level + ".3", "node" + level + ".3") );
>
>              for(int i = 0; i < children.size(); i++) {
>                  TreeNode child =
> this.addNode((MyTreeNode)children.elementAt(i), level + 1);
>                  node1.getChildren().add(child);
>              }
>          }
>
>          return node1;
>      }
>
>      public UITreeData getTree() {
>          return tree;
>      }
>
>      public void setTree(UITreeData tree) {
>          this.tree = tree;
>      }
>
>      public UISelectBoolean getCheckbox() {
>          return checkbox;
>      }
>
>      public void setCheckbox(UISelectBoolean checkbox) {
>          this.checkbox = checkbox;
>      }
>
>      public void submitTree(ActionEvent e) {
>
>          TreeNode root = this.tree.getNode();
>
>          if(root != null) {
>             ...   //   *** ROOT IS ALWAYS NULL. THIS BLOCK IS NEVER EXECUTED ***
>          }
>      }
> }
>
> MyTreeNode is a simple bean:
>
> class MyTreeNode {
>
>     private String name;
>     private String id;
>
>     public MyTreeNode(String id, String name) {
>          this.id = id;
>          this.name = name;
>     }
>
>     public String getId() { return id; }
>     public String getName() { return name; }
>     public void setId(String id) { this.id = id; }
>     public void setName(String name) { this.name = name; }
> }
>
> And here's the view:
>
> <%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
> <%@taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>
> <%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
>
> <f:view>
>      <h:form>
>      <t:tree2 binding="#{myBean.tree}"
>               value="#{myBean.treeData}"
>               var="node"
>               varNodeToggler="t"
>               clientSideToggle="false"
>               showLines="true"
>               showRootNode="true"
>               preserveToggle="true"
>               id="tree">
>          <f:facet name="root">
>              <h:panelGroup>
>                      <h:outputText value="<strong>root</strong>"
> styleClass="nodeFolder" escape="false"/>
>              </h:panelGroup>
>          </f:facet>
>          <f:facet name="central-node">
>              <h:panelGroup>
>                  <h:selectBooleanCheckbox id="relation"
> binding="#{myBean.checkbox}" />
>                  <h:commandLink immediate="true" action="#{t.toggleExpanded}">
>                      <h:outputText value="<strong>#{node.description}</strong>"
> styleClass="nodeFolder" escape="false" />
>                  </h:commandLink>
>              </h:panelGroup>
>          </f:facet>
>      </t:tree2>
>
>      <h:commandButton value="do something" action="#{myBean.submitTree}" />
>
>      </h:form>
> </f:view>
>
>
> The problem is in the submitTree() method: in fact the root node is always null!
>
>
>
>