Thursday, August 19, 2010

Add a SelectOneChoice List to a non-database item

The problem I was faced with was to move a set of records from one "master" record to another "master" record. For example move all employees from one department to another department. The method is simple enough, select all the employee records and change the Foreign Key to point to the new department, the Foreign key is the Primary key of the master record and is a Database generated sequence number.

In forms I would have used a non-database drop-down list item displaying a list of departments with the description displayed in the list and the Primary key as the value selected allowing the user to make the selection easily.

To achieve the same result in my ADF application I devised this approach.
Step 1


       Create a Read-Only View of the table the list will be based on i.e. Departments

       Go to the bindings Tab of the page that will contain the drop down list.


       Select the Green + icon in the bindings section and select the tree binding from the list.


                        This will present you with the Create Tree Binding Screen


                        In the Root Data Source Select Add and choose the read only view you created earlier.


      Select the Green + icon next to the Tree Level Rules and choose AddRule, this will create a rule entry for the top-level View Object.


Shuttle both of the attributes from the available list to the display list if not already there.
Press OK. 
We have now created our List of Values. 


Step 2
The next step is to add this LOV to our SelectOneChoice list.


Drop a SelectOneChoice component on the page and click Finish without any configuration.
In the Structure window remove the f:selectitems component from the SelectOneChoice.


On the right-click menu choose Insert inside af:selectOneChoice component, ADF faces - For each.


Select the af:forEach  component and in the properties window we need to set the Items property to the tree binding-rangeSet method entry.


Select the arrow next to the Items Property and in the Expression Builder choose

  • bindings
  • <<read only view name.>>
  • rangeSet

the result should be similar to #{bindings.ViewDept1.rangeSet}
Set the Var property to be lov. This defines the name of the variable at runtime that is used to populate the list. 


Select the af: forEach component and insert inside a JSF Core : Select Item (not Select Items).


In the Structure Window select the f: selectItem component and edit its label and value properties.


label = #{lov.DepartmentName}
value= #{lov.DepartmentPrimaryKey}

We have now designed our Drop Down List.


If we run the page we can now select from our list. 


The last thing we have to do is to set the Value item in the properties of the SelectOneChoice field. This will be the field that will hold the "value" of the SelectOneChoice field.


I am using a Number variable deptPrimaryKey in a backing bean {backingbeanscope.backing_dept.deptPrimarykey} but equally I could also set it to a parameter #{pageFlowScope.deptPrimaryKey} if passing control to another page.


Now as you select the Department in the drop down list the value is available in the backing bean or pageFlowScope parameter. 










Sunday, August 15, 2010

Pass a parameter to a Page in ADF and execute a query.

Having worked with Oracle Forms for 20 years I have become accustomed to developing forms and applications in a certain manner. My progression to Jdeveloper ADF has meant that a lot that I took for granted about how to build forms and add functionality to them is no longer the case and I must use different methods to achieve the desired result.

To execute a query with a passed parameter in forms I would use a pre-query trigger to copy the parameter to the requisite field and then execute the query.

In ADF I can use the ExecuteWithParameters operation but only if I have first created the view with a bind-variable that I intend to use. So far OK.

The standard way we are instructed to do this is to add an action binding in the page definition to the ExecuteWithParameters operation, set the parameter we are going to use and use an invokeAction in the executables to bind to the action and fire on page-loading.

I am using a Bounded task flow with page fragments. The page I am calling can be called from numerous points in the Bounded task flow, each point setting a parameter (in my case {pageFlowScope.<>>}.
No matter which way I passed the parameter to the ExecuteWithParameters  action it failed to recognise or use the parameter, executing with a null value or whatever default value I set for the bind-variable.

The solution, dispense with the ExecuteWithparameters and invokeAction on the page and use a method call bound to executeWithParameters call on the page instead. It works perfectly.

I'm not sure if this is a bug or just something I was doing but I shall use the Method Call in my bounded taskflow in future.