Monday, December 10, 2007

JDeveloper 11g and ADF Task Flow Parameters

People probably could think - ADF Task Flow is cool thing, but what it give us in daily life. How it can be applied in our projects? In this post, I will try to answer this question. I will describe two key features, you can start to use ADF Task Flow based on this functionality. ADF Task Flow contain many important things, but those two I think can be used in every project.

First thing - in JDeveloper 10.1.3 there is problem if application contains some 100 or more pages, page flow becomes complicated and diagram is not functional:


Logical solution is to split page flow into separate pieces, but its not so easy in 10g. But, in 11g it becomes very easy - ADF Task Flow provides unbounded and bounded task flows. This means you can split page flow into separate parts and reuse those parts. One rule - called task flow can be only ADF bounded task flow, it can be called from ADF unbounded or bounded task flow. Bounded task flow contains one single entry point and can have many exit points.

Second thing - ADF Task Flow is not limited with only page flow splitting, it allows to pass parameters between separate parts of task flow. So, ADF Task Flow gives much more than just splitting into groups.

Developed sample application - TaskFlowParamaters.zip is based on standard HR schema, Departments and Employees entities. Unbounded task flow contains selectDepartments page and call to separate bounded task flow. Bounded task flow contains employees page and Task Flow Return component, this component allow to return to calling ADF Task Flow.

When I was creating this application, I have used Fusion Web Application (ADF) as a template for developed sample application. Empty unbounded task flow was created automatically - adfc-config.xml. My next step was to create bounded task flow - task-flow-definition.xml:


Bounded task flow will accept parameter - #{pageFlowScope.DepartmentId}, so I have defined it in Input Parameters Definition part:

In Property Inspector for Employees page, in Page Parameters section should be defined mapping between input parameter - #{pageFlowScope.DepartmentId} and paremeter that will be used in Employees page - #{pageFlowScope.departmentId}:


And last thing related to bounded task flow, as Task Flow Return component outcome name I have used word - back.


Unbounded task flow contains selectDepartment page, call for task-flow-definition bounded task flow and navigation between those components. selectDepartment page is used to choose department and with showEmployees Control Flow Case call employees page from separate task flow to display Employees associated with selected department:


One important thing - you should not forget to declare Input Parameter for bounded task flow call component. In Property Inspector, put value - #{pageFlowScope.DepartmentId} for departmentId parameter:


And..., actually we have developed two separate task flows with calls and parameter passing. How it works? Just run selectDepartment.jspx page, select any Department and press Employees button.


When Employees button is pressed, associated af:setActionListener saves #{bindings.DepartmentId.inputValue} into #{pageFlowScope.DepartmentId}. Page from separate task flow is opened with Employees working in selected Department:


Available Back button invokes Task Flow Return component and user is returned to unbounded task flow where selectDepartment page is available.

You may be interested to read my previous post about ADF Task Flows in JDeveloper 11g - ADF Task Flows in JDeveloper 11g.

66 comments:

Jesse said...

In your example you use 'back' as your outcome name for your Task Flow Return Component, but that points to a specific view. What if my bounded task flow can be called from anywhere (i.e. "from action" is *), how do I return to the anonymous?

Andrejus Baranovskis said...

Jesse,

First idea that came to me regarding this:

1. When you navigate to bounded task flow from anywhere, you should store in Managed bean information about from where you navigate.

2. In bounded task flow, you should have several return components.

3. Before calling specific Return component, you can invoke some method and based on information stored in Managed bean, you can decide what exactly Return component you should use.

Hope, this idea will be useful.

Regards,
Andrejus

anshuman said...

How can we pass a managed bean to a task flow?

How to store the information about where I navigated from in a managed bean?

Any pointers

Andrejus Baranovskis said...

Hi,

You can put af:setActionListener on any button that is used to navigate. And set managed bean value from af:setActionListener.

I will develop similar sample application in near future.

Regards,
Andrejus

Anonymous said...

Hi Andrejus,
I have a test case of Passing parameters to a bounded task flow and had a related question.

My requirement is to pass the parameter from one page to other (on a "link clicking"), and the
2nd page should come up as a pop up.

On my base jspx page, I have a link which should invoke this popup. On the base jspx page, I also have a text field, whose value I want to be passed to the pop-up page.
The pop-up page is based on a bounded task flow (dropped in as a region). The bounded task flow takes input parameter and then executes query.
I am trying to use a managed bean to pass the value from base page to the bounded task flow.
Could you tell me how to access the current row/field value in the managed bean, so I can set a public variable. This variable can then be passed as input to the 2nd pop-up page.
So in short, my question is how to pass the current value (from ADF form/page) to Managed bean.

Note - My example, doesn't involve tables, where the handling is a bit different.
I have created Managed Bean on the actionListener for the link on my base page. The Bean is registered under "adfc-config".


Thanks in advance for any pointers,

Andrejus Baranovskis said...

Hi,

If I understood correctly, you can access property in managed bean from ADF form using expression language. For example #{beanName.propertyName}. Where propertyName is setPropertyName(...) method in Managed bean.

Hope this will help.

Regards,
Andrejus

Harikiran said...

Hi Andrejus,
I have a basic question about
the parameters.

1. Why do we need to declare
and set the parameter at
two places - one in the
Task Flow Call Activity
and the other in the
called Bounded Task Flow?

2. After this we set pageFlowScope.DepartmentId to pageFlowScope.departmentId
in the Page parameters.

Why do we need to do this
or can you please explain the concept behind this?

Thanks,
Harikiran

Andrejus Baranovskis said...

Hi Harikiran,

1. Because we need to specify value for parameter in the Task Flow Call activity. But at first, called Bounded Task Flow should declare input parameter.

2. Its just in order to use independent value. To work with copy, but not with original value contained in input parameter.

Hope its more clear.

Regards,
Andrejus

Anonymous said...

Hi andrejus,
I have tried to follow your tutorial, but thereis some place where I lost myself.
The issue is that when I chose the departement and click to see the employees i don´t only see the employees of that derpartment but the all others departments employees too.
can you give me any clue to fix this?
thanks
Rowan

Andrejus Baranovskis said...

Hi Rowan,

I'm not sure, I have tested my sample with TP4, it works fine. You just need to find difference between your app and logic implemented in my sample.

Regards,
Andrejus

Anonymous said...

Hi, Andrejus
Thanks for replying so fast, I have found the diference. Hadn´t implemented in the view object´s sql query the where clause and the bind variable.
About this, I have a little mess in my head with where declare and how to declare and use the bind variables. ¿Is there any book, tutorial, blog, where can find a explanation about this?
Thanks a lot again
Rowan

Andrejus Baranovskis said...

Hi Rowan,

Sure, you can read Section 5.9 in Developer Guide.

Regards,
Andrejus

Avijit said...

Did u have to define an explicit task-flow return parameter for the called task-flow?

Andrejus Baranovskis said...

Hi,

If you have return value, then yes - you need to declare return parameter.

Regards,
Andrejus

Ideas Buster Kqkq said...

Hi,

on your taskflow, I get the warning that the EL token "Department Id" is unknown.

I have TP4 Jdev11.

Fred

sreeja said...

Hi Andrejus,

Thanks for your posts, it helps a lot in understanding the concepts, especially the examples.

If I have to display data from a read-only view (say a list of alert for the logged-in user) should I create a task flow (or) create a JSR 168 portlet (or) an omniportlet. I would like for the alert component to co-exist in a page with other components. I see that there are several ways to do something like that. I would like to know what is the right way and when should I pick one over the other.
Regards,
-Sree

Andrejus Baranovskis said...

Hi,

I think, you can achieve desired behavior with Regions through Task Flow. Functionality will be like portlet type functionality

If you will want to use a 'real' portlet, you will need to have WebCenter licence.

Regards,
Andrej

sreeja said...

Hi Andrej,

Thanks for the quick repsonse.We have WebCenter licence.

In that case should I create a portlet or a taskflow?

Also is it possible for eash task flows to be in it's own separate applications(.jws) and then consumed in one application. If yes, how? The idea is to split the task between developers in an effective way.

Regards,
sree

Andrejus Baranovskis said...

Hi,

You should not compare Task Flow and Portlet, those things are different in nature and are for different things. Task Flow is a controller that can include navigation flow between fragments and pages. Portlet is a source to provide information. With WebCenter you can include Portlets into JSF pages through Task Flows.

You can have Task Flows in separate applications, by packing those Task Flows into ADF Library JAR files you can reuse in one application.

You can find more info in ADF Developer Guide for those things.

Regards,
Andrej

Monica said...

Hi Andrejus,

none of the sample applications' links(ADFTaskFlow.zip, TaskFlowParameters.zip) are accesible. Can you see about that?

Thank you,

Monica

Andrejus Baranovskis said...

Hi,

I'm in the process now of migration to new server.

If you can drop me an email, I will send you those files.

Thanks,
Andrejus

Anonymous said...

Andrejus

Also wanted to know were you able to pass parameters from one task flow to another task flow.

In my example I have

Task Flow 1 (contains 1 or 2 pages)
Task Flow 2 (contains 1 page)

How would you pass a parameter from 1 task flow to another.

Anonymous said...

I followed up the steps from your example. When I click the calling button the navigation to the second page doesn't happen.
Using the debugger (Toggle breakpoint) I get to the next page and then using the Back button I retutn to the first page.
But without breakpoints, the entire flow is executed - without stopping on the second page and immediate return to the first one.
Any idea why this is happening?

Thank you.

Rita said...

Hi Andrejus,

I have a question about using EL with setting the value of a pageFlowScope variable. The value of the variable should be set using the selection on a switcher component.

When the user first enters the taskflow, no value is selected on the swithcer, so I'd like to default a value. The expression that I'm trying to use is:

#{pageFlowScope.searchFor eq null? facet1 : (#{pageFlowScope.searchFor})}

but this doesn't seem to be syntactically correct. What would the correct expression be?

Thanks,
Rita

MUCAHID USLU said...

also look at here to read similar posts;
http://adf.webloji.net

Will said...

Andrejus

Thanks for the post, its quite useful as there is still quite a learning curve for me regarding ADF

Question for you though:

your example has 2 task flows passing departmentID from one to the other to display the list of employees for selected dept.

Can this be done however within a single task flow, with 2 view activities, passing departmentID from one view activity to the other, if so how? .. what is best practice here?

I have seen a similar example of the above with a single task flow however currently its not making much sense.

Thanks

Will

Andrejus Baranovskis said...

Hi,

I recommend to use different Task Flows for those cases, when two pages belong to different Use Cases.

If you want to pass parameter between two pages in the same Task Flow, you can use af:setActionListener to store value in processScope and access this value from processScope in second page.

Regards,
Andrejus

Anonymous said...

HI,

When we are trying to pass the value from a page to the task flow(dropped as a region on the page) the task flow parameter is never getting set. its always null.
this how we have defined the parameter on the task flow
name="param" value="{pageFlowScope.param}".
And we try to access this "param"
in the .jsff page on the task flow using "{pageFlowScope.param}" its null.


on home page the value we want to pass is also stored in "{pageFlowScope.param}".

Please let me know the if I am missing something.

Thanks,
Devi

Andrejus Baranovskis said...

Hi,

Try several things, first try to pass constant value from parent page, instead of getting it from PageFlowScope. May be value is null there already. Second, try to set refresh ifNeeded on region declaration in parent Page Def.

Regards,
Andrejus

Anonymous said...

Thanks a LOT :)
it worked!! we set the refresh ifneeded in the page definition file( where task flow is dropped as a region )

Regards,
Devi

Jesse said...

This may be a silly response to Devi, but you are actually using the parameter on your page as "#{pageFlowScope.param}", correct?

Anonymous said...

Hi Andrejus,

I have tried the same scenario that u have explained, but with different tables like Territories and Resources.First page displays territories and call to a bounded taskflow which has resources display.Territoryversionid is FK in Resources table.I have created EOs, VOs, viewlinks. As I could observe, in your example, employees.jspx pagedef has executewithparams, but in my case, in the pagedef of Resourcesdisplay.jspx, when I select ResoucesVOIterator while adding an action in the bindings section, I can see only execute method available, not executewithparams. what could be the reason for this method not being shown up ?

Kindly reply please.

thanks
Sowjanya

Andrejus Baranovskis said...

Hi,

You should check if you have defined Bind Variables in your View Object.

Regards,
Andrejus

Jolarpet said...

Hi Andrejus,

My current requirment & the issue exctly same like your posting. I did exactly the same what you did..But still I cant carry forward the userID from one page to another page where I am using 2 diffrent task-flows..each task flow in each page....But my first task flow contains 2 fragments and second flow contains one...I would like to pass the userID from the 2nd fragment of first flow to second page..

Any help please... also one another problem.. I cant able to set my managed bean scope anything else other than request...why so?


UserSearch
edu.syr.oim.backing.app.UserSearch
request



thanks
logu

Anonymous said...

I m showing some data vlue using output text El.Can you please tell me which property of output text converts that value in Capital letter

Shilpa said...

Hi,
I have a list page which also has a built in POPup detail page. Detail page has a dropdown field and the same field is binded on to the list page like shown below:

table value="#{bindings.addressForBusiness.collectionModel}"
var="row" id="table1"
rows="#{bindings.addressForBusiness.rangeSize}"
rowSelection="multiple" columnStretching="last"
binding="#{businessCreditAddressTableBean.currentTable}"
selectionListener="#{businessCreditAddressTableBean.rowSelectionChanged}">
........



.......


...................................
..................................



...............



......................


Now the problem is, on the table i should see the display value not the coded value.
for exmaple : code value="US" displayValue = " United States"

I tried changing the output expression
<af:outputText value="#{row.bindings.addressType.inputValue}" but of no use.

Any idea?

jayanti srivastava said...

Hi..
i am passing the selected value from table to next page and try to set the data in form
i am using pageFlowScope.result
but when i try to set the value in input text box like-
pageFlowScope.result._CUSNO
it show error property not found
but the value exist in result

jayanti srivastava said...

Hi.

i am working on oracle JDeveloper 11g and try to consume a remote WSDL service, i have created an adf readonly table with the binding of datacontrol's method it is working fine..
now i want to pass the selected row value on the next page where i will show the form to update the selected row's records.
for this i am using setpropertyListener on the button of table page (.jspx page)
and on next page(also .jspx page) i have set the selected row value in pageFlowScope.result
when i am trying to get the value of "pageFlowScope.result" it shows the value like-

[{Return=[{_RETURNEDROW=[{_XWF0V0=0.00, _XWGFVA=0.00, _XWASDT=2010-05-20, _XWGGVA=14.00, _XWBNCD=AG, _XWGIVA=0.00, _XWF1V0=0.00, _XWF0VA=0.00, _XWF3VA=0.00, _XWG4TX=Customer ACC10, _XWGDVA=0.00, _XWBPD0=2010-05-15, _XWIDV0=0.00, _DSDCDE=AU, _XWF1VA=0.00, _XWBAD0=2010-05-14, _XWF2VA=0.00, _XWF6VA=0.00, _XWGEVA=0.00, _XWF4VA=0.00, _XWE0NB=0, _XWBCCD=ACC10, _XWJUN0=0, _XWBQDT=2010-05-08, _XWARDT=2010-05-19, _PERSON=MTT, _XWGAVA=0.00, _XWGCVA=0.00, _CUSNO=1, _XWGBVA=0.00}], returnValue=11, _ERROROBJECT=[{_SQL_CODE=0, _SQL_STATE=00000}]}]}]

but when i am trying to get the internal value of pageFlowScope.result through-
pageFlowScope.result.Return._RETURNEDROW._CUSNO
it show me error
oracle.adf.model.adapter.dataformat.XMLHandler$DataCollection not have a property "Return"
or
pageFlowScope.result._RETURNEDROW._CUSNO
it show me error
oracle.adf.model.adapter.dataformat.XMLHandler$DataCollection not have a proerty "_RETURNEDROW"

so plz guide me how can i get the value of pageFlowScope.result

please help, its urgent


regards
Jayant

Lakshmi said...

Hi Andrejus,

I created a BPM application which has a human task in the BPM flow. This task takes a parameter (requestor id) and sends an email to this requestor to submit a form.Data enetered should be saved in the database.
How can i achieve this?

Thanks,
Lakshmi.

Anonymous said...

Thanks for all your work.

Maybe this is too basic a question, but I can't get around it.
1. Why is it at all possible to refer to pageFlowScope.DepartmentId? I though that we had to have a managed bean to be able to give it at scope and refer to it.
2. Is this a reference to an existing attribute, or is a variable "automagically" created for us?
Best regards Niels

Andrejus Baranovskis said...

Thats right, its automatically created.

Andrejus

Anonymous said...

Hi Andrejus

I test this example and it worked fine.
Now i have a different situation, i have a combo for department's name in my first page and based on selected department value i want to fetch that particular department record in my next page.

How can i accomplish that by passing parameters to a bounded task flow ?

Andrejus Baranovskis said...

Hi,

I suppose you can get selected value from choice list and pass it as task flow parameter?

Andrejus

Anonymous said...

Hi ,
Yes i tried exactly the same and its working. I have tried this using fusion application. But when i try to do same using oracle webcenter portal application its not working .
These are the steps i followed .
1) Place a combo for department names in home page.

2) create a bounded task flow exactly in the same way as explained in your blog. i.e
employeeView -------> return

3) then in adfc-config.xml file, i drag home.jspx which in turns call above bounded task flow as a result of case "seeDatail"

when i run my application, select a department name from combo and click view detail button, it redirects me to the login page. When i login back to my application, it gives me error like

Caused by: oracle.adf.controller.security.AuthorizationException: ADFC-0619: Authorization check failed: '/WEB-INF/coursefinder-flow-definition.xml#coursefinder-flow-definition' 'VIEW'.

Kindly help me out. Thanks in advance.
Sadia

Andrejus Baranovskis said...

Hi,

WebCenter application is enabled with ADF Security by default. You need to define security permission for that task flow.

Andrejus

Anonymous said...

Hi
Kindly guide me how to define security permission for my task flow.

Sadia

Andrejus Baranovskis said...

Please read this article: http://andrejusb.blogspot.com/2011/04/practical-guide-for-oracle-webcenter.html

Andrejus

Anonymous said...

Hi

Thanks Andrejus.

Your artical really solved my problem.

I need one more help. I want to change the default username and password i-e weblogic and weblogic1 to my own. Kindly tell me how to do that ?

Thanks for all hour support and help

Sadia

Anonymous said...

Hi Andrejus,

MY use case is when I click on link one of my page corresponding to an employee name its should take me to another page which shows the corresponding employee detail page.The another page is present in a separate task flow.
I tried working according to the steps you mentioned in your article. But what I am getting is a blank employee detail page. Can you let me know where might be the problem.
Also how can executewithparams can be used in this situation ,if it can be used?

Andrejus Baranovskis said...

In your case it will be enough to drag and drop same instance of VO, on detail page. ADF will keep in synch both pages automatically for you.

Andrejus

Devi said...

Hi Andrejus,

Your blog helped me many times. I am struck with a problem since 2 days.

I have a menu bar from which I will get various outcomes such as "abc","def" and "xyz". For all those menu items I have a single action and action listener method. I am setting the outcome value in session scoped managed bean property in action listener based on source component id.

In adfc-config.xml I need to navigate to a single bounded task flow for all the above outcomes. I gave #{abcBean.flowoutcomeproperty} in "From Outcome" of control flow case and I tried giving the same in "From Action" also. I gave session scoped managed bean's action method also in "From Action". But nothing worked. It's not at all going to the bounded task flow

I don't want to give multiple control-flow-cases to the bounded task flow.

Is there any way that I can give multiple conditions to navigate to bounded task flow without having multiple control flow cases

Devi said...

Hi Andrejus,

I forgot to tell you that specifying all the outcomes as shown below in "If" behavior of control flow case works. But I don't want to specify like this.

Instead I want to navigate to task flow based on some property value or a return value from a method of a managed bean.

#{abcBean.flowoutcomeproperty=='abc' || abcBean.flowoutcomeproperty=='def' || abcBean.flowoutcomeproperty=='xyz'}

Andrejus Baranovskis said...

I will test this and let you know. Soon.

Andrejus

Andrejus Baranovskis said...

May be this helps: http://andrejusb.blogspot.com/2011/09/programmatic-adf-task-flow-router.html

Andrejus

Devi said...

Hi Andrejus,

Thanks for taking your time to come up with a solution of custom router. That would really help.

Still I have a problem here. How would you come to this unbounded task flow from adfc-config.xml. We have a global menu in a page template which will be used by all the pages and we will get those outcomes from any page. So I need to define those outcomes in adfc-config.xml only.

The only options I am seeing to define in adf-config.xml are
1)to define multiple outcomes in If condition of control flow case
(or)
2)defining different task flows/pages for each menu item and a different contorl flow case for each menu item

Please let me know if u have any other idea.

Anonymous said...

Hi Andrejus,

When I add the taskflow to the catalog, for use with the composer. How could I include default values ​​for taskflow parameters?

Andrejus Baranovskis said...

This doesnt work, is a bug. See this post - http://andrejusb.blogspot.com/2011/05/initializing-adf-task-flow-parameters.html

Andrejus

Muhammad Nasir said...

Hi Andrejus
I followed your post in Jdeveloper R2
but when i try to call a bounded task flow from an unbounded task flow i am getting this error.

"An unbounded task-flow refer to pages, and therefore cannot call bounded task flow "task-flow-definition" that refer to page fragments"
Please Help me i will be very thankful to you.

Andrejus Baranovskis said...

Yes, you cant call task flow with fragments from unbounded task flow. you must wrap it with task flow containing pages.

Andrejus

Cosmas Dedy said...

Hello Andrejus..

I found a problem...
I add ADF Parameter Form, from drag DataControl to jsff page, i fill data, then when I klik OK..
my JDeveloper, can't be use, like no responding

what should I do to solve the problem

regards
Cosmas

Saurav Kumar said...

is it possible to pass parameters to unbounded taskflow, i am calling unbounded taskflow using command link. and i need to pass some page parametes. how do i achieve this? I put it in pageFlowScope also but pageFlowScope itself is not available to unbounded taskflow e.g. adfc-config.xml

I tried few other option, like put it in request or session but when we call the url, parameters are not available.

Andrejus Baranovskis said...

Unbounded task flow is not supposed to get parameters.

Andrejus

Anonymous said...

Hi,

I really need your help. I’m trying to build a simple JSF portlet.

I watch your screencasts and do exactly the same steps you do, but when comes the step that I need to right click the JSF page to “create portlet entry”, the option is not there. The dialog simply doesn’t have the option. Do I need to install anything in the Jdev to make this option available?

I searched all over the internet and I didn’t find a solution for this problem.

I’m working with the new Jdeveloper 11g (production).

Please Answer me.

Anonymous said...

Hi Andrejus,

How to add invoke action in page definition file in 12c .The invokeAction executable has been deprecated in Oracle ADF release 11.1.1.7.1.

Andrejus Baranovskis said...

To use invokeAction is considered bad practice now. You should use ADF Task Flow Method Call instead.

Andrejus

Anonymous said...

Thank you Andrejus

Regards,
Mridu