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
in our first host UI component, declare one component usage to GSURLPOPUP.
in our first host UI component, declare one component usage to GSURLPOPUP.
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:
METHOD GET_P_INTERNAL_ID. 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'. ENDCASE. ENDMETHOD.
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:
DATA: lr_popup TYPE REF TO IF_BSP_WD_POPUP, 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 = 'CLEAR'). 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: DATA: 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. ENDWHILE. lv_index = lv_idx. CHECK lv_index >= 0. lv_result ?= iv_col_wrapper->find( iv_index = lv_index ). CHECK lv_result IS NOT INITIAL. rv_result = lv_result->get_related_entity( 'SocialPostRel' ). "#EC NOTEXT
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:
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.
in component controller of ZSMCQR, do component context node binding for component usage ZSMCATTR:
method WD_USAGE_INITIALIZE. DATA: 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 EXPORTING iv_controller_type = cl_bsp_wd_controller=>co_type_component iv_target_node_name = 'SOCIALPOST' "#EC NOTEXT iv_node_2_bind = 'SOCIALPOST'. "#EC NOTEXT ENDIF. endmethod.
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. TRY. lr_qs = cl_crm_bol_query_service=>get_instance( cl_crm_cm_genil_comp=>gc_query_bo_link ). CATCH cx_root. "#EC NO_HANDLER RETURN. ENDTRY. CHECK lr_qs IS BOUND. 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 ). ENDMETHOD.
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( ). ENDIF. CASE iv_usage->usage_name. WHEN 'AttachmentUploadDet' or 'AttachmentUpload' or 'AttachmentProperty'. CALL METHOD iv_usage->bind_context_node EXPORTING 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 EXPORTING 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'. ENDCASE. ENDMETHOD.
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 ). ENDIF.
implement the inbound of outbound plug of window attachmentWindow,
for source code of these two class please refer to attached document.
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.