CRM and CX Blogs by Members
Find insights on SAP customer relationship management and customer experience products in blog posts from community members. Post your own perspective today!
Showing results for 
Search instead for 
Did you mean: 
Active Contributor

When I was starting to work with SAP CRM and in particular with Interaction Center functionality I was inspired by the document on how to add an IC toolbar button by john.burton. I still remember those funny feeling that there is always a place for fun during routine daily work. But since then I was interested in the following. Ok, we know how to add a button. But if there is a button then we need a place to put its logic in there. There were solutions similar to this one. But this was always a modification of js-files or standard basic components which would probably get you in trouble with any new standard updates in them shipped during next service package or OSS notes. Personally I've seen such issues when standard IC buttons or ICI integration stoped working.

BTW, user parameter WCF_IGNORE_ENHANCEMT set as A has been very handy to identify such issues.

During the latest project I realized that there is already new possibility to add a logic for z-button handling in IC toolbar. But let's start from the scratch. System creates IC toolbar buttons in component ICCMP_CCS page fragment wsb_icon.htm. All buttons (even z-one) are created with onClientClick attribute as the call of buttonCallback function passing button's ID.

There is the way I'm talking about in component CRMCMP_IC_FRAME in Pages with Flow Logic inside header_jscripts.js. No surprises yet.

The code which draw my attention is at the very end of wsb_handler function. This function is called from buttonCallback (which is in ICCMP_CCS/wsb_icon).

    /* simulate htmlb click in current view */
    var vWindow = contextArea.getApplicationWindow( );
    var vContainer = vWindow.document.getElementById( wsb_cButtons );
    if( vContainer == null )
      return ;
    var buttons = vContainer.children;
    var vRegExp = new RegExp( "_" + value + "$" );
    for( i = 0; i < buttons.length; i++ )
      if( buttons[ i ] vRegExp ) !=  - 1 )
    if( i >= buttons.length )
      return ;
    var button = buttons[ i ];
    if( button == null )
      return ;
    event.cancelSubmit = false; );
  catch( ex ){}

There is a comment there which describes what is done. The logic we actually have is:

- find a container element with id 'wsb_buttons' (constant wsb_cButtons). The actual area where the system tries to find this element includes navigation bar area and work area.

- take its (direct) children and go through them looking for a 'button' with id formed as blablabla_<button_id> (RegExp call in mentioned code).

- click it.

Let's assume that we want to handle our button which is defined in IC toolbar as zMyICButton (IMG -> CRM -> Basic Functions -> Communication Management Software Integration -> Define Toolbar Buttons and Define Toolbar Profiles).

So we need to create a container with ID 'wsb_buttons' and put a button inside it with id which ends with underscore and IC toolbar button ID. In our case IC toolbar button ID is zMyICButton. So our button should have an id for instance as btn_zMyICButton.

But where to put this stuff? First place which came to my mind was hidden view (CRMCMP_IC_FRAME/HiddenView ). As far as I started this blog to describe as much a 'standard' way as possible I wouldn't be completely satisfied with this solution.

Exploring some other possibilities I found the way without enhancements. And the answer is Layout Profile

Layout profile (IMG -> CRM -> UI Framework -> Technical Role Definition -> Define Layout Profile) of a business role defines components which are loaded in navigation bar area.

We can create an own 'hidden' component and put our 'buttons' in it.

In my example this component will be quite simple. No context nodes. Just a component, a window, a view. For example ZTESTICBUTTONS component, ZTESTICBUTTONS/MainWindow window and ZTESTICBUTTONS/TestICButton view attached to it.  The htm page of the view should be the following:

<%@page language="abap" %>
<%@extension name="thtmlb" prefix="thtmlb" %>
<%@extension name="chtmlb" prefix="chtmlb" %>
<%@extension name="bsp" prefix="bsp" %>
<SPAN style = "display:none;">
<div id = "wsb_buttons" >
<thtmlb:link  id      = "btn_zMyICButton"
              text    = "standard"
              onClick = "zmyicbutton" />
<%--Other z-IC-buttons have to be placed here--%>

Note that id is case sensitive here.

Certainly, extensions might be reduced. But I left this as it was.

You may complain: 'Hey, it's not a button! It's a link!'. And you will be completely true. We can not use thtmlb:button element because when thtmlb:button is being rendered <a> tag, which includes onClick attribute and appropriate id, is surrounded with an additional <span> tag. And as far as above mentioned code from wsb_handler takes only direct children of 'wsb_buttons' element these <span> tags ruin all the logic.

The thtmlb:link element will satisfy our needs in this case.

Also we will need an event handler for zmyicbutton event in the view controller. Event handler is quite simply. Just for demonstration purpose:

METHOD eh_onzmyicbutton.
* confirm_poput is a view controller attribute:
* public section.
*  data CONFIRM_POPUP type ref to IF_BSP_WD_POPUP .
  IF confirm_popup IS NOT BOUND.
    DATA: lv_title TYPE string,
    lv_text TYPE string.
    lv_title = 'My IC Button'.
    lv_text = 'Does it work?'.
    CALL METHOD comp_controller->window_manager->create_popup_2_confirm
        iv_title          = lv_title
        iv_text          = lv_text
        iv_btncombination = if_bsp_wd_window_manager=>co_btncomb_yesnocancel
        rv_result        = confirm_popup.
  confirm_popup->open( ).

After the component is created define it as layout component ( IMG -> CRM -> UI Framework -> Technical Role Definition -> Define Layout Components ) and attach it to Layout Profile used in your business role.

Comp. Usage is freely (uniquely) defined.

And here the result:

We can utilize these IC-buttons to open own popus (for example implementing directory search from SAP CRM using interface DAI from SAP BCM), implement quick dialing/transfer buttons etc.

But... We are not done yet. If a button not handled in standard way in wsb_handler, corresponding event will be sent to the system using a code just above the code which sends the click to buttons.

  if( bEventSend )
    wsb_action_event_send( value, paramA, paramB );

This particular code might generate for example a warning message in WebUI 'You must be in an active call to use this function' (message class CRM_IC_APPL_UI_CHMSG number 021) when pressing our own z-toolbar button (in phone channel it comes from CL_CRM_MCM_PHONE_CHANNEL->ACTION_HANDLER on send_bsp_msg( msg_type = 'W' msg_number = '021'. call ).

Unfortunately the call to wsb_action_event_send function is made before generating a button click in wsb_handler function. I didn't found any suitable way to prevent this function call rather then avoid this warning message by implementing implicit enhancement in the very begining of CL_CRM_MCM_SESSION->ACTION_HANDLER class as:

METHOD action_handler .
ENHANCEMENT 1  ZMCMSESSION.    "active version
* All z-actions are not handled in MCM if this enhancement is active
  IF action CP 'z*' OR action CP 'Z*'.
  DATA: ex  TYPE REF TO cx_crm_mcm_exception.

Yes, we made one enhancement. But this enhancement is less painful comparing to enhancing js-files and basic components. We can even leave this enhancement aside and take the message as it is. There will be some issues openning confirmation popups. But popups with own components should work well.

Calling to SAP regarding this particular message: Probably it would be better if wsb_action_event_send call is made only if no corresponding button exists for IC toolbar button.