During one of the bi-weekly ADF knowledge sessions I organized at a customer one of the questions that popped up was how the inputparameters on taskflows worked. People got really confused with what to enter and where. In this blog post I’d like to outline the basics of what to enter and where to do so.
In ADF taskflows are used to build functionality, as the name implies, per task. Examples are a taskflow for creating a new customer, filling out an order, etc. If build properly these taskflows can run independently and will be reusable in different parts of the application. One of the ways to achieve this is to use input parameters if you need to have input from outside your own little taskflow. Because you don’t have any references to objects outside your own flow you ensure that your taskflow remains reusable in different places.
Lets take the following taskflow as an example for the rest of this blog post.
We have a single taskflow for creating, editing and showing a single employee. As default activity we have a switcher which evaluates an inputparameter and based on it’s value it will return either toDetails or toCreate as the outcome. The default outcome in this case points to an error page. This ensures that only the expressions we expect to be true continue with our flow and that the unexpected goes to the error page. The CreateEmployee activity makes sure the new employee gets created before we go to the EmployeeDetails page. The FindEmployee activity does an executeQueryWithParams with another inputparameter to ensure we are viewing the requested employee. Within the EmployeeDetails page we again look at an inputparameter to see if we need to render our details readonly.
Before we go on lets take a look at where we need to define the input parameters for our taskflow.
If you click on the Overview (A) tab at the bottom of your taskflow and then on Parameters tab at the side you will see two tables. The bottom one is for Return Value Definitions and important for us at the top Input Parameter Definitions. To add new input parameters to your taskflow hit the green plus to get a new row. There are four columns you can enter values in. The name of your parameter. The java Class (C) of your parameter. This column isn’t mandatory you can leave it empty if you want to. However it does improve the readability of your taskflow when you or someone else looks at it later on. JDeveloper defaults the next column Value (B) to an EL expression pointing to pageFlowScope.[nameOfYourParameter]. Lastly there is the required column. If your taskflow cannot start without the consumer supplying that parameter check the box here.
A lot of the confusion comes into play with the Value column (B). First there is the name of the column: Value. And yes I have seen people fill in the actual value of the input parameter here which doesn’t work. The column should definitely be renamed to something like: Value will be stored at. Which is what this column does. It will save the value of your input parameter at the location you enter. Secondly the default value is: pageFlowScope.[nameOfYourParameter]. If your not careful both the location where your inputparameter is stored as well as the supplied value and references you make to that parameter within your taskflow will all be called the same. Which doesn’t help to understand how it all connects. Not to mention the fact that not everyone realizes every taskflow has it’s own pageFlowScope. All in all the column name and the default entry are adding to the confusion.
In my opinion it’s often better to store your input parameters in a managed bean. All but the simplest taskflow will require a bean to hold some state so generally there is a bean anyway and it will give you several additional benefits.
- A place to put some proper documentation.
- Parameter validation. If you use pageFlowScope it doesn’t matter what you put into it because it’s just another untyped Map. So when you use a bean it not only matters what gets put into it you have a place to check if it meets certain criteria in an easy way.
- Parameter initialization. As everyone knows having an initial/default value for a parameter can be sort of handy at times. A bean provides you a place where you can do just that.
The only thing left now is to (re)use our taskflow in some other places. In ADF there are, simply speaking, two ways to use a taskflow. The first is as a region on another page or fragment. The second is as taskflow call activity on another taskflow. Lets take a look at the first option embedded as a region on another page or fragment.
We have a page with a department table. If we select a record we want to display the manager of that department below the table, so we drag and drop our taskflow below the table. It will then ask us if we want a normal region or a dynamic region. Choose region and the following popup comes up. JDeveloper has detected our taskflow has inputparameters and shows us the popup so we can fill in the values. Here the value column is what it says. The actual value we want to give to our inputparameter, so for employeeId we set the value to an EL expression that will get us the ManagerId of the currently selected row. The taskflowMode inputparameter gets the String value READONLY because we only want to display the manager.
Now if you hit OK the popup dissapears. The page only shows a region tag with a value pointing to a binding. It saved all information in the pagedefinition. You can see it if you go to the pagedefinition; select the regionbinding and hit the edit pencil or look at property inspector. One important thing to note here is that if you want your region to refresh like we do in our example you NEED to set the refresh condition to ifNeeded. This will make sure that if there is a change in the value of a parameter your taskflow will be refreshed with the new value.
Now lets look at the second option, calling our taskflow from another taskflow with a taskflow call activity.
We have a taskflow with a page that shows a department table and below that a form with the details of the currently selected department which can be edited. From that page it should also be possible to go to our taskflow to edit the manager, however while editing the manager the department details should be replaced. So we have put a button in the table which lets you go to our taskflow to edit the manager of that department. The taskflow itself is simple as well. Just drag and drop our employeeflow onto the other taskflow and it will create a Task Flow Call Activity. Now we create a control flow case from our View Activity to the taskflow call so we can actually navigate there. If you select the Task Flow Call activity employeeFlow you can see and fill in the inputparameters.
And that wraps it up. Taskflows can be an intimidating beast when you first start, but take your time to get know them and they’ll soon become your best friend.
A demo application is included and can be viewed here: 201401_TaskflowInputparametersExample.
It uses JDeveloper 22.214.171.124 and a local XE database with the hr schema.