Web Dynpro Valuehelp - The Object Value Selector

SAP Developer Network

Summary

From this article you will learn how to embed the most sophisticated generic valuehelp service provided by the Web Dynpro Java Foundation Framework. This type of valuehelp service is called Object Value Selector (OVS). A generic OVS user interface provides all functionality for entering and executing a search query and copying values of a selected object back to one or many input fields. For utilizing the OVS in your Web Dynpro application, you have to implement some controller coding. First the underlying application context attributes have to be OVS-extended with the Web Dynpro Service class WDValueServices so that input fields bound to these context attributes can open the OVS UI. Another step is declaring an OVS helper context in a separate OVS custom controller for storing search input and output data. Finally the IWDOVSContextNotificationListener interface has to be implemented as an inner class in the OVS custom controller. This OVS listener class acts as some kind of OVS controller for handling OVS-related UI events like opening the OVS pop-up, triggering the OVS search query or selecting a query result.

By Bertram Ganz

17 May 2004

 

Introduction

The Web Dynpro Foundation Framework knows three types of generic valuehelp UI services. The most simple one is called Simple Value Selector (SVS) based on a DropDownByKey-UI-element. The texts to be displayed in the dropdownlist are retrieved from a Simple Datatype's enumeration of key-displaytext-pairs. For utilizing the generic SVS valuehelp an application developer just has to declare the databinding between the UI-element-property selectedKey and a context attribute. At runtime the Simple Datatype of this context attribute must contain a set of key-displaytext-pairs. A Simple Datatype can have diffent origins. The first one is the project internal local Java Dictionary. This Dictionary stores all Simple and Structure Types statically declared at designtime. Another origin of a Simple Datatype is the so-called Logical Dictionary belonging to an imported Adaptive RFC Model. Finally you can programmatically modify the datatype of a single context attribute, so that it either becomes a Simple Datatype or that it changes its metadata (e.g. by adding furhter key-value-pairs to a statically declared Simple Datatype).

The second Web Dynpro valuehelp is called Extended Value Selector (EVS). Like the SVS this valuehelp is there for selecting a key-displaytext-pair of a Simple Datatype. Because the SVS is not suitable for displaying large valuesets (e.g. more than 50) Web Dynpro provides the EVS. This valuehelp is displaying a popup-UI with an inbuilt functionality for browsing and filtering large valuesets in a table. The EVS can be displayed for every Inputfield-UI-Element with the value-property bound to a context attribute of type Simple Datatype (at runtime).

In many application scenarios an additional type of valuehelp is needed for searching objects instead of values. Think of searching for a Airline ID. For finding this ID you want to enter some related data like departure and arrival airport or the flight date in a search form. The search results (matching flight objects) are displayed in a table and after selecting a flight the airplane ID (or other values) is (are) automatically transferred to the corresponding input field(s). For this purpose Web Dynpro provides a third type of generic valuhelp service called OVS (Object Value Selector).

The Object Value Selector

In contrast to SVS and EVS the Object Value Selector is not completely based on a declarative approach. For embedding this sophisticated valuehelp into your Web Dynpro application you have to implement some lines of code in an associated OVS custom controller. As a trade-off for your programmatic efforts the Web Dynpro Runtime automatically renders a generic OVS UI. This user interfaces is based on a special OVS core component belonging to the Web Dynpro Java Runtime Environment.

Utilizing the OVS is mainly based on the following three steps:

  • OVS Helper Context: The OVS stores its data (search input data and the query results) in an OVS helper context part of the OVS custom controller. The application developer declares a context node of caridinality 1..1 for storing the search input data and another node of caridanality 0..n for storing the query results. When a suitable RFC-function is available you just have to declare the model binding. Input- and output-node are then part of the created context structure.

  • OVS Listener: The OVS is using a listener implementation of the IWDOVSContextNotificatiionListener interface. This listener implements three hook methods acting as event handlers called at three points of time: when the OVS UI is requested for a field, when the search query is triggered and when the user selects a line in the search result table (see Figure 1a and 1b).

  • OVS Extension: The OVS is there for finding objects and copying object values to the context (to context attributes). Its a valuehelp service provided for all those context attributes (or better input fields bound to these context attributes) which were programmatically extended with the OVS feature. The Web Dynpro Programming Model API provides the WDValueServices class for adding this OVS-extension to context attributes.

Figure 1a. OVS-related classes and interfaces

Figure 1b. WDValueServices and IWDOVSContextNotificationListener in detail

The runtime aspects of the OVS valuehelp are displayed in the sequence diagram of figure 2.

  1. Instantiation of a OVS listener object implementing the IWDOVSContextNotificationListener interface. This is done in the wdDoInit() hook method which is automatically called on controller startup. In this example the context to be OVS-extended is belonging to a view controller. Adding the OVS extension to context attributes. This is done by calling WDValueServices.addOVSExtension(...). The signature of the method addOVSExtension() is displayed in figure 1b. The startup attributes to be OVS-extended are passed in an array of type IWDAttributeInfo. In addition references to the OVS helper context nodes (queryInputNode and queryOutputNode) and to the used OVS listener implementation have to be passed to the Web Dynpro WDValueServices class.

  2. When a user requests the OVS valuehelp for an input field by clicking the valuehelp button a so-called Web Dynpro service request is sent to the server. The Web Dynpro Runtime then calls the hook applyInputValues() implemented by the OVS listener class. This methods gets a reference to the context node element, the input field is bound to and in addition a reference to the context node element storing the OVS query input data. This initially called OVS hook method is there for initializing the input fileds of the OVS search form.

  3. When clicking the Go-button in the OVS pop-up an OVS action is sent to the Web Dynpro Runtime which then calls the OVS listener's method onQuery(). By accessing the query input data you can execute a search query to the backend. The retrieved search results can then be stored in the OVS helper context node queryOutput.

  4. Now the user selects a line in the OVS search result table. Again an OVS action is sent to the Web Dynpro Runtime. The third hook method of the OVS listener class applyResult() is called for copying values in the selected result object (queryOutputElement) to the context node element to which the input field (from where the OVS was opened) is bound.

Figure 2. OVS sequence diagram

Adding OVS Extension to the Context

The OVS extension of context attributes is being specified programmatically. In this example a view controller context (called application context) stores flight data in a value node Flight with some attributes. In a view layout some input fields are bound to these attributes. We now want to add the OVS valuehelp functionality to the Airline ID input field. For this reason the following lines of code have to be implemented in the view controller's wdDoInit().

//@@begin javadoc:wdDoInit()
				
/** Hook method called to initialize view controller. */
				
//@@end
				
public void wdDoInit() {
				
//@@begin wdDoInit()
				
  IWDAttributeInfo[] ovsStartUpAttributes = { 
				
    wdContext.nodeFlight().getNodeInfo().getAttribute("Airlineid")};
				
  IWDOVSContextNotificationListener listener = 
				
    wdThis.wdGetOVSCustController().getOVSListener();
				
  WDValueServices.addOVSExtension("Flight Selection", // not used yet  
				
    // fields bound to startup attributes will be ovs-enabled 
				
    ovsStartUpAttributes, 
				
    wdThis.wdGetOVSCustController().getOVSInputNode(),
				
    wdThis.wdGetOVSCustController().getOVSOutputNode(), 
				
    listener);
				
//@@end
				
}
				

In this exmaple the OVS helper context exposes public methods for getting references to the OVS listener object and the OVS helper context nodes Input and Output. These methods have to be be declared for the OVS custom controller in the SAP NetWeaver Developer Studio. The OVS helper context contains a structure based on the RFC function BAPI_FLIGHT_GETLIST_INPUT (based on a Adaptive RFC model binding declaration). So the OVS input node is named Bapi_Flight_Getlist_Input and the output node is named Flight_List (see figure 4).

Figure 4. OVS related contexts: the application context and the OVS helper context in a separate OVS custom controller

The OVS Custom Controller

First of all the OVS custom controller stores the OVS helper context data, needed by the generic OVS UI. It is important to know, that the context attributes in this helper context must be adequately typed using Simple Datatypes in a Local or Logical Data Dictionary. Metadata of these Simple Types is read by the generic OVS core component for dynamically creating the OVS user interface with field labels, tooltips or column header texts. For this reason in figure 3 a Logical Dictionary is additionally displayed.

In some application scenarios the backend does not provide an OVS-adapted RFC-function. OVS-adapted means that all required input attributes are on the same level in one input structure (OVS input node after model binding). Likewise all attributes to be displayed in the search result table have to belong to one output structure (OVS output node after model binding). So the OVS does not support input or output attributes on different levels. The solution for this restriction is to declare separate OVS input or output nodes. These nodes are value nodes with all required attributes, properly typed with Simple Types of the Logical Adaptive RFC Dictionary. Copying data between the used model nodes and the additional OVS input and/or output value nodes has to be implemented in the OVS listener.

In addition the OVS custom controller contains the implementation of the required IWDOVSContextNotificationListener interface as an inner class. Because the OVS requires a reference to an existing input node element we have to bind a model object of type Bapi_Flight_Getlist_Input to the homonymous context model node (OVS input node) on controller startup:

//@@begin javadoc:wdDoInit()
				
/** Hook method called to initialize OVS custom controller. */
				
//@@end
				
public void wdDoInit() {
				
//@@begin wdDoInit()
				
  Bapi_Flight_Getlist_Input bapiInput = new Bapi_Flight_Getlist_Input();
				
  wdContext.nodeBapi_Flight_Getlist_Input().bind(bapiInput);
				
//@@end
				
}
				

The public methods getOVSListener(), getOVSInputNode() and getOVSOutputNode() are not documented here.

Implementing the IWDOVSContextNotificationListener Interface

The implementation of the IWDOVSContextNotificationListenerInterface is contained in the OVS helper context as an inner class. The OVS custom controller stores an instance of this listener in a private member variable: private IWDOVSContextNotificationListener ovsListener = new OVSDemoContextNotificationListener(); This object is returned by the public controller method . For being able to get typed access to the OVS helper context the corresponding type casts are required.

...
				
//@@begin others
/* Implement IWDOVSContextNotificationListener as inner class of 
				
 * Custom Controller OVSCust. */
				
private class OVSDemoContextNotificationListener 
				
  implements IWDOVSContextNotificationListener {
				
  /* @see com.sap.tc.webdynpro.progmodel.api
				
   *         .IWDOVSContextNotificationListener#onQuery(...) */
				
  public void onQuery(IWDNodeElement queryInputNodeElement,
				
                      IWDNode queryOutputNode) {
				
     IPublicOVSCust.IBapi_Flight_Getlist_InputElement ovsInput =  
				
      (IPublicOVSCust.IBapi_Flight_Getlist_InputElement) queryInputNodeElement;
				
    IPublicOVSCust.IFlight_ListNode ovsOutput = (
				
      IPublicOVSCust.IFlight_ListNode) queryOutputNode; 
				
    try { 
				
      ovsInput.modelObject().execute();
				
      // invalidate 'Output' model node from via a top-down access approach 
				
      ovsInput.node().getChildNode("Output",0).invalidate(); 
				
    } catch (Exception e) {
				
      IWDMessageManager msgMgr = wdComponentAPI.getMessageManager();
				
      msgMgr.reportException(e.getLocalizedMessage(), false);
				
    }
				
  }
				
				
				
  /* @see com.sap.tc.webdynpro.progmodel.api
				
   *         .IWDOVSContextNotificationListener#applyResult(...)*/
				
  public void applyResult(IWDNodeElement applicationNodeElement, 
				
                          IWDNodeElement queryOutputNodeElement) {
				
    IPrivateOVSView.IFlightDataElement ovsCallerNodeElement =
				
          (IPrivateOVSView.IFlightDataElement) applicationNodeElement;
				
    IPublicOVSCust.IFlight_ListElement output = 
				
     (IPublicOVSCust.IFlight_ListElement) queryOutputNodeElement;
				
    ovsCallerNodeElement.setAirlineid(output.getAirlineid());
				
    ...
				
    ovsCallerNodeElement.setDeptime(output.getDeptime());
				
  }
				
				
				
    /* @see com.sap.tc.webdynpro.progmodel.api
				
   * .IWDOVSContextNotificationListener#applyInputValues(...) */
				
  public void applyInputValues(IWDNodeElement applicationNodeElement, 
				
                               IWDNodeElement queryInputNodeElement) {
				
    Object initialValue = applicationNodeElement.getAttributeValue("Airlineid");
				
    queryInputNodeElement.setAttributeValue("Airline", initialValue);
				
  }
				
}
				
				
				
private IWDOVSContextNotificationListener ovsListener = 
				
          new OVSDemoContextNotificationListener();
				
//@@end
				

Conclusion

The Web Dynpro Object Value Selector simplifies embedding a user interface for searching objects in your Web Dynpro application. Whereas the SVS and the EVS valuehelps are there for searching key and displaytexts contained in Simple Datatypes the Object Value Selector provides functionality for searching objects. The OVS user interface is automatically generated by the Web Dynpro Runtime. It is available for all context attributes with a programmatically specified OVS extension using the Web Dynpro service WDValueServices. An OVS helper context is used to store the OVS query input and output data. The contained helper context elements have to be typed using Dictionary Simple Types. The OVS helper context as well as the OVS listener class implementing the IWDOVSContextNotificationListener interface are part of a separate OVS custom controller.

Table of Contents



Content Options

Copyright © 2005 SAP AG, Inc. All Rights Reserved. SAP, mySAP, mySAP.com, xApps, xApp, and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and in several other countries all over the world. All other product, service names, trademarks and registered trademarks mentioned are the trademarks of their respective owners.

SAP Developer Network