Variations Of Selecting Multiple Options From A List

If you want to provide a user the possibility to select multiple values from a list then you normally have – in other programming languages – a control containing items an the possibiity to mark or unmark them. It’s called a listbox in Visual Basic for example. You eather choose items by holding CTRL key pressed or clicking the check box of the desired list items.

In ABAP you do not have such a simple control; you must build your own.

Using SALV

The most obvious way probably would be to use an SALV as a multi selection box which could look something like this:

The cl_gui_selection_box (no, it does not exist. yet…) can be easily enhanced by adding colors:

By clicking the checkbox the color of the line changes to green.

You could also use Icons instead of the checkbox:

If you would like to invest a little more time you can simulate a modern UI (kind of…):

You can also use the standard row selection of the SALV by marking the lines at the most left side of the SALV table. The user will then have to hold CTRL key to select more than one line. This is a bit problematic because if the user clicks somewehre else in the table the selection will get lost.

Using The Toolbar

A different way to achieve the goal of mutliple selections is using the toolbar-control CL_GUI_TOOLBAR. Here you can define a button as checked which indicates that this button or option is set or active. Using Icons the result might look something like this:

Disadvantages

All the above solutions – which really look quite cool, don’t they? – have one major disadvantage: The cost quite a lot amount of space. If selecting some options from a list is not part of a process step or if there is simply not enought place for showing this control than you use a dropdown menu.

The main advantage of these lists is that you always can see all selected and not selected options.

Using CL_CTMENU

The menu is quite a good option for displaying selected or unselected values because every menu item can be checked or not. If checked it will have a small circle in front of the option:

The disadvantage is that you cannot see all the selected options. You will have to click the menu to see which options are marked.

This dropdown menu has another disadvantage: After hitting an option the menu disappears and you will have to click again.

And this actually is the main reason for posting this: I had the idea to raise the dropdown-menu-clicked-event again after having selected an entry and rebuild the menu. The effect is that you can select an option, the menu entry will be changed to checked and right after the click the menu will be displayed again.

The effect can be set by using the DISPATCH method.

Ennotations & Ennohancements

Modularization

This code is a very good example to show how to build a general function that could be used in several different programs. You will have to add some methods so that a programmer can work with it (setting options, getting th results, placing the control in a given container, setting Icons and so) but I think it’s easy to imagine that such a tool can be very good re-used.

Customizing

With the given coding you can make the class customizable so that the programmer can set icons to be used, displaying titles etc. You could also use this mutliple selection control as a radio button alternative. just make sure that after selecting an option the oter options are unselected.

Multiple States

I could also imagine multiple states which iteratively will be set after clicking: Not only ON and OFF but GREEN, YELLOW, RED or MUST, SHOULD, CAN’T.

Dynamic programming

Dealing with tables where the structure is unknown could also be a possible option. Just pass the table to the class and tell the class which field is the one to use for marking and which one is the text field to display. Using ASSIGN COMPONENT (fieldname_for_text) OF STRUCTURE … you can provide an easy way for selecting mutliple lines of any table.

Code For Dropdown Menu

REPORT. CLASS lcl_main DEFINITION. PUBLIC SECTION. METHODS display. PROTECTED SECTION. TYPES: BEGIN OF ty_option, value TYPE char10, text TYPE string, checked TYPE boolean_flg, END OF ty_option. DATA: mytoolbar TYPE REF TO cl_gui_toolbar, menupos_x TYPE i, menupos_y TYPE i, options TYPE STANDARD TABLE OF ty_option, menu_dynamic TYPE REF TO cl_ctmenu. METHODS build_menu. METHODS on_function_selected FOR EVENT function_selected OF cl_gui_toolbar IMPORTING fcode sender. METHODS on_dropdown_clicked FOR EVENT dropdown_clicked OF cl_gui_toolbar IMPORTING fcode posx posy sender. ENDCLASS. “lcl_my_event_handler DEFINITION CLASS lcl_main IMPLEMENTATION. METHOD build_menu. IF menu_dynamic IS INITIAL. "Create menu CREATE OBJECT menu_dynamic. ELSE. "Clear all entries before rebuild menu_dynamic->clear( ). ENDIF. LOOP AT options ASSIGNING FIELD-SYMBOL(). "add menu entry with current status menu_dynamic->add_function( fcode = CONV #( -value ) checked = -checked text = CONV #( -text ) ). ENDLOOP. ENDMETHOD. METHOD display. "Create docker on Top of the screen DATA(docker) = NEW cl_gui_docking_container( side = cl_gui_docking_container=>dock_at_top extension = 30 ). "create toolbar object mytoolbar = NEW #( parent = docker ). "register events mytoolbar->set_registered_events( VALUE #( ( eventid = cl_gui_toolbar=>m_id_function_selected ) ( eventid = cl_gui_toolbar=>m_id_dropdown_clicked ) ) ). "Set handler SET HANDLER on_function_selected FOR mytoolbar. SET HANDLER on_dropdown_clicked FOR mytoolbar. "set initial values options = VALUE #( ( value = ‘ONE’ text = ‘Option One’ ) ( value = ‘TWO’ text = ‘Option Two’ ) ( value = ‘THREE’ text = ‘Option Three’ ) ( value = ‘FOUR’ text = ‘Option Four’ ) ). "Build menu build_menu( ). "Add button for selecting options mytoolbar->add_button( EXPORTING icon = ‘ICON_TOOL’ fcode = ‘CHOOSE’ butn_type = ‘1’ text = ‘Select options’ quickinfo = ‘Select some options…’ EXCEPTIONS cntb_error_fcode = 1 ). ENDMETHOD. METHOD on_function_selected. "switch option entry LOOP AT options ASSIGNING FIELD-SYMBOL(). IF -value = fcode. IF -checked = abap_true. -checked = abap_false. ELSE. -checked = abap_true. ENDIF. ENDIF. ENDLOOP. "rebuild menu build_menu( ). "raise event dropdown clicked again sender->dispatch( cargo = ‘mytoolbar’ eventid = cl_gui_toolbar=>m_id_dropdown_clicked is_shellevent = abap_false ). "Set coordinates of menu sender->track_context_menu( context_menu = menu_dynamic posx = menupos_x posy = menupos_y ). ENDMETHOD. "lcl_my_event_handler METHOD on_dropdown_clicked. IF fcode = ‘CHOOSE’. "call of dropdown: remember current position for displaying menu menupos_x = posx. menupos_y = posy. ENDIF. "Set coordinates mytoolbar->track_context_menu( context_menu = menu_dynamic posx = posx posy = posy ). ENDMETHOD. "lcl_my_event_handler ENDCLASS. "lcl_my_event_handler IMPLEMENTATION INITIALIZATION. new lcl_main( )->display( ). PARAMETERS p_test.

Code For SALV List

REPORT . CLASS lcl_main DEFINITION. PUBLIC SECTION. TYPES: BEGIN OF ty_option, mark TYPE boolean_flg, icon type icon_d, key TYPE c LENGTH 10, text TYPE c LENGTH 100, _col_ TYPE lvc_t_scol, END OF ty_option, ty_options TYPE STANDARD TABLE OF ty_option with DEFAULT KEY. METHODS set IMPORTING options TYPE ty_options. METHODS get RETURNING VALUE(options) TYPE ty_options. METHODS display. PROTECTED SECTION. DATA mt_options TYPE ty_options. DATA mo_salv TYPE REF TO cl_salv_table. METHODS on_click FOR EVENT link_click OF cl_salv_events_table IMPORTING row column sender. METHODS set_colors. ENDCLASS. CLASS lcl_main IMPLEMENTATION. METHOD set. mt_options = options. set_colors( ). ENDMETHOD. METHOD get. options = mt_options. ENDMETHOD. METHOD display. DATA(docker) = NEW cl_gui_docking_container( extension = 200 side = cl_gui_docking_container=>dock_at_left ). DATA o_column TYPE REF TO cl_salv_column_table. cl_salv_table=>factory( EXPORTING r_container = docker IMPORTING r_salv_table = mo_salv CHANGING t_table = mt_options ). DATA(layout) = mo_salv->get_display_settings( ). layout->set_list_header( ‘Select option’ ). DATA(columns) = mo_salv->get_columns( ). columns->set_color_column( ’_COL_’ ). columns->set_headers_visible( abap_false ). o_column ?= columns->get_column( ‘MARK’ ). * o_column->set_cell_type( if_salv_c_cell_type=>checkbox_hotspot ). o_column->set_technical( abap_true ). o_column ?= columns->get_column( ‘ICON’ ). o_column->set_cell_type( if_salv_c_cell_type=>hotspot ). o_column->set_icon( abap_true ). o_column ?= columns->get_column( ‘KEY’ ). o_column->set_technical( abap_true ). o_column ?= columns->get_column( ‘TEXT’ ). mo_salv->display( ). DATA(handler) = mo_salv->get_event( ). SET HANDLER on_click FOR handler. ENDMETHOD. METHOD on_click. READ TABLE mt_options ASSIGNING FIELD-SYMBOL() INDEX row. IF sy-subrc = 0. IF -mark = abap_true. -mark = abap_false. -icon = icon_led_red. CLEAR -_col_. APPEND INITIAL LINE TO -_col_ ASSIGNING FIELD-SYMBOL(). * -color-col = col_background. ELSE. -mark = abap_true. -icon = icon_led_green. CLEAR -_col_. APPEND INITIAL LINE TO -_col_ ASSIGNING . * -color-col = col_positive. ENDIF. ENDIF. mo_salv->refresh( ). DATA(selections) = mo_salv->get_selections( ). selections->set_selected_cells( VALUE #( ) ). ENDMETHOD. METHOD set_colors. LOOP AT mt_options ASSIGNING FIELD-SYMBOL(). CLEAR -_col_. APPEND INITIAL LINE TO -_col_ ASSIGNING FIELD-SYMBOL(). IF -mark = abap_false. * -color-col = col_background. -icon = icon_led_red. ELSE. * -color-col = col_positive. -icon = icon_led_green. ENDIF. ENDLOOP. ENDMETHOD. ENDCLASS. PARAMETERS p_dummy. INITIALIZATION. DATA(main) = NEW lcl_main( ). main->set( VALUE #( ( text = `One` key = ‘1’ ) ( text = `Two` key = ‘2’ ) ( text = `Three` key = ‘3’ ) ( text = `Four` key = ‘4’ ) ) ). main->display( ). AT SELECTION-SCREEN. cl_demo_output=>display_data( main->get( ) ).

Code For Menu Buttons

REPORT. CLASS lcl_main DEFINITION. PUBLIC SECTION. METHODS display. PROTECTED SECTION. TYPES: BEGIN OF ty_option, value TYPE char10, text TYPE string, checked TYPE boolean_flg, END OF ty_option. DATA: mytoolbar TYPE REF TO cl_gui_toolbar, options TYPE STANDARD TABLE OF ty_option. METHODS build_menu. METHODS on_function_selected FOR EVENT function_selected OF cl_gui_toolbar IMPORTING fcode sender. ENDCLASS. "lcl_my_event_handler DEFINITION CLASS lcl_main IMPLEMENTATION. METHOD build_menu. DATA lv_icon TYPE icon_text. IF mytoolbar IS INITIAL. "Create docker on Top of the screen DATA(docker) = NEW cl_gui_docking_container( side = cl_gui_docking_container=>dock_at_left extension = 130 ). "create toolbar object mytoolbar = NEW #( parent = docker display_mode = cl_gui_toolbar=>m_mode_vertical ). "register events mytoolbar->set_registered_events( VALUE #( ( eventid = cl_gui_toolbar=>m_id_function_selected ) ) ). "Set handler SET HANDLER on_function_selected FOR mytoolbar. ELSE. mytoolbar->delete_all_buttons( ). ENDIF. LOOP AT options ASSIGNING FIELD-SYMBOL(). IF -checked = abap_false. * lv_icon = icon_led_red. * lv_icon = icon_space. lv_icon = icon_unlocked. ELSE. * lv_icon = icon_led_green. * lv_icon = icon_alarm. lv_icon = icon_locked. ENDIF. "add menu entry with current status mytoolbar->add_button( fcode = CONV #( -value ) icon = lv_icon is_checked = -checked butn_type = cntb_btype_button text = CONV #( -text ) ). ENDLOOP. ENDMETHOD. METHOD display. "set initial values options = VALUE #( ( value = ‘ONE’ text = ‘Option One’ ) ( value = ‘TWO’ text = ‘Option Two’ ) ( value = ‘THREE’ text = ‘Option Three’ ) ( value = ‘FOUR’ text = ‘Option Four’ ) ). "Build menu build_menu( ). ENDMETHOD. METHOD on_function_selected. ASSIGN options[ value = fcode ] TO FIELD-SYMBOL(). IF sy-subrc = 0. IF -checked = abap_true. -checked = abap_false. ELSE. -checked = abap_true. ENDIF. ENDIF. build_menu( ). ENDMETHOD. "lcl_my_event_handler ENDCLASS. "lcl_my_event_handler IMPLEMENTATION INITIALIZATION. NEW lcl_main( )->display( ). PARAMETERS p_test. http://bit.ly/2nr84vu #SAP #SAPCloud #AI

Subscribe To Newsletter

Sign up for my newsletter and get the latest technology news

2019 © Craig Brown PhD. All rights reserved.