Adding Select Option to ABAP Web Dynpro Component

Background

Web Dynpro does not have any built in controls for select options, this is achieved using WDR_SELECT_OPTIONS component.

In this blog I am going to create a simple Web Dynpro to show how to add select option in Web Dynpro using WDR_SELECT_OPTION. This Web Dynpro is based on function module GET_MATERIAL_LIST. GET_MATERIAL_LIST function module have importing parameter material and material group in form of range table, which represent underlying data of select option, it retrieve data from MARA table based on importing parameter and put it in exporting parameter which is table type of MARA. This will serve as model for our simple Web Dynpro.

FUNCTION get_material_list.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(FILTER_MATERIAL) TYPE  RANGES_MATNR
*"     REFERENCE(FILTER_MAT_GROUP) TYPE  MDS_MATKL_RANGE_TAB
*"     VALUE(MAXROWS) TYPE  BAPIF4A-MAX_ROWS DEFAULT 10
*"  EXPORTING
*"     REFERENCE(MATERIALS) TYPE  MARA_TT
*"----------------------------------------------------------------------

  DATA : li_matnr TYPE ranges_matnr ,
         li_matkl TYPE mds_matkl_range_tab .

  li_matnr = filter_material .
  li_matkl = filter_mat_group .

  DELETE li_matnr WHERE sign IS INITIAL .
  DELETE li_matkl WHERE sign IS INITIAL .

  SELECT  *
    UP TO maxrows ROWS
    INTO TABLE materials
    FROM mara
   WHERE matnr IN li_matnr
     AND matkl IN li_matkl .

ENDFUNCTION.

Web Dynpro in the end will look like this.

Web Dynpro Select Option

Before I start I will describe in what sequence relevant code in various methods are executed which in turn build this application.

  1. User request for web Dynpro component
  2. WDDOINIT method of view calls method CREATE_SEL_SCREEN where logic to build select options are. Screen is then; along with select option and grid is presented to user.
  3. User interacts with select option and press return.
  4. Hook method WDDOAFTERACTION of view is fired which call method COPY_SEL_VALUES. COPY_SEL_VALUES contains logic which reads select option data and binds it to view context.
  5. COPY_SEL_VALUES calls method EXECUTE_GET_MATERIAL_LIST in component controller which has logic to call function module GET_MATERIAL_LIST.
  6. EXECUTE_GET_MATERIAL_LIST read input values from context (copied by method COPY_SEL_VALUES), call function module GET_MATERIAL_LIST and bind result back to context.
  7. Grid displays the result from context.

Create Web Dynpro Component

Go to SE80 and select ‘Web Dynpro Comp/Intf’ from dropdown and create a new Web Dynpro Component. I am going to name mine as ZPW_MAT_LIST.

create web dynpro

With this step I have window and view in place with view already assigned to window.

Add component WDR_SELECT_OPTIONS to Web Dynpro. WDR_SELECT_OPTIONS encapsulate all logic to build selection screen, very similar to selection screen in report, at runtime and before you can use this magic wand you need to add this lovely component to your Web Dynpro. It’s like include statement or type-pools statement, if I may say so. Double click on Web Dynpro name, top node in SE80 tree structure and enter a name under Component Use, which you would like to use to refer to this component ch is WDR_SELECT_OPTIONS. I am using name SELECTION_SCREEN because it’s easy to remember that way, but you are free to use any name here.

web dynpro component use


Service Call

Create service call to function module GET_MATERIAL_LIST. Right click on Web Dynpro node and navigate to Create, Service call.

web dynpro service call

Follow wizard to create service call EXECUTE_GET_MATERIAL_LIST in component controller. Change Object type in step 4 to ‘Context Node/Attributes’.

After wizard finishes you should have method EXECUTE_GET_MATERIAL_LIST in component controller and context of component controller should look like this



Map Component Controller Context to View Controller

Navigate to context tab of view MAIN. Before we can map Component Controller Context to View Context we need to define component usage. To define this click on Controller Usage button and select Component controller from popup.

Now drag drop context nodes from component controller’s context to view context.

This mapping will ensure automatic transfer of data from view context to component context and vice versa. We need to do this because code to call function module is in component controller and that code can only work on component controller context. On the other hand we also need this data in view for display purpose. Mapping will ensure data is available in both view and component controller and data transfer will be taken care of Web Dynpro runtime.


View User Interface

Our user interface has one GROUP element, one VIEWCONTAINERUIELEMENT and one TABLE as you can see in below figure.

In Layout tab of MAIN view, under ROOTUIELEMENTCONTAINER add below UI elements. You can add UI element by right clicking on ROOTUIELEMENTCONTAINER and choosing option Add Element. Note that Selscreen_Area is added under Group_Selection_Screen

Next step is to define source data for Table. Right click on Matetial_List table, choose Create Binding.

On dialog box click on context and select MATERIALS. Essentially we are saying to display data from MATERIALS context node into TABLE UI element.

You should have elements looking like this after above steps

In final step of UI building, navigate to Window ZPW_MAT_LIST (from tree structure in SE80 left pane) goto Window tab and under MAIN window right click and choose Embed view.

Make sure you got following values from drop down.

Press ok.


Create Select Option

Earlier in step XXX we defined usage of WDR_SELECT_OPTIONS to our Web Dynpro component we need to further extend this to view i.e. define component usage in MAIN view. Navigate to view MAIN and go to Properties tab and add following component using ‘Create Controller Usage’ button.

component use alv web dynpro

Go to attributes tab and add two attributes HELPER_SELECT_OPTION and INTERFACE_SELECT_OPTION as below

Next go to methods tab and add method CREATE_SEL_SCREEN, double click on method and add following code. This method will create select option. See tips on explanation on this code and how to generate this using Web Dynpro code wizard.

METHOD create_sel_screen .

*--------------------------------------------------------------------*
* Code using Web Dynpro Code Wizard - Instantiate Used Component
*--------------------------------------------------------------------*
  DATA lo_cmp_usage TYPE REF TO if_wd_component_usage.

  lo_cmp_usage =   wd_this->wd_cpuse_selection_screen( ).
  IF lo_cmp_usage->has_active_component( ) IS INITIAL.
    lo_cmp_usage->create_component( ).
  ENDIF.


*--------------------------------------------------------------------*
* Code using Web Dynpro code Wizard - Method call in Used Controller
*--------------------------------------------------------------------*
  wd_this->interface_select_option =   wd_this->wd_cpifc_selection_screen( ).
  wd_this->helper_select_option = wd_this->interface_select_option->init_selection_screen( ).

*--------------------------------------------------------------------*
* Add select-option for Material
*--------------------------------------------------------------------*
  DATA lr_range TYPE REF TO data .

  lr_range = wd_this->helper_select_option->create_range_table( 'MATNR' ) .
  CALL METHOD wd_this->helper_select_option->add_selection_field
    EXPORTING
      i_id         = 'FILTER_MATNR'
      i_obligatory = abap_true
      it_result    = lr_range.

*--------------------------------------------------------------------*
* Add select-option for Material group
*--------------------------------------------------------------------*
  lr_range = wd_this->helper_select_option->create_range_table( 'MATKL' ) .
  CALL METHOD wd_this->helper_select_option->add_selection_field
    EXPORTING
      i_id      = 'FILTER_MATKL'
      it_result = lr_range.

*--------------------------------------------------------------------*
* Add parameter for max rows
*--------------------------------------------------------------------*
  DATA lr_maxrows TYPE REF TO data .
  FIELD-SYMBOLS <fs_field> TYPE bapimaxrow .

  CREATE DATA lr_maxrows TYPE ('BAPIMAXROW') .
  ASSIGN lr_maxrows->* TO <fs_field> .
  <fs_field> = 20 . "default value

  CALL METHOD wd_this->helper_select_option->add_parameter_field
    EXPORTING
      i_id    = 'FILTER_MAXROWS'
      i_value = lr_maxrows.

ENDMETHOD.

We need to call this method from hook method WDDOINIT of view. Double click on WDDOINIT method of view and add following code

METHOD wddoinit .
  me->create_sel_screen( ).
ENDMETHOD.

Read User Input

Create method COPY_SEL_VALUES in MAIN view and put following code in it. This method will read data from select-option and bind it to context node. In the end it will call method EXECUTE_GET_MATERIAL_LIST in component controller.

METHOD copy_sel_values .

  DATA lo_nd_importing        TYPE REF TO if_wd_context_node.
  DATA lo_nd_filter_material  TYPE REF TO if_wd_context_node.
  DATA lo_nd_filter_mat_group TYPE REF TO if_wd_context_node.
  DATA lo_el_importing        TYPE REF TO if_wd_context_element.
  DATA ls_importing           TYPE wd_this->element_importing.
  DATA lv_maxrows             LIKE ls_importing-maxrows.

  DATA : lr_matnr_table TYPE REF TO data ,
         lr_matkl_table TYPE REF TO data ,
         lr_maxrows     TYPE REF TO data .

  FIELD-SYMBOLS : <ft_matnr> TYPE ANY TABLE ,
                  <ft_matkl> TYPE ANY TABLE ,
                  <fs_field> TYPE ANY .

* navigate from <CONTEXT> to <IMPORTING> via lead selection
  lo_nd_importing = wd_context->get_child_node( name = wd_this->wdctx_importing ).

* navigate from <IMPORTING> to <FILTER_MATERIAL> via lead selection
  lo_nd_filter_material = lo_nd_importing->get_child_node( name = wd_this->wdctx_filter_material ).

* Get range table for material from helper class and bind it to context
  lr_matnr_table = wd_this->helper_select_option->get_range_table_of_sel_field( 'FILTER_MATNR' ).
  ASSIGN lr_matnr_table->* TO <ft_matnr> .
  lo_nd_filter_material->bind_table( new_items = <ft_matnr> ).

* Get range table for material group from helper class and bind it to context
  lo_nd_filter_mat_group = lo_nd_importing->get_child_node( name = wd_this->wdctx_filter_mat_group ).
  lr_matkl_table = wd_this->helper_select_option->get_range_table_of_sel_field( 'FILTER_MATKL' ).
  ASSIGN lr_matkl_table->* TO <ft_matkl> .
  lo_nd_filter_mat_group->bind_table(  EXPORTING new_items            = <ft_matkl> ).

  lr_maxrows = wd_this->helper_select_option->get_value_of_parameter_field('FILTER_MAXROWS').
  ASSIGN lr_maxrows->* TO <fs_field> .

* get element via lead selection
  lo_el_importing = lo_nd_importing->get_element(  ).

* get single attribute
  lo_el_importing->set_attribute(
    EXPORTING
      name =  'MAXROWS'
      value = <fs_field> ).

*--------------------------------------------------------------------*
* Using code wizard - Call method in used component
*--------------------------------------------------------------------*
  DATA lo_componentcontroller TYPE REF TO ig_componentcontroller .
  lo_componentcontroller =   wd_this->get_componentcontroller_ctr( ).

  lo_componentcontroller->execute_get_material_list( ).

ENDMETHOD.

Call this method from hook method WDDOAFTERACTION of view.

METHOD wddoafteraction .
  wd_this->copy_sel_values( ) .
ENDMETHOD.

This finishes the building of component. In next section, I will explain how to use web dynpro code wizard to generate code. Most of the code above is generated using code wizard which saves a lot of time.


Using Web Dynpro Code Wizard

Most of the code in method CREATE_SEL_SCREEN and COPY_SE_VALUES can be created using Web Dynpro Code Wizard. webdynpro code wizard Quite rightly, it has magic wand icon in toolbar.

Instantiate Used component WDR_SELECT_OPTION

Press button Web Dynpro Code Wizard, choose Instantiate Used Component. From Value help select SELECTION_SCREEN and press ok. You will get this code, nice and easy!!

DATA lo_cmp_usage TYPE REF TO if_wd_component_usage.

lo_cmp_usage = wd_this->wd_cpuse_selection_screen( ).

IF lo_cmp_usage->has_active_component( ) IS INITIAL.
	lo_cmp_usage->create_component( ).
ENDIF.
Calling method INIT_SELECTION_SCREEN in used component WDR_SELECT_OPTION

Again go to Web Dynpro Code wizard select Method Call in Used Controller and follow below screen shot to call INIT_SELECTION_SCREEN.

You will get below lines.

DATA lo_interfacecontroller TYPE REF TO iwci_wdr_select_options .
lo_interfacecontroller = wd_this->wd_cpifc_selection_screen( ).

DATA lo_r_helper_class TYPE REF TO if_wd_select_options.
lo_r_helper_class = lo_interfacecontroller->init_selection_screen( ).

Because we need these objects on both methods I have moved declaration of IWCI_WDR_SELECT_OPTIONS and IF_WD_SELECT_OPTIONS to attributes tab of view and reduced code to

wd_this->interface_select_option = wd_this->wd_cpifc_selection_screen( ).
wd_this->helper_select_option = wd_this->interface_select_option->init_selection_screen( ).
Calling method CREATE_RANGE_TABLE using ABAP Object Pattern

CREATE_RANGE_TABLE creates range table at runtime using data element name. This the range in which user input will be stored. To generate code select good old Pattern button, go to ABAP Objects Patterns and use Call method with value shown in selection screen.

Code you get is

CALL METHOD wd_this->helper_select_option->create_range_table
  EXPORTING
    i_typename     =
*   i_length       =
*   i_decimals     =
  receiving
    rt_range_table =
    .
Calling ADD_SELECTTION_FIELD

This method actually creates select option on view. You can generate a call to this method using ABAP Object pattern.

CALL METHOD wd_this->helper_select_option->add_selection_field
  EXPORTING
    i_id                         =
*    i_within_block               = MC_ID_MAIN_BLOCK
*    i_description                =
*    i_is_auto_description        = ABAP_TRUE
*    it_result                    =
*    i_obligatory                 = ABAP_FALSE
*    i_complex_restrictions       =
*    i_use_complex_restriction    = ABAP_FALSE
*    i_no_complex_restrictions    = ABAP_FALSE
*    i_value_help_type            = IF_WD_VALUE_HELP_HANDLER=>CO_PREFIX_NONE
*    i_value_help_id              =
*    i_value_help_mode            =
*    i_value_help_structure       =
*    i_value_help_structure_field =
*    i_help_request_handler       =
*    i_lower_case                 =
*    i_memory_id                  =
*    i_no_extension               = ABAP_FALSE
*    i_no_intervals               = ABAP_FALSE
*    i_as_checkbox                = ABAP_FALSE
*    i_as_dropdown                = ABAP_FALSE
*    it_value_set                 =
*    i_read_only                  = ABAP_FALSE
*    i_dont_care_value            =
*    i_explanation                =
*    i_tooltip                    =
    .

And I have adapted above code to

  DATA lr_range TYPE REF TO data .

  lr_range = wd_this->helper_select_option->create_range_table( 'MATNR' ) .
  CALL METHOD wd_this->helper_select_option->add_selection_field
    EXPORTING
      i_id         = 'FILTER_MATNR'
      i_obligatory = abap_true
      it_result    = lr_range.
Accessing context

Calling method in component controller

DATA lo_componentcontroller TYPE REF TO ig_componentcontroller .
lo_componentcontroller = wd_this->get_componentcontroller_ctr( ).
lo_componentcontroller->execute_get_material_list( ).

2 Replies to “Adding Select Option to ABAP Web Dynpro Component

Leave a Reply