Pages

Sunday, October 12, 2008

Dynamic Regions with Task Flow in Jdeveloper 11G

I made a new dynamic region example but now build with the JDeveloper 11G production release. In this project I have a jsf page which has a Tree and a dynamic region. This example uses the the department and employee tables of the HR demo schema.
Here are some pictures of the result.


These are the steps I did to get this result.
First I used the ADF Business Components wizard the fill the model project. I changed the Application Module so the tree has its own iterators.

Create a new JSF template in the viewcontroller project with 2 facets definitions. In this template I add a panel splitter with two facet ref's.
Open the adfc-config and create a view called mainPage to the Task Flow. Select the view and create the jsf page based on the just created template.
Drag the departmentsViewTree viewobject from the datacontrol to the Tree facet of the jsf page and select the ADF Tree option.

Also add the EmployeeTreeView to the tree binding.
Create two task flows called employee-task-flow-definition and department-task-flow-definition.

First we open employee-task-flow-definition where we add a view and we also drag the SetCurrentRowWithKeyValue operation of the employeesView to the task flow. ( do this from the datacontrol). Next we add a control flow case between the SetCurrentRowWithKeyValue method and the view. Make sure you set the SetCurrentRowWithKeyValue method as the default activity ( so it fires when the region is loaded).

It looks a bit strange to add an SetCurrentRowWithKeyValue operation in the Task Flow to lookup the right employee because in JDeveloper 10.1.3 we used an invoke action in the page definition to fire the SetCurrentRowWithKeyValue operation on an iterator. Invoke action in JDeveloper still works but has some side effects.
Select the employee_region view and create the JSF page fragment. In this page fragment we can drag the employeesView from the datacontrol and select a read only form option.
The last step is to add an input parameter to the Task Flow so this parameter can be used by the SetCurrentRowWithKeyValue method.

Select the SetCurrentRowWithKeyValue method and go to the page definition of this task flow method, where we will use the input parameter value.


Do the same with the department task flow.
Go the main jsf page where we will drag the employee or department Task Flow to the body facet of the main jsf page. We will get an option if we want to create a dynamic region.

JDeveloper gives you the option to create a new backing bean where it will add the necessary code for the dynamic region. Here the code of the backing bean.

package nl.ordina.view.backing;

import oracle.adf.controller.TaskFlowId;
public class MainPageBean {
private String taskFlowId = "/WEB-INF/employee-task-flow-definition.xml#employee-task-flow-definition";

public MainPageBean() {
}

public TaskFlowId getDynamicTaskFlowId() {
return TaskFlowId.parse(taskFlowId);
}

public String employeeRegionLayout() {
taskFlowId = "/WEB-INF/employee-task-flow-definition.xml#employee-task-flow-definition";
return null;
}

public String departmentRegionLayout() {
taskFlowId = "/WEB-INF/department-task-flow-definition.xml#department-task-flow-definition";
return null;
}
}

We have to change this backing bean scope to session or application. Open the adfc-config for this

Now we can change the tree in the mainpage so the right key is passed on and the right region is activated. We use a switcher and setActionListener for this. The setActionListener copies the department or employee Id to a pageflowscope variable. The value is passed on to the input parameter of the region task flow. ( This happens in the page definition of the main page)

<af:panelHeader text="Department Employee Tree">
<af:tree value="#{bindings.DepartmentsViewTree.treeModel}"
var="node"
selectionListener="#{bindings.DepartmentsViewTree.treeModel.makeCurrent}"
rowSelection="single">
<f:facet name="nodeStamp">
<af:switcher facetName="#{node.hierType.viewDefName}">
<f:facet name="nl.ordina.model.dataaccess.DepartmentsView">
<af:commandLink text="#{node}"
action="#{MainPage.departmentRegionLayout}">
<af:setActionListener from="#{node.DepartmentId}"
to="#{pageFlowScope.TreeKey}"/>
</af:commandLink>
</f:facet>
<f:facet name="nl.ordina.model.dataaccess.EmployeesView">
<af:commandLink text="#{node}"
action="#{MainPage.employeeRegionLayout}">
<af:setActionListener from="#{node.EmployeeId}"
to="#{pageFlowScope.TreeKey}"/>
</af:commandLink>
</f:facet>
</af:switcher>
</f:facet>
</af:tree>
</af:panelHeader>

The last step is to change the page definition of the main page. Where we need to change the refresh conditions and the value of the inputparameter. This inputparameter has to have the same name as the inputparameter name of the region task flows.


We are finished. Here you can download the project

17 comments:

  1. Hi,

    thanks for the nice example it works fine but for each selection in the node (whether employees or departments node) the tree is completely updated. I think this is not good for the performance.

    My experiment:
    af:tree value="#clientComponent="true"...
    af:commandLink clientComponent="true" ...

    does not have the desired effect.

    Has anybody an idea?

    Many Thanks!

    ReplyDelete
  2. Hi,

    I now have a switcher in the tree maybe you can evaluate in a backing bean the type ( department or employee) and it's primary key.

    Thanks Edwin

    ReplyDelete
  3. Hi,

    I have another question. You wrote "Invoke action in JDeveloper still works but has some side effects." Can you explane the side effects a little please?

    Many Thanks!

    ReplyDelete
  4. Hi Silver.

    Please look at http://biemond.blogspot.com/2008/05/adf-jdeveloper-11g-tp4-need-to-knows.html

    it has something to do with validation and insert mode.

    thanks Edwin

    ReplyDelete
  5. Hi,
    Many thanks for the example this was really similar to what I have to do but I have one question following you example I adapted my application to click a table column (with a key value) and the run the ExecuteWithParams method call in my taskflow. The problem I am having is that the taskflow runs the first time (when the page is loading) but does not run again after I click on a column containing the key. The column has the following action:

    af:commandLink text="#{row.keyId}"
    action="#{TestBacking.keyDetailsRegionLayout}"
    af:setActionListener from="#{row.keyId}" to="#{pageFlowScope.Key}"
    af:commandLink

    I would really appreciate if you could inform me how to pass the control to a taskflow from a jspx page.

    Thanks

    Ola.

    ReplyDelete
  6. Hi,

    in the main page def there is a reference to the task flow. make sure you set the refresh condition ifneeded and always.

    see the pagedef pics in this blog entry

    thanks

    ReplyDelete
  7. Hi Edwin Thanks for the reply.

    I was trying to use a project gantt chart as the source input for the dynamic region (i.e. the left hand side of the gantt had the commandLink) and I was having the problem that when clicked the commandLink was not activating the taskflow as you described in your tutorial. I then changed the input from a project gantt to a normal table and ever thing worked as you explained it.

    Once again thanks very much for the article.

    Ola

    ReplyDelete
  8. Hi,
    thanks for your example, it's very important for me, because actually I'm develop a application in JDeveloper 11, also i have got some problems with tasks.
    I have got a menu( < af:menu ...) and I want link with a region dynamic, but I don't know.
    any idea?
    Many Thanks from Peru!

    ReplyDelete
  9. Hi,

    just drop a task flow on a page and create a dynimic region, This will create a backing bean.

    in this backing bean you can add your own method which set the region.

    and call this method from the menu item like this
    "#{MainPage.employeeRegionLayout}"

    else send me a test case at biemond at gmail dot com.

    thanks

    ReplyDelete
  10. thanks for reply! , I'll send you an email with the demo

    ReplyDelete
  11. Hello Edwin,

    we have a customer project with dynamic regions similar to yours.
    In our case we have only one jspx.
    Every page is a pagefragment containing pagefragments for each block (e.g. one fragment for master block and one for detail block)
    We have the problem that selecting a row in af:table triggers refresh of all regions in the page.
    Even changing only a value in af:inputtest (autosubmit=true) triggers this refresh.

    do you have any idea what may be wrong?

    Using Jdev 11gR1 with ADF BC.

    regards
    Peter

    ReplyDelete
  12. Hi,

    Can you make a small testcase and I will take a look.

    biemond at gmail dot com

    thanks Edwin

    ReplyDelete
  13. Hello Edwin,

    Thanks for your offer to send you a test case.
    After the vacation my colleague checked the issue again and found the root cause of the refreshes.
    There was an partial trigger on a underlaying page template.

    regards
    Peter

    ReplyDelete
  14. Hi,

    for each selection in the node (whether employees or departments node) the tree is completely updated.

    in jdev 11g r1 ps1 you can use events on the tree, for example department and employee events then this problem is solved.

    Frank Nimphius did a presentation on this openworld and will be in his book

    ReplyDelete
  15. Thanks man..
    It was very ussesfull

    Regards from México!!!

    ReplyDelete
  16. Hi Edwin,

    Firstly, let me thank you for all your posts...its a life saver.

    I am having an issue with task flows and hoping you would help me resolve it.

    I am having an issue while working with task flow and menu bar. I can make either one of them work at a time but not both.

    jDeveloper version: 11.1.1.5.0

    Created brand new webcenter portal application.
    modified adfc-config.xml to have flow from wildcard -> home.jspx -> todaysContent-flow.xml(contains todaysContent.jspx)
    Added todaysContent-flow.xml as a commandlink on home.jspx
    turn on adf security

    Scenario 1:

    run the applicaion by right clicking on home.jspx and choose "run" (target url will be http://127.0.0.1:7101/WebCenterApp-Portal-context-root/faces/home).

    Behavior:

    Home.jspx is in PageHirarchy with anonymous access removed
    task flow call inside home.jspx works
    home menu tab throws exception given below


    home.jspx is removed from page hirarchy, added to default-navigation-model.xml and security defined in jazn-data.xml (same access rights as it was in pageHirarchy)
    Taskflow call inside home.jspx fails. nothing happenes upon clicking on the link
    hoem menu tab works.


    Scenario 2:

    menu node and task flow links behaves differently if running the application by right clicking portal project adn select run where the run url is http://127.0.0.1:7101/WebCenterApp-Portal-context-root/faces/oracle/webcenter/portalapp/pages/home.jspx

    Behavior:

    Home.jspx is in PageHirarchy with anonymous access removed
    task flow call inside home.jspx fails. nothing happenes upon clicking on the link
    home menu tab throws exception


    home.jspx is removed from page hirarchy, added to default-navigation-model.xml and security defined in jazn-data.xml (same access rights as it was in pageHirarchy)
    Taskflow call fails. clicking on the link sothing happenes
    hoem menu tab works.



    exception:
    LifecycleImpl> <_handleException> ADF_FACES-60098:Faces lifecycle receives unhandled exceptions in phase INVOKE_APPLICATION 5
    javax.faces.el.EvaluationException: oracle.adf.controller.AdfcIllegalArgumentException: oracle.adf.controller.ControllerException: ADFC-0618: View ID 'oracle/webcenter/portalapp/pages/home.jspx' is invalid.
    at org.apache.myfaces.trinidadinternal.taglib.util.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:58)
    at org.apache.myfaces.trinidad.comp..............


    Thanks
    Sudha

    ReplyDelete
  17. Good approach for task management and specification. But what I figured out from this particular post that this kind of task management is possible only for the developers who are aware and concerned about some programming stuff. A generalized personal like me may not be understandable with regards to, all otherwise its a lucrative option for the task management. But like us I think that the better option will be of the usage and deployment of the task management tools specifically. Any thoughts?

    ReplyDelete