{"id":915,"date":"2014-01-31T11:54:47","date_gmt":"2014-01-31T10:54:47","guid":{"rendered":"http:\/\/oprsteny.cz\/?p=915"},"modified":"2014-01-31T11:55:34","modified_gmt":"2014-01-31T10:55:34","slug":"abap-alv-context-menu-keep-row-selection-after-a-filter-is-applied","status":"publish","type":"post","link":"https:\/\/oprsteny.cz\/?p=915","title":{"rendered":"ABAP &#8211; ALV Context menu + keep row selection after a filter is applied"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"358\" data-permalink=\"https:\/\/oprsteny.cz\/?attachment_id=358\" data-orig-file=\"https:\/\/oprsteny.cz\/wp-content\/uploads\/SAP.jpg\" data-orig-size=\"44,50\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Picasa&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1365690880&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"SAP\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/oprsteny.cz\/wp-content\/uploads\/SAP.jpg\" class=\"alignleft size-full wp-image-358\" alt=\"SAP\" src=\"http:\/\/oprsteny.cz\/wp-content\/uploads\/SAP.jpg\" width=\"44\" height=\"50\" \/>Standard functionality of an ALV grid offers row selection by clicking on the row headers. You can also use Ctrl or Shift keys to do mutliple row selection. Drawback of this is when you need to select some rows and apply some filters at the same time. Setting or deleting filter (or any operation which does grid <em>refresh<\/em>) clears the row selection. If you need to keep the row selection together with functionality of filter (and others), you can follow my little suggestion<!--more--><\/p>\n<p>The idea is simple &#8211; extend the selection model with separate column to hold the selected\/not-selected information. It can be interpreted as a checkbox for example.<\/p>\n<p>Selection of rows can now be made either by clicking on check boxes OR by clicking on the row headers <strong>+ applying a context menu action.<\/strong><\/p>\n<p>Here I&#8217;ll provide a sample code how to achieve this.<\/p>\n<p>Prerequisites:<\/p>\n<ul>\n<li>I have a Z-program where I implement local class handling the ALV<\/li>\n<li>In SE80 I created screen 0100 for this program<\/li>\n<\/ul>\n<p>Note:<\/p>\n<ul>\n<li>I&#8217;ll show a demo for simple field catalog (material and plant columns)<\/li>\n<li>Data loading is faked (hard coded values) to limit complexity of the code<\/li>\n<\/ul>\n<p>Structure of data in ALV grid:<\/p>\n<pre lang=\"abap\">TYPES:\r\n  BEGIN OF gty_data,\r\n    selected TYPE char1,\r\n    matnr TYPE matnr,\r\n    plant TYPE werks_d,\r\n  END OF gty_data.<\/pre>\n<p>Global data and PBO code for screen 0100:<\/p>\n<pre lang=\"abap\">DATA:\r\n  gr_grid TYPE REF TO lcl_demo.\r\n\r\nSTART-OF-SELECTION.\r\n  CALL SCREEN 100.\r\n\r\nMODULE pbo_0100 OUTPUT.\r\n  CREATE OBJECT gr_grid.\r\n  gr_grid-&gt;show_grid( ).\r\nENDMODULE.<\/pre>\n<p>Class definition:<\/p>\n<pre lang=\"abap\">CLASS lcl_demo DEFINITION.\r\n  PUBLIC SECTION.\r\n    METHODS show_grid.\r\n\r\n  PRIVATE SECTION.\r\n    DATA:\r\n      mt_fieldcat TYPE lvc_t_fcat,        \r\n      mo_data_grid TYPE REF TO cl_gui_alv_grid,\r\n      mt_data TYPE STANDARD TABLE OF gty_data WITH KEY matnr.\r\n\r\n    CONSTANTS:\r\n*     Functions used in the context menu\r\n      BEGIN OF mc_functions,\r\n        select_rows              TYPE ui_func VALUE 'SELECT_ROWS',\r\n        unselect_rows            TYPE ui_func VALUE 'UNSELECT_ROWS',\r\n      END OF mc_functions.\r\n\r\n*   Own method for handling ALV context menu request\r\n    METHODS my_ctx_menu_request_handler      \" CONTEXT_MENU_REQUEST\r\n       FOR EVENT context_menu_request OF cl_gui_alv_grid\r\n         IMPORTING\r\n           e_object.\r\n\r\n*   Own method for handling user command sent from context menu\r\n    METHODS my_user_command_handler                 \" USER_COMMAND\r\n       FOR EVENT user_command OF cl_gui_alv_grid\r\n         IMPORTING\r\n           e_ucomm.\r\n\r\n    METHODS set_rows_selected\r\n      IMPORTING is_selected TYPE abap_bool.\r\n    METHODS build_fieldcat.\r\n    METHODS load_data.\r\nENDCLASS.<\/pre>\n<p>Implementation of the class:<\/p>\n<pre lang=\"abap\">CLASS lcl_demo IMPLEMENTATION.\r\n  METHOD build_fieldcat.\r\n    FIELD-SYMBOLS:\r\n      &lt;fs_fcat&gt; TYPE lvc_s_fcat.\r\n\r\n*   Checkbox column used to determine if a row is selected\r\n    APPEND INITIAL LINE TO mt_fieldcat ASSIGNING &lt;fs_fcat&gt;.\r\n    &lt;fs_fcat&gt;-fieldname = 'SELECTED'.\r\n    &lt;fs_fcat&gt;-checkbox  = abap_true.\r\n    &lt;fs_fcat&gt;-edit      = abap_true.\r\n    &lt;fs_fcat&gt;-scrtext_s = 'Selected'.\r\n    &lt;fs_fcat&gt;-outputlen = 5.\r\n\r\n    APPEND INITIAL LINE TO mt_fieldcat ASSIGNING &lt;fs_fcat&gt;.\r\n    &lt;fs_fcat&gt;-fieldname = 'MATNR'.\r\n    &lt;fs_fcat&gt;-scrtext_s = 'Material'.\r\n\r\n    APPEND INITIAL LINE TO mt_fieldcat ASSIGNING &lt;fs_fcat&gt;.\r\n    &lt;fs_fcat&gt;-fieldname = 'PLANT'.\r\n    &lt;fs_fcat&gt;-scrtext_s = 'Plant'.\r\n  ENDMETHOD.                    \"build_fieldcat\r\n\r\n* Method to load data for ALV grid\r\n  METHOD load_data.\r\n    FIELD-SYMBOLS:\r\n      &lt;fs_data&gt; TYPE gty_data.\r\n\r\n    APPEND INITIAL LINE TO mt_data ASSIGNING &lt;fs_data&gt;.\r\n    &lt;fs_data&gt;-matnr = 123456.\r\n    &lt;fs_data&gt;-plant = 'P001'.\r\n\r\n    APPEND INITIAL LINE TO mt_data ASSIGNING &lt;fs_data&gt;.\r\n    &lt;fs_data&gt;-matnr = 654321.\r\n    &lt;fs_data&gt;-plant = 'P999'.\r\n  ENDMETHOD.                    \"load_data\r\n\r\n  METHOD show_grid.\r\n    DATA:\r\n      ls_layout   TYPE lvc_s_layo.\r\n\r\n    IF mo_data_grid IS INITIAL.\r\n*     Create the ALV grid object using the whole screen\r\n*     as container\r\n      CREATE OBJECT mo_data_grid\r\n        EXPORTING\r\n          i_parent      = cl_gui_container=&gt;screen0\r\n          i_appl_events = abap_true.\r\n\r\n      ls_layout-sel_mode = 'A'.\r\n      ls_layout-no_rowmark = abap_false.\r\n\r\n      me-&gt;build_fieldcat( ).\r\n      me-&gt;load_data( ).\r\n\r\n*     Register handler for context menu request\r\n      SET HANDLER my_ctx_menu_request_handler FOR mo_data_grid.\r\n\r\n*     Register handler for user action in context menu\r\n      SET HANDLER my_user_command_handler FOR mo_data_grid.\r\n\r\n*     Display the ALV grid\r\n      mo_data_grid-&gt;set_table_for_first_display(\r\n        EXPORTING\r\n          is_layout             = ls_layout\r\n        CHANGING\r\n          it_fieldcatalog       = mt_fieldcat\r\n          it_outtab             = mt_data ).\r\n    ENDIF.\r\n  ENDMETHOD.                    \"show_grid\r\n\r\n* Implementation of the context menu request\r\n  METHOD my_ctx_menu_request_handler.\r\n    DATA:\r\n      ls_row    TYPE lvc_s_row,\r\n      ls_col    TYPE lvc_s_col.\r\n*   Get cell which was clicked\r\n    CALL METHOD mo_data_grid-&gt;get_current_cell\r\n      IMPORTING\r\n        es_row_id = ls_row\r\n        es_col_id = ls_col.\r\n\r\n*   Add ctx-menu items only if clicked on row header where\r\n*   FIELDNAME is initial\r\n    CHECK ls_col-fieldname IS INITIAL.\r\n\r\n*   Adding custom functions\r\n    CALL METHOD e_object-&gt;add_function\r\n      EXPORTING\r\n        fcode = mc_functions-select_rows\r\n        text  = 'Select highlighted rows'.\r\n\r\n    CALL METHOD e_object-&gt;add_function\r\n      EXPORTING\r\n        fcode = mc_functions-unselect_rows\r\n        text  = 'Unselect highlighted rows'.\r\n  ENDMETHOD.                    \"my_context_menu_request_handler\r\n\r\n* Set the selected rows checked or unchecked \r\n* modifies the first column\r\n  METHOD set_rows_selected.\r\n    DATA:\r\n    lt_selected_rowids TYPE lvc_t_roid.\r\n\r\n    FIELD-SYMBOLS:\r\n      &lt;fs_data&gt; TYPE gty_data,\r\n      &lt;fs_selrow&gt; TYPE lvc_s_roid.\r\n\r\n*   Get selected rows (using row headers)\r\n    CALL METHOD mo_data_grid-&gt;get_selected_rows\r\n      IMPORTING\r\n        et_row_no = lt_selected_rowids.\r\n\r\n*   Modify ALV grid data - first column\r\n    LOOP AT lt_selected_rowids ASSIGNING &lt;fs_selrow&gt;.\r\n      READ TABLE mt_data ASSIGNING &lt;fs_data&gt; INDEX &lt;fs_selrow&gt;-row_id.\r\n      CHECK sy-subrc = 0.\r\n      &lt;fs_data&gt;-selected = is_selected.\r\n    ENDLOOP.\r\n  ENDMETHOD.                    \"set_rows_selected\r\n\r\n* Method to handle response on user actions in context menu\r\n  METHOD my_user_command_handler.\r\n    CASE e_ucomm.\r\n      WHEN mc_functions-select_rows.\r\n        set_rows_selected( abap_true ).\r\n\r\n      WHEN mc_functions-unselect_rows.\r\n        set_rows_selected( abap_false ).\r\n    ENDCASE.\r\n    IF mo_data_grid IS NOT INITIAL.\r\n      mo_data_grid-&gt;refresh_table_display( ).\r\n    ENDIF.\r\n  ENDMETHOD.                    \"my_user_command_handler\r\nENDCLASS.<\/pre>\n<p>Output:<br \/>\n<a href=\"http:\/\/oprsteny.cz\/wp-content\/uploads\/ALV_CONTEXT_MENU.png\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"916\" data-permalink=\"https:\/\/oprsteny.cz\/?attachment_id=916\" data-orig-file=\"https:\/\/oprsteny.cz\/wp-content\/uploads\/ALV_CONTEXT_MENU.png\" data-orig-size=\"391,366\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"ALV Context menu\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/oprsteny.cz\/wp-content\/uploads\/ALV_CONTEXT_MENU.png\" class=\"size-medium wp-image-916 alignnone\" alt=\"ALV Context menu\" src=\"http:\/\/oprsteny.cz\/wp-content\/uploads\/ALV_CONTEXT_MENU-300x280.png\" width=\"300\" height=\"280\" srcset=\"https:\/\/oprsteny.cz\/wp-content\/uploads\/ALV_CONTEXT_MENU-300x280.png 300w, https:\/\/oprsteny.cz\/wp-content\/uploads\/ALV_CONTEXT_MENU-320x300.png 320w, https:\/\/oprsteny.cz\/wp-content\/uploads\/ALV_CONTEXT_MENU.png 391w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Standard functionality of an ALV grid offers row selection by clicking on the row headers. You can also use Ctrl or Shift keys to do mutliple row selection. Drawback of this is when you need to select some rows and &hellip; <a href=\"https:\/\/oprsteny.cz\/?p=915\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":358,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"ABAP - ALV Context menu + keep row selection after a filter is applied","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[16,86,136,9],"tags":[210,263,264],"class_list":["post-915","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-abap","category-alv","category-alv-tutorial","category-development","tag-cl_gui_alv_grid","tag-context_menu_requrest","tag-user_command"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/oprsteny.cz\/wp-content\/uploads\/SAP.jpg","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p3nYbe-eL","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/posts\/915","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=915"}],"version-history":[{"count":3,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/posts\/915\/revisions"}],"predecessor-version":[{"id":919,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/posts\/915\/revisions\/919"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/media\/358"}],"wp:attachment":[{"href":"https:\/\/oprsteny.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=915"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=915"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=915"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}