1 Reply Latest reply on Jul 2, 2009 3:31 AM by Anton Lisovenko

    Editable rich:tree

    Anton Lisovenko Newbie

      Hello. Strange, but could not find much information on the editable tree (add, edit, remove nodes) on the forum or manuals. So, implemented this in my own maner, and faced several problems. Here is my code:

      <rich:toolBar rendered="#{editable}">
       <rich:menuItem submitMode="ajax" value="#{payment_bundle.newGroup}"
       action="#{expenseBean.addNewGroup}" reRender="expenseTree">
       </rich:menuItem>
       <rich:menuItem submitMode="ajax"
       value="#{payment_bundle.newInnerGroup}"
       action="#{expenseBean.addNewChildGroup}" reRender="expenseTree">
       </rich:menuItem>
       <rich:menuItem submitMode="ajax"
       value="#{payment_bundle.newExpense}"
       action="#{expenseBean.addNewExpense}" reRender="expenseTree">
       </rich:menuItem>
       </rich:toolBar>
      
      <rich:tree styleClass="#{styleClass}" switchType="client"
       binding="#{expenseBean.tree}" id="expenseTree"
       stateAdvisor="#{expenseBean}"
       nodeSelectListener="#{expenseBean.nodeSelected}">
       <rich:recursiveTreeNodesAdaptor roots="#{expenseBean.rootExpenses}"
       var="item" nodes="#{item.children}">
       <rich:treeNode>
       <rich:inplaceInput layout="block"
       value="#{item.name}"
       id="inplace"
       editEvent="ondblclick" >
      
       <a4j:support event="onchange" action="#{expenseBean.updateExpense}">
       <!--<f:setPropertyActionListener doesn't work -->
       </a4j:support>
      
       </rich:inplaceInput>
       </rich:treeNode>
       </rich:recursiveTreeNodesAdaptor>
       </rich:tree>


      and the bean:

       /** */
       transient private UITree tree;
      
       /** */
       private Expense currentSelectedExpense;
      
       public Object updateExpense() {
       assert currentSelectedExpense != null;
      
       // CAUSES NPE!
       tree.getRowData()
       ....
       }
      
       public void addNewGroup() {
       // why this doesn't work??
       // Expense exp = (Expense) tree.getRowData();
      
       Expense newGroup = new Expense();
      
       newGroup.setType(ExpenseType.group);
      
       newGroup.setParentId(currentSelectedExpense.getParentId());
      
      
       try {
       dao.saveOrUpdate(newGroup);
      
       currentSelectedExpense = newGroup;
      
       this.ent = null;
       }
       catch (DatabaseException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
       }
       }
      
       public void nodeSelected(NodeSelectedEvent nodeSelectedEvent) {
      
       UITree tree = (UITree)nodeSelectedEvent.getComponent();
      
       currentSelectedExpense = (Expense)tree.getRowData();
       }
      


      Sorry for lots of code.

      The problem:
      How to get the new value of changed inplaceInput and make changes in db after this?

      - ValueChangeListener gives the new string value, but not the Expense element itself.
      - tree.getRowData() in the method, pointed as 'action' in <a4j:support> raises NPE.
      - The "onviewactivated" in <a4j:support> seems to work correctly, but not always (if after editing inplaceInput I click on other inplaceInput, the "nodeSelected" value is not called).

      Thanks in advance!