onsdag, maj 30, 2007

ADF Faces Multi Select Table using JDeveloper 11g Technology Preview

About a year ago Frank Nimphius wrote this post (http://www.orablogs.com/fnimphius/archives/001778.html) about multi-selection in ADF Faces tables. I tried out this approach recently using the JDeveloper 11g Technology Preview release and found that things have changed slightly since then. The purpose here is not to fully describe this feature, for that please see Frank's post, but to point to the changes between 10.1.3 and the 11g Preview version.

These are the main changes in short:
  • No need to create the selectMany component any longer.
  • A Slightly different way to iterate through the rows is needed.

Once you have created the table using 11g, you will notice that it looks slightly different:
























As mentioned before, you no longer needs to use a 'tableSelectMany' component to get multi-selections for the table, instead you define the 'rowSelection' and 'binding' attributes directly on the 'table' element, like:

<af:table value="#{bindings.DeptView1.collectionModel}" var="row"
rows="#{bindings.DeptView1.rangeSize}"
first="#{bindings.DeptView1.rangeStart}"
emptyText="#{bindings.DeptView1.viewable ? 'No rows yet.' : 'Access Denied.'}"
fetchSize="#{bindings.DeptView1.rangeSize}"
rowSelection="multiple" id="table1"
selectionListener="#{api.table1_selectionListener}"
binding="#{api.myTable}"
>

Next, you need to map the managed bean to use the RichTable class, like:

<managed-property>
<property-name>myTable</property-name>
<property-class>oracle.adf.view.rich.component.rich.data.RichTable</property-class>
<value>#{table1}</value>
</managed-property>


and, also to use this class also in the backing bean:

private RichTable _table;

public RichTable getMyTable() {
return _table;
}

public void setMyTable(RichTable table) {
this._table = table;
}


As mentioned before, the way to iterate through the rows have also changed a bit. In 10.1.3 you could use:

Key _key = (Key) keyIter.next();

directly, in 11g I noticed that you have to use this approach instead:

List l = (List)rowSetIter.next();
Key key = (Key)l.get(0);

Also, you use the 'getSelectedRowKeys()' method instead of 'getSelectionState().getKeySet()'. The full code will look something like:

RichTable table = this.getMyTable();
RowKeySet rowSet = table.getSelectedRowKeys();
Iterator rowSetIter = rowSet.iterator();
DCBindingContainer bindings = this.getBindingContainer();
DCIteratorBinding iter = bindings.findIteratorBinding("DeptView1Iterator");

while (rowSetIter.hasNext()) {
List l = (List)rowSetIter.next();
Key key = (Key)l.get(0);
iter.setCurrentRowWithKey(key.toStringFormat(true));
Row r = iter.getCurrentRow();
System.out.println("selected dept " + r.getAttribute("Dname"));
}


Finally, with these changes in mind, the result of the above should end up in an output similar to:

07/05/30 13:36:33 selected dept SALES
07/05/30 13:36:33 selected dept RESEARCH


I hope this have illustrated the changes between the 10.1.3 and the 11g Preview Release for the multi-selection table.