Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
TusharShinde
Active Participant

The reason, I choose these topic is because in many ways we never develop a component keeping the perspective of UIBB in mind, where FPM UIBB's actually means breaking the application into several components so as to make it reusable in n-applications to provide common functionalities in different applications in your system landscape.

Creation of Custom Class for sharing Data between 2-UIBB’s (FPM User Interface Building Blocks)

In order to facilitate data exchange between 2-components a class is created which is added in attributes of both UIBB’s Component Controller. Class consists of CLASS-CONSTRUCTOR, which is initialized once and is available till the scope of application persists.

What is CLASS-CONSTRUCTOR or Static Constructor?

Each class has a single static constructor. This is a predefined public static method of the constructor class. If you want to use the static constructor, you must declare the static method class_constructor in the public section of the declaration part of the class using the CLASS-METHODS statement, and implement it in the implementation part. The static constructor has no interface parameters and cannot raise exceptions. Unless you implement it explicitly, it is merely an empty method.

The static constructor is called once per class and internal session. The static constructor of a class class is called automatically before the class is accessed for the first time. The static constructor is always called immediately before the class is accessed, with one exception: If your first access to the class is to address a static attribute, the static constructor is executed at the beginning of the processing in which access takes place.

Here for demonstration, I am creating class named ZCL_SESSION_SHARING so as to facilitate sharing of data between 2-UIBB’s (Web Dynpro Components) i.e. ZWD_UIBB_COMP1 & ZWD_UIBB_COMP2.

Please find below the Class ZCL_SESSION_SHARING Definition.

class ZCL_SESSION_SHARING definition
public
final
create public .

public section.
*"* public components of class ZCL_SESSION_SHARING
*"* do not include other source files here!!!

data MV_X type INTEGER .
data MV_Y type INTEGER .
data MV_RESULT type INTEGER .
data MV_RETURN type STRING .

class-methods CLASS_CONSTRUCTOR .
methods ADD_VALUES .
methods SUB_VALUES .
methods MULTI_VALUES .
methods DIVI_VALUES .
class-methods S_GET_INSTANCE
returning
value(RO_INSTANCE) type ref to ZCL_SESSION_SHARING .
protected section.
*"* protected components of class ZCL_SESSION_SHARING
*"* do not include other source files here!!!
private section.
*"* private components of class ZCL_SESSION_SHARING
*"* do not include other source files here!!!

class-data GO_ME type ref to ZCL_SESSION_SHARING .
ENDCLASS. *"* End class Definition.

Here class-methods CLASS_CONSTRUCTOR, helps in initializing Static Attribute of class i.e. GO_ME, as per the definition of Static Constructor, it is invoked whenever any Static Attribute of class is accessed, so here when the class-methods S_GET_INSTANCE( ) is called the Static Attribute go_me gets initialized because Static Constructor is invoked implicitly because of access to Static Attribute GO_ME. Static Method S_GET_INSTANCE( ) helps in getting instance of class ZCL_SESSION_SHARING for that session.

In this class, instance attributes MV_X & MV_Y are initialized by ZWD_UIBB_COMP1, whereas the instance attribute MV_RESULT for selected action (i.e. Addition, Subtraction, Division or Multiplication) is calculated in ZWD_UIBB_COMP2 using the methods available in class.

User Interface Building Blocks (FPM UIBB)

From an FPM perspective, UIBBs are the interface views (Web Dynpro ABAP windows) that are provided by the external application and not by FPM itself.

From other end we can consider UIBB as reusable components for reuse in several applications.

Building 1st UIBB – ZWD_UIBB_COMP1

Note: - To designate any Web Dynpro Component as a UIBB, IF_FPM_UI_BUILDING_BLOCK Interface needs to be implemented in Web Dynpro Component.

UIBB Component Structure

View V_COMP1 will be the default view visible when the application is started; User will fill the input fields and click on button calculate to get the Output which will be actually processed in another UIBB Component i.e. ZWD_UIBB_COMP2.

Attributes in Component Controller

MO_FPM is used to store the current instance of FPM.

MO_FPM_IDR is used to store the current instance of IDR (Identification Region). It is also used to change the information displayed in IDR area at runtime to display necessary information based on user actions.

MO_SESSION is used to store the instance of shared custom class that was created for exchange of data in runtime between 2-UIBB.

Important Methods in Component Controller

Code for wddoinit( ) method in Component Controller.

METHOD wddoinit.

"Get Instance of FPM.
wd_this
->mo_fpm = cl_fpm_factory=>get_instance( ).

"Get Instance of IDR (Identification Region) for the
"current FPM Instance.
wd_this
->mo_fpm_idr ?= wd_this->mo_fpm->get_service(
cl_fpm_service_manager
=>gc_key_idr ).

"Get instance of Shared Class ZCL_SESSION_SHARING.
wd_this
->mo_session = zcl_session_sharing=>s_get_instance( ).

"Set KEY-VALUES for RadioButtonByKey Element
wd_this
->set_radiobutton_key( ).

ENDMETHOD
.

Code for set_idr( ) method setting IDR Area at runtime based on selection of RadioButton Key in View to change Title & display the Radio Button Key selected alongwith Current Date & Time.

METHOD set_idr .

DATA: lv_title            TYPE          string,
lv_title_tooltip   
TYPE          string.

DATA: lv_text             TYPE          string,
lv_data            
TYPE          string,
lv_data_temp       
TYPE          c LENGTH 100.

DATA: lt_idr_item         TYPE          if_fpm_idr=>t_items_val,
ls_idr_item        
LIKE LINE OF  lt_idr_item.

***Set IDR Title

lv_title
= 'Communication between UIBB Demo'.
CONCATENATE lv_title space
INTO lv_title
SEPARATED BY space.

lv_title_tooltip
= lv_title.
wd_this
->mo_fpm_idr->set_application_title(
EXPORTING
iv_title        
= lv_title
iv_title_tooltip
= lv_title_tooltip ).


"Set Extended IDR Area (i.e. Ticket Area as well as Item Area)

"Set Ticket Area
TRY.
lv_text
= 'Action'.
lv_data
= lv_action.

wd_this
->mo_fpm_idr->set_ticket( EXPORTING
iv_top           
= lv_text
iv_bottom        
= lv_data
iv_top_tooltip   
= lv_text
iv_bottom_tooltip
= lv_data ).
CATCH cx_fpm_idr.
ENDTRY.

TRY.
wd_this
->mo_fpm_idr->set_ticket_visibility( abap_true ).
CATCH cx_fpm_idr.
ENDTRY.

"Set Item Area
lv_text
= 'Date = '.
WRITE sy-datum TO lv_data_temp DD/MM/YYYY.
lv_data
= lv_data_temp.

ls_idr_item
-label_name    = lv_text.
ls_idr_item
-label_tooltip = lv_text.
ls_idr_item
-value         = lv_data.
ls_idr_item
-value_tooltip = lv_data.
APPEND ls_idr_item TO lt_idr_item.
CLEAR: lv_text, lv_data, lv_data_temp.

lv_text
= 'Time = '.
WRITE sy-uzeit TO lv_data_temp.
lv_data
= lv_data_temp.
ls_idr_item
-label_name    = lv_text.
ls_idr_item
-label_tooltip = lv_text.
ls_idr_item
-value         = lv_data.
ls_idr_item
-value_tooltip = lv_data.
APPEND ls_idr_item TO lt_idr_item.
CLEAR: lv_text, lv_data, lv_data_temp.

IF lt_idr_item[] IS NOT INITIAL.
"initialize_items( ) clears existing Items from Items Area
CALL METHOD wd_this->mo_fpm_idr->initialize_items( ).

"add_item_group_by_val( ) adds the New Items into IDR's Item Area.
CALL METHOD wd_this->mo_fpm_idr->add_item_group_by_val( it_items =
lt_idr_item
).

"Need to set Ext. IDR Item Area visibility to true.
wd_this
->mo_fpm_idr->set_items_visibility( abap_true ).
ENDIF.

ENDMETHOD.

On execution of above method, on selection of a Radio Button item screen changes as shown in below screenshot.

When application is executed for first time below screen is displayed.

On selection of any option in Radio Button, the FPM Title & Extended IDR Area is changed using method SET_IDR( ) from component controller. Please find the below screenshot.

This will be useful in many applications, like displaying the status of Order in Logistics, Employee Details in ESS, or ESS Travel Request related Header Information and can be changed at runtime based on any user action.

View

View contains 2- Input fields, a Radiobutton Group with different actions and a calculate button which displays the Result in Pop-up (Processed by another Component).

Methods or Actions in View

METHOD onactioncalculate.

DATA lo_fpm_event     TYPE REF TO cl_fpm_event.
DATA lv_event_id      TYPE        fpm_event_id.
DATA lr_fpm_parameter TYPE REF TO if_fpm_parameter.

DATA: lt_business_param TYPE apb_lpd_t_params,
ls_business_param
LIKE LINE OF lt_business_param.

"Accessing Context Data.
DATA lo_nd_testnode TYPE REF TO if_wd_context_node.

DATA lo_el_testnode TYPE REF TO if_wd_context_element.
DATA ls_testnode TYPE wd_this->element_testnode.

*   navigate from <CONTEXT> to <TESTNODE> via lead selection
lo_nd_testnode
= wd_context->get_child_node( name = wd_this->wdctx_testnode ).

*   get element via lead selection
lo_el_testnode
= lo_nd_testnode->get_element( ).

*   get all declared attributes
lo_el_testnode
->get_static_attributes(
IMPORTING
static_attributes
= ls_testnode ).

"Setting Values entered by User in Shared Session class
"so as to make it available in ZWD_UIBB_COMP2 for calculation.
wd_comp_controller
->mo_session->mv_x = ls_testnode-var1.
wd_comp_controller
->mo_session->mv_y = ls_testnode-var2.


"Preparing Business Parameters for rasing FPM Event.
ls_business_param
-key = 'ACTION'.             "Key
ls_business_param
-value = ls_testnode-rbtxt"Value
APPEND ls_business_param TO lt_business_param.

ls_business_param
-key = 'TEXT'.
CONCATENATE ls_testnode-rbtxt '=' INTO ls_business_param-value
SEPARATED BY space.
APPEND ls_business_param TO lt_business_param.

"Creating FPM Parameter Instance to encapsulate Business Parameter values
"in it.
lr_fpm_parameter
= cl_fpm_parameter=>create_by_lpparam(
lt_business_param
).

"Create Instance of cl_fpm_event with FPM Parameters.
CREATE OBJECT lo_fpm_event
EXPORTING
iv_event_id     
= 'CALCULATE'
iv_is_validating
= abap_false
io_event_data   
= lr_fpm_parameter.

"Raise the event which is used to display Result in Popup.
"The raised event will be processed in another UIBB in the
"method Process_Event() for  calculation & the results
"will be displayed in a popup.
CALL METHOD wd_comp_controller->mo_fpm->raise_event
EXPORTING
io_event
= lo_fpm_event.

ENDMETHOD.

On click of button Calculate, FPM Event ‘CALCULATE’ is raised with required parameters for processing in another UIBB. Events raised in FPM can be processed in method process_event( ) of Component Controller for any UIBB’s added in FPM Component Configuration.

Now let’s see what need to be done in second UIBB named as i.e. ZWD_UIBB_COMP2.

Building 2nd UIBB – ZWD_UIBB_COMP2

UIBB Component Structure

V_BLANK view is created so as to make sure that UIBB gets initialized in FPM config when the application is started, but there is nothing to display from this component, so it is just a blank view embedded in Window W_BLANK which is added in FPM Component Configuration. When the calculate button is clicked in 1st UIBB, an FPM event is raised which is processed in 2nd UIBB’s Component Controller method process_event( ) which will perform the calculation & fire the event SHOW_POPUP, which will be received by this V_BLANK view so as to create a Popup Window to display results via view V_COMP2 embedded in window W_COMP2.

In this component view V_BLANK is purposely kept blank with no UI Elements whereas view V_COMP2 will display the Result in simple TextView element which is also infact dynamically created in views WDMODIFYVIEW( ) method at runtime.

Attributes in Component Controller

MO_FPM is used to store the current instance of FPM.

MO_FPM_IDR is used to store the current instance of IDR (Identification Region). It is used to change the information displayed in IDR area at runtime to display Result computed in this UIBB.

MO_SESSION is used to store the instance of shared custom class that was created for exchange of data in runtime between 2-UIBB. I this UIBB MO_SESSION provide the value of instance attributes MV_X & MV_Y which are set by 1st UIBB before raising FPM event. I this UIBB these values are used to compute the result for desired action.

MV_EVENT_ID – to store the FPM Event ID.

MV_RESULT – is used to store the result computed and to be displayed in View.

Events in Component Controller

It is fired for displaying popup window to show result computed. Event fired is handled by event handler in V_BLANK view which displays result in Popup Window. This is the main reason for using V_BLANK View and getting it added & initialized in background for handling SHOW_POPUP event raised by UIBB’s component controller.

Important Methods in Component Controller

Code for wddoinit( ) method in Component Controller.

METHOD wddoinit .

"Get Instance of FPM.
wd_this
->mo_fpm = cl_fpm_factory=>get_instance( ).

"Get Instance of IDR (Identification Region) for the
"current FPM Instance.
wd_this
->mo_fpm_idr ?= wd_this->mo_fpm->get_service(
cl_fpm_service_manager
=>gc_key_idr ).

"Get instance of Shared Class ZCL_SESSION_SHARING. Here for that session      

"already the Class is instantiated so the same instance is available

"for this UIBB and hence the attributes are also available for Computation
wd_this->mo_session = zcl_session_sharing=>s_get_instance( ).

ENDMETHOD.

Code for set_idr( ) to get existing list of Items added by 1st UIBB and to add additionally Result computed in it to display it in IDR Item Area.

METHOD set_idr .

DATA: lv_title            TYPE          string,
lv_title_tooltip   
TYPE          string.

DATA: lv_text             TYPE          string,
lv_data            
TYPE          string,
lv_data_temp       
TYPE          c LENGTH 100.

DATA: lt_idr_item         TYPE          if_fpm_idr=>t_items_val,
ls_idr_item        
LIKE LINE OF  lt_idr_item,
lt_item_group_keys 
TYPE          if_fpm_idr=>t_item_group_keys,
ls_item_group_keys 
LIKE LINE OF  lt_item_group_keys.

"Used to get item group keys in IDR Item Area
lt_item_group_keys
= wd_this->mo_fpm_idr->get_item_group_keys( ).

"Loop at all Item Group Keys to get all Items in it,
"In our example we have only One Item Group Key for all Items.
TRY.
LOOP AT lt_item_group_keys INTO ls_item_group_keys.
wd_this
->mo_fpm_idr->get_item_group(
EXPORTING
iv_key      
= ls_item_group_keys
IMPORTING
et_items_val
= lt_idr_item ).
ENDLOOP.
CATCH cx_fpm_idr.    " IDR exceptions
ENDTRY.

"Set Computed Result in FPM IDR Item Area.
lv_text
= 'Result = '.
lv_data
= wd_this->mv_result.

ls_idr_item
-label_name    = lv_text.
ls_idr_item
-label_tooltip = lv_text.
ls_idr_item
-value         = lv_data.
ls_idr_item
-value_tooltip = lv_data.
APPEND ls_idr_item TO lt_idr_item.
CLEAR: lv_text, lv_data.

IF lt_idr_item[] IS NOT INITIAL.
"Clear Existing Items
CALL METHOD wd_this->mo_fpm_idr->initialize_items( ).

"Add items in IDR Item Area
CALL METHOD wd_this->mo_fpm_idr->add_item_group_by_val( it_items =
lt_idr_item
).

"Set visibility of IDR Item Area.
wd_this
->mo_fpm_idr->set_items_visibility( abap_true ).
ENDIF.

ENDMETHOD.

Code for PROCESS_EVENT( ) method which is actually available from FPM Interface that is implemented. This method helps in processing any FPM events raised in a particular FPM Instance. Here in our example, 1st UIBB raises a FPM Event named ‘CALCULATE’ which is processed in 2nd UIBB to compute result and display it in a popup window as well as in IDR Region.

METHOD process_event.

"Check the Event Raised.
IF io_event->mv_event_id = 'CALCULATE'.
"If true, means Calculate Event raised by UIBB COMP1 is raised
"and need to be processed here in ZWD_UIBB_COMP2 to calculate
"result and also to modify IDR for displaying Result in IDR Item Area.

DATA: lv_str TYPE string.
DATA: lv_action TYPE string.
DATA: lv_result TYPE string.

"Read Business Parameters from IO_EVENT instance
CALL METHOD io_event->mo_event_data->get_value
EXPORTING
iv_key  
= 'TEXT'
IMPORTING
ev_value
= lv_str.

CALL METHOD io_event->mo_event_data->get_value
EXPORTING
iv_key  
= 'ACTION'
IMPORTING
ev_value
= lv_action.

CASE lv_action.
WHEN 'ADDITION'.
wd_this
->mo_session->add_values( ).
lv_result
= wd_this->mo_session->mv_result.
WHEN 'SUBTRACTION'.
wd_this
->mo_session->sub_values( ).
lv_result
= wd_this->mo_session->mv_result.
WHEN 'DIVISION'.
wd_this
->mo_session->divi_values( ).
lv_result
= wd_this->mo_session->mv_result.
IF wd_this->mo_session->mv_return IS NOT INITIAL.
lv_result
= wd_this->mo_session->mv_return.
ENDIF.
WHEN 'MULTIPLICATION'.
wd_this
->mo_session->multi_values( ).
lv_result
= wd_this->mo_session->mv_result.
WHEN OTHERS.
lv_result
= 'Invalid Selection'.
ENDCASE.

CONCATENATE lv_str lv_result
INTO wd_this->mv_result
SEPARATED BY space.

"Change the FPM IDR to display Result in IDR Item Area.
wd_this
->set_idr( ).

"Fire SHOW_POPUP event to display result in Popup.
"The event fired will be received by Blank View V_BLANK
"and will display view V_COMP2 with desired result.
wd_this
->fire_show_popup_evt( ).
ENDIF.
ENDMETHOD.

V_BLANK View – No UI Element is added in this view

SHOW_POPUP Event Handler for Event raised by Component Controller

METHOD show_popup .

DATA lo_window_manager TYPE REF TO if_wd_window_manager.
DATA lo_api_component  TYPE REF TO if_wd_component.
DATA lo_window         TYPE REF TO if_wd_window.

lo_api_component 
= wd_comp_controller->wd_get_api( ).
lo_window_manager
= lo_api_component->get_window_manager( ).
lo_window        
= lo_window_manager->create_window(
window_name           
= 'W_COMP2'
title                  = 'Result Window'
*                    close_in_any_case      = abap_true
message_display_mode  
= if_wd_window=>co_msg_display_mode_selected
*                    close_button           = abap_true
button_kind           
= if_wd_window=>co_buttons_ok
message_type          
= if_wd_window=>co_msg_type_none
default_button        
= if_wd_window=>co_button_ok
).

"Will display view V_COMP2 as a Popup alongwith Computed Results.
lo_window
->open( ).

ENDMETHOD.

The above method will display a Pop-Up Window containing window 'W_COMP2'.

V_COMP2 view – to show result computed

A Text View Element is added at runtime to show the result.

Below code is written in WDDOMODIFYVIEW( ) method to dynamically create a TextView UI Element with Result displayed on it.

METHOD wddomodifyview .

"In runtime a Text View element is added in View to display Computed Results
"binding the component controller WD_COMP_CONTROLLER->MV_RESULT
"attribute to it TEXT property.

DATA lr_container  TYPE REF TO cl_wd_uielement_container.
DATA lr_layout_data  TYPE REF TO cl_wd_flow_data.
DATA lr_txt      TYPE REF TO cl_wd_text_view.

IF first_time EQ abap_true.

"Get Reference to ROOT Container of View.
lr_container ?= view
->get_element( 'ROOTUIELEMENTCONTAINER' ).

"Create a Instance of Text View Element
cl_wd_text_view
=>new_text_view(
EXPORTING
id                     'TEXTV'   " ID
text                   wd_comp_controller->mv_result   "Computed Result
RECEIVING
control                lr_txt   " CONTROL
).

"Create Layout Data reference for Newly Created Text View Element.
lr_layout_data
= cl_wd_flow_data=>new_flow_data( lr_txt ).

"Set Layout data for Text View
lr_txt
->set_layout_data( lr_layout_data ).

"Add the Text View element in Root Container as a child element   
CALL METHOD lr_container->add_child
EXPORTING
index     = 1
the_child
= lr_txt.

ENDIF.

ENDMETHOD.

Just a Quick glance on Web Dynpro FPM Application, FPM Application Configuration, FPM OIF Component Configuration & FPM IDR Component Configuration for the Demonstrated Scenario.

Web Dynpro Application – OIF based Application


Application Configuration for ZWD_A_UIBB_COMP Web Dynpro Application


FPM OIF Component Configuration


1st UIBB will be presented as main view whereas 2nd UIBB will be initialized in background and displays result as a pop-up only when FPM Event is raised.

FPM IDR Component Configuration


To conclude, the main intent behind writing this blog is to demonstrate the use of ABAP Class to share data between 2-UIBB (or Web Dynpro Components), to add a silent UIBB to work in background (i.e. 2nd UIBB), to display result in a Popup by raising Event of Component Controller, and to set FPM IDR Header dynamically. The IDR Area can be used in many applications like Displaying Order Status in Logistics, to show Employee’s general details, to show Trip Status in ESS Travel Management, to show subordinates statistics like total employees on Leave, New Joiners in MSS – Managers Cockpit while displaying Team Viewer to Manager.

Please check the application demo video below of above developed scenario.

Statutory Warning - chris.paine2/blog/2011/03/28/sorry-singleton-i-dont-love-you-anymore  :wink:

Cheers.


Br.

Tushar Shinde

- Team Enteg

11 Comments
Labels in this area