Skip to Content
Author's profile photo Uwe Kunath

Confirmation boxes in Floorplan Manager

Confirmation boxes vs. Dialog boxes

In FPM, there is a concept called “Dialog Boxes” which allows you to embed any FPM component configuration in popups. Usually, this is overkill for simple confirmation boxes as you usually want to display a warning message there. Depending on the user decision “Yes” or “No” there is be some further backend logic to be invoked. This blog post deals with the question how showing these confirmation boxes can be achieved with quite few effort in a clear, transparent way.

Standard approach (FPM)

Use the FPM Interfaces for GUIBBs whenever possible. These interfaces are called IF_FPM_*_EXT*. These interfaces each provide a method called NEEDS_CONFIRMATION which allows you to intercept and defer event processing.

GUIBB Interfaces.PNG

For freestyle UIBBs, there is also a method IF_FPM_UI_BUILDING_BLOCK~NEEDS_CONFIRMATION.

You can specify a warning message by using the exporting parameter EO_CONFIRMATION_REQUEST. It allows you to specify title, message and which button texts should be displayed. In case the user confirmed the warning message, the PROCESS_EVENT is called.

Whenever possible, use this standard approach.

Individual approach (custom developed)

However, this approach has its drawbacks. One of the drawbacks is that multiple message lines do not look that good as you need to concatenate the texts. Also, mixing success and warning or even error messages (which is not recommended to use in confirmations) is not possible. Last but not least, the width of the popup cannot be changed.

So this chapter is about how you can define your own popup windows in FPM.

The first step starts with raising an FPM event in the GUIBB feeder class / freestyle UIBB and attaching a message table like BAPIRET2_TAB and a self-defined callback object. I do not further describe how the callback object could work. Please see this blog post for further details to get an idea how such a callback could work.

There will be another UIBB to handle this event and show the popup with the messages that are defined in the message table attached to the event.



DATA lo_event TYPE REF TO cl_fpm_event.
lo_event = cl_fpm_event=>create_by_id( iv_event_id = ‘OPEN_CONFIRMATION_POPUP’ ).
lo_event->mo_event_data->set_value( iv_key = ‘MESSAGES’iv_value = lt_bapiret2 ).
lo_event->mo_event_data->set_value( iv_key = ‘CALLBACK’ iv_value = lo_callback_activity_complete ).
mo_fpm->raise_event( lo_event ).


Create a webdynpro component with an empty main window and empty view V_POPUP_EMBEDDER which implements IF_FPM_UI_BUILDING_BLOCK. This allows you to embed this webdynpro component into your FPM application. As this component only needs to be visible, when a popup needs to be shown, you can embed an empty window with an empty view V_POPUP_EMBEDDER to your FPM application. It is crucial that the component takes part in every event loop so the empty view should not be in a tab, rather at a position which is always displayed.

Create an event POPUP_WITH_CALLBACK with the IMPORTING parameters to cover both the callback object type and BAPIRET2-table type.

Create a webdynpro component with an empty main window and empty view V_POPUP_EMBEDDER which implements IF_FPM_UI_BUILDING_BLOCK. This allows you to embed this webdynpro component into your FPM application. As this component only needs to be visible, when a popup needs to be shown, you can embed an empty window with an empty view V_POPUP_EMBEDDER to your FPM application. It is crucial that the component takes part in every event loop so the empty view should not be in a tab, rather at a position which is always displayed.

Create an event POPUP_WITH_CALLBACK with the IMPORTING parameters to cover both the callback object type and BAPIRET2-table type.

Component controller event to raise the popup window.png

The process event method retrieves the attached event parameters and raises the internally used webdynpro event:


METHOD process_event.
 DATA lv_title TYPE string.
 DATA lt_message TYPE string_table.
 DATA lr_event TYPE REF TO data.
 FIELD-SYMBOLS <lo_event> TYPE REF TO cl_fpm_event.

 FIELD-SYMBOLS <lv_key> LIKE LINE OF lt_keys.
 FIELD-SYMBOLS <lv_any> TYPE any.
 DATA lr_data TYPE REF TO data.
 DATA lo_object TYPE REF TO object.

 CASE io_event->mv_event_id.
 WHEN ‘OPEN_CONFIRMATION_POPUP’.
 io_event->mo_event_data->get_value(
 EXPORTING
 iv_key =  ‘MESSAGES’
 IMPORTING
 ev_value = lt_bapiret2 ).
 io_event->mo_event_data->get_value(
 EXPORTING
 iv_key =  ‘CALLBACK’
 IMPORTING
 ev_value = lo_callback ).
      wd_this->fire_popup_with_callback_evt(
 io_callback = lo_callback
 it_bapiret2 = lt_bapiret2
 ).
 ENDCASE.ENDMETHOD.

Create the component controller’s event handler in the empty view.

Popup handler view methods.png


METHOD open_popup_with_callback.
”store callback object in view’s attributes
 wd_this->mo_callback = io_callback.
 DATA lo_comp_api TYPE REF TO if_wd_component.
 DATA lo_controller_api TYPE REF TO if_wd_controller.
 DATA ls_config TYPE wdr_popup_to_confirm.
 DATA: lt_text_table TYPE string_table,
 lv_text_table TYPE string,
 lv_title TYPE string.

 ls_config-button_cancel-enabled = abap_false.

 lo_controller_api = wd_this->wd_get_api( ).
 lo_comp_api = wd_comp_controller->wd_get_api( ).
 lv_title = ‘Sure?’

 DATA: l_api_component  TYPE REF TO if_wd_component,
 l_window_manager TYPE REF TO if_wd_window_manager,
 l_api_view       TYPE REF TO if_wd_view_controller.


 l_api_component = wd_comp_controller->wd_get_api( ).
 l_window_manager = l_api_component->get_window_manager( ).

 wd_this->mo_window = l_window_manager->create_window(
 window_name = 'W_POPUP'
 title = iv_title
 button_kind = if_wd_window=>co_buttons_yesno ).

 wd_this->mo_window->open( ).

 l_api_view = wd_this->wd_get_api( ).

 wd_this->mo_window->set_on_close_action(
 view        = l_api_view
 action_name = 'CLOSE_POPUP' ).
 wd_this->mo_window->subscribe_to_button_event(
 button      = if_wd_window=>co_button_yes
 action_name = 'CONFIRM_POPUP'
 action_view = l_api_view ).
 wd_this->mo_window->subscribe_to_button_event(
 button      = if_wd_window=>co_button_no
 action_name = 'CLOSE_POPUP'
 action_view = l_api_view ).
 ENDMETHOD.


Create the actions CLOSE_POPUP and CONFIRM_POPUP in the view. CONFIRM_POPUP should execute the callback object’s callback method, like



 IF wd_this->mo_callback IS NOT INITIAL.
 wd_this->mo_callback->callback( ).
 CLEAR: wd_this->mo_callback.
 ENDIF.

Create the window W_POPUP with its own view V_POPUP. Show the content of the message table that came with the FPM event e.g. in a message area.

Sample Popup view in the generic webdynpro component.png

The popup will look like this. The screenshot shows only one warning message, so there is no benefit yet compared to the standard approach provided by the FPM runtime. But it is capable of showing multiple warnings and even different message types.

Popup.png

Assigned Tags

      11 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Johannes Schnatz
      Johannes Schnatz

      Interesting Blog, Uwe. Thanks.

      Author's profile photo Uwe Kunath
      Uwe Kunath
      Blog Post Author

      Thank you, you are welcome 🙂

      Author's profile photo Naveen Y
      Naveen Y

      Hi Uwe,

      I like your Blog.. I have one issue with FPM-OIF , could you please take a look and let me know your feedback.

      Is it possible to open a web dynpro window whose view embeds the FPM_GAF_COMPONENTu2019s FPM_WINDOW multiple times in dialog window?

      I have a web dynpro component WDC1 which use FPM_GAF_COMPONENT and provide the component configuration for FPM.

      Thereu2019s a WINDOW1 (with View1) in WDC1 which has a view container and the FPM_GAF_COMPONENTu2019s FPM_WINDOW is embedded.

      I have a button in WDC1 which create a new dialog window by calling if_wd_window_manager->CREATE_WINDOW as code below.

            lo_window = lo_window_manager->CREATE_WINDOW(

                MODAL                = ABAP_TRUE

                WINDOW_NAME          = 'WINDOW1'

                TITLE                = 'Test opening FPM multiple times'

                CLOSE_BUTTON         = ABAP_TRUE

      *          BUTTON_KIND          =

      *          MESSAGE_TYPE         = IF_WD_WINDOW=>CO_MSG_TYPE_NONE

      *          CLOSE_IN_ANY_CASE    = ABAP_TRUE

      *          MESSAGE_DISPLAY_MODE =

      *          DEFAULT_BUTTON       =

                IS_RESIZABLE         = ABAP_TRUE

            ).

      .

      It works for the first time when I click the button, a dialog window opens with my FPM GAF stuff.

      But when I click the button the second time after closing the dialog window, it generates a dump with error message saying u201CComponent Usage Group MESSAGE_AREA_USAGES Already Existsu201D.

      In ST22, the dump was generated in WDDOINIT of view u201CMAINu201D on FPM_GAF_COMPONENT which looks to me like the message manager is already created in the first time.

        lr_component = wd_comp_controller->wd_get_api( ).   lr_usage_group = lr_component->create_cmp_usage_group(                        name            = 'MESSAGE_AREA_USAGES'                        used_component  = 'FPM_MESSAGE_MANAGER' ).   wd_this->mo_message_area_usage = lr_usage_group->add_component_usage( 'MESSAGE_AREA_USAGE' ).   wd_this->mo_message_area_usage->create_component( 'FPM_MESSAGE_MANAGER' ).

      I tried to remove the component usage of FPM in my WDC1 or delete  the component directly, hoping that this will clear the memory , but doesnu2019t work, only bring more different dumps  which make this look like a wrong direction as I am interfering the lifecycle of FPM itself.

      Can anyone share some ideas here? Thanks in advance.

      P.S. The FPM GAF works fine when I open the window in new browser (by calling if_wd_window_manager->create_external_window).

      Author's profile photo Uwe Kunath
      Uwe Kunath
      Blog Post Author

      Dear Neevan,

      opening an FPM application will work as this is the common way of using FPM applications and every new browser windows has its own roll area.

      Unfortunately you can not have multiple FPM applications in one application.

      I already tried before, but differently than what you are trying to do: I tried to embedd more than one floorplan in one webdynpro component at a time. This caused a dump similar to the one you described. However, I still do not understand why this restriction seems to apply also in your case as you are just showing / hiding one single floorplan application at a time. Maybe the sap colleagues can help in the FPM space...

      regards,

      Uwe

      Author's profile photo Mainak Aich
      Mainak Aich

      Dear Uwe,

      It was a nice blog. I have one requirement but not sure how to do it -

      I need to show a popup in my GAF FPM. But the user wants if the browser window is minimized when the popup comes, the browser window will be blinked to inform the user to open the window. Or else, the popup window should display as a separate modal browser window that will attract user attention if user works in other tab in the browser or any other windows application.

      Basically the idea is user should know as soon as the popup comes to notify new item arrived based on automatic periodic refresh activity in my application. Do you think any of these 2 way is possible to implement?

      Thanks,

      Mainak

      Author's profile photo Ovidiu Hancila
      Ovidiu Hancila

      Hi,

      First thank you for the blog.

      I have another requirement but I dont know exactly how to do it.

      I have some checks with some warnings messages. After the first popup is raised with a message , and the user decision is "YES" , I need to raise the next popup with another message, and so on for the same event(for example, i have some checks for the FPM event leave_initial_screen).


      I`m enhancing a standard component , and I am using the standard way (...~NEEDS_CONFIRMATION) .


      It is possible to implement?

      Thanks a lot,

      Ovidiu



      Author's profile photo Uwe Kunath
      Uwe Kunath
      Blog Post Author

      Dear Hancila,

      what you are talking about will not work with the NEEDS_CONFIRMATION - method as you can only prevent the event loop here once.

      In your case I would go for the Callback-based approach: Pass the FPM instance of type IF_FPM and an individual message structure to each of the callbacks and raise popup events with the follow-up popup there using similar coding like that.

      DATA lo_event TYPE REF TO cl_fpm_event. 

      lo_event = cl_fpm_event=>create_by_id( iv_event_id = ‘OPEN_CONFIRMATION_POPUP’ ).  

      lo_event->mo_event_data->set_value( iv_key = ‘MESSAGES’iv_value = lt_bapiret2 ). 

      lo_event->mo_event_data->set_value( iv_key = ‘CALLBACK’ iv_value = lo_callback_activity_complete ). 

      mo_fpm->raise_event( lo_event ). 

      Regards,

      Uwe

      Author's profile photo Former Member
      Former Member

      Any simpler solution for the requirement of a simple popup with a question and a Yes or No button we can capture (the old popup_to_confirm fm) that can be implemented with an FPM?

      Thanks

      Author's profile photo Former Member
      Former Member

      Replying to myself - I actually resolved my own question by implementing the relevant IF_FPM_*_EXT interface in my class feeder then coding in the NEEDS_CONFIRMATION method to identify where to have a confirmation popup, then creating my own object of class cl_fpm_confirmation_request with the confirmation text I wanted (instead of the default provided by go_data_loss) and voila, I got my basic confirmation popup that will allow the user to stop the action or proceed if desired.

      😀

      Author's profile photo Former Member
      Former Member

      Simple & effective!

      Author's profile photo Wout Rerren
      Wout Rerren

      Hi,

       

      Very nice blog!

       

      I was wondering which object type was linked to the IO_CALLBACK event parameter?