2 Replies Latest reply on Feb 11, 2013 12:44 PM by _user

    ADF Faces - How to create an editable rich table at runtime

    809994
      Hi,

      JDeveloper version - 11.1.1.4.0

      I have been trying to create an editable table (wherein the user can enter text into the input text boxes contained in the columns added at runtime). The values thus entered are to be captured in the backing bean for further processing.

      Below are my attempts to achieve this in various ways but without success.

      Attempt 1 : Created a Read-Only Dynamic table by dropping the view object instance from the Data Control. Here, the default being output text components, I used input text components and programatically make it updatable in the backing bean, which however, shows as an output text component.
      1) UI - .jspx file
      <af:table rows="#{bindings.TestViewObject1.rangeSize}"
                          fetchSize="#{bindings.TestViewObject1.rangeSize}"
                          emptyText="#{bindings.TestViewObject1.viewable ? 'No data to display.' : 'Access Denied.'}"
                          var="row" rowBandingInterval="0"
                          value="#{bindings.TestViewObject1.collectionModel}"
                          selectedRowKeys="#{bindings.TestViewObject1.collectionModel.selectedRow}"
                          selectionListener="#{bindings.TestViewObject1.collectionModel.makeCurrent}"
                          rowSelection="single" 
                          id="t1" 
                          partialTriggers="::cb1 ::cb2"
                          binding="#{TestDynamicTable.t1}">
                  <af:forEach items="#{TestDynamicTable.attributeDefns}"
                              var="def">
                    <af:column headerText="#{def.name}"
                               sortable="true" sortProperty="#{def.name}" id="c1">
                      <af:inputText value="#{row[def.name]}" id="it1"
                                    label="Label 1"
                                    autoSubmit="true" />                
                    </af:column>
                  </af:forEach>
                 
                </af:table>
      2) Backing bean -
          public void listenMeForAction(ActionEvent ae) {
             //adding attribute dynamically
            ViewAttributeDefImpl def = (ViewAttributeDefImpl)vo.addDynamicAttribute("testDynamicAttr"+columnCount);
            def.setUpdateableFlag(def.UPDATEABLE);
      
           byte b = def.UPDATEABLE;
            
           def.setEditable(true);
           //def.setProperty(def.ATTRIBUTE_CTL_TYPE,);
           //def.getUIHelper().HINT_NAME_UPDATEABLE
           def.setProperty(def.ATTRIBUTE_DISPLAY_HINT_DISPLAY, def.HINT_NAME_UPDATEABLE);
           columnCount ++ ;
           AdfFacesContext.getCurrentInstance().addPartialTarget(this.t1);
          }
      Attempt 2 : Created a ADF table by dropping the view object instance from the Data Control. Here, the columns and its cells are added programatically in the backing bean. However
      1) UI - .jspx file
      <af:table value="#{bindings.Test5ViewObj1.collectionModel}" var="row"
                          rows="#{bindings.Test5ViewObj1.rangeSize}"
                          emptyText="#{bindings.Test5ViewObj1.viewable ? 'No data to display.' : 'Access Denied.'}"
                          fetchSize="#{bindings.Test5ViewObj1.rangeSize}"
                          rowBandingInterval="0" 
                          id="richDynamicTable"
                          binding="#{TestDynamicTable.richDynamicTable}">
      </af:table>
      2) Backing bean - When the buildRichTable method is invoked from the constructor, the table shows the input text boxes as required, but the entered values is not getting retrieved (). Tried adding a valuchangelistener to the added cell, but this does not fire as well.

      Below code however, creates a new instance of RichTable. Also, if an overloaded method is invoked on an ActionEvent, the columns added are not displayed.
        //called from costructor  
        public void buildRichTable() {
          
          
          dynamicVO.clearCache();
          //create this table
          richDynamicTable = new RichTable();
          int noOfCols = 2;
          for(int i=0; i<noOfCols; i++) {
            //create new column for the table
            richDynamicCol = new RichColumn();
            richDynamicCol.setHeaderText("ColTest"+i);
             // richDynamicCol.isVisible()
             // richDynamicCol.setVisible(arg0);
      
            richDynamicCol.setParent(richDynamicTable);
            richDynamicTable.getChildren().add(richDynamicCol);
            
            richDynamicTable.getChildCount();
            richDynamicTable.getRowCount();
            richDynamicCell = new RichInputText();
            richDynamicCell.setLabel("aCell"+i);
           // richDynamicCell.isVisible()
              MethodExpression methodExpression = FacesContext.getCurrentInstance().getApplication().
                                                                        getExpressionFactory().createMethodExpression(
                                                                          FacesContext.getCurrentInstance().getELContext(), 
                                                                          "#{TestDynamicTable.inputBoxValueChangeListener}",
                                                                          null,
                                                                          new Class[] {ValueChangeEvent.class});
            //this does not work too - on adding some text and tabbing out
            richDynamicCell.addValueChangeListener(new MethodExpressionValueChangeListener(methodExpression));
            richDynamicCell.setParent(richDynamicCol);
            richDynamicCell.setValue("#{row.ColTest"+i+"}");
            richDynamicCol.getChildCount();
            richDynamicCol.getChildren().add(richDynamicCell);
              
           dynamicVO.addDynamicAttribute("ColTest"+i);
          }
          
          //dynamicVO.insertRow(dynamicVO.createRow());
          dynamicVO.getRowCount();
          
         AdfFacesContext.getCurrentInstance().addPartialTarget(this.getRichDynamicTable());
         AdfFacesContext.getCurrentInstance().addPartialTarget(this.getRichDynamicCol());
         AdfFacesContext.getCurrentInstance().addPartialTarget(this.getRichDynamicCell());
         buildTable = false;
         this.setDynamicVO(dynamicVO);
        }
      //captures the input data
        public void captureRichTableData(ActionEvent ae) {
      //gives null below
          this.getDynamicVO().getCurrentRow().getAttribute("ColTest0");
          this.getDynamicVO().getCurrentRow().getAttribute("ColTest1");
      //again null    
          List<UIComponent> listCols = richDynamicTable.getChildren();
          for(UIComponent aColComp : listCols) {
              RichColumn aCol = (RichColumn)aColComp;
              List<UIComponent> listCells = aCol.getChildren();
              for(UIComponent aCellComp : listCells) {
                RichInputText anInputText = (RichInputText)aCellComp;
                  anInputText.getValue();
              }
          }
        }
      Not sure what I must be missing. May be I need to add bindings to the text boxes added but cant figure how to go about it. I found some posts on dynamically adding columns pointing to displaying contained data. Any help would be highly appreciated.

      Thanks for your time.

      Dinu
        • 1. Re: ADF Faces - How to create an editable rich table at runtime
          809994
          Hi,

          Not too sure if I am heading the right way, but tried adding the bindings and value expression at runtime for the added columns. The values added at the screen is again found null at the VO and RichInputText child / cell. The updated method is as below -
                buildRichTable() {
                ...
                ...
                //adding binding for the added cell
                DCBindingContainer bc = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
                if(bc.findCtrlBinding("ColTest"+i) == null) {
                    bc.addControlBinding("ColTest"+i, new JUCtrlAttrsBinding(null, 
                                                           bc.findIteratorBinding("Test5ViewObj1Iterator"), 
                                                               new String[]{"ColTest"+i}));
                    
                }
                //the expression to be set in value attribute for richInputText component  
                String theExpression = "#{row.bindings."+"ColTest"+i+".inputValue}";
                //setting the expression
                richDynamicCell.setValueExpression("ColTest"+i, getValueExpression(theExpression));  
                richDynamicCell.setAutoSubmit(true);
                richDynamicCol.getChildCount();
                richDynamicCol.getChildren().add(richDynamicCell);
                  
              dynamicVO.addDynamicAttribute("ColTest"+i);
              }
              
              dynamicVO.insertRow(dynamicVO.createRow());
              dynamicVO.getRowCount();
              
              AdfFacesContext.getCurrentInstance().addPartialTarget(this.getRichDynamicTable());
              AdfFacesContext.getCurrentInstance().addPartialTarget(this.getRichDynamicCol());
              AdfFacesContext.getCurrentInstance().addPartialTarget(this.getRichDynamicCell());
             buildTable = false;
             this.setDynamicVO(dynamicVO);
            }
            
            private ValueExpression getValueExpression(String theExpression) {
             FacesContext fc = FacesContext.getCurrentInstance();
             Application app = fc.getApplication();
             ExpressionFactory elFactory = app.getExpressionFactory();
             ELContext elContext = fc.getELContext();
             return elFactory.createValueExpression(elContext, theExpression, Object.class);
            }
          It would be great help to have any leads.

          Thanks,
          Dinu
          • 2. Re: ADF Faces - How to create an editable rich table at runtime
            _user
            hi,
            did u fix this issue?
            if u fix it, can u reply with code?

            thanks