JDeveloper 11.1.1.6.0 Use Selection in LOV to Navigate to Detail

This post shows how a selection in a list of value (LOV) can be used to navigate to another page to show detailed information about the selected item in the LOV. The sample uses the HR db schema, the work space can be loaded using the link provided at the end of the post.

Use Case
Using a af:selectOneChoice showing the department names of the departments table we want to select on department. Then by clicking a button we want to navigate to a different page which shows the details of the selected department.

Let’s start with a look at the finished application:

Running Application

Running Application

After selecting a department from the af:selectOneChoice we see the index of the selected department.

Select Department

Select Department

This is shown in the outputText below the LOV. Selection ‘Human Resources’ selects the index 3 in the LOV.

Navigate to Detail Page

Navigate to Detail Page

And finally the detail Page where we see the correct department id for ‘Human Resources’ of 40.

Detail Page

Detail Page

Implementation
To implement this use case we define two view objects (VO). One which we use for the LOV of department names (DepartmentLOVView) and one which we use to show the detail on a form for the detail page (DepartmentView1).

Data Model

Data Model

In the UI we define a bounded task flow (lov-select-detail-btf.xml) which is build using fragments. This task flow is put on a page (Start.jspx) as region.

lov-select-detail-btf

lov-select-detail-btf

Before we begin to setup the LOV we need a place to store the selected value from the LOV. For this we create a pageDef file for the DepSelect.jsff by right clicking on the page and selecting ‘Go to Page Definition’ from the menu. As there is no pageDef file one is created for us. We define a variable DepId inside the variable section of the ‘Exceutables’ section. Then we add an attributeValue ‘DepId’ in the bindings section.

Define Variable DepId inside the Executables Section

Define Variable DepId inside the Executables Section

Variable DepId

Variable DepId

Add attributeValue Binding

Add attributeValue Binding

Select DepId from variabels

Select DepId from variabels

To setup the LOV drag the DepartmentId from the DepaermentLOVView from the Data Controls section onto the DepSelecte.jsff fragment. Change the values in the dialog to match the image below:

Edit List Binding for DepartmentId

Edit List Binding for DepartmentId

In the property editor for the selectOneChoice set the label property to ‘Depaertment’ and the value property to ‘#{bindings.DepId1.inputValue}’ which is the attribute we defined in the variables section. Set the autoSubmit property to true so that selected values are posted into the variable once the value changes. The final selectOneChoise code is

        <af:selectOneChoice label="Department" id="soc1" required="#{bindings.DepartmentId.hints.mandatory}" value="#{bindings.DepId1.inputValue}"
                            autoSubmit="true" valuePassThru="true">
          <f:selectItems value="#{bindings.DepartmentId.items}" id="si1"/>
        </af:selectOneChoice>

To show the selected item we add an outputText which shows the “#{bindings.DepId1.inputValue}”, which is the place the value is stored after selecting a department in the LOV. Notice that we don’t see the DepartmentId (the PK of the VO), but the index of the selected department in the list binding. As we don’t use a value driven LOV we have to map the index back to the row key ourselves. One more reason to stick to model driven LOV whenever possible. In this use case we don’t use a model driven LOV by intent. This is to show how to map the index back to the row key of the list.

The missing element is a button we use to navigate to the next page, the detail page, showing the departments detail as a form (read only). To get this button, open the data controls section and then open the DepartmentsLOVView and open the ‘Operations’ node. Select the ‘setCurrentRowWithKeyValue’ operation and drag it onto the fragment. Drop it as operation->button. This will add the operation into the pageDef for the fragment. The image below shows the final pageDef:

Final pageDef

Final pageDef

The missing part is the mapping of the selected index to the needed key of the department. For this we select the button, go to the properties of the button. In the action property we select ‘Edit’ from the drop down list (small arrow) on the right side of the property. In the Dialog we create a new bean ‘DepSelectBean’ in the package ‘de.hahn.blog.lovselectdetail.view.beans’. In the method part we choose ‘new’ to create a new method ‘showSelectedDep’. Finally we change over to the source tab of the fragment and delete the ‘#{bindings.setCurrentRowWithKeyValue.execute}’ from the actionListener property. The reason for this is that we execute the method from the bean after we got the real DepartmentId from the LOV. The magic is done in the action method ‘showSelectedDep()’ in the bean.

    public String showSelectedDep() {
        BindingContext lBindingContext = BindingContext.getCurrent();
        BindingContainer bindings = lBindingContext.getCurrentBindingsEntry();
        // get the list binding for the department lov
        JUCtrlListBinding list = (JUCtrlListBinding)bindings.get("DepartmentId");

        // get the selected index from the list which is stored in the DepId1 attribute
        AttributeBinding attr = (AttributeBinding)bindings.getControlBinding("DepId1");
        Integer selid = (Integer)attr.getInputValue();

        // load the listdata
        Object row = list.getDisplayData();
        // get the selected row from the list
        Row lFromList = (Row)list.getValueFromList(selid);
        // from the row we get the PK the DepartmentId
        Object lAttribute = lFromList.getAttribute("DepartmentId");
        Number newVal = (Number)lAttribute;
        _logger.info("Information: selected Department = " + newVal);
        // get the MethodAction for setCurrentRowWithKeyValue
        OperationBinding method = bindings.getOperationBinding("setCurrentRowWithKeyValue");
        // set hte needed parameter as the department id
        method.getParamsMap().put("rowKey", newVal);
        method.execute();
        // after execution check for errors
        List errors = method.getErrors();
        if (!errors.isEmpty()) {
            Exception ex = (Exception)errors.get(0);

            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), "");
            FacesContext.getCurrentInstance().addMessage(null, msg);
            // keep on page in case of an error
            return null;
        }

        // navigate to the next page
        return "show";
    }

This concludes the implementation. The workspace can be loaded from ADF EMG Samples Project. The sample uses the HR db schema and was developed using JDeveloper 11.1.1.6.0

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s