abapalv

Dynamic custom toolbar


I try to dynamically build a toolbar depending on given criterias thanks to "toolbar" event in class cl_gui_alv_grid.

The problem is that the toolbar is getting my custom button but as soon as my criteria does not match anymore and that I'd like to remove one button, the toolbar is not getting refreshed. Example here below

"Refresh button


CLEAR ls_toolbar.
  ls_toolbar-icon        = icon_refresh.
  ls_toolbar-quickinfo   = TEXT-ref.
  ls_toolbar-butn_type   = 0.
  ls_toolbar-text        = TEXT-ref.
  ls_toolbar-function    = 'REFRESH'.
  ls_toolbar-disabled    = abap_false.
  APPEND ls_toolbar      TO e_object->mt_toolbar.

  "Save button
  IF my_criteria is false.
    DELETE e_object->mt_toolbar WHERE function EQ 'SAVE'.
  ELSE.
    CLEAR ls_toolbar.
    ls_toolbar-icon        = icon_system_save.
    ls_toolbar-quickinfo   = TEXT-sav.
    ls_toolbar-butn_type   = 0.
    ls_toolbar-text        = TEXT-sav.
    ls_toolbar-function    = 'LAMA_SAVE'.
    ls_toolbar-disabled    = abap_false.
    APPEND ls_toolbar      TO e_object->mt_toolbar.

  ENDIF.

When I create my ALV I do call method lo_alv->set_toolbar_interactive( ).

When I go into debug mode I see that the save button is added or removed but it is not getting reflected on the screen once the toolbar has been displayed at leat once.


Solution

  • I can achieve the functionality that you're looking for, but it's not clear what is your exact flow, there could be several origins of the issue. So, here's a demonstration program to adjust the toolbar after any user action in the ALV grid.

    The program displays one button Click me to show "Info" and "Custom" and one button Custom in the toolbar. The "Info" button is a standard one. By clicking the button "click me" the two buttons are hidden and clicking it again make them come back. The rest of the ALV grid remains unchanged.

    To achieve this, a handler method of the event TOOLBAR must be defined to adjust the standard toolbar, which is provided in the attribute MT_TOOLBAR of the parameter E_OBJECT. This event is called implicitly when SET_TABLE_FOR_FIRST_DISPLAY is called (unless the component NO_TOOLBAR of the parameter IS_LAYOUT is set to "X") or explicitly by calling the method SET_TOOLBAR_INTERACTIVE.

    For information, the program also demonstrates how to hide definitely any standard button by filling the parameter IT_TOOLBAR_EXCLUDING of SET_TABLE_FOR_FIRST_DISPLAY with the function codes of all standard buttons to exclude. These function codes are the constants prefixed MC_FC_ in CL_GUI_ALV_GRID. All the excluded buttons are never passed to the event TOOLBAR (NB: it's possible to include it during the event, but the more logical way is to not exclude it initially and exclude it during the event).

    Demo to adjust ALV Grid toolbar 1/3

    Demo to adjust ALV Grid toolbar 2/3

    Demo to adjust ALV Grid toolbar 3/3

    Demo program:

    REPORT zdemo.
    CLASS lcl_app DEFINITION.
      PUBLIC SECTION.
        METHODS pbo.
    
      PRIVATE SECTION.
        DATA alv_grid            TYPE REF TO cl_gui_alv_grid.
        DATA flights             TYPE TABLE OF sflight.
        DATA info_button_shown   TYPE abap_bool              VALUE abap_false.
        DATA custom_button_shown TYPE abap_bool              VALUE abap_false.
    
        METHODS on_user_command FOR EVENT user_command OF cl_gui_alv_grid
          IMPORTING sender e_ucomm.
    
        METHODS handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
          IMPORTING e_object e_interactive.
    ENDCLASS.
    
    
    CLASS lcl_app IMPLEMENTATION.
      METHOD pbo.
        DATA ls_exclude TYPE ui_func.
        DATA lt_exclude TYPE ui_functions.
        DATA ls_layout  TYPE lvc_s_layo.
        DATA ls_variant TYPE disvariant.
    
        IF alv_grid IS BOUND.
          RETURN.
        ENDIF.
    
        SELECT * FROM sflight INTO TABLE flights.
    
        ls_variant-report = sy-repid.
    
        alv_grid = NEW #( i_parent = cl_gui_container=>screen0 ).
    
        SET HANDLER handle_toolbar FOR alv_grid.
        SET HANDLER on_user_command FOR alv_grid.
    
        " Booleans to retain and restore the toolbar composition.
        info_button_shown = abap_true.
        custom_button_shown = abap_true.
    
        " Hide definitely some standard buttons.
        " NB: if some standard buttons may be hidden or shown after some buttons are
        "     pressed, hide them in the TOOLBAR event handler, e.g. demo Info/End user documentation.
        ls_exclude = cl_gui_alv_grid=>mc_fc_graph.
        APPEND ls_exclude TO lt_exclude.
    
        alv_grid->set_table_for_first_display( EXPORTING  i_structure_name     = 'SFLIGHT'
                                                          is_variant           = ls_variant
                                                          i_save               = 'A' " Allow saving layout into variant
                                                          is_layout            = ls_layout
                                                          it_toolbar_excluding = lt_exclude
                                               CHANGING   it_outtab            = flights
                                               EXCEPTIONS OTHERS               = 4 ).
      ENDMETHOD.
    
      METHOD handle_toolbar.
        DATA ls_toolbar TYPE stb_button.
    
        IF custom_button_shown = abap_true.
          ls_toolbar-function = 'CLICK_ME'.
          ls_toolbar-text     = 'Click me to hide "Info" and "Custom"'.
          APPEND ls_toolbar TO e_object->mt_toolbar.
          ls_toolbar-function = 'CUSTOM'.
          ls_toolbar-text     = 'Custom'.
          APPEND ls_toolbar TO e_object->mt_toolbar.
        ELSE.
          ls_toolbar-function = 'CLICK_ME'.
          ls_toolbar-text     = 'Click me to show "Info" and "Custom"'.
          APPEND ls_toolbar TO e_object->mt_toolbar.
          " Hide Info/End user documentation
          DELETE e_object->mt_toolbar WHERE function = cl_gui_alv_grid=>mc_fc_info.
        ENDIF.
      ENDMETHOD.
    
      METHOD on_user_command.
        IF e_ucomm = 'CLICK_ME'.
          IF custom_button_shown = abap_true.
            custom_button_shown = abap_false.
          ELSE.
            custom_button_shown = abap_true.
          ENDIF.
          " Trigger the event TOOLBAR to build and redisplay the toolbar
          sender->set_toolbar_interactive( ).
        ENDIF.
      ENDMETHOD.
    ENDCLASS.
    
    PARAMETERS dummy.
    
    LOAD-OF-PROGRAM.
      DATA go_app TYPE REF TO lcl_app.
    
      go_app = NEW #( ).
    
    AT SELECTION-SCREEN OUTPUT.
      go_app->pbo( ).