Wednesday, 24 September 2014

list of values hierarchy in af:query

The requirement is to provide ability to search locations by counties from HR schema using af:query component. Query panel should contain list of values for countries attribute which is filtered by regions list of values field. In other words - af:query contain regions select one choice UI component which influences on countries component.

As prerequisits please create three readonly view objects based od REGIONS, COUNTRIES and LOCATIONS tables. In the application module's data model put only the LocationsView.


In CountriesView please create view criteria on RegionId attribute. Ignore null values not needed here. Bind variable is created using the wizard, so don't change it.


Please open LocationsView and add there new transient attribute called (in this example) RegionId.


Now go to View Accessors section. Please add there CountriesView and RegionsView as accessors. Additionaly please select the CountriesView1 (default name) and click on the pencil icon. Apply view criterias there and, it is important, fulfill RegionIdVar value with RegionId. It doesn't mean it'll put it as a string but it'll evaluate Groove there - it'll get RegionId transient attribute.


For CountryId and RegionId in Attributes tab please create list of values. Screenshots for begginers:



Do similar to RegionId attribute and then click pencil icon to edit it. Select Control Hints from the menu and set Auto Submit to true.


You can use implicit view criteria to develope proof of concept but it'll add view criterias and then drag and drop them on the page as query panel with table.


Running example:


What else could be done - as you can see RegionId is not used in the query, it's transient. To make it useful, please read about SQL tricks in view criterias post and try to adapt it here :)

Wednesday, 17 September 2014

TaskFlow Return Value example (communication between two task flows)

One of the interesting patterns regarding communication between task flows are return value parameters. It is possible to expose more than one return parameter. Also it is possible not to use them at all. OK, prerequisites are two task flows, one will be named innerTaskFlow and the second one outerTaskFlow. First one should contain two activities, one will be the view and the second will call an action in the parent (outer) task flow.




It should also define an output parameter. For example purposes I've defined it as a String. EL expression  in the Value column points to the attribute's value.



The page itself is as plain as it could be. I've decided to put the value directly (and implicitly) into pageFlowScope memory.



As for outerTaskFlow, it consumes innerTaskFlow as default activity. In its Property Inspector I've defined what needs to be done with innerTaskFlow output attribute - put it into current pageFlowScope.




The page is just to proof that value is properly consumed there. I've defined also back flow to allow you check it few times :)


Please create also test JSPX page to run and verify the example (drag and drop outerTaskFlow on it).

The question you may have is "why do I need to assign the pageFlowScope.varName1 to pageFlowScope.varName2 instead of using pageFlowScope.varName1 in both task flows?". To answer that please review (once again, I suppose :)) ADF memory scopes.


(source: http://docs.oracle.com/cd/E24382_01/web.1112/e16182/img/adf_scopes3.png)


The pageFlowScope from innerTaskFlow is something different than pageFlowScope in outerTaskFlow. There is another way to interact between two task flows - bean injection. More or less you could pass outerTaskFlow pageFlowScope as an input parameter to innerTaskFlow:


And after that in the innerTaskFlow view activity call #{pageFlowScope.parent.retVal}. But about bean injections I'll talk about in the future :)

Thursday, 11 September 2014

af:query operators

One of few tricks that I'd like do talk about refers to advanced mode of af:query component. Each queryable attribute (property of an attribute at view object level) can be a part of SQL where clause. In basic mode framework builds the query with default equal operator. In advanced mode user can pick an operator from the list. By default we've got 14 operators which, for plain business user, may sounds silly. For example how to compare surnames using "Greater than" operator. What do i get as a result?

To cut the list of such "silly" operators you need to go to the view objects source. It is not possible to acheive it using wizards. The trick requires to add CompOper sub-nodes to the specified queryable ViewAttribute with additional proper values.



Each CompOper node has several flags. ToDo flag with -1 value means that the operator will be removed from the list. I've removed most of the "silly" operators. I've also defined one "less-silly" operator just to check if adding works as nice as removing. In the source code screenshot it's the node with ToDo="1".

Test page is build as drag&drop All Queriable Attributes from iterator's Named Criteria package in the Data Control to the Design section as ADF Query Panel with Table. Run the example:



Plain and simple, isn't it? Where to get more information about it? First place that you need to visit is the Fusion Middleware Developer's Guide documentation itself on http://docs.oracle.com/cd/E14571_01/web.1111/b31974/web_search_bc.htm#ADFFD2457. And how to solve operators' names? Not need to guess, they're described in oracle.jbo.common.JboCompOper table of Java API of ADF Model that can be found on http://docs.oracle.com/cd/E15051_01/apirefs.1111/e10653/constant-values.html.

Wednesday, 3 September 2014

multiple master - one detail relationship in BC4J

In most of the cases the real life structures can be simplified to one master with 0 to N details. Each detail can be a treated as a master to other details. But there are cases when the cardinality changes 180 degrees. For the first time it sounds strange to have multiple master tables that influences on the detail one but... think about plane flights. The requirement is to display two lists of airports and display flights between them. For performance point of view destination list will be dependent on the departure one. Another example, we would like to filter employees basing on both departments and jobs lists simultanously. Lookups and employees should be displayed as tables. Is it possible in ADF? It is, and it doesn't need a lot of coding! I belive you've already got HR example scheme with you.

We need to have view objects departments, jobs and employees tables (read only will be enough). Also there should be view links between them (on EMP_DEPT_FK and EMP_JOB_FK foreign keys). Model project structure should be similar to this:


Now let us focus more on Application Module Data Model definition. Please click on DepartmentsView and rename New View Instance to Departments and move it right.


Select EmployeesView via EmpDeptFkLink, rename it to Employees and move it as detail of Depatrments instance.


Select JobsView, rename it to Jobs and move it to the right. Now please select EmployeesView via EmpJobFkLink and rename it, the tricky part, to Employees.



An error? Not exactly, it will be the same instance for both Jobs and Departments. So, please click Yes. Data Model and AppModuleDataControl should look like this:



Last thing to do is to prepare test page for it. Please expand Departments node in the AppModuleDataControl, select Employees iterator and drag it to the test page as ADF Master Table, Detail Table.


Then drag and drop Jobs iterator on the test page. Select table with employees and add partial trigger to the Jobs table (partial trigger to Departments table should already be there). My page structure after simple layout rework is:


And if somebody is interested in the page definition:



The running example: