Using one ViewObject for Global Lookup Data (Part 2)

Based on the other post ‘Using one ViewObject for Global Lookup Data’ I got an other question on how to use this approach in a way, that a LOV is initalized with an area of lookup data before the page in shown to the user.
This can be done, all declarative without the need to write java code e.g. in an onLoad() method. The solution is to use a bounded task flow which initializes the LOV before navigation to the page the LOV is used.
To show this we create a simple navigation model in the adfc-config.xml like

Navigation Model

Navigation Model

‘Generic Lookup’ is used to show how to do this inside a page, where the lookup is presented in a region, the ‘LookupInitPosition’ shows how to preset an area for the lookup data (POSITION in this case) before showing the page in a region too.
Before we go into detail on how to setup the UI we need to add another view object to our data model which we use the acquire the lookup data

VO to get Lookup Data

VO to get Lookup Data


The ‘GeneralLookup’ view object is the same we used in part 1 to get the lookup data of an area, only this time we don’t specify lookup area but a dummy value (‘1’ in this case) for the area. This dummy value is set so that we don’t get any result back. If the ‘GeneralLookup’ view is executed without an area given from the outside, we don’t get any result. Keep this in mind when we are looking at the running sample later on.

Back to the UI. As both use cases uses a region it’s a nice sample how a bounded task flow (btf) can be reused in different use cases. The bounded task flow itself looks like

Navigation Model Bounded Task Flow

Navigation Model Model Bounded Task Flow

Bounded Task Flow to Show preselected Lookup Data

Bounded Task Flow to Show preselected Lookup Data


As you see the bounded task flow uses a method call (ExecuteWithParams) as it’s start activity. A task flow parameter is used to pass the name of the lookup area we want the LOV to initially show.
The name of the input parameter does not really matter, what you have to note down is the value part ‘#{pageFlowScope.selectedType}’ as this is the the variable we use to set the bindType parameter of the method call activity ExecuteWithParams.

Setup of the ExecuteWithParams Method Call

Setup of the ExecuteWithParams Method Call

After executing the query with the new set bindType we navigate to to page to show the result:

Region View1 which shows the LOV with the Preselected Lookup Data

Region View1 which shows the LOV with the Preselected Lookup Data


We see the LOV as af:selectOneChoice which stores the selected value in an attribute from the variable iterator (see Creating Variables and Attribute Bindings to Store Values Temporarily in the┬áPageDef for more info on this). The input text below the LOV can be used to change the area parameter used for the LOV. If we enter e.g. WEEKDAY and click the ‘Refesh’ button, the input value is read and transferred to the parameter (#{pageFlowScope.selectedType}) for the executeWithParameter method via a af:setPropertyListener. This allows to change the LOV on the fly from within the region.
The LOV source is a dynamic list generated from the Generallookup VO as seen in the next image
Setup LOV for af:selectOneChoice

Setup LOV for af:selectOneChoice

After we know how the region (the bounded task flow) works, we can build the GenericLookup.jspx page. This page allows to enter the name of an ares into an input text field and then to refresh the bounded task flow, which we put on the page as region.

The final use case is to navigate to a page with with a preselected lookup area, POSITION in this case. For this we use the button ‘goto Page with init on POSITION’ at the bottom of the page.

You can download the sample workspace which was build JDeveloper 11.1.1.7.0 and using the HR schema from the ADF EMG Samples side BlogStaticVOLov_V3.zip. You can open the workspace using JDev 11.1.1.6.0 without a problem. If you are asked if you like to migrate the workspace to 11.1.1.6.0 answer with Yes.

Advertisements

JDeveloper 11.1.1.6.0: af:inputText with self made Look-Up not using LOV

In this blog entry shows how to setup an af:inputText with a look-up which gets its data from a db table for easy reference. This sounds like an af:inputListOfValues you might say. The difference is that an af:inputListOfValues validates the input against the data present in the DB. In case you want to allow the user to chose values available, but also allow adding values which are currently not present, you can’t use af:inputListOfValues.

After you drop a VO from the data control which has an attribute setup an attribute as InputListOfValue you get the following code:

                      <af:inputListOfValues id="emailId" popupTitle="Search and Select: #{bindings.Email.hints.label}" value="#{bindings.Email.inputValue}"
                                            label="#{bindings.Email.hints.label}" model="#{bindings.Email.listOfValuesModel}"
                                            required="#{bindings.Email.hints.mandatory}" columns="#{bindings.Email.hints.displayWidth}"
                                            shortDesc="#{bindings.Email.hints.tooltip}">
                        <f:validator binding="#{bindings.Email.validator}"/>
                      </af:inputListOfValues>

Now when we run the sample (which is build using the HR schema and JDev 11.1.1.6.0, source code available using the link provided at the end of the blog) we see the form like:

Running Application

Running Application

You can click on the magnifying glass to search for an existing value for the EMail attribute.

EMail Look Up

EMail Look Up

However, if we enter a value into the inputText which is not part of the LOV, we get an error

Error when Value isn't Part of the LOV

Error when Value isn’t Part of the LOV

One way to get around this is to delete the validator from the af:inputListOfValues. However, this means that no validations take place on this field. The idea of this post is to build the look-up part of the af:inputListOfValues our self and add it to an af:inputText. The look and feel remains the same:

Application with Self-made Look-UP

Application with Self-made Look-UP

As you see there is no difference on the first look. However, clicking the magnifying glass we get a slightly different look-up

Self-made Look-Up

Self-made Look-Up

Now we can enter any value into the EMail field without getting an error

EMail with 'new' Value

EMail with ‘new’ Value

How is this implemented?
In the model project we have two VOs: one fro the form (EmployeesView) and one for the EMail look-up (EmployeesEmailView). This second VO has a view criteria which we later use to build the look-up in the popup. A third VO in the model project (TestEmpView) is used to show the normal behavior of the EMail attribute with a LOV attached to it.

In the view controller project we have one start page (Page1) which hosts a panelTabbed for the different solutions. The self-made look-up is done in the bounded task-flow input-text-lookup-btf, which is dropped as region into the first tab. The region (input-text-lookup-btf.xml) is build by dragging the EmployeesView from the data control onto the fragment (test1.jsff) as ‘ADF Form’. To get the look & feel of the af:inputListOfValue we have add an icon behind the af:inputText. To make this possible we use an af:panelLabelAndMessage which shows the label for the EMail attribute. Inside this we place an af:inputText in simple format (otherwise the label would show up twice) and finally the icon for the look-up.

          <af:panelLabelAndMessage label="#{bindings.Email.hints.label}" id="plam1">
            <af:inputText value="#{bindings.Email.inputValue}" label="#{bindings.Email.hints.label}" required="#{bindings.Email.hints.mandatory}"
                          columns="#{bindings.Email.hints.displayWidth}" maximumLength="#{bindings.Email.hints.precision}"
                          shortDesc="#{bindings.Email.hints.tooltip}" id="it2" simple="true">
              <f:validator binding="#{bindings.Email.validator}"/>
            </af:inputText>
            <af:commandImageLink id="cil1" icon="/images/icon_Pruefen.gif" immediate="true" blocking="true">
              <af:showPopupBehavior popupId="p1" triggerType="action"/>
            </af:commandImageLink>
          </af:panelLabelAndMessage>

The generated af:inputText for the EMail attribute we simply delete. As you see the validator is still there but doesn’t show an error when we enter a value which is not part of the LOV from the popup. The popup used for the look-up, is a normal popup with a dialog as layout component. The dialog shows an af:query component generated by dragging the view criteria from the EmployeeEmailView from data control.

The missing part is how the value selected in the look-up is set into the EMail attribute on the form. This is done in the dialog listener which controls the dialog outcome:

    public void dialogListener(DialogEvent dialogEvent) {
        if (dialogEvent.getOutcome().equals(DialogEvent.Outcome.ok)) {
            // get the binding container
            BindingContainer bindings = BindingContext.getCurrent().getCurrentBindingsEntry();
            // get an ADF attributevalue from the ADF page definitions
            AttributeBinding attr = (AttributeBinding)bindings.getControlBinding("EmailPopup");
            Object inputValue = attr.getInputValue();
            // set the value into the other attribute
            attr = (AttributeBinding)bindings.getControlBinding("Email");
            attr.setInputValue(inputValue);
        }
    }

The second tab (Test) hosts the normal use case using a af:inputListOfValue on the EMail attribute. This is just for reference.

The source for the sample can be loaded from GitHub. The sample is build on the HR db schema using JDeveloper 11.1.1.6.0.