JDev & ADF Goodies

22. January 2012

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.

Advertisement

4 Comments »

  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

    Comment by uday — 24. January 2012 @ 06:06 | Reply

    • 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

      Comment by Timo Hahn — 24. January 2012 @ 11:11 | Reply

  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

    Comment by Hemant — 23. February 2012 @ 18:18 | Reply

    • 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

      Comment by Timo Hahn — 23. February 2012 @ 20:20 | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Theme: Rubric. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 45 other followers