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
Master handling Date/Time in E2E Fiori Scenario – Index
Generally handle with Date/Time data is a common skill for all developers.
But when you starting to develop Fiori applications, it gets far more complex than you think.
In a typical Fiori development scenario, different technologies are involved, they are ABAP, OData, and SAPUI5. There will be more backend languages involved if you use SAP Cloud Platform or other backend technologies.
In this series blog, what I want to do are:
Point out possible questions about Date/Time data.
Give the answer based on S/4 HANA scenario by examples and reference to SAP’s documents.( That means ABAP plays the backend role)
Help developer using other languages as the backend service to get the idea of how to figure out Date/Time problems in their own development scenario.
Blogs in this series planned ( with planned date ) are list below:
*
Identity Requirements for Date/Time operation(Plan: 2018-1-13)
*
How ABAP deal with Date/Time(Plan: 2018-1-20)
*
Conversion of ABAP Date/Time type to OData Date/Time type(Plan:2018-1-27)
*
How SAPUI5 deals with OData Date/Time(Plan:2018-2-3)
*
How to handle the representation of Date/Time in SAPUI5(Plan:2018-2-10)
*
Handling create request for entity with Date/Time fields(Plan:2018-2-17)
*
Handling entity which has Date/Time key field(Plan:2018-2-24)
*
Using Date/Time field as OData Query Option(Plan:2018-3-3)
*
Dealing with Time Zone and Time Difference(Plan:2018-3-10)
http://bit.ly/2nsIAOq #SAP #SAPCloud #AI
Reconsider Recruiting Tactics to Find Older Workers
ICYMI: Age bias is a myopic view that employers facing tightening labor markets continue to hold at their peril. A panel looks at ways to broaden recruitment efforts to attract older workers. https://goo.gl/UL3aZ9 #GlobalHR #HRTech