Technology: ADF11g
Developed in: JDeveloper 11.1.1.4.0
Browsers tested: Firefox 3.6.13 and Internet explorer 7 (7.0.6002.18005)
Used database schema: HR
Used tables: EMPLOYEES, DEPARTMENTS
Summary
In the blog 'How to fix menu item navigation when using bounded taskflows' I explained how to abandon a taskflow so you could start another taskflow from the menu bar. This works fine as long as the taskflows are not started from a dynamic region.
When you use dynamic regions (so each bounded taskflow is created using page fragments) and the current application state is somewhere in a taskflow then I would expect if you use the menu bar and select the same taskflow as the application is currently in that it would restart the taskflow so it’s default start activity is executed. Without any interference this is not the case, when you use the menu and select the current taskflow nothing is happening. However if you select another taskflow there is no custom code needed to start a new taskflow.
In this blog a solution is provided to make the current taskflow restart when using the menu option.
Overview of the page flow, the red arrows indicate the current flow, the green arrow the requested behavior after clicking on the menu:
Setup example application
For this blog an example application is created based on the HR schema. The example application contains a table of employees with detail form and a departments table and detail form. The detail forms are created in a separate page. For the employees table and form a bounded task flow is created this bounded task flow is started from the menu. For the departments table and form another bounded task flow is created which is also started from the menu.
Model layer
Create the following entities:
Entity name | Based on table of HR schema | Customizations made |
---|---|---|
Employee | EMPLOYEES | None |
Department | DEPARTMENTS | None |
Create the following view objects:
View object name | Based on entities | Customizations made |
---|---|---|
EmployeesView | Employee | None |
DepartmentsView | Department | None |
Create an application module HrAppModule which exposes the EmployeesView and DepartmentsView.
Task flow
Unbounded task flow
The unbounded task flow only contains the declaration of the managed bean used for the dynamic region (scope = view):
Bounded task flow
The employees task flow and the departments task flow are bounded task flows. Both look like this (but for departments the view is DepartmentsTable and DepartmentDetails).
The next properties are set (for both bounded task flows):
Property | Value |
---|---|
usePageFragments | true (this is the default value) |
Share data controls with calling task flow | true |
Home page
An empty page containing a default layout of 2 column and two rows (first fixed size second stretchable):
In the first row the menu is created:
<af:menuBar id="mb1">
<af:commandMenuItem id="cmi1"
text="Employees"
action="#{viewScope.dynamicRegionManager.startEmployeesTaskFlow}"
immediate="true"/>
<af:commandMenuItem id="cmi2"
text="Departments"
action="#{viewScope.dynamicRegionManager.startDepartmentsTaskFlow}"
immediate="true"/>
</af:menuBar>
<af:panelGroupLayout layout="scroll"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
id="pgl1">
<af:region id="r1"
value="#{bindings.dynamicRegion1.regionModel}"
partialTriggers="::cmi1 ::cmi2"/>
</af:panelGroupLayout>
DynamicRegionManager
This managed bean class contains methods for each menu item and a method to get the current taskflow:
public class DynamicRegionManager {
private String taskFlowId = "/WEB-INF/EmployeesFlow.xml#EmployeesFlow";
public DynamicRegionManager() {
}
public TaskFlowId getDynamicTaskFlowId() {
return TaskFlowId.parse(taskFlowId);
}
public String startEmployeesTaskFlow() {
taskFlowId = "/WEB-INF/EmployeesFlow.xml#EmployeesFlow";
return null;
}
public String startDepartmentsTaskFlow() {
taskFlowId = "/WEB-INF/DepartmentsFlow.xml#DepartmentsFlow";
return null;
}
}
Table page
The table pages are created by drag and drop from the Data Controls. The table is dropped as ADF Read-only table with Single Row Selection checked, all columns are displayed.
For display purposes the styleclass is set:
Property | Value |
---|---|
styleClass | AFStretchWidth |
Underneath the table two buttons are added to go to the details page and to end the current task flow:
<af:panelGroupLayout id="pg1"
layout="horizontal">
<af:commandButton id="cb1"
text="Show details"
action="detail"/>
<af:commandButton id="cb2"
text="End"
action="end"/>
</af:panelGroupLayout>
Form page
The form pages are created by drag and drop from the Data Controls. The form is dropped as ADF Form all attributes are displayed and a submit button is added.
Underneath the form in the footer two more buttons are added to navigate back to the table and to end the taskflow. A rollback operation is added (form the data control palette) on top of the back button:
<af:group id="g1">
<af:commandButton id="cb1"
text="Submit"
actionListener="#{bindings.Commit.execute}"/>
<af:commandButton id="cb3"
text="Back"
actionListener="#{bindings.Rollback.execute}"
immediate="true"
action="back">
<af:resetActionListener/>
</af:commandButton>
<af:commandButton id="cb2"
text="End"
action="end"/>
</af:group>
Fix the menu navigation
When the application described above is deployed the navigation from the menu does not work (properly) if you’re in the details page and then click on the menu entry of the same taskflow.
The reason the menu doesn’t work is that the region concludes you’re already in this taskflow so no actions are needed.
A solution to this issue is to force the refresh of the region. This can be done by binding the region to the dynamicRegionManager bean instance and whenever a menu item is clicked (the action of the dynamicRegionManager will be executed) force a refresh:
- Add the binding to the region tag:
<af:region id="r1"
value="#{bindings.dynamicRegion1.regionModel}"
partialTriggers="::cmi1 ::cmi2"
binding="#{viewScope.dynamicRegionManager.dynamicRegion}"/>
- Define the region in the DynamicRegionManager class (include accessors):
private RichRegion dynamicRegion;
- Refresh the region when an action is triggered:
public String startEmployeesTaskFlow() {
taskFlowId = "/WEB-INF/EmployeesFlow.xml#EmployeesFlow";
getDynamicRegion().refresh(FacesContext.getCurrentInstance());
return null;
}
public String startDepartmentsTaskFlow() {
taskFlowId = "/WEB-INF/DepartmentsFlow.xml#DepartmentsFlow";
getDynamicRegion().refresh(FacesContext.getCurrentInstance());
return null;
}
Nice Blog...
BeantwoordenVerwijderenHi Marianne,
BeantwoordenVerwijderenNice blog,
Sorry, Unable to view images.