|
Not Yet Documented ADF Sample Applications
As part of helping customers be successful with JDeveloper and ADF
I'm often creating little example applications to illustrate a
point. My goal is to document them and put them together with an
OTN "HowTo" paper to accompany them, but I don't always have the
time to do this. If you try to use one examples in the meantime and can't figure
something out about how to use it, please post a question in the
OTN
JDeveloper discussion forum then drop me an email containing the
link to that forum posting and I'll do my best to help. Additional samples are available on the following ADF-related web sites:
Unless otherwise noted, the examples use the EMP and DEPT tables in the familiar SCOTT schema. If you would like SQL scripts to (re)create and populate the tables in the SCOTT and HR schemas, you can download demoscripts.zip. NOTE for 10.1.3.x Examples: If the example you want to try was built with a JDeveloper 10.1.3.x release different than the one you are using, the only change you need to make to the downloaded workspace is to copy the correct versions of the adf-faces-impl.jar and jsf-impl.jar from the version of JDeveloper 10.1.3.x you are using to the example workspace's ./ViewController/public_html/WEB-INF/lib directory before opening/running the example in your version of 10.1.3.x. These files are located in the JDEVHOME/jlib and JDEVHOME/jsf-ri directories respectively | 128. | Synchronizing Emp Details with a Dept/Emp Tree [10.1.3.3] 21-FEB-2008
The Example.jspx page in this workspace illustrates a
tree based on the Departments view object
instance. The DeptView view object definition on which
this view instance is based, is viewlinked to the
EmpView view object with a view link accessor named
EmployeesInDepartment. The tree binding in the page
definition is configured with two rules in order to show the
Dname attribute for the DeptView rows, to
"drill down" into the EmpView details for each
DeptView row using the EmployeesInDepartment
view link accessor attribute, and to display the Ename
attribute for each EmpView in the tree. The tree
control has an id of myTree so that the
panelGroup component surrounding the employee detail
information can have its partialTriggers property set
to that id. This way, any user interaction with the tree
control will repaint the panelGroup and everything inside
it. Since we want to be able to conditionally toggle the
rendered property of the panelBox on and off, combined
with the fact that you cannot trigger a partial page refresh
event for a UI component that is not rendered, we need to
introduce this wrapping panelGroup component to be a stable UI
component in the page on which to configure the partial page
updating. The nodeStamp facet of the tree component
includes an switcher component to conditionally render
the tree nodes based on the current level of the tree. The
current level of the tree is determined by referencing the
expression node.hierType.viewDefName which allows us
to access the fully-qualified view definition name of the
hierarchy type (representing the tree binding rule) of the
current node. This will return a string of
"test.model.DeptView" for the nodes in the tree coming
from the DeptView view object, and a string of
"test.model.EmpView" for the nodes coming from the
EmpView view object. In order to avoid using these
"raw" view definition names as the switcher
component's facet names, we introduce a treeLevel map
in the Example backing bean to map the view definition
name to a logical facet name. The entries in this map
{(""test.model.DeptView", "DeptNode"),
("test.model.EmpView", "EmpNode")} are
configured declaratively in the faces-config.xml file
using the JSF managed bean facility. The facetName
property of the switcher is set to the EL expression
"#{Example.treeLevel[node.hierType.viewDefName]}"
which resolves to the logical facet name corresponding to the
view definition name of the current node in the tree, via this
map. In other words, DeptView nodes render using the
contents of the DeptNode switcher facet as a
outputText, while EmpView nodes render using the
contents of the EmpNode facet as a commandLink. The
command link is configured to have its action listener invoke
the declarative action binding
setCurrentRowInEmployeesIteratorWithKey which is the
name of the action binding in the page definition that uses the
built-in setCurrentRowWithKey operation against the
EmployeesIterator iterator binding. This action
binding is configured to pass the value of the EL expression
"#{node.rowKeyStr}" as the one parameter this built-in
operation requires. It is the stringified row key of the
current node in the tree that the user has clicked on. In the
Example backing bean, the onTreeNodeDisclosed
method is configured as the tree's disclosureListener. It has a
bit of code to set the set of expanded tree nodes to be only
the currently selected node, as well as a line of code that
hides the employee information panel box by setting its
rendered property to false. The
onClickEmployeeCommandLink is configured as the action
of the commandLink in the tree and it includes one line of code
that shows the employee info panel box. This panelbox includes
a panelForm that shows the employee detail information and
allows the user to edit the salary. In order to avoid the tree
interaction from posting data, it has its immediate
property set to true. This way, any user change to the form is
saved only if the user explicitly clicks on the (Save)
button. Last, but not least, the commandLink includes a nested
resetActionListener component to ensure that the editable UI
components on the page "pull" or "reset" their bound values
after the partial page request caused by clicking on the
tree. This ensures that the Sal field on the employee detail
panel is always correctly showing the value of the current
employees salary.
| | 127. | Counting Number of Rows Changed (Inserted, Updated, Deleted) [10.1.3.3] 20-FEB-2008
This example illustrates an approach to count the number of
rows changed in the transaction (presumably for notifying the
end user). In the example, the total number of changed rows
(also broken down by inserts, deletes, and updates) is printed
to the console. The implementation involves a customized
DBTransactionImpl class which manages the counters in
the UserData hashmap in the Session and a custom
EntityImpl class (used by the Emp EO in the
project) which increments the appropriate insert, update, or
delete counter in its afterCommit() method.
| | 126. | Using Comma-Separated String Bind for Variable IN List [10.1.3.3] 10-JAN-2008
This example illustrates a simpler way to achive a variable
IN list in a view object's query. For example, imagine
that you want a DeptView view object to feature a
WHERE like DEPTNO IN (:TheDeptNo) but you need
the IN clause list to allow specifying one or more
department numbers at runtime. One approach illustrated by
example number 1 below involves writing some
code that assigns an array of one or more deptno values for the
bind variable. The approach presented here avoids the need for
any code in the ADF layer by using a database function
instead. Run the CreateTypeAndFunction.sql script to
create the NUM_TABLE type and the
IN_NUMBER_LIST() function. The function accepts a
comma-separate string argument and returns a NUM_TABLE
as its result. This allows the
CommaSeparatedListOfDeptno bind variable in the
example's DeptView view object to be of type
String. The view object's WHERE clause looks like
DEPTNO IN (SELECT * FROM TABLE( CAST (
in_number_list(:CommaSeparatedListOfDeptno) as num_table) )
). Run the AppModule in the tester can try
entering values like "10" and "10,40" for the bind variable to
see it in action.
| | 125. | Uploading Contents of af:inputFile to a CLOB Column [10.1.3.3] 03-OCT-2007
This sample is a CLOB-based version of example
#85. Using ADF BC's support for
the Oracle Intermedia ORDImage, ORDDoc, ORDAudio, and ORDVideo,
you can simplify uploading, downloading, and displaying media
and documents. However, since numerous users have asked for it,
this example illustrates a simple JSF page with an
inputFile component and the backing bean logic to
handle inserting the contents of the uploaded file into a CLOB
column in the database. Run the CreateTables.sql script
to drop and create the simple UPLOADED_FILES
table. Then, run the UploadFileToClob.jspx page. Note
that the page uses the af:form container with its
usesUpload attribute set to true. Also notice
that the inputFile control is bound to the backing bean
property named fileInputComponent, allowing the backing
bean to reference the UI component programmatically. The
valueChangeListener on the inputFile is mapped
via EL to the onFileUploaded() method in the backing
bean. That method accesses the ExampleModule client
interface of the ExampleModule application module, and
invokes the saveUploadedFile() method on it. It passes
in the file name, and a ClobDomain class representing
the contents of the uploaded file. The (Upload File) button's
action property is mapped via EL to the
onUploadFileButtonClicked() method in the backing bean.
This method either displays an error message if the filename to
be uploaded is bad, or else causes the "Last File Files
Uploaded" iterator to be re-executed to retrieve the latest list
of the last file files uploaded (by any user). See Configuring
ADF Faces File Uploading Servlet Parameters for information
on some settings you might need to configure.
| | 124. | Validating and Rendering Conditionally Required Attributes [10.1.3.3] 10-SEP-07
This example illustrates how to validate and render
conditionally-required attributes. After running the included
CreateTables.sql script to create the
OPTIONAL_REQUIRED_TEST table, run the
TestPage.jspx to see that when a row has its
RowType attribute set to the value A then the
ValueA inputText component renders, while if its
RowType attribute is instead set to the value
B then the ValueB inputText field
renders. These fields set the showRequired property to
true to show the required field indicator to the
end-user even though the underlying ValueA and
ValueB attribute are not marked as mandatory. The
conditional mandatory validation is performed in the
TestEntity entity object using entity-level method
validators. The radio group UI component is marked to have its
autoSubmit property true, and the
ValueChangeListener method in the backing bean for the
page sets a request-scope attribute as a flag to indicate that
the row type is changing. This flag is then referenced by the
ConditionalValidationPageController -- identical in
function to the one you might have seen in Example# 62
Cascading Lists in JSF -- which is configured to be used
by the TestPage by setting the ControllerClass
property of its page definition. This customized page
controller avoids validating the row if it detects that the row
type is changing. The conditional rendering of the ValueA or
ValueB inputText components is handled declaratively using an
appropriate EL expression for the component's rendered
property. When the autoSubmit radio group (with component id
"RowTypeRadio") causes its partial-page request, the panelForm
component in which the ValueA and ValueB inputText's reside is
declaratively "repainted" by having its
partialTriggers attribute set to that "RowTypeRadio"
id value. By performing the partial-page triggering on the
enclosing panelForm component, you avoid the gotchas related to
having PPR events delivered to currently-unrendered components.
| | 123. | Using a Custom Number Formatter to Parse/Format Social Security Numbers (SSN) [10.1.3.3] 31-AUG-07
This example includes a SocialSecurityNumberFormatter class
that extends the default ADF Business Components number
formatter class (DefaultNumberFormatter). It overrides the
parse() and format() methods to implement the parsing and
formatting of a United States social security number whose
format is 000-00-0000. The default number formatter does not
work with this format mask as is because the JDK DecimalFormat
class on which it's based doesn't correctly support that format
mask as you might expect. You'll need to run the provided
CreateEmpWithSocialSecurityNumber.sql script to create a
version of the EMP table with an addition SSN column to store
the social security number as a numerical value. The Emp entity
object sets the custom property named Ssn_FMT_FORMATTER to the
fully-qualified class name of the custom formatter class. This
property and its value are stored in the entity object's
companion EmpImplMsgBundle.java message bundle class. The
CustomDCErrorHandler class in the FwkExtensions project
contains logic that sets the attribute information on the
DataCreationException that is thrown if that information is not
already provided in the exception. This allows the error
message to be correctly reported as an exception specific to a
given attribute. Run the TestPage.jspx page to try entering
valid and invalid social security numbers. Notice that the
default <f:convertNumber> component has been commented out for
the <af:inputText> component for Ssn on the page.
| | 122. | Running Custom Backing Bean Code Before/After Default Table Selection Listener [10.1.3.2] 16-AUG-07
This example illustrates a TestPage.jspx page with an
af:table component whose selectionListener
property has been modified from the default EL expression dropped
when the table was created, to instead call a selection listener
method named onTableSelectionChanged() in the
TestPage backing bean. This default EL expression
normally looks like
#{bindings.TableBindingName.collectionModel.makeCurrent}
which declaratively "wires" the table selection event to invoke
the makeCurrent() method on the CollectionModel
of the table binding. In order to preseve the default
data binding functionality that reacts to the table selection
change, this backing bean method uses the invokeMethod()
helper method of the EL helper class to call the default
functionality with custom code before and after it. The EL helper
class is in the FwkExtensions project, which is marked
as a project-level dependency.
| | 121. | Declaratively and Programmatically Refreshing a View Object's Query Results [10.1.3.2] 24-JUL-07, Upd: 27-JUL-07
This example contains four JSF pages that each show a table of
department rows. The Departments.jspx page illustrates
how to use an invokeAction combined with an
Execute operation binding (and appropriate settings for
the Refresh and RefreshCondition properties of
the invokeAction) to conditionally refresh a view
object's query results based on the presence of a request-scope
flag attribute. You can read more about these settings in section
10.5.5
How to Use Refresh Correctly for InvokeAction and Iterator
Bindings. The AnotherPage.jspx, to which you can
navigate from Departments.jspx, contains two
af:commandLink components that navigate back to the
Departments.jspx page. One of those links uses a nested,
af:setActionListener component to declaratively set the
value of the request-scope attribute named refreshFlag
to the value true. The presence of this flag attribute
causes the invokeAction mentioned above to force a
requery of the rows. The DeptView view object is
instrumented to print a diagnostic message to let you see when
its base query and its estimated row count query get
executed. The range size of the iterator binding used on this
page is set to 2 to you can see the table paging behavior even
with only 4 rows of DEPT table data. When you use an
af:table and have a range size of N set
on your iterator binding to show only N rows per
page, then the estimated row count query will be used since the
table component needs that count to build its paging control. The
DepartmentsProgrammatic.jspx page is nearly identical to
the Departments.jspx page, except that it illustrates
how to accomplish the conditional requery of the view object from
code using the basic technique described in section 10.5.4.3
Using Custom ADF Page Lifecycle to Invoke an onPageLoad Backing
Bean Method section of the ADF Developer's Guide for
Forms/4GL Developers. It also uses a range size of 2. The
DepartmentsAlwaysRequestOnPageEntry.jspx page
illustrates how to create a page the refreshes its data each time
you navigate to it from another page (but not when you post-back
to it from the same page). And finally, the
DepartmentsTimedAutoRefresh.jspx page illustrates how to
use the combination of an af:poll component and an
Execute action binding to refresh the page without user
intervention every 5000 milliseconds (i.e. 5 seconds). Notice
that the af:poll component has an id attribute
set to the value "timer" and that an
af:outputText on the page as well as the
af:table UI components list this "timer" id in
their partialTriggers property so that they will be
partial-page refreshed to "repaint" any updated results. The
af:outputText just shows the current date/time to make
it easier to see when the timer is firing. In constrast to the
other three pages, this page has no explicit (Refresh) button, so
to create the Execute action binding in the page
definition I selected the Go to Page Definition choice in
right mouse context menu of the JSPX page visual editor window
and then used the Structure Window view of the page definition
for that page to select the bindings heading and
{Insert Inside bindings -> action}
right-mouse menu choice to create an action binding for the
DepartmentsIterator using the built-in operation named
Execute.
| | 120. | Simple AJAX-Style Partial Page Rendering (PPR) Example with AutoSubmit SelectOneChoice Control [10.1.3.2] 14-JUL-07
This examples contains a single JSF page with an EmpView
editing form. The EmpView view object includes the
Emp entity object as its primary entity usage, as well
as the Dept entity object as a secondary, reference
entity usage, in order to display the related Loc value
for the department to which the current employee is assigned. The
Deptno is bound to a af:selectOneChoice
component whose autoSubmit property has been set to
true. This causes a PPR postback whenever the end-user
changes the value of the list. The Loc field is
displayed as a read-only af:inputText, and has its
partialTriggers property set to the value of the id of
the af:selectOneChoice component
("DeptnoPoplist") that should trigger the partial page
re-paint of the that Locaf:inputText
component. When you run the page notice that if you navigate
between rows in the EmpView the PPR counter at the top
of the page increments to illustrate that the entire JSF page is
being re-rendered. In contrast, if you just change the value of
the autoSubmit-enabled Deptno poplist, then the value of
the corresponding Loc field repaints on the page, but
the PPR counter at the top stays the same (since only the bit of
the page that needed to be repainted was redrawn). Notice that
other than the PPRDemo managed bean that facilities
showing a counter on the page to better visualize when PPR is
occurring and not, the example requires no Java code to
implement.
| | 119. | Simple EJB-Based CRUD-Style Contacts Application [10.1.3.2] 13-JUL-07, Upd: 23-JUL-07
This example illustrates a simple JSF application that allows you
to list, edit, add, and remove contacts. The MyServiceBean
in the Model project is the stateless EJB 3.0 Session Bean
that acts as the business service. To keep the example simple, the
session bean works with an in-memory set of Contact POJOs
(Plain Old Java Objects). The Session Bean's service methods each
prints a diagnostic message to the console so you can better
understand and appreciate when the ADF Model layer is working with
the cached results of the finder methods as well as when it invokes
business service facade methods to add, edit, and remove a
Contact. The example is designed so that when the name of a
Contact is changed, the Contact's
updated property is updated inside the business service to
reflect the update time. When a new contact is added, edited, or
deleted, the application causes the executeQuery() method on the
method iterator to be executed to rebuild the RowSet of
data being managed by the RowSetIterator of the iterator
binding.
When an iterator is refreshed during the ADF page lifecycle it gets
a chance to decide whether its data needs to be recalculated by
asking the business service, or whether it can use its cached
data. For a method iterator, this decision is based on checking
whether the associated method action has stored the result of its
execution yet for a given set of its parameter values. If either
its result has not yet been calculated, or if any of its parameter
values has changed, then the method iterator is implicitly
requeried. When a method iterator is requeried, it invokes its
related method action binding and caches the result (unless the
CacheResults property is explicitly set to false,
which is not the case in this example!) and then rebuilds
the RowSet of Row objects that wrap the actual
data beans -- Contact beans in this example. These
Row objects adapt all bean data to have the same generic
API and delegate to the wrapped "dataProvider" bean in each row to
get/set the attribute values. It illustrates both programmatic and
declarative techniques for accomplishing this: the former by
invoking the executeQuery() in backing bean code, while
the latter using a combination of an Execute action
binding related to the method iterator and an invokeAction
executable whose Refresh and RefreshCondition
properties have been set to control the ADF lifecycle phase during
which the Execute action should fire as well as a boolean
EL expression to qualify under what conditions it should fire. You
can read more about these settings in section 10.5.5
How to Use Refresh Correctly for InvokeAction and Iterator
Bindings. It's important to note that since the
findContactsByName(String) method takes a parameter, we
take maximum benefit of the ADF Model layer's results caching when
we insure that the EL expression used to pass the method action
parameter continues to evaluate to the same value used when the
data was originally retrieved. In this example, the value of the
nameSearch that the end-user might apply to filter the
results is kept in the session-scoped UserInfo managed
bean so it can be referenced by the method action on both the
ListPage.jspx and the EditPage.jspx pages. If you
are not careful to insure this, then having the parameter values be
different on different pages, given the conditions described above
for the implicit execution of the method iterator, will cause
potentially unwanted re-execution of the business service
methods. The FwkExtensions project in the example includes
generic helper objects and framework extension classes to customize
the error handling very similar to those described in the ADF
Developer's Guides. The FindOrMergePage.jspx illustrates
an example of performing data binding to a method result that
returns a single Contact bean instead of a collection of
beans (List<Contact>), using the helper method
executeQueryForMethodIterator to re-execute the method
iterator's query (since JDeveloper design time prevents the
creation of a declarative Execute binding against such a method
iterator at the moment). If you enter an email address on this
page, it will find an existing contact by email if it exists and
update its name if you supply a non-null value for the name
parameter. If you enter an email that does not exist, it will add
it to the list. This page also shows off some programmatic
techniques for conditionally clearing the page definition variables
used by the ADF parameter form dropped onto the page. Since the
FindOrMergePage can make updates as well as add new rows,
the af:commandLink on the page sets the requestScope flag
to signal to the ListPage to refresh its data on
navigating there.
| | 118. | Selectively Uppercase String Bind Variable Values Through a Custom Metadata Property [10.1.3.2] 11-JUL-07
This example illustrates a framework extension class
CustomViewObjectImpl that overrides the
bindParametersForCollection method to conditionally
uppercase any String-valued bind variable parameter values that
happen to have a custom metadata property named Uppercase
set on them in their bind variable definition. You can use the view
object editor to inspect the bind variable named TheName
on both the DeptView and EmpView view objects to
see that they both have this Uppercase custom metadata
property set. Both of these view object specify
CustomViewObjectImpl as their base class in inherit this new,
generic functionality that is metadata-driven. To experiment with
the example, run the application module and enter a department name
is lower/mixed case like "research". Then click on the ":id" icon
of the detail Employees view instance and try filtering the
employees to ones whose Ename starts with the letter "s"
(entered in lowercase, too).
| | 117. | Editable Checkbox in an ADF Faces Table [10.1.3.2] 19-JUN-07
This example illustrates a simple technique for supporting an
editable checkbox in an ADF Faces table to allow toggling a
persistent status flag on or off. Before running the example JSPX
page, run the CreateTable.sql script in the Model
project to create a SETTINGS table with three rows of
example data. Since SQL does not have a native boolean datatype to
use for the type of a column in a table, the STATUS column
in the SETTINGS table is defined as NUMBER(1)
with 0 representing false and 1 representing
true. The example illustrates how you can introduce a transient
Boolean-valued attribute StatusAsBoolean to work
with the numerical true/false value as a Boolean. In the custom
SettingsViewRowImpl row class, the
getStatusAsBoolean and setStatusAsBoolean methods
have been written to convert the numerical value to a boolean upon
reading it and convert a boolean value to the correct
Number value upon writing it. In the JSPX page in the
ViewController project, the
af:selectBooleanCheckbox is bound declaratively to the
StatusAsBoolean attribute in the current row using the EL
expression #{row.StatusAsBoolean}. When you run the page,
try changing the state of the checkboxes and clicking
(Commit). Then from SQL*Plus, you can verify that the changed
boolean checkbox states have been correctly saved as 0 or
1 appropriately.
| | 116. | Including Multiple Levels of Automatically-Updated Reference Information in a View Object [10.1.3.2, HR schema] 09-MAY-07
This example illustrates an EmployeesView view object that
queries employees from the HR schema. It contains four levels of
reference entity usages, showing for the current employee: (1) the
name of the Department they work in, (2) the StreetAddress of the
Location of that Department , (3) the Country name in which that
location resides, and (4) the Region name in which that country
resides. Run the DemoModule in the ADF Business Components
browser and double-click on the Employees view object
instance to see its data. Experiment with changing the DepartmentId
foreign key attribute of an existing employee to notice that all
four levels of reference information correctly synchronize. You can
use the AllDepartments view object instance to remind
yourself of what some valid department id numbers are, and you can
use the four-level master/detail-coordinated view object instances
(Regions -> Countries -> Locations ->
Departments) to understand better what to expect when
changing the DepartmentId. The trick to having this
multi-level reference information synchronization work correctly is
that at each level the foreign key attribute referencing the next
level is included in the view object's attribute list. Notice that
the attributes whose names start with "PK" in the view object have
a Display control hint set to "Hide", so the ADF Business
Components browser hides them.
| | 115. | Custom Domain to Persist Transient ArrayList of Account Beans [10.1.3.2] 03-APR-07
This example shows a custom ListOfAccounts domain that
implements the necessary interfaces to allow its contents -- a list
of Account beans -- to be passivated and activated
correctly to the application module persistent state snapshot. It
shows a combination of required aspects including implementing the
XMLDomainWriter and DomainInterface interfaces, as
well as containing a public static getXMLDomainFactory()
method that returns an instance of a class that implements the
XMLDomainReaderFactory and XMLDomainFactory
interfaces. The ExampleTransientView in the project is a
transient view object with one String-valued attribute
marked as the key attribute, and another ListOfAccounts
attribute of type model.types.common.ListOfAccounts, our
custom domain. Both of these attributes are marked as updateable
and have their "passivate" property set to true. This view object's
create() method contains the best practice code required
for a transient view object that will be programmatically populated
by creating and inserting rows. Run the TestClient class
to exercise the creation of two rows in the transient view,
passivating the transient state, releasing the application module,
acquiring a new application module, activating the passivated
state, and iterating the transient rows again.
| | 114. | Showing a JSF Message if Search Produces No Rows or Too Many Rows [10.1.3.2] 30-APR-07
This example illustrates a SearchPage.jspx built using the
technique described in section 18.3.5
How To Create Search and Results on the Same Page of the ADF
Developer's Guide for Forms/4GL Developers that has been enhanced
with a small amount of backing bean code that customizes the ADF
page lifecycle to add a JSF FacesMessage in case the
EmployeesResultsIterator returns either no rows or too
many rows (with the limit hard-coded for this example to 10). The
SearchPage backing bean inherits from the
BackingBeanBase class as described in section 10.5.4.3
Using Custom ADF Page Lifecycle to Invoke an onPageLoad Backing
Bean Method of the Dev Guide (simplified slightly by using my
favorite EL helper class). The rendered attribute on
the af:table showing the search results in the
SearchPage.jspx uses an EL expression to cause the table
to render only when the number of rows found is between 1 and the
maximum allowed (10).
| | 113. | Apply Bind Varible Values to Filter View Link Accessor RowSets [10.1.3.2] 17-APR-07
This example illustrates a TestPage.jspx with a tree binding
based on a Departments view object instance of type DeptView.
The WorksInDeptLink view link defines a view link accessor attribute
named EmpView that is used by the tree binding to access the detail
rowsets of employees for each department. The DeptView
view object defines a custom method named
setLowHighSalaryRangeForDetailEmployeesAccessorViewObject()
that is exposed on the view object's client interface. The
TestPage.jspx includes a declaratively-bound parameter
form for invoking this method, passing in values for a
low-salary and high-salary range. This method accesses the view
object instance that the system creates at runtime to support
the view link accessor accesses, and sets the values of the two
named bind variables defined by the EmpView. The
DeptViewImpl class also contains an overridden
createViewLinkAccessorRS() method that applies the
bind variable values to each view link accessor rowset
created. Run the TestPage.jspx page and enter values
for the low and high salary range you want to see for employees
in the tree. For more information on the difference between the
view object instances in the application module's data model
and the system-created view object instance used to provide the
view link accessor attribute rowset, see 27.1.3 Understanding View Link Accessors Versus Data Model View Link Instances.
| | 112. | Using XSQL Pages with ADF Iterators in a JSF Application [10.1.3.2] 22-MAR-07
This example illustrates a TestPage.jspx with a button
whose action navigates to an XSQL page TestPage.xsql
to format the data in the iterator using XML/XSLT
techniques. The TestPage.xsql uses the custom XSQL
action class test.view.xsql.ADFViewObject that is
identical to the one that appeared in the ADF Toy Store Demo,
only refactored to live in a different package. The interesting
things to note about getting this example to work are: (1) The
web.xml file defines a filter-mapping for the
*.xsql URL pattern, (2) the DataBindings.cpx
has been modified in the code editor to contain an additional
page mapping entry for the /TestPage.xsql path so ADF
knows what page definition you want to use for that page, and
(3) by insuring that the URL requesting the page contains the
"/faces/" prefix in the path, this triggers the handling of the
request by the Faces Servlet (and indirectly the
ADFPhaseListener that is registered to be used by the
Faces infrastructure). This makes sure that the request-scoped
bindings attribute is correctly set to reference the
current page's runtime binding container.
| | 111. | Avoiding Runtime Describe Overhead When Defining Dynamic Read-only View Objects [10.1.3.2] 19-MAR-07
This example illustrates the code necessary to programmatically
create view definitions at runtime for dynamically-created
SQL-based view objects to avoid the runtime DESCRIBE overhead
that is associated with using the simpler API
createViewObjectFromQueryStmt(). The
TestClient program calls an application module's
client interface method named
createViewObjectAndViewLinks(). That method constructs
two view objects instances and a view link between them. Then,
the client code finds and iterates through the results of these
view objects. Since we programmatically define the names and
data types of the view object's attributes, ADF will not need
to perform a runtime DESCRIBE (involving a round-trip to the
database) to discover that information at runtime.
| | 110. | Updating Another Area of the Page When Table Selection Changes [10.1.3.2] 15-MAR-07
It's common to want a JSF page with a summary table that allows
the user to select a current row and a detail area showing more
information about the currently selected row. If you have enabled
the autoSubmit property of the af:tableSelectOne
component your af:table's selection facet, then it can
be a little puzzling why the other information on the page does
not update when you change the current row. This example
illustrates how to declaratively configure your af:table
and an af:panelForm that displays additional information
about the selected row in the table. The secret lies in
configuring the partialTriggers property of the
component that you want to be updated when the table selection
changes. In the example, you see that I'd assigned an id of
myTable to the af:table component, and on the
af:panelForm component I've
listed myTable as one of the component id's that should
trigger a partial-page request "repaint" (of the
af:panelForm). To allow you to experiment with toggling
the autoSubmit property of the tableSelectOne on or off at
runtime, I've configured a simple SessionSettings
session-scoped managed bean that has a single property named
useAutoSubmit. By setting the value property of
the af:selectBooleanCheckbox at the top of the page to
the EL expression #{SessionSettings.useAutoSubmit} we can
allow the user to use the checkbox to toggle the value of that
managed bean property. By also using the same EL expression
#{SessionSettings.useAutoSubmit} for the value of the
af:tableSelectOne component's autoSubmit
property, we allow the changing value of the managed bean
property to influence the runtime behvaior of the table
selection to be auto-submitting or not. Finally, since a change
in state of the checkbox needs to cause the table to repaint, I
have assigned an id value of
tableAutoSubmitControl to the checkbox, and listed that
tableAutoSubmitControl component id in the
partialTriggers property of the af:table. At
runtime, you'll see that if auto-submit it off, then the current
row changes when you click on the (testCurrentRow) button. If
auto-submit is on, then the current row changes as soon as you
click into the radio group button on the new current row. In both
cases, the panelForm to the right is updated to reflect
the values of the new current row. The (testCurrentRow) button is
a bound declaratively to the testCurrentRow() method on the
application module's client interface. It was created by dropping
that method from the Data Control Palette onto the page. When you
click on the button, you can see that the
getDeptView1().getCurrentRow() method call inside that
method already "sees" the new current row (and prints out its
Deptno value to the console).
| | 109. | Declaratively Populating Attributes from an Oracle Sequence [10.1.3.2] 15-MAR-07
Section 9.4.1.2
Eagerly Defaulting an Attribute Value from a Database
Sequence from the ADF Developer's Guide explains the two
lines of code you would add to an overridden create()
method of your entity object to programmatically populate its
primary key attribute from a sequence at row-creation time. Even
though this is only a couple of lines, if many of your entity
objects have sequence-valued primary key attributes and you are
not using database-trigger-assigned sequence values (described in
section 6.6.3.8
Trigger-Assigned Primary Key Values from a Database
Sequence), then you might be interested in a more generic,
metadata-driven solution. This example illustrates a simple
CustomEntityImpl framework extension class on which both
the Dept and Emp entities in the sample are
based. It's overridden create() method tests for the
presence of a custom attribute-level metadata property named
SequenceName and if detected, populates the attribute's
default value from the next number in that sequence using the
same basic code as above. The Dept entity defines the
custom SequenceName property on its Deptno
attribute with the value DEPT_TABLE_SEQ, while the
Emp entity defines that custom property on its
Empno attribute with the value
EMP_TABLE_SEQ. The supplied
CreateDeptAndEmpTables.sql script creates the tables and
sequences for you.
| | 108. | Customzing ADF Faces Convert Number Detail Error Message from a Message Bundle [10.1.3.2] 05-MAR-07
The af:convertNumber tag supports a number of attributes
that allow you to customize the detail error message when
conversion fails. For the basic number conversion failure, this
attribute is named convertNumberMessageDetail. In order
to reference a resource bundle message, normally you would expect
to be able to use an f:loadBundle tag in your page to
define a variable for a Map of the resource bundle strings, and
then reference the message using an EL expression like
#{res.NOT_A_NUMBER}. The complication is that the
resource bundles loaded with loadBundle are only
available during the page rendering phase, but not during the
validation phase. So, in order to drive the
convertNumberMessageDetail from a message bundle, I
needed to borrow some of the code from the JSF reference
implementation's loadBundleTag class that exposes a
resource bundle as a Map, and I put it in the
AppliationMessageMap managed bean class in this
example. I've configured that to be a session-scoped managed bean
and configured its basename managed property to have the
value view.resources.JSFMessages in
faces-config.xml. This allows me to reference my custom
error message for "Field 2" in the demo, in its
f:convertNumber tag's
convertNumberMessageDetail attribute using the EL
expression AppMessages.messages.NOT_A_NUMBER. To see the
custom error message, try typing a value like "adf" into Field 2
and clicking (Submit). You can run the demo with your browser
set to prefer "Italian [it]" to see the custom error message
translated in Italian.
| | 107. | Displaying ADF BC Mandatory Field Errors Using UI Hint Labels [10.1.3.2] 05-MAR-07, Upd: 13-MAR-07
The TestPage.jspx page in this example contains an ADF
Form dropped from the data control palette based on the
Employees view object. It consciously chooses to avoid
performing client-side required-field validation by not
setting the required property of the inputText
controls (which defaults to false). Instead, it sets the
showRequired property of the components to the same EL
expression that would normally be used by the client-side
required property. This has the effect that required
fields are rendered with the visual required indicator, but the
mandatory field validation is performed by the ADF BC layer
instead of on the client. The ViewController project
includes a custom ADF Phase Listener, a custom Faces Page
Lifecycle class, and a custom ADF Error Handler class just like
the SRDemo sample application (explained in section 20.8.1
of the Dev Guide) in order to customize the error reporting
behavior. A few enhancements that have been made in this
example's version of these classes are (1) The use of the
getComponentClientId method on the
FacesCtrlAttrsBinding object to retrieve the Faces
component client id in order to construct a FacesMessage
that is specifically related to a given UI component, (2) the use
of the ADF Faces LabeledFacesMessage class to create a
FacesMessage that remembers the label of the component
to which it's associated, and (3) the special-case handling of
AttrSetValException errors for mandatory fields in order
to display a custom string from the CustomMessageBundle using the
end-user-friendly UI label string of the attribute name that is
required. In addition, since we've disabled the use of
client-side mandatory field enforcement, combined with the fact
that the ADF model layer does not by default validate the binding
container if the end-user has not entered any values into any of
the fields, we've overridden the validateModelUpdates()
method in the CustomFacesPageLifecycle class in order to
call a helper method
forceValidationOfNewRowWithAllNullMandatoryAttributes()
which does what it's name suggests. This ensures that if the user
creates a new row and immediately clicks (Save) without entering
any values for any fields, they see the expected errors about any
mandatory fields. In addition, by running the
TestHomePage.jspx you can running two different
standalone create forms by clicking on an appropriate command
button. The CreateNewEmployeePage.jspx page is a more
traditional, declarative create form based directly on a view
object as described in section 13.6
Creating an Input Form of the Dev Guide. The
CreateNewEmployeePageUsingAMMethodViaEntity.jspx page
shows an alternative approach that requires coding an application
module custom method, exposed on its client interface, dropped
onto the page as an ADF Parameter Form. Note that using the
method-based approach, the method parameters are named the same
as the underlying entity object attributes so that the created
page definition variables and bindings have names that match the
entity object attributes. Also note that the application module
method uses an entity-based view object to create the new
employee rather than directly creating the entity object so that
the automatic bundled-exception handling is preserved. Try
setting the "Ename" to the value XXXXX in order
to observe what happens when an attribute-level validation rule
fails. Finally, also note that the UI Hints for the parameter
form page definition variables are defined in a message bundle
specific to the page definition. With the view object based
approach, those are automatically inherited from the underlying
entity object. The example also illustrates the use of
selectOneChoice "dropdown list" controls for mandatory
fields. Their corresponding list binding is configured to allow a
null value to correctly handle the fact that in a newly-created
row the value of that attribute will be null if your entity
object does not provide an alternative default value. The example
contains workaround code in the form of the
viewcontroller.util.ListBindingHelper to workaround bug#
5930745 where an additional blank entry can inadvertently be
added to the list when the list binding related to a
selectOneChoice control has a validation exception due to its
being mandatory. Finally, the backing beans for the
CreateNewEmployeePage and the
CreateNewEmployeePageUsingAMMethodViaEntity pages were
created in order to workaround bug# 5930784 where ADF/JSF
incorrectly performs page navigation even when exceptions have
been registered on the current page. By double-clicking on the
declaratively-bound button and allowing JDeveloper to generate
the ADF binding code in the backing bean, this reliably avoids
page navigation when the action binding has caused exceptions to
be raised. If you notice that sometimes the attribute-level
exceptions are reported with errors that appear next to the
fields and other times with errors reported only at the top, this
is related to bugs# 5918276 and 5929646 where the
getComponentClientId() function of the
FacesCtrlAttrsBinding returns null if the binding has
not previously "seen" a non-null value during the session as well
as the fact that the FacesCtrlListBinding does not
support a getComponentClientId() method. It is the
ability to retrieve the client id of the component related to a
binding that allows this example's custom error reporting to
construct an ADF Faces Message that will be rendered next to the
component to which it relates.
You can run the demo with your browser set to
prefer "Italian [it]" to see the page translated in Italian.
| | 106. | Further Filtering View Link Accessor RowSets at Runtime [10.1.3.1] 08-FEB-07
The test() method in the TestModule in this
example illustrates the important point discussed in section 27.1.3
Understanding View Link Accessors Versus Data Model View Link
Instances of the ADF Developer's Guide for Forms/4GL
Developers. It highlights how the view link accessor rowset is
based on a distinct, system-created view object instance as
compared with the developer-created view linked detail view
object instance in the data model, despite the fact that they are
both instance based on the same base view object definitionEmpView. The code shows adding an additional runtime
WHERE clause filter to the view link accessor rowset by
accessing its view object instance, and then performs a similar
task on the data model detail view object instance to show they are
indepdent. Run the TestClient.java class to see the
results of the test() method in action.
| | 105. | Efficiently Enforcing Uniqueness of Non-Primary Attribute Value [10.1.3.1]
This example illustrates how to implement an efficient existence
check to enforce the uniqueness of a non-primary-key
attribute. Using a Dept entity object based on the
DEPT table, we assume that in addition to the
Deptno primary key's uniqueness that is declaratively
enforced using the ADF UniqueKeyValidator, we also want to enforce
the uniqueness of the Dname attribute value. For the sake
of argument, we assume we'd like the value to be unique in a
case-insensitive way so that we won't allow one department called
"Sales" while another is named "SALES". The DeptDefImpl
class in this example implements an existsByDname() method
following the technique outlined in section 9.6.2
Implementing an Efficient Existence Check of the ADF
Developer's Guide for Forms/4GL Developers. This routine on the
custom entity definition class uses the
FindDeptByUniqueDname view object to test
case-insensitively whether a row exists in the DEPT table
with the supplied department name. If it doesn't exist in the
database, it then searches the entity cache to detect whether
perhaps another new instance created in the current transaction
might already be using the candidate department name value,
too. The Dept entity object class has an attribute-level
method validator defined to trigger the validateDname()
method in the DeptImpl class. This method gets the custom
entity definition class and calls the existsByDname()
method, returning true if the candidate department name does not
already exist. See section 9.3.1 How to Create an
Attribute-Level Method Validation for more information on
creating an attribute-level method validator. You can use the ADF
Business Components tester to verify that it's impossible to insert
two departments with the same department name.
| | 104. | Selecting a Row to Edit from a Popup Dialog [10.1.3.1]
The EditDepartment.jspx page in the example allows the
user to edit a row in the DEPT table. A button on that page has its
Action property set to dialog:selectDepartment
and has its useWindow property set to true so
that it invokes a modal, popup dialog containing the page
SelectDepartment.jspx. The commandButton on that page
contains a nested af:returnActionListener component whose
value is provided by the EL expression
#{row.rowKeyStr}. That will evaluate to the string format
of the current row's key (described in more detail in section 10.5.6
Understanding the Difference Between setCurrentRowWithKey and
setCurrentRowWithKeyValue of the ADF Developer's Guide for
Forms/4GL Developers.) The
onReturnFromSelectDepartmentDialog return listener method
in the EditDepartment backing bean shows how to process
the selected key value returned from the dialog and to set that row
as the current row for editing, followed by forcing the calling
page to refresh.
| | 103. | Programmatically Scrolling the JSF Table's Current Page of Rows [10.1.3.1, HR schema]
The ProgrammaticScroll JSF backing bean in this example
illustrates three different approaches to perform programmatic
scrolling of the 25 rows in the HR schema's COUNTRIES
table. Run the ProgrammaticScroll.jspx page and try using
the (<<) and (>>) buttons, optionally changing the scrolling
increment value in the text field located between these
buttons. You can use the drop-down list to pick among the three
different programmatic scrolling approaches.
| | 102. | Entity Object with Attributes that Must be Stored in Encoded Format [10.1.3.1]
This example illustrates the methods to override in order to
implement an entity object one or more of whose string attributes
must be stored to the database in an encoded format. The example
includes a simple CreateTablesAndPopulateData.sql script
that creates a USER_INFO table with USERNAME and
PASSWORD columns. As a trivial example of a entity object
String-valued attribute stored in encoded format, the corresponding
UserInfo entity object assumes that its Password
should be stored in this way. The encoding technique employeed in
the example is simple. A string like "abcd" is encoded when stored
in the database as "[dcba]", that is, with its letters reversed and
surrounded by brackets. Upon retrieving the entity object data from
the database, the example decodes a queried value for the password
by turning a string like "[dcba]" back into "abcd". The code is
implemented as a CustomEntityImpl framework extension
class, which the UserInfo entity uses as its base
class. The generic encode/decode logic in this class is enabled on
an entity object's String-valued attribute by setting the custom
attribute property named EncodeValue, which the
UserInfo entity's Password attribute has set. I
was hoping the code involved would have been more elegant, and if I
discover a more elegant approach I'll update this sample to reflect
what I learn. Of course, we make the assumption that encoded
attributes are not going to be user-queriable, however the example
code does nothing to stop the user from trying to query on it.
| | 101. | Reporting Model-layer Warnings and Informational Messages to JSF [10.1.3.1]
ADF Business Components has a built-in warnings facility that
complements the validation and exceptions features. This example
illustrates how to configure a custom FacesPageLifecycleClass
(described in more details in 10.5.4.1
Globally Customizing the ADF Page Lifecycle of the ADF
Developer's Guide for Forms/4GL Developers) which registers
itself as the JboExceptionHandler. This allows it to
receive the handleWarning() notification when any
business components warning is signalled in custom code. As
illustrated in the DeptImpl class in the example, you
signal a warning by constructing an instance of the
JboWarning class and passing it to the
addWarning() method of the
ApplicationModule. To distinguish between a warning and
a purely information message, the example introduces a subclass
InformationalMessage that extends JboWarning
and the handleWarning() method in the
CustomFacesPageLifecycle class reports the warning as a
FacesMessage with the appropriate severity. To
experiment with the demo, run the TestPage.jspx page and
try entering the value "ERROR" for the Dname
field. That will cause an attribute-level validation to fail for
that attribute. If you instead enter a Dname value of
"WARN", then you'll see a warning reported. And if you
simply make a change and save it successfully, you'll see a
purely informational message reported.
| | 100. | JSF Parameter Form to Invoke a Stored Procedure [10.1.3.1]
The example illustrates how to create a JSF parameter form for
calling a PL/SQL stored procedure. You'll need to run the
supplied CreatePLSQLPackages.sql script to create the
PL/SQL package named example_pkg used by the demo. This
package contains a single procedure do_something which
accepts a string parameter, number parameter, and date parameter
and inserts these values into a new row in the
EXAMPLE_PKG_TABLE table. In the J2EE application, the
stored procedure invocation is encapsulated inside the business
service inside the custom application module method
collectDataUsingStoredProcedure. It accepts one string
parameter, one number parameter, and one date
parameter. Internally the method calls the stored procedure using
the helper routine described in section 25.5.2
Invoking Stored Procedure with Only IN Arguments of the
developer's guide. This custom application module method is
published on the client interface as described in section 8.4.1
How to Publish Custom Service Methods to Clients. The JSPX
page in the ViewController project was created by
dragging the collectDataUsingStoredProcedure from the
Data Control Palette and dropping it onto the page as an ADF
Parameter Form. The page defintion variables get automatically
cleared after each page submit due to a navigation rule that
redirects back to the same page. The table below the input form
was created by dropping the data collection named
ExamplePkgTable from the Data Control Palette as a
read-only table. Both the view object attributes and the page
definition variables are leveraging ADF UI control hints to
supply translatable prompts and format masks.
| | 99. | Avoiding Clearing a View Object's Queried Rows at Rollback [10.1.3.2] 2006, Upd: 17-APR-2007
This example illustrates a technique to avoid having a view
object's queried rows cleared on rollback. There are three view
objects in the project, one named DeptView which is an
entity-based view object, one named
DeptViewNonEntityBased which is a read-only,
non-entity-based view object, and one named
TransientViewObject that is programmatically populated
and not based on a query. For read-only SQL-based view objects
and transient view objects, you can
prevent a rollback from clearing the view row cache by overriding
both the beforeRollback() and afterRollback()
method and commenting out the call to super. For an
entity-based view object, you need to override these two methods
as well as call the setClearCacheOnRollback() method on
the oracle.jbo.Transaction interface, passing
false. Note that this technique applies only to queried
rows and not to newly added rows. This is due to the fact that
during a rollback, as noted in the state diagram in section 9.2.5
Understanding Entity Objects Row States of the ADF
Developer's Guide for Forms/4GL Developers, any entity object
with 'New' status is removed (which transitions its status to
'Dead'). Note that the TransientViewObject is populated
by the prepareSession() method of the application
module, and that on its "Tuning" panel in the view object editor
it is set to never query rows by using the "No Rows" setting in
the "Retrieve From Database" section. This is equates to
declaratively setting the max fetch size of the view object to zero.
| | 98. | Entity Object Lightweight Event Publish and Subscribe [10.1.3.1]
This example illustrates one way to use the lightweight JavaBeans
event publish/subscribe mechanism that ADF Business Components
supports for entity objects. The Dept entity in the
project has published an event named
OnDnameOrLocChanged. When you define a new event on the
Publish tab of the Entity Object Editor, you indicate zero
or more entity attributes that will be delivered as part of the
event "payload" to any subscribed listeners. The event name is
user-defined and your code decides when it will fire by calling
the automatically generated method of the same named as the
event. In this case, looking in the DeptImpl.java class,
you can see that I've added a call to this
OnDnameOrLocChanged() method inside the
setDname() and setLoc methods. When you publish
an event, in addition to the generated method used to fire the
event, JDeveloper also generates code into a custom Entity
Definition class for the entity publishing the event. If you look
in the DeptDefImpl.java, you'll see generated methods to
addOnDnameOrLocChangedListener() and
removeOnDnameOrLocChangedListener. Other entities that
want to subscribe to the event can do so programmatically by
looking up the entity definition object of the publishing entity,
casting it to the more specific custom entity definition class
name, and then calling the addEventNameListener()
method. The Emp entity in the demo declaratively
subscribes to the OnDnameOrLocChanged event, indicating
that the event should be delivered to all associated Emp
entities based on a particular association that relates it to the
publishing entity. Note that the method to be invoked to receive
the notification must have a signature that matches the number,
type, and order of the attributes delivered in the payload of the
published event. Otherwise, you can choose to have the event
only delivered to entities that have programmatically registered
to receive the event using the methods mentioned above. If you
test the AppModule application module and try changing
the value of the Loc or Dname attribute of a
department, you can observe in the JDeveloper Log window that the
associated Emp entities in that department receive the
notification.
| | 97. | Force View-Object Attribute Default to Override Entity Default [10.1.3.1]
By design, if a view object attributes supplies a declarative
default value, it will be used as long as the underlying entity
object attribute (if there is one) has not already defaulted the
attribute to some non-null value. If you want to force a
view-object-attribute-level default to always be used, even if
the underlying entity object default has been provided, then this
example illustrates a MyViewRowImplframework
extension class that will achieve that. The DeptView
view object in the example indicates that it should use the
MyViewRowImpl class as its view row implementation
class. The Dept entity object supplies default values
for its Loc and Dname attributes, and the
DeptView view object specifies a further
view-object-attribute-level default value for the Loc
attribute as well. You can use the ADF Business Components tester
to try creating a new row to observe the behavior.
| | 96. | Sortable Transient View Object [10.1.3.3] 2006, Upd: 01-OCT-2007
This example illustrates a technique to override the
applySortCriteria() method in a custom ADF BC data
control to call setSortBy() on the iterator binding's
underlying view object instance instead of the default of calling
setOrderByClause(). The effect is that this leverages
the view object's built-in support for performing in-memory
sorting described in more detail in section 27.5.2
Sorting View Object Rows In Memory in the ADF Developer's
Guide for Forms/4GL Developers. The ViewController
project contains a custom subclass of the ADF BC data control, a
custom subclass of the ADF BC Data Control Factory, and a
reference to this factory in the DataBindings.cpx
file. The CountryList view object retrieves its data
from the companion CountryList.properties file. When you
run the CountryList.jspx page, try clicking the table
headings to sort ascending or descending by the
CountryCode or the Description. While not
required for the in-memory sorting example, the workspace also
includes a few classes required if you don't want your
application module to make any database connection at all. The
NoDatabaseConnectionApplicationPoolImpl class that
subclasses the default application module pool implementation to
return null in a few strategic places to avoid the application
module's connection to the database. The custom database
transaction factory class
NoDatabaseConnectionDatabaseTransactionFactory is
configured to be used by setting the TransactionFactory
property of the configuration, and it creates an instance of the
custom NoDatabaseConnectionDBTransactionImpl2 class
which overrides the doRollback() method to do nothing.
| | 95. | Change Preferred UI Locale with a Button in the Page [10.1.3.1] 2006, Upd: 07-MAR-2007
This example illustrates a technique to allow the user to toggle
the preferred UI locale between English and Italian by pressing a
button in the UI. The CustomFacesPageLifecycle class is
a custom ADF Faces page lifecycle class that overrides the
prepareRender phase of the ADF page lifecycle to adjust
the locale of the JSF UI View Root (from which the current user's
preferred locale is derived for the rest of ADF at runtime). For
more details about how its configured in the project see 10.5.4.1
Globally Customizing the ADF Page Lifecycle of the ADF
Developer's Guide for Forms/4GL Developers. It references the
App managed bean to see what the user's preferred locale
is. In the overridden prepareRender method, if
App.preferredLocale is different from the current UI
View Root's locale, then the method sets the locale of the view
to the preferred locale before calling
super.prepareRender. If it ends up changing the locale,
it also forces any List Binding objects with a translatable label
for their null entry (like "<No Department>") to have their
list of valid values recalculated so the null entry will render
in the new current locale. The TestPage.java backing bean sets
the value of the App.preferredLocale to either
ENGLISH or ITALIAN depending on the button you
click. Notice that the JSF resource-bundle-based message strings
change, as well as the ADF BC component UI hints that supply the
strings for the table column titles and field prompts. Also, the
AnotherPage.jspx page allows the user to change the
value of a transient number attribute that was added to the
entity object. The format mask of #0.00 is specified as
part of the UI control hints at the entity object level and you
can see that when in Italian a number like 3.45 is
presented and edited using the locale-appropriate decimal symbol
3,45. The regular JSP page
RegularJSPPageNotUsingJSF.jspx in the project
illustrates how a regular JSP page might test and set the JSF
managed bean that holds the user's preferred locale setting. This
might be interesting to understand if you are trying to allow the
user to set their preferred language from a regular JSP acting as
a login page in an otherwise-JSF-based application.
| | 94. | View Link Accessor Driving Details from a Parameterized Table Function [10.1.3]
This example contains two read-only view objects in its
Model project, one named MasterView and the
other named ListBasedOnTableFunction. The former is a
simple SELECT from DUAL that unions two rows of dummy data. The
first row has the value "D" for its LIST_TYPE column,
and the second row has the value "E". The
ListForMasterRow view link defines a link between the
master views ListType attribute and an attribute in the
detail view object (which one doesn't actually matter), and it
contains a custom view link SQL WHERE clause of simply "1 =
1". The ListBasedOnTableFunction view object defines a
named bind variable Bind_ListType that has exactly the
same name as the bind variable that the framework will
automatically add for the view link. The expert-mode SQL
statement for this view object references this bind variable
as the argument to the GET_NAME_VALUE_LIST() PL/SQL
function whose invocation it wraps in a TABLE() operator
to treat the table-valued function result as if it were a table
of data. The CreateTypesAndFunctions.sql script in the
Model project creates the NAME_VALUE_TYPE object type,
the NAME_VALUE_LIST type, and the
GET_NAME_VALUE_LIST() function. The function is written
to return a list of (Dname,Deptno) pairs from the DEPT
table if the value passed in is 'D' and a list of (Ename,Empno)
pairs if the value passed in is 'E'. Of course, the
implementation of the function could be arbitrarily more
interesting and dynamic without affecting the view object. The
ViewController project contains a simple JSF page with a
tree control displaying the two rows in the master view and their
parameterized detail rows (which are a function of the value of
the ListType attribute in each master row). The
SwingView project contains a simple Panel1
panel with a similar Swing tree control showing the same thing.
| | 93. | Entity and View Object Based on Web Service [10.1.3]
This example contains two separate workspaces
DeptADFBCWebService and
EntityAndViewBasedOnWebService. The former contains two
projects. The first is named Project and contains a
simple DeptService application module, and a default
Dept entity object, and entity-based DeptView
view object. The application module has custom methods on its
client interface like retrieveDepartmentData(),
estimateCount(), findDepartmentByDeptno(),
insertDepartment(), updateDepartment(),
mergeDepartment(), and
deleteDepartmentByDeptno(). The DeptService
application module has been published as a J2EE Web Service as
described in section 33.4
Publishing Application Modules as Web Services of the ADF Dev
Guide. The second project in the DeptADFBCWebService
workspace is a Tests project that contains JUnit tests
to test both the application module's local client interface as
well as testing the deployed web service. The tests should all
succeed if you have run the supplied
CreateEmpAndDeptTables.sql in the SCOTT
account. The WAR deployment profile in the Project
project deploys the web service to an external OC4J instance,
which you can launch most easily by running the
start_oc4j batch file (or shell script) in the
./jdev/bin subdirectory of your JDeveloper installation
home directory. After deploying, you can test the web service by
pointing your browser at the URL http://localhost:8888/DepartmentServices/DeptServiceSoapHttpPort.
Note that the web service unit test fixture makes use of a web
service proxy class named DeptServiceSoapHttpPortClient
that was generated using JDeveloper's Web Service Proxy wizard,
using the WSDL URL of http://localhost:8888/DepartmentServices/DeptServiceSoapHttpPort?WSDL
The second EntityAndViewBasedOnWebService workspace
contains an HRModule application module, and default
entity objects and view objects for the DEPT and
EMP tables. The DeptImpl.java has overridden
appropriate methods in a way similar to what is described in
section 26.4
Basing an Entity Object on a PL/SQL Package API of the ADF
Dev Guide to have this Dept entity based on a web
service. Similarly, the DeptViewImpl.java class has
overridden appropriate methods, similar to the technique
described in section 27.8.4
How to Create a View Object on a REF CURSOR of the
guide. When you use the Business Components Tester to test the
HRModule -- and you make sure you have the webservice in
the other workspace deployed and currently running -- you can
work with the data in the EmpView and DeptView
view object instances. When the data is read for the
DeptView it will pull it in from the underlying web
service. If you update the data for an existing department,
create a new department, or delete an existing department, the
changes are saved back using the web service in the other
workspace. Also try using simple view criteria in the tester to
search for department rows in the DeptView. That should work,
too.
| | 92. | Dynamic, Data-Driven JSF Parameter Form [10.1.3]
This example illustrates one technique for implementing a
dynamic, data-driven parameter form. The Database
project in the workspace contains CreateTables.sql and
InsertData.sql scripts that define and populate four
simple tables: PARAMETER_FORM_DEFINITION,
PARAMETER_DEFINITION, PARAMETER_CHOICES, and
PARAMETER_FORM_ITEM_SET. See the database diagram in
that project for a visual view of how they are related. The
insert data script populates some sample data for two parameter
forms named "Form1" and "Form2", each of which has some
collection of parameters in its form item set. The
ParameterFormItems view object queries the list of
parameters for a given parameter form by its form id, which is
passed in as a named bind variable (TheFormId). There is
a view link defined between the ParameterFormItems view
object and the ParameterChoicesView that enables a view
link accessor attribute named ParameterChoices in each
row of the ParameterFormItems view object's results. In
the ViewController project, you will find three
pages. The TestParameterForm.jspx page allows you to
select any of the defined parameter forms and test it by setting
the #{processScope.ParameterFormId} attribute to the
parameter form you've selected and navigating to the
DynamicParameterForm.jspx page. That page is the real
meat of the example. It includes a ADFM tree binding to expose
the hierarchical collection of data for the
ParameterFormItems and its collection of available
choices (via the ParameterChoices view link accessor
attribute). The page definition for this page includes an
invokeAction that triggers the firing of an
ExecuteWithParams action binding when the page is not
handling a post-back
(RefreshCondition="#{adfFacesContext.postback==false}"). This
allows the ParameterFormItems view object's
TheFormId named bind variable to be declaratively set to
the value in the #{processScope.ParameterFormId}
attribute that defines which data-driven parameter form to
show. The page defines uses an <af:forEach> to iterate
over the parameter form items. Inside this loop, it uses an
<af:switcher> based on the value of the
DisplayType attribute of the parameter definition. The
switcher determines whether to display the item as an
inputText, a selectOneChoice (i.e. dropdown
list), or a selectOneRadio (i.e. radio group) depending
on whether the DisplayType of each parameter is
'I', 'S', or 'R' respectively. In the
case of rendering the parameter as a dropdown list or radio
group, an inner <af:forEach> accesses the nested
collection of available choices defined to populate the list. The
last part of the example involves understanding where the user's
entered values are posted and stored. This is handled by a
transient view object attribute named UserValue that has
been added to the ParameterFormValues view object. The
ShowUserEnteredValues.jspx page renders the parameters
along with the user-entered values, and the
DynamicParameterForm.java backing bean class contains
code that illustrates how you would access the values of the
users parameter item values in the backing bean if needed. For
extra credit, you can use the ADF Business Components Tester on
the ParameterFormModule to maintain the parameter form
metadata that drives the parameter forms, adding a new form, new
items, or new item choices as needed.
| | 91. | Reusing Databound ADF Swing Panels with Different View Object Instances Using Model Parameters [10.1.3]
The EmployeePanel in this example was created using the
Panel wizard in the ADF Swing category in the New
Gallery. Then, I manually parameterized its data control and
iterator name using two page definition parameters named
dcParam and rsiParam (where 'rsi' is short for
RowSetIterator). The example includes four other ADF Swing panels
that then reuse the EmployeePanel, each passing in
appropriate values for the dcParam and rsiParam
parameters. To drop an instance of a reusable ADF Swing panel,
simply select the Component Palette page named ADF Swing
Regions and you'll see that the EmployeePanel
automatically appears there as a reusable component. When you
drag/drop the EmployeePanel onto a panel where you want
to use it, JDeveloper pops up a dialog asking you to fill in EL
expressions to give appropriate values for the panel's
dcParam and rsiParam parameters. In this way,
you can reuse the same panel with different view objects. You'll
see a special "page" binding appear in the Executables
section of the including panel's page definition, along with
metadata capturing the EL expressions you've entered. The example
features a Panel1 panel that reuses
EmployeePanel to display the results of the data
collection named EmpView1 in
TestModule1DataControl. A Panel2 panel reuses
the EmployeePanel panel bound to the data collection
named AllEmployees in the
TestModule2DataControl, based on a different application
module. The Panel3 panel illustrates that you can reuse
the EmployeePanel for a data collection that is a
view-linked detail view object instance, in particular the
EmployeesInDepartment data collection in the
TestModule2DataControl. And finally, the Panel4
panel shows that you can reuse the EmployeesPanel bound
to a view object that's completely different than the original
one that was designed to create it, provided that it has the
expected attribute names with the expected data types. In this
case, it is bound to the data collection named
EmployeesReadOnly in the
TestModule2DataControl, an instance of the
non-entity-based (and hence read-only) view object of the same
name.
| | 90. | Avoiding Dirtying the ADF Model Transaction When Transient Attributes are Set [10.1.3]
At the ADF Model data binding layer, there is no distinction
between attributes that are transient or persistent. When any
attribute's value is changed through an ADFM binding, the
ADFM-layer transaction is marked as dirty. This can have the
unwanted side-effect of enabling the JClient navigation bar's
Commit and Rollback buttons even if the only thing the end-user
did was to change the value of a transient field, potentially
leading to end-user confusion. This JClient example illustrates a
DeptView to which an additional transient Boolean
attribute named Selected has been added. The
View project in the example illustrates a custom ADF
Business Components data control class
(MyCustomADFBCDataControl) that extends the default ADFBC data
control class (JUApplication). The custom version
overrides the setTransactionModified() method to avoid
dirtying the transaction unless the transaction related to the
underlying application module is actually dirty. The companion
MyCustomDataControlFactoryImpl is required to
instantiate the custom data control class, and the
DataBindings.cpx file references the fully-qualified
class name of the custom data control factory class in the
FactoryClass property of the
<BC4JDataControl> element in the
<dataControlUsages section of that file. Run the
Panel1 class to see the code in action. Clicking on the
Selected? checkbox toggles the value of the transient
flag, as visible by the message that the setSelected()
method in the custom view row class prints to the console, but
the JClient toolbar does not enable the Commit or Rollback
buttons until you actually modify some persistent attributes.
| | 89. | Maintaining Many-to-Many Intersection Rows in a Multiselect Table [10.1.3, SRDemo schema]
This example illustrates a very model-centric approach for
managing the rows in an intersection table of a many-to-many
relationship using a multi-select table. It is based on the
tables in the SRDemo schema USERS, PRODUCTS,
EXPERTISE_AREAS. The Staff view object is an
entity-based view object based on the User entity object
that has a WHERE clause to retrieve only the users having a
USER_ROLE is either 'technician' or
'manager'. The ProductExpertiseAreas is an
entity-based, expert-mode view object whose SQL statement is
crafted to use outer joins to return exactly one row for each
available product. The view object has the Product
entity object as its primary entity usage, and has
ExpertiseArea as a secondary, reference entity usage. It
defines a named bind variable Bind_UserId that is
consciously named exactly the same as the system bind
variable the framework will add for the view link between
Staff and ProductExpertiseAreas (based on the
UserId). That view link has a customized view link SQL
clause to allow the USER_ID to be NULL so that
the detail rowset retains a row for every product, even when the
current user does not have expertise for that product
currently. Due to the outer join, rows retrieved retrieved in the
ProductExpertiseAreas view object will have a non-null
ExpertiseArea entity row part when the current user has
expertise area in that product. Conversely, if the current user
does not have expertise in a given product, the
ExpertiseArea entity row part will be a blank entity
row. To simplify the client, we introduce a transient
Boolean-valued attribute on the
ProductExpertiseAreas view object named
HasExpertise. We override the getHasExpertise()
and setHasExpertise() methods in the view row class to
handle retrieving and setting this transient attribute. The
setter method handles either creating a new
ExpertiseArea instance corresponding to the current
userId and prodId combination, or removing an
existing entity row, depending on whether HasExpertise
is being toggled on or off. Implementing a model-centric solution
gives three interesting benefits: (1) You can test and debug the
complete functionality just using the ADF
Busines Components Tester, (2) UI can just bind a checkbox to
the Boolean HasExpertise property, and the functionality
works the same in JSF, JSP, or Swing. The ViewController
project contains a simple JSF page that displays a table
containing a selectBooleanCheckbox bound directly to the
HasExpertise attribute. In other words, it is not using
a special tableSelectMany component in its selection
facet. The checkbox is just a part of the "data" in each row.
Note: This example uses the SRDEMO schema from the SRDemo sample application. | | 88. | Dynamically-Updating JSP Graph in JSF Page [10.1.3.2] 2006, Upd: 25-JUL-2007
This example illustrates a JSF page with a dynamically-updating
graph. In the 10.1.3 release, ADF supports creating graphs and
the corresponding graph binding, however the graph tag is not yet
a JSF UIComponent. The PageWithDataAndGraph.jspx page in
this example illustrates how you can still use the
<graph:Graph> tag inside the JSF page by wrapping it
with an <f:verbatim> tag. In addition, to allow this
non-JSF component to still be updated dynamically (AJAX-style)
you further wrap the <f:verbatim> tag by a panel like
panelGroup. The backing bean for the page illustrates
how to allow an updateable UIComponent in a table to trigger
partial page rendering for other elements in the page by
programmatically calling the ADF Faces addPartialTarget
API. I initially created the graph tag by creating a regular
(i.e. non-JSF) JSPX page, and dropping the
EmployeesInDepartment data collection from the Data
Control Palette as a Graph, then I copied the graph tag and its
corresponding tag namespace to the page I wanted to include it
in. Lastly, I then copied the Graph binding into the page
definition of the target page, and ensured that its binding id
was unique. After renaming the graph binding to be unique, I
updated the EL expression in the Graph tag's
data attribute to reference the renamed graph
binding. Finally, I edited the chart's visual properties by
double-clicking on the BIGraphDef1.xml node in the
navigator and using the graph definition editor, the Structure
Window, and the Property Inspector. Also of interest is that the
chart binding is setup to graph a transient entity object
attribute called TotalComp which simply is the sum of
the Sal and Comp attributes to provide an
employees total compensation. Notice that you can edit the
Sal or Comm values in the table and the graph
dynamically updates. You can also use the navigation list or the
(Next) / (Previous) buttons to change the department, and the
graph updates to reflect the employees in the current
department. The Emp entity in the Model project
uses the generic, automatic attribute recalculation logic
explained in section 26.8
Implementing Automatic Attribute Recalculation of the ADF
Developers Guide for Forms/4GL Developers, and implemented in
the SRDemo
Sample ADFBC Version.
| | 87. | Expose Original Attribute Values in Pending Transaction [10.1.3]
Section 9.9
How to Access Original Attribute Values in the ADF
Developers Guide for Forms/4GL Developers explains the
getPostedAttribute() API you can use to access the value
of any attribute as it existed at the beginning of the current
transaction. This example illustrates a technique for exposing
that API in a generic way to the ADF binding layer so that your
application pages can display that original value to the
end-user. This could come in handy to allow the user to visually
review their pending changes in the transaction before finally
confirming to save the changes with a (Commit) button. In the
Model project, The technique involves: (1) exposing the
getPostedAttribute() API as public in a
CustomEntityImpl framework extension class since
otherwise the method would be protected, (2) automatically adding
a "shadow" attribute named OrigAttrName_orig for
each attribute in the view object (in the overridden
create() method of the CustomViewObjectImpl
class, and (3) returning the original value of the appropriate
underlying entity attribute using getPostedAttribute()
in an overridden getAttributeInternal() method of the
CustomViewRowImpl class. The Dept entity is
configured to use the CustomEntityImpl and the
DeptView view object is configured to use the
CustomViewObjectImpl component class and the
CustomViewRowImpl row class. In the
ViewController project, the technique involves
referencing the "_orig" attribute names in the EL
expressions for the values of certain UIComponents. Try
navigating through multiple rows in the DeptView and
making changes to the Dname and or Loc
attributes in any of them. As you scroll back and forth before
issuing the final transaction commit, you will notice that the
previous value of the changed attributes appear next to your
modified values wherever you've modified them.
| | 86. | Registering a Customized Page Lifecycle as JSF Managed Bean [10.1.3]
This example illustrates an interesting technique (that I
initially learned from the always-clever JHeadstart
team). The CustomFacesPageLifecycle class is registered
in the faces-config.xml file as an application-scoped
managed bean named PageLifecycle (the name is arbitrary,
of course). The CustomADFPhaseListener class is
registered in the "Life Cycle" section of the
faces-config.xml as well. Its overridden
createPageLifecycle() method uses the EL helper
class to return the custom page lifecycle class using the method
EL.get("#{PageLifecycle}"). Why would you want to do
this, you ask? The TestPage.jspx illustrates two simple examples
(and there may be more). The (Some Button) on the page has its
Action property set to the EL expression
#{PageLifecycle.onButtonClicked}, illustrating that the
custom lifecycle class (being EL-accessible) can have global
helper routines like an action listener method. Another example
is the Dname af:inputText fields whose Value
property is set to the EL expression
#{PageLifecycle.attributeBindingWrapper[bindings.Dname]}.
This shows that the helper routines in the custom page lifecycle
class can leverage a customized Map approach to
effectively provide simple, one-argument callable methods. In
this case, the getAttributeBindingWrapper map wraps the
AttributeBinding passed in as an argument. The second of
the two Dname inputText's shows that by wrapping the
attribute binding in this way and setting the Disabled
property to true, you can get an inputText that shows as a
disabled field instead of a read-only label which is the default
rendering of read-only inputText fields.
| | 85. | Uploading Contents of af:inputFile to a BLOB Column [10.1.3.3] 2006, Upd: 03-OCT-2007
Using ADF BC's support for the Oracle Intermedia ORDImage,
ORDDoc, ORDAudio, and ORDVideo, you can simplify uploading,
downloading, and displaying media and documents. However, since
numerous users have asked for it, this example illustrates a
simple JSF page with an inputFile component and the
backing bean logic to handle inserting the contents of the
uploaded file into a BLOB column in the database. Run the
CreateTables.sql script to drop and create the simple
UPLOADED_FILES table. Then, run the
UploadFileToBlob.jspx page. Note that the page uses the
af:form container with its usesUpload
attribute set to true. Also notice that the
inputFile control is bound to the backing bean property
named fileInputComponent, allowing the backing bean to
reference the UI component programmatically. The
valueChangeListener on the inputFile is mapped
via EL to the onFileUploaded() method in the backing
bean. That method accesses the ExampleModule client
interface of the ExampleModule application module, and
invokes the saveUploadedFile() method on it. It passes
in the file name, and a BlobDomain class representing
the contents of the uploaded file. The (Upload File) button's
action property is mapped via EL to the
onUploadFileButtonClicked() method in the backing bean.
This method either displays an error message if the filename to
be uploaded is bad, or else causes the "Last File Files
Uploaded" iterator to be re-executed to retrieve the latest list
of the last file files uploaded (by any user). See Configuring
ADF Faces File Uploading Servlet Parameters for information
on some settings you might need to configure.
| | 84. | Declaratively Toggling Display of PanelBox Based on Radio Group Value [10.1.3]
This example illustrates a simple JSF page with a
selectOneChoice and a selectOneRadio, each
with its respective value bound to an Integer-valued
backing bean property. The switcher controls use the
respective property value to toggle the display of an
appropriate PanelBox, and the partialTriggers
property setup on the containing panelGroup component
causes the panel to repaint when the value of the respective
selectOneXXX component changes.
| | 83. | Dump Application Module Pooling Statistics Servlet [10.1.3]
This example illustrates a servlet that dumps application module
pooling statistics and/or ADFBC database connection pooling
statistics to the browser. The
DumpPoolStatisticsServlet is configured in the
web.xml to map to the URL
/DumpPoolStatistics. The
DumpConnectionPoolStatisticsServlet is configured in
the web.xml to map to the URL
/DumpConnectionPoolStatistics. In contrast to using a
JSP page to dump these statistics, using servlets configured
this way instead avoids engaging the ADF Binding Filter, the ADF
Faces filter, or the ADF Faces servlet when viewing pooling
statistics. Run the EditEmps.jspx and click (Next) or
(Previous) a few times. Then click the "DumpPoolStatistics"
and/or "DumpConnectionPoolingStatistics" links in the page to
open a new browser window with the pooling statistics. Recall
that if your ADF application using J2EE datasources instead of a
JDBC URL connection, then you will be using your application
server's connection pool instead of the ADFBC connection
pool. In that case, the database connection pooling statistics
won't appear using this mechanism. CAVEAT: the connection
pools are named using the fully-qualified JDBC connection
credentials, which includes the password. We recommend using the
DumpConnectionPoolStatistics servlet with care in a
production environment and not leaving the configured
permanently (unless you protect access to it with a password
using HTTP authentication).
| | 82. | Adding a Dynamic 'Valid' Attribute to View Objects [10.1.3]
This example illustrates an framework extension approach for
adding a dynamic attribute named Valid to any view
object whose value returns true if the primary entity usage in
the row is valid, or false if it is invalid. The
CustomViewObjectImpl class adds the dynamic attribute
in its overridden create() method. The
CustomViewRowImpl class overrides the
getAttributeInternal() method to return the desired
value for the dynamic attribute. The Emp entity object
in the example has four different validation methods that
enforce business rules like: (1) If Deptno=40, then Job must be
SALESMAN or CLERK, (2) Salesmen in department 40 must have
salary of 1500, (3) Clerks in department 40 must have salary
1000, and (4) Comm is not greater than Sal. The
untitled1.jspx page in the ViewController project has a
ADF Faces table and references the dynamic Valid
attribute to highlight invalid rows in yellow using some
appropriate EL expressions in the inlineStyle attribute
of the fields in the table. The untitled1PageDef.xml
file had to be hand-modified to include the dynamic
Valid attribute in the AttrList of the
EmpView table binding so that the EL expression used
above of #{row.Valid} would be resolvable. And finally,
the Untitled1PageController class is registered as a
custom page controller for the untitled1.jspx page (by
setting the ControllerClass attribute at the root of
the page def XML document. This custom controller overrides the
default way that the validateModelUpdates() phase of
the ADF page lifecycle is implemented to force invalid rows to
be revalidated. This works around Bug# 5396224, where clicking a
second time on the ADF faces table's "Next" or "Previous"
navigation link causes a validation error to not be reported
again.
| | 81. | Refreshing Calling Page After Adding New Row in Popup Dialog [10.1.3]
This example illustrates one technique for causing the current
page, containing a "Browse Employees" table, to refresh upon
returning from a popup dialog wherein the user has added a new
employee. The onReturnFromDialog() in the
BrowseEmployees backing bean is configured as the
ReturnListener for the button. It calls a
refreshCurrentPage() helper method to accomplish the
page refresh. It works in combination with setting the
partialSubmit property and the
useWindow properties to true on the (Add New
Employee) button in the page. The onSaveNewEmployee()
method is required for the ActionListener on the (Save
New Employee) button since we want to conditionally return from
the dialog, only when no errors occur during the execute
operation on the "Commit" action binding. Using the declarative
<af:returnActionListener>, we couldn't accomplish
this conditional behavior. As a bonus, the example also
illustrates edit and delete behavior as well. By choice, the add
a new employee is performing an immediate commit, while the edit
and delete operations need to be explicitly committed or
rolled-back by the user.
| | 80. | Simple JSF Popup List of Values Page [10.1.3]
This example contains an "untitled1.jsp" page that uses a
separate "pickDept.jsp" page as a popup List of Values (LOV) dialog
page. The pickDept page includes
<af:returnActionListener> and
<af:setActionListener> as nested children
components of the submit button. These cause the popup dialog
page to return to the calling page and to set the selected value
into the Deptno attribute binding that I've added to the
pickDept page's page definition.
| | 79. | Setting First Row in New Page Current When Paging Through Table [10.1.3.3] 2006, Upd: 22-OCT-2007
This example contains an onRangeChanged() range-change listener
method in the TestPage.java backing bean for the TestPage.jspx
page. It uses a couple of lines of code to set the range starting
row to the new starting row index (zero-based) passed in the
RangeChangeEvent object, then sets the first row in the new range
to be the current row. It also sets a requestScope attribute as a
flag to allow the onSelectionChanged method to known whether or
not it should ignore the firing of the normal ADF selection
change listener or not. Note that the EmpView view object has its
"Fill last page of rows when paging through rowset?" property set
to false on the Tuning panel of the View Object editor.
| | 78. | Updating Form Fields When Using Immediate=True [10.1.3]
This example contains a DEPT-based view object presented
in both a table and a form display. The (Create), (Delete), and
(Rollback) buttons are set to have their immediate
property to the value true which causes validation to be
circumvented. There are two functionally-identical JSPX pages,
one which programmatically calls resetValue() on the
Faces UI components in the backing bean to cause their values to
be refreshed, and the other which uses the <af:resetActionListener>
to accomplish the same thing declaratively.
| | 77. | Using a View Object with SQLXML to Query Data from XML [10.1.3]
This example contains a DepartmentDataFromXML view
object that uses the SQL XML support in Oracle 9i Release 2 (or
later) to query the data from an XML document into a view
object. The view object accepts the XML text in a named bind
variable, and uses the xmltype() constructor to treat
that XML text as an XML document. Then it uses the
xmlsequence() operator to treat the results of
extract()-ing the <ROWSET>/<ROW> elements
from the XML document as individual rows of source data. Finally,
it uses the table() operator in combination with the
extractValue() operator to retrieve the data values from
each row of <ROW> fragments, breaking out a
DEPTNO, DNAME, and LOC value from the
row. The TestPage.jspx in the ViewController project allows you
to experiment with passing in different XML as the value of the
bind variable.
| | 76. | Optionally F |
|