11 Replies Latest reply: Apr 17, 2012 11:32 AM by 882847 RSS

    ADF dynamic table

    882847
      Hi,

      There is a requirement to create a dynamic table on page load. The number of columns and data varies based on user logged in.
      For example: If user is ABC ( then no. of columns of the table will be 7)
      and if the user is XYZ ( then no. of columns of the table will be 17)
      I have written a method in the impl which calls the procedure and gets the number of columns and data based on user logged in. Then i stored that data in two arraylist. one containing the column header and other arraylist containing the data.
      So now can you please help me to create a dynamic table by calling this method on page load. One more advice: can you tell the best way of calling the impl method which returns arraylist on page load.

      Thanks in advance.
        • 1. Re: ADF dynamic table
          Shay Shmeltzer-Oracle
          I think you should be calling this method before your reach your page - so put a method call in your page flow before the page.
          Then that method can store the arraylist in a pageflow scope that you'll be able to refer to from your page.

          One other approach is to do something like this:
          Have your AM method create a VO dynamically that your form is based on:
          https://blogs.oracle.com/shay/entry/adf_faces_dynamic_tags_-fora
          • 2. Re: ADF dynamic table
            882847
            Thanks Shay for the reply. Can you also give some example for creating the table dynamically.
            • 3. Re: ADF dynamic table
              MavenDev
              If i were you, i will return hashMap (that contains values for columns ) and ArrayList (that contains columns)... that means i will call two AM functions. and get it in the manged bean .... and then create table programmtically. Since i recently work on such project and it is successful.

              just create <af:table id="myTable" binding="#{pageflowscope.myBean.myTableBinding}" /> in jsff file...

              and on setter of the binding :

              setMyTableBinding(RichTable rc){
              this.myTableBinding = rc;
              createDynamicTable();
              }

              public void createDynamicTable(){

              // now using this binding "myTableBinding" create dynamic columns and values ... if you how to do..


              }

              hope that's helpful...

              Thanks
              • 4. Re: ADF dynamic table
                882847
                Hi MavenDev,

                Thanks for the idea. It worked for me. I was able to create a table dynamically.
                Now need to modify this table in many ways. 1) Need to always hide the last two columns of this dynamic table. 2) The first column of this table is a default column. I mean an extra column which i wn't get in my arraylist. So how can i add a default column as the first column which will have radio buttons in it and the data in this column will be the data of the column which needs to be hidden.3) One of the column return me this data 8330411. I need to convert this into hyperlink.

                Thanks in advance.
                • 5. Re: ADF dynamic table
                  MavenDev
                  i would say roughly,
                        RichColumn headerCol=
                          (RichColumn) app.createComponent(RichColumn.COMPONENT_TYPE);
                        headerCol.setId("headerCol");
                        headerCol.setHeaderText("My 1st column");
                        myTable.getChildren().add(headerCol);
                  This is how i add columns to the table..

                  well, can you post your code how you created dynamic table and columns .... so that i can suggest in ur way...

                  Thanks
                  • 6. Re: ADF dynamic table
                    882847
                    Sure. Here goes my code:

                    Jspx page:
                    <af:table varStatus="rowStat" summary="table"
                    value="#{TableBean.collectionModel}"
                    rows="#{TableBean.collectionModel.rowCount}"
                    rowSelection="none" contentDelivery="immediate" var="row"
                    rendered="true" id="t1" styleClass="AFStretchWidth"
                    binding="#{TableBean.myTableBinding}">
                    <af:forEach items="#{TableBean.columnNames}"
                    var="name">
                    <af:column sortable="true" sortProperty="#{name}"
                    rowHeader="unstyled" headerText="#{name}"
                    inlineStyle="width:100px;" id="c1">
                    <af:activeOutputText value="#{row[name]}" id="aot1">
                    </af:activeOutputText>
                    </af:column>
                    </af:forEach>
                    </af:table>

                    TableBean:

                    public void setMyTableBinding(RichTable rc) {
                    this.myTableBinding = rc;
                    createDynamicTable();
                    }

                    public void createDynamicTable() {
                    BindingContext bctx = BindingContext.getCurrent();
                    oracle.binding.BindingContainer bindings =
                    BindingContext.getCurrent().getCurrentBindingsEntry();
                    OperationBinding method =
                    (OperationBinding)bindings.get("getStoredProcedureforDocList");
                    method.execute();
                    Object obj = method.getResult();
                    if(obj!=null){
                    ArrayList colArr = (ArrayList)obj;
                    List columnheader = (List)colArr.get(0);
                    List columnvalue = (List)colArr.get(1);
                    columnNames = new ArrayList<String>();
                    columnData = new ArrayList<List>();
                    columnNames=(List<String>)columnheader;
                    columnData= (List<List>)columnvalue;
                    generateColumnModel();
                    }
                    }

                    public void generateColumnModel() {
                    this.model = new SortableModel(createRows(columnNames,columnData));
                    }

                    private static List<Map> createRows(List<String> columnNames,List<List> columnData) {
                    List<Map> mapListforRows = new ArrayList<Map>();
                    Map newRow = new HashMap();
                    HashMap hm = new HashMap();
                    for(int i=0 ; i < columnNames.size(); i++){
                    System.out.println("ColumnNames : " + columnNames.get(i).toString());
                    hm.put(i,columnNames.get(i).toString());
                    }
                    for(int x=0 ; x < columnData.size(); x++){ 
                    newRow = new HashMap();
                    mapListforRows.add(newRow);
                    System.out.println("==" + columnData.size());
                    List rowValues= columnData.get(x);
                    for(int z=0 ; z < rowValues.size(); z++){
                    newRow.put(hm.get(z), rowValues.get(z));
                    // System.out.println("row==" + rowValues.get(z));
                    }
                    }
                    return mapListforRows;
                    }

                    This is how i created a table.
                    Thanks
                    • 7. Re: ADF dynamic table
                      MavenDev
                      Looking at your code i would like to suggest many things but above all i would say:

                      Create a Taskflow ( parametrized) whose default activity is a method from AM and pass that parameter to this method .... extract data from db or wtever using that parameter and store them into List<List<List> ( i hope that is what ur returning back)
                      and return List from this method which is set to managedbean property; through taskflow .... meaning to say that .. when u drag am method to the Taskflow, you also have option to return the value from the method to the managed bean ... click on the method that you have dragged and then go to the Parameters just in ther you will see "Return Value" use expression builder to locate manageBean and the property you want it to bind.

                      since it's good do to all possible things in Model project :

                      => add new column that u wanted to add on the 1st index(i.e at 0 position of list) of the columnList...since you also need value corresponding to this list , so add value for all the value list corresponding to this column list at their index 1st .i.e at 0 position of each list.

                      e.g.
                      List columnList = new ArrayList();
                      columnList.add(0,"your new default Column which is not from any source") ;

                      List individualList = new ArrayList();
                      individualList .add(0,null); //// some value... whatever fits otherwise null.

                      i assume you will return List<List><List> from AM method.



                      Now in same Taskflow from That Drag Am method draw a navigation to managed bean method, that do custom process and check for null/error if any.

                      Basically, this method will do is do the preliminary things like checks for null , like this.model = new SortableModel(createRows(columnNames, columnData)); and so forth. (just trying to make re-usual taskflow)

                      and then load a view ... from this method drag a navigation to view jsff page which is actual page that has dynamic table .

                      In the jsff file : you will need visible property to be computed from bean.

                      as:
                      <af:column visible="#{Tablebean.showHideStatus}" sortable="true" sortProperty="#{name} ........

                      Similarly you will need af:switcher component for showing radio button and hyperlink things

                      Thanks
                      • 8. Re: ADF dynamic table
                        882847
                        Hi MavenDev,

                        Thanks for the reply. Actually i had thought of using taskflow with default activity as my method. But i think my approach was not right so it was not working as i had not used taskflow initially.

                        I created a bounded taskflow. Dragged from datacontrol the method which is in AM. That method returns an arraylist. Added parameters initially as hardcode values. Now the method is not returning List<List<List> is that ok?? Not clear with the point what you mentioned about "Return Value".
                        Then i added the navigation to the method generateColumnModel and connected that to the view jspx page.
                        Removed binding of table ( binding="#{pageFlowScope.Tablebean.myTableBinding} ) from jspx page.

                        Now as we cn't run taskflow so which activity should i run? Do i need to drag the taskflow to adfc-config? Can you help for the same.

                        Thanks.
                        • 9. Re: ADF dynamic table
                          882847
                          Hi,

                          <af:forEach items="#{backingBeanScope.TableBean.columnNames}"
                          var="name">
                          <af:column sortable="true" sortProperty="#{name}"
                          rowHeader="unstyled" headerText="#{name}"
                          inlineStyle="width:100px;" id="c1"
                          visible="#{backingBeanScope.TableBean.showHideStatus}">
                          <af:activeOutputText value="#{row[name]}" id="aot1">
                          </af:activeOutputText>
                          </af:column>
                          </af:forEach>

                          The visible property should run for each column to achieve what i want. But it either shows all the columns or doesn't show any columns.How can we customise the visible property for each column?
                          Thanks
                          • 10. Re: ADF dynamic table
                            MavenDev
                            AM will not be able to return generic return type like in ur case List<List<List>> .... rather u have to return simple List. meaning to say that, your AM method return type should be Just List , but u will be actually returning List<List<List>>... (you will see warning yellow line , which you can ignore) ....small demo:

                            public List yourAMFunction(){
                            List<List<List> realReturnList = new ArrayList<List<List>>();
                            realReturnList .add(....)
                            .....
                            .....

                            return realReturnList;
                            }

                            return List from this AM method to managedbean property......

                            How to do this in taskflow :
                            when u drag AM method to the Taskflow, you also have option to return the value from that method to the managed bean.... for that, click on the AM method that you have dragged and then go to Property Inspector and locate the Parameters section in the Property Inspector, just in there you will see "Return Value" use expression builder to locate manageBean (in your case Managebean is "TableBean") and the property you want it to bind.

                            By Property you want to bind, i mean create private instance variable in the TableBean of type List<List<List>> and create getters and setters for that and bind AM Method return value to this setter through expression builder as mention above.

                            => don't remove binding="#{pageFlowScope.Tablebean.myTableBinding}

                            => now this taskflow can to be dropped to same place where u had previous code done.... meaning to say, if you had action ( say loadTable) on button click that called your old view..... then same thing for this too.. point to this new taskflow instead from now.
                            • 11. Re: ADF dynamic table
                              882847
                              Thanks alot for explaining the approach. Will try implementing in this way.
                              In my old view there was no action like button. The table is needed on pageload itself.

                              Also was able to achieve hiding of columns by using begin end property of <af: forEach>.

                              Now in many cases i can get columns having value as a <a href> tag.
                              How can I simply display this DB column in dynamic table as a link.
                              Currently it shows the whole source url not the hyperlink.