Lately a question on the Oracle JDev forum came up, asking for a solution for a problem with a ViewObject in ‘RangePaging’ mode and a single selection af:table defined on this ViewObject. The problem is to get the current selected row in such a case. Under some circumstances (which are not always reproducible) using the default
#{bindings.YOUR_VIEWNAME.collectionModel.makeCurrent}
doesn’t mark the selected record and a call in a bean to get the selected record returns null:
BindingContext lBindingContext = BindingContext.getCurrent(); BindingContainer lBindingContainer = lBindingContext.getCurrentBindingsEntry(); DCBindingContainer bindingsIte = (DCBindingContainer) lBindingContainer ; DCIteratorBinding dciter = bindingsIte.findIteratorBinding("YOUR_VIEWNAMEIterator"); Row row = dciter.getCurrentRow(); if (row == null) { return null; // no current row }
For ViewObjects in ‘Scrollable’ mode you get the selected record without any problem. ViewObjectes in ‘RangePaging’ mode are mostly used for tables which contain many rows and the use case doesn’t allow to filter the result set to a reasonably number. The ‘RangePaging’ option is a tuning parameter in the ViewObject definition
I run into this condition myself and use the following work around:
- remove the current selectionlistener from the table (#{bindings.YOUR_VIEWNAME.collectionModel.makeCurrent})
- define a new selection listener (use the small arrow on the right side) in a bean of your choice. The scope of the bean has to be view or pageflow depending on where you need access to the selected row
- in the new selectionListener you get the selected row from the event, get the key of the row and store it in a bean attribute
- when you need the selected row you use the stored row key and work with this. If you need attributes from the row you have to query the row again, as you only have the key
If you only need the key of the row you can e.g. pass this key to a service method defined in the application module or the ViewObject. Here is a sample of such a selection listener:
public void singleSelectionListener(SelectionEvent selectionEvent) { RowKeySet rksAdd = selectionEvent.getAddedSet(); if (rksAdd.isEmpty()) return; // no selection Object[] it = rksAdd.toArray(); // as this is for single selection there should only be one, but... for (Object obj: (List) it[0]) { mLogger.fine("Selected :" + obj); // log selected row Key k = (Key) obj; // the object is the row key Object[] kv = k.getKeyValues(); // get the key value for later // strore the key value in a bean attribute: mLastSelectedOID is defined in the bean mLastSelectedOID = (Integer) kv[0]; // store the key value (if the key has multiple parts you need to store them all) } }
The variable mLastSelectedOID is defined in the bean. The type of the attribute depends on the type the primary key of the table has. If you like you can generate getter/setter methods for the attribute and use them instead of assigning the value directly.