-
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
248
Practices for Lesson 18
When you built the ProductCatalog page, you created three
separate areas on the page to display Categories, SubCategories,
and Products. Now you modify the page to display only one table at
a time.
Initially the Categories table should appear. When the user
clicks the name of a category, the Subcategories table should
display the subcategories for the category that the user clicked.
Then if the user clicks a subcategory, the Products table should
display the products for that subcategory.
You accomplish this by using parameters. In the practices for
this lesson, you modify the ProductCatalog page to display specific
tables and data based on those parameters.
Modified By : Amr Abdo
-
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
249
Practice 18-1: Conditional Rendering Based on Parameters In this
practice, you define parameters and set up the tables on the
ProductCatalog page to conditionally appear based on the parameter
values.
1) You need to change the tables on the ProductCatalog page to
accept a parameter toset the row, rather than relying on row
concurrency as it does now. First, disable rowselection for the
tables.
a) Open the ProductCatalog page.
b) Select the Categories table either in the Structure window or
the visual editor(the default id of the table was md1)
c) In the Property Inspector, click Edit.d) Select None at Row
Selection and click OK.
Note: By using the editor, JDeveloper removes the row selection
and whateverlisteners were required. If you just remove the row
selection manually in theProperty Inspector, the listeners still
remain.
e) Select the SubCategory table and remove the Row Selection in
the same way.2) Now you add page parameters.
Set page parameters on the ProductCatalog page to accept
parameters namedparam_CategoryId, param_SubCategoryId,
param_CategoryName, andparam_SubCategoryName.
The page parameters should get their values from pageFlowScope
variables namedCategoryId, SubCategoryId, CategoryName, and
SubCategoryName.
a) Open the Page Definition for the ProductCatalog page
(right-click the page andselect Go to Page Definition.)
b) Form Parameters tab click then from property Inspector add
the following parameters
id Value
param_CategoryId #{pageFlowScope.CategoryId}
param_SubCategoryId #{pageFlowScope.SubCategoryId}
param_CategoryName #{pageFlowScope.CategoryName}
param_SubCategoryName #{pageFlowScope.SubCategoryName}
The Page Definitions Parameters section should look like:
-
Practice 18-1: Conditional Rendering Based on Parameters
(continued)
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
250
Leave the page definition file open for the next step.
3) There is a method named setCurrentCategory() in the
FODProductAMapplication module. This method takes two arguments: a
category ID and asubcategory ID. It reexecutes the BrowseCategory,
BrowseSubcategory, andBrowseProduct view object queries based on
the values that are passed to it.
Edit the bindings for the ProductCatalog page so that this
method is executed uponloading the page. Pass to the method two of
the parameters that you defined above.
a) Still in the page definition At Bindings of the
ProductCatalog page, add amethodAction to FODProductAMDataControl
> setCurrentCategory.
b) In the Create Action Binding Editor, set the value of the
categoryId parameterto #{bindings.param_CategoryId} and the value
of subCategoryId to#{bindings.param_SubCategoryId} (you can use
Expression Builder; theparameters are shown under ADF Bindings >
bindings).
The Parameters section of the Create Action Binding Editor
should look like:
c) Add an InvokeAction to the Executables. Set the id
toinvokeSetCurrentCategory and bind it to setCurrentCategory. Set
theRefresh property to ifNeeded.
d) Make sure that invokeAction is the first executable in the
list. This insuresthat the method is executed first when the page
is loaded. (If you need to move it,you drag it to the top of the
list.)
e) Save your work, and leave the page definition file open for
the next step.
-
Practice 18-1: Conditional Rendering Based on Parameters
(continued)
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
251
4) You have defined parameters that take their values from
pageFlowScope variables.But how do those values get stored in the
pageFlowScope variables? In this step, you store these values.
In the Category and Subcategory tables, convert the category
name to a link that stores the name and ID in pageFlowScope
variables. Use a Set Action Listener operation to store each
variable value. Hint: You first must add the category ID to the
page bindings.
a) Add CategoryId to the page bindings for both BrowseCategory1
andBrowseSubCategory1.
i) Still in the page definition file for ProductCatalog, edit
the BrowseCategory1binding and add CategoryId as a display
attribute. Hint: Click theBrowseCategory Binding; click Edit;
select the rule in the Tree BindingEditor; shuttle the CategoryId
from Available to Display Attributes.
Here is what the Tree Binding Editor should look like:
ii) Repeat this step for BrowseSubCategory1, because you are
going to use theCategoryId that is selected in the SubCategories
table to set thesubcategory-related parameters.
b) In the ProductCatalog page, convert the CategoryName field to
be a link in theCategories table. When a user clicks the link, the
page should usesetActionListeners to set the pageFlowScope
parameters.
-
Practice 18-1: Conditional Rendering Based on Parameters
(continued)
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
252
i) In the Structure window for the ProductCatalog page, expand
the af:table- md1.
ii) Click af:outputText for CategoryName and copy [Ctrl + c] the
Valueproperty (when you convert the outputText to a Link, you lose
the Valueproperty).
iii) Right-click the af:outputText for CategoryName and select
Convert.
iv) Select Link, and then click OK in the Confirm Convert dialog
box.v) Paste into the Text property the value you copied a moment
ago. The value
should be #{row.CategoryName}.vi) Insert two setActionListeners
(Form Component palette )inside the Link with the following
properties.
From To#{row.CategoryId}
#{pageFlowScope.CategoryId}#{row.CategoryName}
#{pageFlowScope.CategoryName}
Note: You use the CategoryName and SubCategoryName parameters
when you set breadcrumbs in the next section.
c) Repeat the steps for the SubCategory table. (Make sure to pay
close attentionto the pageFlowScope variable names in each
setActionListener.)
i) Expand the af:table - SubCategory in the second panel
header.
ii) Click af:outputText for CategoryName and copy [Ctrl + c] the
Valueproperty.
iii) Right-click the af:outputText for CategoryName and select
Convert.
iv) Select Link, and then click OK in the Confirm Convert dialog
box.v) Paste into the Text property the value you copied a moment
ago. The value
should be #{row.CategoryName}.vi) Insert two setActionListeners
inside the Link with the following properties.
From To#{row.CategoryId}
#{pageFlowScope.SubCategoryId}#{row.CategoryName}
#{pageFlowScope.SubCategoryName}
5) Modify the rendering of the tables so that only a single
table appears at a time.Hint: If both category and subcategory
parameters are null, the Categories tableshould appear (no links
have been clicked to set the parameters). If only thecategoryId
parameter is set, the Subcategories table should appear, becausethe
user clicked a link on the Categories table to set the category ID.
If bothparameters are set, the Products table should be displayed
(both Category andSubcategory links have been clicked, so both
parameters have been set).
-
Practice 18-1: Conditional Rendering Based on Parameters
(continued)
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
253
a) Select the first af:table (ms1) and set the Rendered property
so thatthe table appears if the param_CategoryId and the
param_SubCategoryId are both null. (This means that there were no
parameters set). The EL code is: #{bindings.param_CategoryId ==
null && bindings.param_SubCategoryId == null}
b) Select the second af:table (SubCategory) and set the Rendered
property sothat the table appears if the CategoryId parameter is
set but theSubCategoryId parameter is null. (This means that the
page set a Categorybut not a subCategory) The EL code
is:#{bindings.param_CategoryId != null
&&bindings.param_SubCategoryId == null}
c) Select the third af:table (Products) and set the Rendered
property so that thetable appears if there is a categoryId and a
subCategoryId. (This means thatthe page has set a Category and
subCategory) The EL code is:#{bindings.param_CategoryId != null
&&bindings.param_SubCategoryId != null}
6) Modify the layout of the ProductCatalog page so that all
tables are under a singlepanel header whose title changes depending
on the table that appears.
a) In the Structure window for the ProductCatalog page, select
af:table SubCategory in the second af:panelHeader and drag it to
the firstaf:panelHeader (the one currently labeled Categories.)
b) Drag the af:table from the third af:panelHeader to the first
af:panelHeader.
c) Delete the second and third af:panelHeaders.
d) Select af:panelHeader and set the Text property
to#{bindings.param_CategoryId == null
||bindings.param_SubCategoryId == null
?storefrontuiBundle.CATEGORIES :storefrontuiBundle.PRODUCTS}
e) Move the command buttons on the page to a toolbar in the
toolbar facet of the panelheader.
i) Expand Panel Header facets.ii) Drag a toolbar to the toolbar
facet.iii) Drag the Search and Show Cart buttons to the
toolbar.
f) The Structure should now look something like:
-
Practice 18-1: Conditional Rendering Based on Parameters
(continued)
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
254
7) Test the page.
a) Run FODShoppingDashboard from the adfc-config task flow.b)
The page should initially display categories. Click one of the
category names.
c) The page should now display subcategories (the title of the
panel header still saysCategories.) Click one of the subcategory
names.
d) The page should now display products, and the title of the
panel header changesto Products. Notice that there is no way to
navigate back to the Categoriestable. You fix this in the next
practice.
e) Close the browser and undeploy the application as described
in step 6(i) ofPractice 2-4.
-
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
255
Practice 18-2: Using Parameters for Dynamic Breadcrumbs When
users click through links in the tables to display either the
Subcategories or the Products table, they need a way to navigate
back through the chain of tables. This is what the breadcrumbs on
the page should enable them to do.
When users click the first breadcrumb, they should return to the
top level of the breadcrumb list to display the Categories table.
You have already set the page to use the pageFlowScope parameters
to display the correct section of the page, so in this practice,
you just set those parameters based on which breadcrumb is
clicked.
1) For the first breadcrumb, you want the Categories table to
appear, so reset all theparameters to null.Hint: Remember that the
parameters get their values from the pageFlowScopevariables.
a) In the ProductCatalog page, select the first
af:commandNavigationItemtheone labeled Store.
b) Add four setActionListeners with the following
properties:
From To#{null} #{pageFlowScope.CategoryId}#{null}
#{pageFlowScope.CategoryName}#{null}
#{pageFlowScope.SubCategoryId}#{null}
#{pageFlowScope.SubCategoryName}
Hint: After you add the first setActionListener, you could use
the Source tab to copy, paste, and then modify the code.
2) Set the second breadcrumb to appear only if the user has
clicked a category name inthe Categories table. Label the
breadcrumb with the Category name that the userclicked in the
Categories table. Set the second breadcrumb to display
theSubcategory table when a user clicks it.
a) Select the second of the three navigation items in the
Structure window.b) Set the Text property to
#{bindings.param_CategoryName}. You can use
Expression Builder to set this (ADF Bindings > bindings >
param_CategoryName).
c) Set the Rendered property to#{bindings.param_CategoryId !=
null}.
d) If a user clicks the second breadcrumb, he or she wants to
see the SubCategories.You use the setActionListeners to reset just
the SubCategory parameters.
Add 2 setActionListeners with the following properties:
From To#{null} #{pageFlowScope.SubCategoryId}#{null}
#{pageFlowScope.SubCategoryName}
-
Practice 18-2: Using Parameters for Dynamic Breadcrumbs
(continued)
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
256
3) Set the third breadcrumb to appear only if the user has
clicked a category name in theSubCategories table. Label the
breadcrumb with the Category name that the user clicked in the
SubCategories table. Set the third breadcrumb to display the
Products table when a user clicks it.
a) Select the last of the three navigation items in the
Structure window.b) Set the Text property to
#{bindings.param_SubCategoryName}.
c) Set the Rendered property to#{bindings.param_CategoryId !=
null && bindings.param_SubCategoryId != null}
d) The Structure should look like:
4) Test the page.
a) Run FODShoppingDashboard from the adfc-config task flow and
use the tablelinks and the breadcrumbs to navigate around the
shopping region.
b) Close the browser when you are finished and undeploy the
application asdescribed in step 6(i) of Practice 2-4.
-
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
257
Practice 18-3: Implementing the Add to Cart Functionality In
this practice, you add a router and a method call to the shopping
cart flow so that it can be used either to display the cart or to
add items to it. The calling page, ProductDetails, in the shopping
flow sets some parameter values that it passes to the shopping cart
flow.
1) Modify the shopping cart flow to accept the following two
input parameters:
Name Value RequiredAction #{pageFlowScope.Action} True ProductId
#{pageFlowScope.ProductId} False
a) Open ShoppingCartFlow.b) Click the task-flow-definition in
the Structure window.
c) Select Parameters in the Property Inspector.d) Click Add to
add the two parameters shown above.
2) Add a method call to the shopping cart flow that calls the
addItemToCart() method of FODShoppingCartAM. Set the value of its
productId argument to #{pageFlowScope.ProductId}. Navigate to the
ShoppingCart view when finished.
a) In the Data Controls panel, expand
FODShoppingCartAMDataControl.b) Drag addItemToCart(Number) to the
shopping cart flow diagram.c) In the Edit Action Binding dialog
box, set the Value of the productId parameter
to #{pageFlowScope.ProductId}, and then click OK.
d) Add a Control Flow Case from addItemToCart to ShoppingCart
and label itdone (you later change this to include a commit
function, but for now you simplywant to go to the cart after the
method call.)
e) In the addItemToCart method call, change the fixed-outcome
property to done.
-
Practice 18-3: Implementing the Add to Cart Functionality
(continued)
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
258
3) Add a router named ChooseAction as the default activity for
the shopping cartflow. The router should either display the
shopping cart (display control flow case) or add an item to it (add
control flow case), depending on whether pageFlowScope.Action has a
value of Display or Add. The default action should be to display
the cart.
a) Add a Router to the flow and name it ChooseAction.
b) Mark the ChooseAction router as the default activity for the
page flow.c) Create two Control Flow Cases from ChooseAction: One
to addItemToCart
named add, and the other to ShoppingCart named display.
d) Add two expressions to the ChooseAction router that
evaluatepageFlowScope.Action. If the value is Add, use the add
outcome. If it isDisplay, use the display outcome. Hint: The add
expression is:#{pageFlowScope.Action == 'Add'}Note: The
ChooseAction property is in the Cases section under the Common
tabof the Property Inspector.
e) Set the display outcome to be the default outcome of the
router.
4) The shopping cart flow is expecting parameters named Action
and optionally,ProductId. Modify the shopping flow to send the
correct parameters.
a) Open the ShoppingFlow diagram.b) Two parameters have been
added to the DisplayShoppingCart task flow call in
the Parameters section of the Property Inspector. Set a value
for the Actionparameter as follows:
Name Value
Action Display
ProductId Leave blank (or empty)
-
Practice 18-3: Implementing the Add to Cart Functionality
(continued)
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
259
c) The same two parameters have been added to the
AddShoppingCart task flowcall; set the values as follows:
Name Value
Action Add
ProductId #{requestScope.ProductId}
The ShoppingFlow is now set up to send the Action parameter and,
if needed, to send the ProductId as well.
5) Finally you need to get the productId from the calling page
and put it into therequestScope variable ProductId. The call to add
the item to the cart should beplaced on the ProductDetails page.
Hint: There is currently no binding for ProductId.a) Open the
ProductDetails page.
b) Add a button to the toolbar of the panel headers toolbar
facet and label it Add Item to Cart. Set its Action to add.
c) Add a binding for ProductId.
i) Click the Bindings tab.ii) In the Bindings section, click Add
(plus icon.)iii) Add an attributeValues binding whose Data Source
is
FODProductAMDataControl.BrowseProduct and whose Attribute
isProductId.
d) Add a setActionListener to the Add Item button that sets the
value of#{requestScope.ProductId} to the value
of#{bindings.ProductId.inputValue} when the button is clicked.Hint:
Right-click af:commandButton, select Insert inside > ADF Faces
> SetAction Listener and set the From and To values. Make sure
to put the correctvalue in the To and the From properties.
6) Test by running FODShoppingDashboard from the adfc-config
unbounded taskflow. Remember that the Add to Cart functionality is
available from the ProductDetails page. When you have finished,
close the browser and undeploy theapplication as described in step
6(i) of Practice 2-4.
-
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
260
Practice 18-4: Implementing Create Supplier Functionality In
this practice, you add a router to the ManageSupplierFlow task flow
that decides whether the UpdateSupplier page should display a
supplier for update or should display a new record where users can
create a new supplier. You also add a method call to create a new
record.
1) Modify the manage supplier flow to accept the following input
parameter:
Name Value RequiredSupplierAction
#{pageFlowScope.SupplierAction} True
a) Open ManageSupplierFlow.b) Click the task-flow-definition in
the Structure window.
c) Select Parameters in the Property Inspector.d) Click Add to
add the parameter shown above.
2) Add a method call to the ManageSupplierFlow task flow to call
the CreateInsertoperation for a new supplier and connect it to the
SupplierUpdate activity whenfinished.
a) Open the ManageSupplierFlow task flow.b) In the Data Controls
panel, expand FODSupplierAMDataControl > Supplier1
> Operations and drag the CreateInsert operation to the task
flow diagram tocreate a method call activity.
c) At the property Inspector Change the fixed-outcome of the
CreateInsert method call activity to done.
d) Drag a Control Flow Case from CreateInsert to SupplierUpdate;
its fixed-outcome should default to done.
3) Set up the task flow so that a new supplier is created when a
parameter passed to ithas a value of New, or that an existing
supplier is updated when the parameter value isUpdate.
a) Add a Router to the flow and name it ChooseAction.
b) Mark the ChooseAction router as the default activity for the
page flow.c) Create two Control Flow Cases from ChooseAction: One
to SupplierUpdate
named update, and the other to CreateInsert named new.
-
Practice 18-4: Implementing Create Supplier Functionality
(continued)
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
261
d) Add two expressions to the ChooseAction router that
evaluatepageFlowScope.SupplierAction. If the value is New, use the
new outcome. If it is Update, use the update outcome. Hint: The new
expression is: #{pageFlowScope.SupplierAction == 'New'}Note: You
define these expressions in the Cases section under the General
block of the Property Inspector.
e) Set the update outcome to be the default outcome of the
router.
4) The manage suppliers flow is expecting a parameter named
SupplierAction.Modify the show suppliers flow to send the correct
parameter.
a) Open the ShowSuppliersFlow diagram.b) Add a parameter to the
ShowSuppliersFlow task flow call using the Parameters
section of the Property Inspector:
Name Value
SupplierAction #{requestScope.SupplierAction}
5) Set the requestScope variable SupplierAction. The calls to
create a newsupplier or update an existing one should be placed on
the BrowseSuppliers page.
a) Open the BrowseSuppliers page.
b) Add a toolbar to the panel headers toolbar facet.
c) Add a toolbar button to the toolbar and label it New
Supplier. Set its Action to update.
-
Practice 18-4: Implementing Create Supplier Functionality
(continued)
Oracle Fusion Middleware 11g: Build Applications with ADF I A -
262
d) Add a setActionListener to the New Supplier button that sets
the value of#{requestScope.SupplierAction} to New when the button
is clicked.Hint: Right-click af:commandToolbarButton, select Insert
inside > ADFFaces > Set Action Listener and set the From and
To values. Set the Fromproperty to #{'New'}.
e) Add a setActionListener to the SupplierId link that sets the
value of#{requestScope.SupplierAction} to Update when the link is
clicked. Set the From property to #{'Update'}.
6) Finally, change the panel header text of the SupplierUpdate
page to conditionallydisplay either Update Supplier or New
Supplier, depending on the value of theparameter that is
passed.
a) On the SupplierUpdate page, select the panel header.b) You
need to make some entries to the resource bundle. Although you
could edit it
directly, it may be easier to change the Text to Update
Supplier, using theresource bundle (use UPDATE_SUPPLIER_TITLE as
the key), and then change itagain to New Supplier, using the
resource bundle (use NEW_SUPPLIER_TITLEas the key).
c) Now that you have the text resources entered in the resource
bundle, you can usethem in a conditional expression to define the
title based on the parameter. Enterthe following in the Text
property (all on one line):#{pageFlowScope.SupplierAction == 'New'
?storefrontuiBundle.NEW_SUPPLIER_TITLE
:storefrontuiBundle.UPDATE_SUPPLIER_TITLE}
7) Test by running FODShoppingDashboard from the adfc-config
unbounded taskflow. Remember that the New Supplier functionality is
available from theBrowseSuppliers page. There is not yet a way to
commit updates or inserts; you addthis in a later practice. When
you are finished, close the browser and undeploy theapplication as
described in step 6(i) of Practice 2-4.