Skip to Content
Author's profile photo Jerry Wang

maintain attachment in popup window

Hi friends,
you can see attachment UI everywhere in SAP CRM UI but most of them appear within assignment block.
This article just tells you how to put the attachment maintenance UI within pop up window.
The user can click hyperlink in table column “Post ID” to maintain the attachments for the selected post.
This article also shares the tip how to control the enablement of attachment maintenance dynamically.
As you see there is a checkbox “Allow Edit” in first table UI. If checked and navigate to attachment popup window, the attachment maintenance is enabled. Otherwise you will see all buttons in attachment popup window is disabled.
The involved UI component in this solution:
1. ZSMCQR – the first UI, contains search view with only one search parameter “Post Internal ID”, the checkbox to control attachment
maintenance, and the search result view.
2. ZSMCATT – our wrapper component to load the reuse attachment component.
3. GS_CM – standard UI component provided by SAP exposing attachment operation like create, save and delete. The benefit of using it is that now
it is not necessary for application developer to care about those CRUD operations on attachment – they are all taken over by content management
4. GSURLPOPUP – standard UI component about popup window implementation
Step 1:
in our first host UI component, declare one component usage to GSURLPOPUP.
Step 2:
we would like to make field INTERNAL_ID ( label in UI: Post ID) as hyperlink and trigger a pop up window, so we need to implement a
P-Getter on it:
  CASE iv_property.
      WHEN if_bsp_wd_model_setter_getter=>fp_fieldtype.
        rv_value = cl_bsp_dlc_view_descriptor=>field_type_event_link.
      WHEN if_bsp_wd_model_setter_getter=>fp_onclick.
        rv_value = 'ATTACHMENT'.
Then create a event handler for event ATTACHMENT to pop up a window. In the event handler implementation, we plan to pop up the
attachment maintenance window. Before we write code, we need to define one more component usage:
Now we are ready to implement the event handler:
          lv_post TYPE REF TO cl_crm_bol_entity,
          lv_bol_col TYPE REF TO CL_CRM_BOL_BO_COL.
    lv_post = zcl_jerry_tool=>get_selected_post_by_event( iv_col_wrapper = me->typed_context->searchresult->collection_wrapper
        iv_event = htmlb_event_ex->event_id ).
    CREATE OBJECT lv_bol_col.
    lv_bol_col->IF_BOL_BO_COL~add( lv_post ).
  lr_popup = comp_controller->window_manager->create_popup(
     iv_interface_view_name = 'ZSMCATT/MainWindow'
     iv_usage_name = 'ZSMCATT'
     iv_title = 'Social Post Attachment Maintenance' ).
  lr_popup->set_on_close_event( iv_view = me iv_event_name =
  lr_popup->open( iv_inbound_plug = 'FROM_SEARCH' iv_collection = lv_bol_col ).
all the content in pop up window is encapsulated in interface view MainWindow of ZSMCATT. Our next step will focus on its implementation.
the method get_selected_post_by_event is a handy method which just returns the selected post BOL entity via event:
    lv_index_str TYPE string,
    lv_idx       TYPE string,
    lv_index     TYPE i,
    lv_result    TYPE REF TO cl_crm_bol_entity.
    lv_index_str = iv_event.
  SHIFT lv_index_str UP TO '[' LEFT CIRCULAR.
  SHIFT lv_index_str BY 1 PLACES.
  WHILE lv_index_str(1) <> ']'.
    CONCATENATE lv_idx lv_index_str(1) INTO lv_idx.
    SHIFT lv_index_str BY 1 PLACES.
  lv_index = lv_idx.
  CHECK lv_index >= 0.
  lv_result ?= iv_col_wrapper->find( iv_index = lv_index ).
  rv_result = lv_result->get_related_entity( 'SocialPostRel' ). "#EC NOTEXT
Step 3:
component ZSMCATT just contains one overview page and one post header page.
The overview page has two assignment blocks: one( headerWindow ) for post header which indicates the current post being maintained, the other one( attachmentWindow ) just displays the UI of reuse component GS_CM.
see picture below:
the view contained in the attachmentWindow is not developed by us, but reuse from GS_CM.
so we define one component usage AttachmentUploadDet and include its interface view MainWindow into our attachmentWindow, as shown below:
Again the new pop up window shown in right part of screenshot above is also another standard UI of GS_CM, so we just define another component usage to include it into our component:
in previous figure you observed that there is a hyperlink “Properties”, once clicked it will navigate to attachment property UI, which is also one standard part of GS_CM.
I call this window as “DetailWindow”. So finally I have the following windows:
It means we need to define the third component usage on GS_CM to include that part into our own UI:
Step 4:
you may find that in three component usage, the same interface view MainWindow of GS_CM is included. So the real page that would be displayed in GS_CM.MainWindow depends on which outbound plug from our own UI component is called and which inbound plug of target UI will catch that.
So in this step we will define navigate link to specify the navigation behavior of each.
Step 5
in component controller of ZSMCQR, do component context node binding for component usage ZSMCATTR:
          lv_usage  TYPE REF TO if_bsp_wd_component_usage,
          lo_entity TYPE ref to cl_crm_bol_entity.
    CHECK me->typed_context->socialpost->collection_wrapper IS NOT INITIAL.
    lv_usage = me->comp_controller->get_component_usage( iv_usage->usage_name ).
    IF lv_usage->usage_name = 'ZSMCATT'.
      CALL METHOD lv_usage->bind_context_node
           iv_controller_type  = cl_bsp_wd_controller=>co_type_component
           iv_target_node_name = 'SOCIALPOST'                   "#EC NOTEXT
           iv_node_2_bind      = 'SOCIALPOST'.                  "#EC NOTEXT
Step 6
in component ZSMCATTR, create a custom controller and create a context node CMBO. Implement its on_new_focus method:
METHOD on_new_focus.
 DATA: lr_qs              TYPE REF TO cl_crm_bol_query_service,
       lr_data            TYPE REF TO data,
       ls_cmbo_prop       TYPE crmt_cmic_rfolder_attr,
       lr_entity_col      TYPE REF TO if_bol_entity_col.
  FIELD-SYMBOLS: <fs_guid> TYPE crmt_genil_object_guid.
  CHECK focus_bo IS BOUND.
      lr_qs = cl_crm_bol_query_service=>get_instance( cl_crm_cm_genil_comp=>gc_query_bo_link ).
    CATCH cx_root.                                      "#EC NO_HANDLER
  lr_data = focus_bo->get_property( 'UUID' ).
  ASSIGN lr_data->* TO <fs_guid>.
  ls_cmbo_prop-instid = <fs_guid>.
  ls_cmbo_prop-typeid = 'BUS1006'. ------------- use your own BOR type here!
  ls_cmbo_prop-catid = 'BO'.
  lr_qs->set_properties( ls_cmbo_prop ).
  lr_entity_col = lr_qs->get_query_result( ).
  me->collection_wrapper->clear_collection( ).
  me->collection_wrapper->set_collection( lr_entity_col ).
in component controller of ZSMCATTR, do the context node binding logic:
METHOD wd_usage_initialize.
DATA: lr_cn       TYPE REF TO cl_bsp_wd_context_node,
           lr_property         TYPE REF TO if_bol_bo_property_access,
           lr_cn_attr  TYPE REF TO if_bol_bo_property_access,
           lr_cuco_attachement TYPE REF TO CL_ZSMCATT_CMBO_IMPL,
           ls_cm_attr  TYPE crmt_cm_comp_st.
   IF NOT me->context IS BOUND.
     me->wd_create_context( ).
   CASE iv_usage->usage_name.
     WHEN 'AttachmentUploadDet' or 'AttachmentUpload' or 'AttachmentProperty'.
      CALL METHOD iv_usage->bind_context_node
          iv_controller_type  = cl_bsp_wd_controller=>co_type_custom
          iv_name             = 'ZSMCATT/CMBO'
          iv_target_node_name = 'CMBO'                "#EC NOTEXT
          iv_node_2_bind      = 'CMBUSOBJ'.                "#EC NOTEXT

       CALL METHOD iv_usage->bind_context_node
          iv_controller_type  = cl_bsp_wd_controller=>co_type_component
*         node at the calling component
          iv_target_node_name = 'SOCIALPOST'                       "#EC NOTEXT
*         name of the called component
          iv_name             = iv_usage->usage_name
*         node at the called component
          iv_node_2_bind      = 'PARENTNODE'.
never forget to call on_new_focus of custom controller context node manually:
lr_cuco_attachement ?= get_custom_controller( 'ZSMCATT/CMBO' ).
 IF lr_cuco_attachement IS BOUND.
        lr_property = me->typed_context->socialpost->collection_wrapper->get_current( ).
        lr_cuco_attachement->typed_context->cmbo->on_new_focus( lr_property ).
        lr_cuco_attachement->typed_context->attribute->on_new_focus( lr_property ).
Step 7:
implement the inbound of outbound plug of window attachmentWindow,
and DetailWindow:
for source code of these two class please refer to attached document.
that’s all.
Summary: in this solution we use three component usage on GS_CM, one for attachment list page in attachment assignment block, the second for Attachment upload page and the third for attachment property page. If you would like to know how to control the enablement of attachment maintenance dynamically, please continue to read the next blog.

Assigned Tags

      1 Comment
      You must be Logged on to comment or reply to a post.
      Author's profile photo R M
      R M


      I understand this is an old post. Could you please suggest me for adding the only upload attachment option from local drive through a pop up in GSTEXT and the uploaded attachments should be linked under attachment assignment block of main transaction from when GSTEXT (Notes) was opened.

      I have created a Attach button on GSTEXT for one of our note types and on clicking it opens a pop up (have done component usage for GS_CM and trying to use reuse_popu->open(‘2DOCLIST’).). It opens the pop up and allows to upload from local but is stuck at CL_GS_CM_BSPWDCOMPONENT_IMPL=>SAVE and never comes back to GSTEXT. My goal is when something is attached, should get attached in main component.

      I have all standard components. (from Component-1, I click on Notes AB which opens the GSTEXT component (Component-2) and then from GSTEXT upon clicking custom attach button opens the pop up of GS_CM (Component-3)).


      Note - in Component-1 already we have Attachment AB (GS_CM)