Own Widgets

An implementation recommendation of custom widgets cannot be described in general, because the possibilities are almost unlimited. The implementation of a widget is basically always done in two classes (Widget Controller and Model), where both classes must be derived from a UI-specific abstract base class (form, tree, ALV, etc.).

The implementation of the widget and model class is very efficient and easy due to the ProFramework architecture and the complete abstraction of the UI layer. The big challenge in ProFramework are the very extensive events. Basically, event handling is implemented exclusively in the widget class. The widget decides if and how the model should be informed about events. Since the model is statically known, the widget can directly call methods in the model. Each model already has some core functions, some of which are called automatically (e.g. Refresh).

Most widgets respond in some way to these events to determine what data to display. The following therefore describes the procedure for implementing a widget that displays data for an object in the interface.

Activating events

Basically, the abstract widget classes already provide a handler method for each intended event, which can be redefined in the widget. However, the handling of these events must be activated (and also deactivated again!) individually via the corresponding ABAP statements. Two methods are available for this purpose, each of which has the activation as parameter IV_ENABLE.

  • GLOBAL_EVENTS_REGISTER Events that should always be active as soon as the widget has been loaded once. These events are relevant even if the widget is no longer displayed. Basically, most events are to be registered globally.

  • EVENTS_REGISTER These events are only active when the widget is displayed. The method is therefore always called when the widget is shown or hidden. Basically, only events that required a UI (e.g. validating the form data, requesting the current data, etc.) are to be enabled or disabled here.

Configuration Objects

Both the widget and the model have a configuration object in which specific data can be stored. The configuration object is used for the uniform transport of data from the framework to the widget and from the widget to the model and the view. Accordingly, the configuration object of the model should be used to transport the object from the widget to the model, for example.

Identification of the current object

The identification of the object to use depends on whether the widget should support multiple objects or only a single object.

If a widget is to provide data for exactly one object type only, the widget reacts to the SWITCHED event of the corresponding object handler. The widget already provides the ON_OBJECT_SWITCHED method for this purpose. Since the object handler instance is required for registering the event, this should already be read by the central framework controller when the widget is initialized with the INIT method. The framework controller provides the method GET_OBJECT_HANDLER for this purpose, which expects the ID of the object handler.

If a widget supports multiple objects, then this can be implemented using the same principle as described above if the types are known statically. However, if it is a dynamic widget that is supposed to support arbitrary objects, it can no longer react to the events of object handlers. Instead, it must only react to events of the navigation controller, which triggers an event for each object (type) change. As soon as the current object type changes, the OBJECT_TYPE_CHANGED event is triggered accordingly and handled with the ON_NAVIGATION_OBJ_TYPE_CHANGED methods. In addition, when the object changes, the OBJECT_CHANGED event is triggered and handled with the ON_NAVIGATION_OBJECT_CHANGED method. A change of the type always also triggers a change of the object key, whereby the key can also be empty.

Basically in both cases, the object is to be communicated to the model over its configuration. The configuration object has the method SET_OBJECT for this purpose.

When the corresponding events are handled, the model may not yet be available because it is not built until the widget is displayed for the first time. This must be taken into account when implementing the methods described above.

Widgets are not initialized until they have been loaded in a layout. Consequently, no events are handled until this point. If the widget is now displayed for the first time, the model is automatically built. Since the events described above have already been triggered at this point, it must be ensured manually that the corresponding object is enriched in the configuration of the model. This takes place by Redefnition of the method MODEL_CONFIGURATION_SETUP. Here, depending on the scenario, the current object can be determined from the object handler (attribute MO_BUSINESS_OBJECT) or directly from the navigation controller (method GET_CURRENT_OBJECT).

Managing the object in the model

Basically, setting the object in the configuration of the model also leads to an event that could be handled by the model with the method ON_CONFIGURATION_CHANGED. However, since each model must store an instance of the respective business object in its attributes and the LOAD method is run through on each server roundtrip, the locally stored instance of the business object can instead be compared directly in the LOAD method with the current key in the configuration of the model. If the object has changed, the existing business object can be released with the method FREE and (if set) a new business object instance can be created. At the same time, it must be ensured that the data is read again in this case.

© ProNovia AG | Imprint | Data Protection