Technology: ADF11g
Developed in: JDeveloper 11.1.1.3.0
Browsers tested: Firefox 3.6.13 and Internet explorer 7 (7.0.6002.18005)
Used database schema: HR
Used tables: EMPLOYEES, DEPARTMENTS, LOCATIONS
Summary
In this blog we create ‘standard’ LOVs and a custom LOV. A custom LOV is in the end created because of some disadvantages I see in the standard LOVs like:- Possibility to resize LOV popup
- All columns in the LOV table have the same width
Standard LOV
First we’ll create a standard LOV. With a standard LOV I mean a LOV defined in the view object as a List of Values on the ID column.For this example the EMPLOYEES table is used with LOVs on the ManagerId attribute and DepartmentId attribute (the DepartmentId LOV is created in the next paragraph).
Model layer
Create the following entities:Entity name | Based on table of HR schema | Customizations made |
---|---|---|
Employee | EMPLOYEES | None |
Create the following view objects:
View object name | Based on entities | Customizations made |
---|---|---|
EmployeesLovView | Employee | None |
ManagersView | Employee | None |
Open the EmployeesLovView and go to the ManagerId attribute. Add a List of Values:
The ManagersView is the view accessor (renamed to ManagersAccessor), the view attribute is the ManagerId and the list attribute the EmployeeId. On the UI Hints tab set the following properties:
Property | Value |
---|---|
Default List Type | Input Text with List of Values |
Display Attributes | Select all |
List Search | <No Search> |
"Include No Selection" Item | Deselect all |
Create an application module HrAppModule which exposes the EmployeesView.
Page
A form page is created by drag and drop from the Data Controls. The form is dropped as ADF Form only the EmployeeId, FirstName, LastName, JobId and ManagerId items are displayed. All items except ManagerId are displayed as Output text with label. ManagerId is displayed as input list of values:Select Include Navigation Controls and Include Submit Button.
If we run this page it looks like this:
The opened popup contains scrollbars and is not resizable. When a row is selected (by double click or by using the OK button) the ID of the employee is copied to the ManagerId attribute.
Extended standard LOV
The first thing I thing needs to be changed is that the ManagerId is displayed. I think the managers name is a more desirable field to see (of course in the database the manager ID should be filled).To create an example to show how this can be achieved another LOV is created for the department. In the screen we’ll display the department name and the LOV is on this name but the department ID is filled as well (to prove this the department ID will be made visible but read only in the page).
Model layer
Create the following entities:Entity name | Based on table of HR schema | Customizations made |
---|---|---|
Department | DEPARTMENTS | None |
Location | LOCATIONS | None |
A FK association will be created at the same time between Department and Location.
Create the following view objects:
View object name | Based on entities | Customizations made |
---|---|---|
DepartmentsLocationView | Department Location |
None |
Change the EmployeesLovView:
- Add a transient attribute DepartmentLovName of type String
- Make the attribute always updatable
- Check the Mapped to Column or SQL checkbox
- Fill the expression of the Query Column:
- (SELECT department_name FROM departments WHERE department_id = Employee.department_id)
- Set the type of the Query Column to VARCHAR2(30)
The last 3 steps are necessary to display the current department name when the page is opened.
- Add a List of Values to the DepartmentLovName attribute:
The DepartmentsLocationView is the view accessor (renamed to DepartmentsLocationAccessor), the view attribute is the DepartmenLovName and the list attribute the DepartmentName.
Add a second return value from DepartmentId to DepartmentId:
On the UI Hints tab set the following properties:
Property | Value |
---|---|
Default List Type | Input Text with List of Values |
Display Attributes | Select all |
List Search | <No Search> |
"Include No Selection" Item | Deselect all |
Page
Drop the DepartmentId and DepartmentLovName attribute from the Data Controll palette onto the page created for the Manager LOV. The DepartmentId is displayed as Output text with label, the DepartmentLovName as Input list of values.If we run this page it looks like this:
When a row is selected (by double click or by using the OK button) the Name and the ID of the department is copied to the page. That is an improvement compared to the Manager ID. But the opened popup still contains scrollbars and is not resizable.
Create a custom (resizable) LOV
Finally we’ll create a resizable LOV. This is also done for the department.Model layer
Change the EmployeesLovView (make a copy of DepartmentLovName):- Add a transient attribute DepartmentLovName2 of type String
- Make the attribute always updatable
- Check the Mapped to Column or SQL checkbox
- Fill the expression of the Query Column:
- (SELECT department_name FROM departments WHERE department_id = Employee.department_id)
- Set the type of the Query Column to VARCHAR2(30)
Page
Drop the DepartmentId (same as used for the department LOV) and DepartmentLovName2 attribute from the Data Controll palette onto the page underneath a seperator. The DepartmentId is displayed as Output text with label, the DepartmentLovName2 as Input text with label.Surround the DepartmentLovName2 input text in a panelGroup with layout style horizontal. After the input text add a command image link with the LOV icon. The command link triggers a popup:
<af:panelGroupLayout id="lovGroup"
layout="horizontal">
<af:inputText value="#{bindings.DepartmentLovName21.inputValue}"
label="#{bindings.DepartmentLovName21.hints.label}"
required="#{bindings.DepartmentLovName21.hints.mandatory}"
columns="#{bindings.DepartmentLovName21.hints.displayWidth}"
maximumLength="#{bindings.DepartmentLovName21.hints.precision}"
shortDesc="#{bindings.DepartmentLovName21.hints.tooltip}"
id="departmentLovNameInputText">
<f:validator binding="#{bindings.DepartmentLovName21.validator}"/>
</af:inputText>
<af:commandImageLink id="departmentLovNameCommandLink"
icon="/common/images/lov.png">
<af:showPopupBehavior popupId="departmentLovPopup"
triggerType="action"/>
</af:commandImageLink>
</af:panelGroupLayout>
- Run your application, in the IntegratedWebLogicServer log you see a destination where the EAR is copied to. On my computer is that:
- [03:25:38 PM] Wrote Web Application Module to C:\Users\mhorsch\AppData\Roaming\JDeveloper\system11.1.1.3.37.56.60\o.j2ee\drs\HR_demo_app\ViewControllerWebApp.war
- Go to the o.j2ee folder and in that folder go to: \.wlLibs\jsp
- Open the ADF-Faces-Components11.war
- Go to \WEB-INF\lib and open the adf-richclient-impl-11.jar jar file
- Go to adf\images
<af:popup id="departmentLovPopup">
<af:dialog id="lovDialog"
title="LOV"
type="okCancel"
dialogListener="#{employeeBean.lovDialogListeners}"
resize="on"
contentWidth="600"
stretchChildren="first">
</af:dialog>
</af:popup>
This bean class is defined in the unbound task flow:
Managed bean property | Value |
---|---|
Name | employeeBean |
Class | nl.hr.demo.view.beans.EmployeeBean |
Scope | request |
The DepartmentsLocationView table is inserted in the dialog by drag and drop from the data control palette:
The Row Selection property must be checked, this causes the following properties to be set in the table:
Property | Value |
---|---|
selectedRowKeys | #{bindings. DepartmentsLocationView.collectionModel.selectedRow} |
selectionListener | #{bindings. DepartmentsLocationView.collectionModel.makeCurrent} |
rowSelection | single |
Although in the JSPX page the selectedRowKeys and selectionListener statements contains warnings that the references methods cannot be found they can be found runtime.
In the EmployeeBean we have to implement the lovDialogListeners method. The method is only executed when the LOV is closed by the OK button. In the method the department ID and name of the selected row are copied to the EmployeesLovView row:
package nl.hr.demo.view.beans;
import javax.faces.context.FacesContext;
import nl.hr.demo.model.services.HrAppModuleImpl;
import oracle.adf.model.binding.DCBindingContainer;
import oracle.adf.model.binding.DCDataControl;
import oracle.adf.view.rich.event.DialogEvent;
import oracle.binding.BindingContainer;
import oracle.jbo.domain.Number;
import oracle.jbo.server.ViewRowImpl;
public class EmployeeBean {
public EmployeeBean() {
super();
}
private static HrAppModuleImpl getService() {
DCBindingContainer bc = (DCBindingContainer)FacesContext.getCurrentInstance().getApplication().evaluateExpressionGet(FacesContext.getCurrentInstance(), "#{bindings}", BindingContainer.class);
DCDataControl dc = bc.findDataControl("HrAppModuleDataControl");
return (HrAppModuleImpl) dc.getDataProvider();
}
public void lovDialogListeners(DialogEvent dialogEvent) {
ViewRowImpl row = (ViewRowImpl)getService().getDepartmentsLocationView().getCurrentRow();
if (row != null) {
Number departmentId = (Number) row.getAttribute("DepartmentId");
String departmentName = (String)row.getAttribute("DepartmentName");
ViewRowImpl employeeRow = (ViewRowImpl)getService().getEmployeesLovView().getCurrentRow();
employeeRow.setAttribute("DepartmentId", departmentId);
employeeRow.setAttribute("DepartmentLovName2", departmentName);
}
}
}
The popup is resizable, the name and id are copied and refreshed and the width of each column can be modified individually (by setting the width property of the af:column).