Pre filtering table data
I've recently spent a few rough weeks doing something I would consider rather trivial. Unfortunately, the task of actually doing it was harder than I had anticipated. The documentation on how to accomplish this is somewhat sparse at best so I've decided it was a perfect opportunity for an entry because this seems like a very common scenario.
The scenario is this.
I am a developer and have a requirement to display a table on a JSP page. Easy enough to do if you have a pre-defined DC (Data Control) with a VO (View Object) to drag over an iterator to a jsp page. What if you want that data already filtered? You can drag over a query from the 'Operations' folder under the selected VO. The problem is, this wants to create a query form or some other visual element that THEN filters the table. What if you want the data already filtered by the time the page even renders. This seems like a very common requirment yet is not 'out of the box' behavior. Rarely does one want a SELECT * FROM tableName without some sort of WHERE clause to filter the data. Many times we want to pre filter this data before it reaches the end user without them entering the data themselves.
In my example, I pull the data from a field in an object in pageFlowScope. pageFlowScope is a scope, similiar to session scope. It is only within the lifecycle of a task flow. I wish they had called it taskFlowScope. It took me a little while, and some research, before I realized that pageFlowScope was task flow scope. It sounds too much like pageContext scope to me personally and was a little confusing.
Apparently there was an easier way to do this in previous releases. I am using 11g and always have been. I've never used a previous version. It is a bit more difficult now because they wanted to split up the logic of the task logically into more of an MVC pattern instead of the previous way of doing things, which stuck too much at the View layer.
Here is what we are trying to accomplish;
SELECT ..... FROM tableName WHERE fieldName = ?
We want to set ? to a pageFlowScoped variable BEFORE we even reach our page so the table is pre-filtered.
The first place to accomplish this is in the Model layer. We used ADF BC components. These are the components that become your DataControls. You should have already created a VO for the table in question.
Within the VO we need to add the WHERE clause. To do this, open the VO and you should be under the overview tab. Click the 'Query' link option from the left hand side of the VO. Then click the '+' at the bottom right under the 'View Criteria' section.

This is the next screen you'll see. Give your criteria a name and click the 'Add Item' button.

Choose the 'Attribute', or field, you wish to add to your WHERE clause. Then choose the 'Operator'. In our case we want the 'Equal to'.

Now we need to define a variable that will our our data to be passed into the query. This is the value that will go into the '?' in our SQL above. Click the 'Operand' and choose 'Bind Variable'. Now we have to create our bind variable. To do this, click the '+'.

Give your variable a logical name. I also use a literal. When the query is finally called, whatever variable you bound to this bind variable will be passed as a literal. You can use expression, but I'm not sure why. I guess if you want it evaluated the same way every time later. Since I'm using a literal, I give a default value. I also chose to make this NOT required. The reason is, you will get errors if this VO is ever referenced and your bind variable is not set. Click 'Ok'.

I left the validation optional, for the same reasons given in the previous paragraph. This yields the following SQL. Notice that it has an OR condition that allows NULLs which removes any errors from just trying to use the VO without the bind variable being set. Click 'Ok' and save your VO.

Notice now that you can see your newly created criteria and bind variable.

Now open the AM (ApplicationModule) for this VO. We need to set it so that this criteria runs when anyone tries to access this VO. In the 'Overview' tab click the 'Data Model' link on the left hand side. Choose the Data Model with the newly created criteria filter in it. In my case it is called 'Addressee1'. Click the 'Edit' button.

Choose your filter criteria and then click the '>' or add button to add it to the list of criteria selected to run on this VO. Notice the parameter added to the 'Bind Parameter Values' section. Click 'Ok'.

Now save and build your new AM.
Those were the steps for the Model layer.
Now for the controller layer.
We need to set the variable before we display our VO as a table in the JSP, otherwise, it will show all data, because the bind variable will be set to null, which is acceptable because we set it as optional at the model layer.
The way that was recommended that I do this was to add an activity to a task flow that gets called before our JSP to display the data.
If you don't already have a task flow, create one. You should have your VO as part of a data control listed on JDeveloper's left side (typically) under 'Data Controls'. Click on 'ExecWithParams' Operation and drag it onto your task flow. This is the task that will set the parameter. You may notice the parameter nested within the 'ExecWithParams' operation.

You should now see the 'Edit Action Bindings' dialog. Most of it should be filled in correctly for you. Here you may want to change the option, if its mandatory or not. It is within this screen where you finally set the variable that maps to the '?' in our WHERE clause in our SQL for our base requirement.

Click the down arrow in the 'Value' and choose 'Show EL Expression Builder'. Choose the piece of data you wish to bind to the criteria bind variable. Mine is in a pageFlowScope variable. There is a problem with the latest GA release that does not allow you to browse to the variable even though it is within scope. It is fixed already for the next relase. You'll just havet to enter it by hand. Click 'Ok'.

From the 'Edit ActionBindings' screen click 'Ok'. You should now see the action available on your task flow. It will also create a data binding page for your task flow/activity if one was not already created. To view the bindings file, just right click on your 'ExecWithParams' activity and choose 'Go to Page Definition'. There you will see, under structure on JDeveloper's lower left side, the ExecuteWithParams action along with the bind variable as a NamedData node under it.
Now just connect this activity however you want in your task flow. The key thing is, of course, it has to occur BEFORE you get to your JSP page with the filtered table data. Here you can see an initialization action that occurs first in my task flow. This sets the variable in my page flow scoped object that is passed into my VO bind variable. The next is the activity we just generated and performs the filtering. Notice it has a warning. It says 'ExecuteWithParams' not found even though it created it. You can see in the bindings file it is there. Just ignore this warning. The next page is a JSP page. The page after that, the second one in the train, is the JSP page that displays the newly filtered data.

The JSP page is nothing special. I just drug the VO over to the page and said make table from the options it gave me.
That's it. Wshew.
p>