Written By Duncan
Mills, Oracle Corporation
June, 2006
Introduction
Using list bindings ADF makes it very easy to associate
drop-down lists and radio groups with either static or dynamic sets of
data. When a suitable attribute is bound by dragging from the
Data Control Palette and dropping as "Single Selection" the
user specifies the value that will be populated and the label to use on
the list entries themselves.
Where things get slightly confusing with such bound list UIs
is the matter of a developer's initial expectation as to how the list
should work. Taking the example of the EMPLOYEES and DEPARTMENTS table
from the HR demo schema. If the Employee DepartmentID
attribute is bound as a list and populated from the DEPARTMENTS table,
the natural assumption would be that the list is composed of a set of
elements, each of which, has a DepartmentID value and a DepartmentName
label, for example 10-Administration, 20-Marketing, 30-Purchasing
...80-Sales and so on.
With this assumption in mind, developers often make the
mistake of treating the value of the list binding as one of
these
expected values and trying to write code or expressions based on that.
For example
the developer might decide to conditionally render the Commission field
on the screen using an expression based on the value of the
DepartmentId field. In the example of a JavaServer Faces UI this might
look like the following:
However, the expected result is not
achieved because that
initial assumption about the "value" of the list binding is actually
incorrect. ADF actually manages the selected value of the list item
internally and the value that is exposed through the list binding
itself is only the index number of the selection in the list. So in the
above example, the evaluated value of bindings.EmployeesView1DepartmentId.inputValue
will probably evaluate to 8 rather than 80, depending on the contents
of the DEPARTMENTS table.
This article examines how you can access the true value of the
selected list item or radio button directly from ADF.
Creating a Secondary Binding
The simplest way to gain direct access to the true value of an
attribute that is populated from a list binding is to create a
secondary value binding to the underlying data. This secondary binding
can then be used within expressions to access the true value of the
attribute. Reverting to the example of the DepartmentId field, here are
the steps. This assumes that you have suitable collections of data
defined, in this case we're using ADF Business Components with default
view objects for EMPLOYEES and DEPARTMENTS. We also assume here that
you have already bound the DepartmentId attribute of the Employees
collection as a list (for example an af:selectOneChoice
if using JSF)
Open the page that contains the list item if it is not
already
open, and select Go
to Page Definition from the right-click menu.
In the Structure window, select the bindings node, and from
the right-click menu choose Insert inside bindings
| attributeBindings.
The attribute Binding Editor will appear. From the drop
down
list labeled Select an Iterator, select the iterator that the
form fields are based on i.e. the Employees in this case. Then select
the DepartmentId attribute on the right hand side. The dialog should
look like the following illustration:
OK the dialog and a new binding (in this case called simply
DepartmentId) is created. The primary (list) binding for the
DepartmentId attribute will be called something like
EmployeesView1DepartmentId.. You might want to clarify the
purpose of the secondary binding by selecting it in the Structure
window and using the Property Inspector to change the Id property to
something that describes its function, such as
"DepartmentIdCurrentValue".
Now the secondary binding is created you can go ahead and
use
it in expressions, for example "#{bindings.DepartmentIdCurrentValue.inputValue
=='80'}" and it will evaluate as expected. You can also
use the binding in code for example:
AttributeBinding
deptIdBinding =
(AttributeBinding)getBindings().getControlBinding("DepartmentIdCurrentValue");
Number deptId =
(Number)deptIdBinding.getInputValue();
Summary
The ability to specify multiple bindings against the same
attribute
provides the developer with a great deal of flexibility. This example
of working with list bindings shows one common use of the technique,
but it can also be used in alternative contexts such as combinations of
table and attribute bindings for "Summary Table + Detail View" type UIs.
Duncan Mills is a
Senior
Principal Product Manager and Java Evangelist in the Application
Development Tools division at Oracle. You can view Duncan's blog at groundside.com