1

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.

1
  • Did you attach event handler before calling the grid? Commented Sep 18, 2018 at 9:27

4 Answers 4

0

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( ).
Sign up to request clarification or add additional context in comments.

Comments

0

If I'm not mistaken, refreshing the ALV grid does not rebuild the toolbar.

I think you have to reinitialise the ALV grid with 'SET_TABLE_FOR_FIRST_DISPLAY' in order to have the additional toolbar functionality.

1 Comment

Re-displaying everything is the last thing to do. Only the toolbar needs to be refreshed, and this can be achieved (the question is just to know what @flowx1710 did and what he missed).
0

Sandra Rosssi is right. There was two different instances of the ALVG and it got messy with the handler that's why the toolbar was not getting refreshed correctly.

Thanks all,

Comments

0

If I create an ALV grid instance (1), add it to an parent custom container, set its handlers, free it with instance1->free() and free instance1, and then ... add a new identical ALV grid instance (2) to the same custom container, with handlers, the handlers of (2) are not working (the handlers of (1) neither!), and the toolbar of (1) is kept being displayed.

To escape from this unloved state, and to get a dynamic tool bar ...

If I put an simple cl_gui_cfw=>flush( ) in between the creation and freeing of (1) and the creation of (2), the handlers of (2) are working as expected, and the toolbar reflects the icons of instance (2), as expected.

As said, this is only relevant for the case of two instances created "in one go". The problem does not occur having only one.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.