Wednesday, August 11, 2010

Add buttons to a view

Creating the new button involves the following four steps:
  1. Enhance the component and view
  2. Create a method to create the button
  3. Call the new method from the do_prepare_output
  4. Implement the event to be triggered when the button is clicked
1. Enhancing the component and view
First enhance the component and enhance the view. How to enhance a component and a view can be found here.

2. Creating the method to create the button
In the workbench, navigate to the implementation class of the view. The implementation class is located directly under the view controller. The implementation class typically ends with '_IMPL'.

Double click on this Z-class. If the class does not start with a Z, you have either not enhanced the view yet, or you should go one screen back and re-open the component in the workbench.
In the attributes tab, create a new attribute called GT_BUTTONS (Instance Attribute, Public) of type CRMT_THTMLB_BUTTON_T




In the Methods tab, create a new method called 'CREATE_TOOLBAR' or 'CREATE_BUTTONS' (Instance Method, Private).

In the Method, add the following code:

---------------------------------------------------------
  DATA: ls_button     TYPE crmt_thtmlb_button.
  CLEAR gt_button.
  ls_button-type     = cl_thtmlb_util=>gc_icon_add
  ls_button-text     = text-001.
  ls_button-on_click = [name of the event].
  ls_button-enabled  = [abap_true|abap_false].
  ls_button-id       = [ID].
  APPEND ls_button TO gt_buttons.
  CLEAR ls_button.
---------------------------------------------------------

One of the variables is the name of the event. You can name this event anything you like. For instance 'create_line' or 'edit_line'. The implementation of the event will be done in step four.

The following attributes are available to buttons, and can be set:

ID    
   Identifies the button at runtime
TEXT    

   This is the text as displayed on the button -Keep it short!-
TOOLTIP    

   This is the text that shows when the mouse hovers over the button
ON_CLICK    

   This is the event that is raised when clicking the button
ON_CLIENT_CLICK

   ???
ENABLED

   If this is set to false, the button is greyed out, and cannot be clicked.
ICON_SRC

   This can be used to refer to an externally located gif image, i.e. '/sap/bc/bsp/...../w_pdf__s.gif',
TYPE

   This is used to add standard icons to the button. The available set can be found in cl_thtmlb_util, in the attributes tab.

3. Redefine the do_prepare_output to call the method as defined in step 2.

In the view, navigate to the Request Processing, and redefine the method do_prepare_output.
How to redefine a method can be found here.
In this method, call the newly created method to create the toolbar buttons.
This would be a statement like create_toolbar( ) or create_buttons( ).



4. Create the event to be raised when clicking the button 

In the view, navigate to the node 'Event Handler'. Right click on it, and click on 'create'. Create an event with the exact name as coded in step 2.

The system will now create a method within the event handler called 'EH_ON[event_name]'. Double click this event to enter the logic to be performed when clicking the button.


Examples:
Having the button switch between edit and change mode.
me->view_group_context->set_view_editable( me ).

Call a transaction launcher transaction.
In order to navigate to a screen or launch transaction in the coding, you should customize a 'Generic OP Mapping' in the nav bar profile.


IMG:
SAP IMG -->  Customer Relationship Management --> UI Framework --> Technical Role Definition --> Define Navigation Bar Profile.


Within the nav bar customizing transaction, Select the correct profile, and double click on 'Define Generic OP Mapping' on the left side of the screen.


Add a line to the table where you map the new object name to an existing logical link. You can use this object name in the coding to call the logical link. The action should be the same as the action as customized in the OP Mapping.



---------------------------------------------------------
  DATA: lr_col            TYPE REF TO cl_crm_bol_bo_col.
  DATA: lr_nav_descr TYPE REF TO if_bol_bo_property_access.

  lr_nav_descr = cl_crm_ui_descriptor_obj_srv=>create_ui_object_based(
                 iv_ui_object_type   = [name of the object type]
                 iv_ui_object_action = 'D' ).

  CREATE OBJECT lr_col.
  lr_col->if_bol_bo_col~insert( iv_bo    = lr_nav_descr
                                iv_index = 1 ).

  op_tobt( iv_data_collection = lr_col ).


---------------------------------------------------------

If you do this, you should also implement the outbound plug op_tobt.
This outbound plug contains the following coding:


---------------------------------------------------------
  DATA:
  lr_window      TYPE REF TO cl_bsp_wd_window.

  lr_window = me->view_manager->get_window_controller( ).
  lr_window->call_outbound_plug( iv_outbound_plug   = 'TOBT'
                                 iv_data_collection = iv_data_collection ).
 
 
---------------------------------------------------------

15 comments:

  1. If we create a Z component do we still need to enhance?
    Can we create multiple enhancement set for same component and how do we manage the changes in such cases?

    ReplyDelete
  2. Geor,

    You don't need to enhance if you have a Z-component, you can just code it in there.
    I personally prefer to have as little enhancement sets as possible. Only if you have multiple clients on your CRM system that require different programming in the interface layer, you should consider having multiple enhancement sets I think (convince me otherwise ;-)).

    Regards,
    Pieter

    ReplyDelete
  3. Hi,

    I did what you say.I open the other window.
    But the other window, I can not transfer the context.What should I do?

    Thanks.
    Fatih.

    ReplyDelete
  4. Dear Fatih,

    The transfer of the context is handled in the launch transaction definition. My best guess would be that there is something missing there.

    Feel free to email me screenshots if you have doubts :-).

    Regards,
    Pieter

    ReplyDelete
  5. Hi Pieter,

    I sent an e-mail.Please help :)

    Thanks.

    ReplyDelete
  6. Hi pieter,

    Can I use this method to enhance a search view? Where the buttons will be visible?

    Gitesh.

    ReplyDelete
  7. Gitesh,

    I am afraid not. The buttons in search screens are hardcoded in the BSP. If you look at the MainSearch.HTM in the search component in the component workbench (for instance in the BP_HEAD_SEARCH), you will notice there are two buttons defined.
    One is called SEARCH_BTN, the other is CLEAR_BTN.
    You can add a button here if you like.
    To enable the button to do something, add the OnClick parameter to the button, for instance 'MYBUTTON'.
    You can now implement the event MYBUTTON in the event handler node (which will result in a class eh_onmybutton). The rest you can implement as desribed in the post.

    Regards,
    Pieter

    ReplyDelete
  8. Hi pieter,

    thank you for the note. do you have any examples of enhancing the view itself? Like superimposing a view on an existing view?
    My requirement is to add a custom view in blank area of the search view. What we are doing is that moving all fields of the search view to the left side and keeping the right side on the screen empty. Can we superimpose a custom view on it?

    ReplyDelete
  9. Dear Gitesh,

    I have never added a custom view to a search view, and I doubt if it will work. I think the platform won't support it, especially if you would want interaction with for instance the search criteria.

    Good luck,
    Pieter

    ReplyDelete
  10. Hi Pieter,

    I added a button to BT115QH_SLSQ/MainWindow.
    Component: BT115QH_SLSQ/MainWindow
    Method: IF_BSP_WD_TOOLBAR_CALLBACK~GET_BUTTONS
    Source: ls_button-text = 'Payment'.
    ls_button-on_click = 'payment'.
    ls_button-enabled = abap_true.
    ls_button-TYPE = cl_thtmlb_util=>GC_PICT_BENEFITS.
    * ls_button-tooltip = 'TEST BUTTON'
    APPEND ls_button TO rt_buttons.
    CLEAR ls_button.

    and I created an event that "EH_ONPAYMENT" in BT115QH_SLSQ/Details.

    I see payment button and I can click it but could not handle its event.

    Something missing.Can you help me?

    ReplyDelete
  11. Muhammed,

    I am not sure, but maybe ls_button-on_click = 'payment' should be 'PAYMENT' (in capitals).

    I think it should be possible to raise the event in one view and handling it in another view (as you are doing) without any further adjustments...

    Regards,
    Pieter

    ReplyDelete
  12. Thanks for your helping.

    I tried all combitination of 'PAYMENT' :) but nothing happen.:S I dont know what is the problem.

    Are you sure everything is ok in my code and technique?

    I add button to MainWindow button try to handle it in DetailsView. Is it true?

    ReplyDelete
  13. Just found out that the ON_CLIENT_CLICK option triggers processing on the client side without any server processing. An example would be the following to open a new browser window.

    ls_button-on_client_click = `javascript:window.open('http://www.google.com')`.

    ReplyDelete
  14. Hi Pieter,
    I create new button on component BTCUSTOMER_H following your post above. But on webui, this error appears:
    An error occurred during event processing in view CustomerH.htm1 of &2 &3
    An exception has occurred
    Exception Class CX_BSP_WD_INCORRECT_IMPLEMENT - Create Outbound Plug 'TO_OPP' in Window 'BTCUSTOMER_H/MainWindow'.
    Method: CL_BTCUSTOM_MAINWINDOW=>CALL_OUTBOUND_PLUG
    Source Text Row: 17
    Can you help me, please!
    Longnd

    ReplyDelete
  15. Dear Longnd,

    I am not sure, but I think the outbound plug has to exist on the window where the view you have enhanced is embedded. In this case, it seems to be BTCUSTOMER_H/Mainwindow.
    You can try to enhance the BTCUSTOMER_H and implement the outbound plug there.


    Hope this helps.

    Regards,
    Pieter

    ReplyDelete