Wednesday, August 25, 2010

Implementing a valuehelp using the GET_V for a DDLB

In the CRM webclient you implement or redefine the valuehelp logic. Sometimes a valuehelp is not implemented in the standard, or you might want to implement a more company-specific valuehelp. This can be done by redefining the GET_V of an attribute of a context node.
A GET_V for a DDLB (DropDown List Box) would particularly contain the following code:
----------------------------------------------------------
DATA:  lt_ddlb  TYPE             bsp_wd_dropdown_table,
          lr_ddlb TYPE REF TO cl_crm_uiu_ddlb.

lt_ddlb = cl_crm_uiu_bt_tools=>get_strcmp_ddlb(
                iv_structure = [name of the structure the field is part of]
                iv_component = [Fieldname])
                .

IF NOT lr_ddlb IS BOUND.
     CREATE OBJECT lr_ddlb EXPORTING iv_source_type = 'T'.
ENDIF.
lr_ddlb->set_selection_table( it_selection_table = lt_ddlb ).

rv_valuehelp_descriptor = lr_ddlb.

----------------------------------------------------------
If you want the dropdown listbox to be occupied with values from a domain, you can use the following code:
----------------------------------------------------------

  DATA:lt_ddlb TYPE bsp_wd_dropdown_table.  
  SELECT domvalue_l ddtext INTO TABLE lt_ddlb FROM dd07t WHERE
      domname = [domain] AND ddlanguage = sy-langu.
  

  INSERT INITIAL LINE INTO lt_ddlb INDEX 1.
  SORT lt_ddlb BY value.
  IF sy-subrc = 0.
       CREATE OBJECT rv_valuehelp_descriptor TYPE cl_bsp_wd_valuehelp_pldescr

        EXPORTING
            iv_source_type = 'T'
            iv_selection_table = lt_ddlb.
 ENDIF.

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

The values from the valuehelp are determined when building the screen (do_prepare_output). This means, that if you want the available values to vary based on the contents of another field, you only have to trigger a roundtrip to the server (like raising a server event, which can be implemented in the get_p) when the contents of the field which it depends on are changed.

Furthermore, you will have to implement in the get_v of the field how the available values are filtered.

Wednesday, August 18, 2010

Field properties modification using the GET_P

In the CRM webclient, the properties of a field can be changed.
The change can vary from changing the field type, for instance changing a dropdown listbox to an ordinary input field or a checkbox or a radiobutton, to changing the tooltip text, to implementing navigation to another screen when clicking on the field.
The changes are done in the GET_P of an attribute of the context node.

1. Determine the component and view to be changed.
In the CRM webclient navigate to the search screen to be adjusted, click in a field and press . Note the component and the viewname.

2. Enhance the component and view
First enhance the component and enhance the view. How to enhance a component and a view can be found here.

3. Redefine the method DO_INIT_CONTEXT.
Redefine the DO_INIT_CONTEXT Remember to always call the super class. How to redefine a method can be found here.

[IMG OF WORKBENCH SELECTING THE CONTEXT NODE].

The GET_P is run several times when adding the field to the screen at runtime.
Examples:
Changing a field to a hyperlink:
The following example changes the field to a hyperlink, which when clicked upon, will navigate to a different screen

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 = 'NAVIGATE_TO_TARGET'.
ENDCASE.

Of course, you will also need to implement the event EH_ONNAVIGATE_TO_TARGET. 

Changing a field to a checkbox and adding a tooltip.
CASE iv_property.
  WHEN if_bsp_wd_model_setter_getter=>fp_fieldtype.
      rv_value = cl_bsp_dlc_view_descriptor=>field_type_checkbox.
  WHEN if_bsp_wd_model_setter_getter=>fp_tooltip.
      rv_value = text-001.
ENDCASE.
Additional comments.
One of the importing parameters of the get_p is the field IV_DISPLAY_MODE. This field can be checked to see whether the field is in change or in display mode. You can implement different properties to the field in change and in display mode.
Another of the importing parameters is the IV_INDEX. This can be used to determine in which line you are in the table.

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 ).
 
 
---------------------------------------------------------

Wednesday, August 4, 2010

Redefining a method of a view

If you need to redefine a method because you want to alter the standard behavior of the system, you should always first 'enhance the component and enhance the view'. When enhancing, the system generates enherited z-classes containing only inherited methods. How to redefine a view can be found here.

If you want to alter the coding of the standard, you can now redefine an inherited method. Redefining means that the system no longer calls the standard class, but your redefined class.

It is recommended to always call the standard coding either in the beginning of the redefined class or in the end, depending on what kind of alteration you are planning. This way, if the standard functionality changes, your code still calls this changed functionality.

The standard (inherited) method can always be called using ABAP coding:

CALL METHOD super->[NAME OF THE CURRENT METHOD]
    EXPORTING
        [IMPORTING PARAMETERS] = [IMPORTING PARAMETERS]
    IMPORTING
        [EXPORTING PARAMETERS] = [EXPORTING PARAMETERS]

Of course if there are no parameters, the importing and exporting parameters can be left out.

Example:

CALL METHOD super->do_prepare_output
    EXPORTING
        iv_first_time = iv_first_time.

This method calls the do_prepare_output of the parent class.