JDev: Custom selectionListener for ViewObjects in ‘RangePaging’ mode

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

Set a ViewObject to 'RangePaging' mode

Set a ViewObject to 'RangePaging' mode


I run into this condition myself and use the following work around:

  1. remove the current selectionlistener from the table (#{bindings.YOUR_VIEWNAME.collectionModel.makeCurrent})
  2. 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
  3. 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
  4. 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.

6 thoughts on “JDev: Custom selectionListener for ViewObjects in ‘RangePaging’ mode

  1. Hi Timo,

    Thanks for the workaround. When I first encountered the issue I filed an ADF bug for it. The row returns null when the selected row is not currently bound the iterator. for eg, when the user scrolls down on the table and new rows are fetched, the rows that are currently being displayed are no longer bound to the iterator. Selecting one of these rows returns null. The issue is easily reproduced by using a small iterator range size. The ST developer suggested that using incremental range paging will avoid this issue all together.

    Regards,
    Uday

    • Hi Uday,
      one reason not to use internal rang paging for single selection tables is that rows you scroll over are kept in memory. If you do this for large tables, and knowing my users, you end up with all rows in memory. Essential this is like you keep the iterator in scroll mode.
      Timo

  2. Hi Timo,

    I have set the cache property of binding iterator as false. Now when I use itertor.getCurrentRow, it always returns first row regardless of other row selected.

    Can you please help me out.

    Regards,
    Hemant

    • Hemant,
      without more detailed description of your problem I can’t.
      Anyway, you should ask this in the OTN forum where more users can help you solve the problem. Please open a thread in the OTN forum and provide your jdev version and a use case you try to implement. You should also mention why you set the cache property to false.

      Timo

  3. Hi Timo,
    While I was searching for solving my use case, I found your post almost near to my use case.
    What should I do in the Selection Listener of a tree Table to get the Selected Row Key ?
    Thanks
    Nigel.

    • Nigel,
      this is more complicated as you have to deal with multiple keys depending on the level of the tree table. Essentially you need to get all primary keys on the way to the selected row in the tree.
      I never tried this, but it should be possible.

      Timo

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.