[ABAP] HTML-basierte Anzeige: Ausklappbarer Dockingcontainer im Selektionsbild, Eventhandling

* http://www.tricktresor.de/blog/fly-out-menu/
TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

CONSTANTS c_dock_open TYPE i VALUE 400.
CONSTANTS c_dock_close TYPE i VALUE 150.
CONSTANTS c_cmd_open TYPE string VALUE 'OPEN'.
CONSTANTS c_cmd_close TYPE string VALUE 'CLOSE'.
CONSTANTS c_cmd_click TYPE string VALUE 'CLICK'.

DATA: o_docker TYPE REF TO cl_gui_docking_container.

PARAMETERS: p_field TYPE char10 DEFAULT '####'.

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.

    CLASS-METHODS:
      on_sapevent FOR EVENT sapevent OF cl_gui_html_viewer
        IMPORTING
            action
            frame
            getdata
            postdata
            query_table.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
  METHOD on_sapevent.

    IF o_docker IS BOUND.
      CASE action.
* Container ausklappen
        WHEN c_cmd_open.
          o_docker->set_extension( EXPORTING
                                     extension = c_dock_open ).
* Container einklappen
        WHEN c_cmd_close.
          o_docker->set_extension( EXPORTING
                                     extension = c_dock_close ).
      ENDCASE.
    ENDIF.

* Action im Parameterfeld ausgeben
    p_field = action.

  ENDMETHOD.

ENDCLASS.

INITIALIZATION.
* Docking-Container für HTML-Viewer-Element
  o_docker = NEW #( extension               = c_dock_close
                    side                    = cl_gui_docking_container=>dock_at_right
                    no_autodef_progid_dynnr = abap_true ).

* HTML-Viewer
  DATA(o_html) = NEW cl_gui_html_viewer( parent = o_docker ).

* SAP-Events registrieren
  DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_html_viewer=>m_id_sapevent
                                          appl_event = abap_true ) ).

  o_html->set_registered_events( events = it_events ).

  SET HANDLER lcl_events=>on_sapevent FOR o_html.

* HTML-Code
  DATA(it_html) = VALUE html_table( ( |<html>| )
                                    ( |  <meta http-equiv="content-type" content="text/html" charset="ISO-8859-1">| )
                                    ( |  <head>| )
                                    ( |  <title>Test</title>| )
                                    ( |  <script type="text/javascript">| )
                                    ( |    function open_close(element)| )
                                    ( |    \{| )
                                    ( |      location.href = "SAPEVENT:" + element;| )
                                    ( |    \}| )
                                    ( |    function mouse_click(element)| )
                                    ( |    \{| )
                                    ( |      location.href = "SAPEVENT:" + element;| )
                                    ( |    \}| )
                                    ( |  </script>| )
                                    ( |  </head>| )
                                    ( |  <body style="overflow:auto">| )
                                    ( |    <table border="0" width="300px">| )
                                    ( |      <tr>| )
                                    ( |        <td><button onmouseover="open_close('{ c_cmd_open }')">&laquo; Show</button></td>| )
                                    ( |      </tr>| )
                                    ( |      <tr>| )
                                    ( |        <td>--------------------&raquo; <a href="#" onclick="mouse_click('{ c_cmd_click }')">Klick</a></td>| )
                                    ( |      </tr>| )
                                    ( |      <tr>| )
                                    ( |        <td><button onmouseover="open_close('{ c_cmd_close }')">&raquo; Hide</button></td>| )
                                    ( |      </tr>| )
                                    ( |    </table>| )
                                    ( |  </body>| )
                                    ( |</html>| ) ).

* HTML anzeigen
  DATA: lv_url TYPE swk_url.

  o_html->load_data( IMPORTING
                       assigned_url = lv_url
                     CHANGING
                       data_table   = it_html ).

  o_html->show_url( url = lv_url ).

[ABAP] Baumstruktur mit Hilfe des cl_gui_list_tree anzeigen, Events abfangen

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

DATA: it_nodes TYPE treev_ntab.
DATA: it_items TYPE STANDARD TABLE OF mtreeitm WITH DEFAULT KEY.

CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: on_node_double_click FOR EVENT node_double_click OF cl_gui_list_tree
      IMPORTING
          node_key.
    CLASS-METHODS: on_expand_no_children FOR EVENT expand_no_children OF cl_gui_list_tree
      IMPORTING
          node_key.
    CLASS-METHODS: on_item_double_click FOR EVENT item_double_click OF cl_gui_list_tree
      IMPORTING
          node_key
          item_name.
    CLASS-METHODS: on_button_click FOR EVENT button_click OF cl_gui_list_tree
      IMPORTING
          node_key
          item_name.
    CLASS-METHODS: on_link_click FOR EVENT link_click OF cl_gui_list_tree
      IMPORTING
          node_key
          item_name.
    CLASS-METHODS: on_checkbox_change FOR EVENT checkbox_change OF cl_gui_list_tree
      IMPORTING
          node_key
          item_name
          checked.
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
  METHOD on_node_double_click.
    WRITE: / |Node double click on node: { node_key }|.
  ENDMETHOD.

  METHOD on_item_double_click.
    WRITE: / |Item double click on node: { node_key }, item: { item_name }|.
  ENDMETHOD.

  METHOD on_link_click.
    WRITE: / |Link click on node: { node_key }, item: { item_name }|.
  ENDMETHOD.

  METHOD on_button_click.
    WRITE: / |Button click on node: { node_key }, item: { item_name }|.
  ENDMETHOD.

  METHOD on_checkbox_change.
    WRITE: / |Checkbox change on node: { node_key }, item: { item_name }|.
  ENDMETHOD.

  METHOD on_expand_no_children.
    WRITE: / |Expand no children on node: { node_key }|.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

* Container-Objekt erzeugen
  DATA(o_dock) = NEW cl_gui_docking_container( no_autodef_progid_dynnr = abap_true
                                               side = cl_gui_docking_container=>dock_at_left
                                               ratio = 20
                                               caption = 'Datenausgabe' ).

* Tree-Objekt erzeugen
  DATA(o_tree) = NEW cl_gui_list_tree( parent = o_dock
                                       node_selection_mode = cl_gui_list_tree=>node_sel_mode_single
                                       item_selection = abap_true
                                       with_headers = abap_false ).

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE ty_it_events( ( eventid    = cl_gui_list_tree=>eventid_node_double_click
                                          appl_event = abap_true )
                                        ( eventid    = cl_gui_list_tree=>eventid_item_double_click
                                          appl_event = abap_true )
                                        ( eventid    = cl_gui_list_tree=>eventid_expand_no_children
                                          appl_event = abap_true )
                                        ( eventid    = cl_gui_list_tree=>eventid_link_click
                                          appl_event = abap_true )
                                        ( eventid    = cl_gui_list_tree=>eventid_button_click
                                          appl_event = abap_true )
                                        ( eventid    = cl_gui_list_tree=>eventid_checkbox_change
                                          appl_event = abap_true ) ).

  o_tree->set_registered_events( events = it_events ).

  SET HANDLER lcl_event=>on_node_double_click FOR o_tree.
  SET HANDLER lcl_event=>on_item_double_click FOR o_tree.
  SET HANDLER lcl_event=>on_expand_no_children FOR o_tree.
  SET HANDLER lcl_event=>on_link_click FOR o_tree.
  SET HANDLER lcl_event=>on_button_click FOR o_tree.
  SET HANDLER lcl_event=>on_checkbox_change FOR o_tree.

* Tree-Nodes einfügen -> die Bezeichner müssen eindeutig sein
  it_nodes = VALUE #( ( node_key  = 'ROOT'
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_true )

                      ( node_key  = 'NODE1'
                        relatkey  = 'ROOT'
                        relatship = cl_gui_list_tree=>relat_last_child
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_true )

                      ( node_key  = 'NODE1_1'
                        relatkey  = 'NODE1'
                        relatship = cl_gui_list_tree=>relat_last_child
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_false )

                      ( node_key  = 'NODE1_2'
                        relatkey  = 'NODE1'
                        relatship = cl_gui_list_tree=>relat_last_child
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_false )

                      ( node_key  = 'NODE1_3'
                        relatkey  = 'NODE1'
                        relatship = cl_gui_list_tree=>relat_last_child
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_false )

                      ( node_key  = 'NODE2'
                        relatkey  = 'ROOT'
                        relatship = cl_gui_list_tree=>relat_last_child
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_false )

                      ( node_key  = 'NODE3'
                        relatkey  = 'ROOT'
                        relatship = cl_gui_list_tree=>relat_last_child
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_false ) ).

* Items für die Nodes definieren
  it_items = VALUE #( ( node_key  = 'ROOT'
                        item_name = '1'
                        style     = cl_gui_list_tree=>style_default
                        class     = cl_gui_list_tree=>item_class_text
                        alignment = cl_gui_list_tree=>align_auto
                        font      = cl_gui_list_tree=>item_font_fixed
                        text      = 'Root'
                        t_image   = icon_led_green )
* Ordner
                      ( node_key  = 'NODE1'
                        item_name = '1'
                        style     = cl_gui_list_tree=>style_default
                        class     = cl_gui_list_tree=>item_class_text
                        alignment = cl_gui_list_tree=>align_auto
                        font      = cl_gui_list_tree=>item_font_fixed
                        text      = 'Node 1'
                        t_image   = icon_led_yellow )
* Item Button
                      ( node_key  = 'NODE1_1'
                        item_name = '1'
                        style     = cl_gui_list_tree=>style_default
                        class     = cl_gui_list_tree=>item_class_button
                        alignment = cl_gui_list_tree=>align_auto
                        font      = cl_gui_list_tree=>item_font_fixed
                        text      = 'Node 1_1'
                        t_image   = icon_led_green )
* Item Checkbox
                      ( node_key  = 'NODE1_2'
                        item_name = '1'
                        style     = cl_gui_list_tree=>style_default
                        class     = cl_gui_list_tree=>item_class_checkbox
                        alignment = cl_gui_list_tree=>align_auto
                        font      = cl_gui_list_tree=>item_font_fixed
                        text      = 'Node 1_2'
                        t_image   = icon_led_green
                        editable  = abap_true )
* Item Link
                      ( node_key  = 'NODE1_3'
                        item_name = '1'
                        style     = cl_gui_list_tree=>style_default
                        class     = cl_gui_list_tree=>item_class_link
                        alignment = cl_gui_list_tree=>align_auto
                        font      = cl_gui_list_tree=>item_font_fixed
                        text      = 'Node 1_3'
                        t_image   = icon_led_green )
* Item mit 4 Spalten
                      ( node_key   = 'NODE2'
                        item_name  = '1'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_auto
                        font       = cl_gui_list_tree=>item_font_fixed
                        text       = ''
                        t_image    = icon_led_green
                        usebgcolor = abap_true )

                      ( node_key   = 'NODE2'
                        item_name  = '2'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_left
                        font       = cl_gui_list_tree=>item_font_fixed
                        length     = 4
                        text       = '1000'
                        usebgcolor = abap_true )

                      ( node_key   = 'NODE2'
                        item_name  = '3'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_left
                        font       = cl_gui_list_tree=>item_font_fixed
                        length     = 10
                        text       = 'Liter'
                        usebgcolor = abap_true )

                      ( node_key   = 'NODE2'
                        item_name  = '4'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_auto
                        font       = cl_gui_list_tree=>item_font_prop
                        text       = 'Testeintrag 1' )
* Item mit 4 Spalten
                      ( node_key   = 'NODE3'
                        item_name  = '1'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_auto
                        font       = cl_gui_list_tree=>item_font_fixed
                        text       = ''
                        t_image    = icon_led_green
                        usebgcolor = abap_true )

                      ( node_key   = 'NODE3'
                        item_name  = '2'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_left
                        font       = cl_gui_list_tree=>item_font_fixed
                        length     = 4
                        text       = '0100'
                        usebgcolor = abap_true )

                      ( node_key   = 'NODE3'
                        item_name  = '3'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_left
                        font       = cl_gui_list_tree=>item_font_fixed
                        length     = 10
                        text       = 'mm'
                        usebgcolor = abap_true )

                      ( node_key   = 'NODE3'
                        item_name  = '4'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_auto
                        font       = cl_gui_list_tree=>item_font_prop
                        text       = 'Testeintrag 2' ) ).

  o_tree->add_nodes_and_items( node_table                = it_nodes
                               item_table                = it_items
                               item_table_structure_name = 'MTREEITM' ). " Typ muss gleich mit Zeilentyp von it_items sein

* Root-Nodes des Trees expandieren
  o_tree->expand_root_nodes( ).

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

  WRITE space. " wichtig für Erzwingung der Listenausgabe und Anzeige des Trees

Weiterführende Infos: Link und Link

[ABAP] Eigene GUI-Toolbar in einem Split-Container anzeigen, Eventhandling

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_function_selected FOR EVENT function_selected OF cl_gui_toolbar
        IMPORTING
            fcode
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Toolbar Button geklickt
  METHOD on_function_selected.

    CASE fcode.
      WHEN 'BTN_CLOSE'.
        LEAVE PROGRAM.
      WHEN 'BTN_TEST'.
        MESSAGE 'TEST' TYPE 'I' DISPLAY LIKE 'S'.
    ENDCASE.

  ENDMETHOD.

ENDCLASS.

INITIALIZATION.

* Splitter erzeugen
  DATA(o_splitter) = NEW cl_gui_splitter_container( parent = cl_gui_container=>default_screen
                                                    no_autodef_progid_dynnr = abap_true
                                                    rows = 2
                                                    columns = 1 ).

* Absoluter Modus für Zeilenhöhe
  o_splitter->set_row_mode( mode = cl_gui_splitter_container=>mode_absolute ).

* Höhe absolut 24 Pixel für Splitter oben
  o_splitter->set_row_height( id = 1 height = 24 ).

* Splitter für oberen Container fest und verborgen
  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_movable
                            value = cl_gui_splitter_container=>false ).

  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_sashvisible
                            value = cl_gui_splitter_container=>false ).

  DATA(o_container_top) = o_splitter->get_container( row = 1 column = 1 ).
  DATA(o_container_bottom) = o_splitter->get_container( row = 2 column = 1 ).

* Toolbar hoizontal
  DATA(o_tool) = NEW cl_gui_toolbar( parent = o_container_top
                                     display_mode = cl_gui_toolbar=>m_mode_horizontal ).

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_toolbar=>m_id_function_selected
                                          appl_event = abap_true ) ).

  o_tool->set_registered_events( events = it_events ).

* Toolbar-Buttons hinzufügen
* Buttontypen sind in Typgruppe CNTB definiert
  o_tool->add_button( fcode       = 'BTN_TEST'
                      icon        = icon_activate
                      butn_type   = cntb_btype_button
                      text        = 'Test'
                      quickinfo   = 'Test'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

  o_tool->add_button( fcode       = ''
                      icon        = ''
                      butn_type   = cntb_btype_sep
                      text        = ''
                      quickinfo   = ''
                      is_checked  = abap_false
                      is_disabled = abap_false ).

  o_tool->add_button( fcode       = 'BTN_CLOSE'
                      icon        = icon_close
                      butn_type   = cntb_btype_button
                      text        = 'Schließen'
                      quickinfo   = 'Schließen'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

* Eventhandler registrieren
  SET HANDLER lcl_events=>on_function_selected FOR o_tool.

* im unteren Splitter Beispieldaten anzeigen
  DATA: it_sflight TYPE STANDARD TABLE OF sflight.

  SELECT * FROM sflight INTO TABLE @it_sflight.

  DATA: o_salv TYPE REF TO cl_salv_table.

  cl_salv_table=>factory( EXPORTING
                            r_container    = o_container_bottom
                          IMPORTING
                            r_salv_table   = o_salv
                          CHANGING
                            t_table        = it_sflight ).

  o_salv->get_functions( )->set_all( ).
  o_salv->display( ).

* leere Standard-Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

* Ausgabe von cl_gui_container=>default_screen erzwingen
  WRITE: space.

[ABAP] HTML-Code im cl_gui_html_viewer anzeigen, Eventhandling

* Demoprogramme:
* SAPHTML_EVENTS_DEMO
* SAPHTML_SCRIPT_DEMO
* DEMO_TABLE_EXPRESSIONS

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

PARAMETERS: p_url TYPE string.

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.

    CLASS-METHODS:
      on_navigate_complete FOR EVENT navigate_complete OF cl_gui_html_viewer
        IMPORTING
            url
            sender.

    CLASS-METHODS:
      on_sapevent FOR EVENT sapevent OF cl_gui_html_viewer
        IMPORTING
            action
            frame
            getdata
            postdata
            query_table
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.

* nach Aufbau des Dokuments
  METHOD on_navigate_complete.
    p_url = url.
  ENDMETHOD.

* Link- oder Button-Klick
  METHOD on_sapevent.
    MESSAGE |Action: { action }, get: { getdata }| TYPE 'S'.
  ENDMETHOD.
ENDCLASS.

INITIALIZATION.

  DATA(o_dock) = NEW cl_gui_docking_container( ratio = 50
                                               side = cl_gui_docking_container=>dock_at_bottom
                                               no_autodef_progid_dynnr = 'X' ).

* HTML-Viewer
  DATA(o_html) = NEW cl_gui_html_viewer( parent = o_dock ).

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_html_viewer=>m_id_navigate_complete
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_html_viewer=>m_id_sapevent
                                          appl_event = abap_true ) ).

  o_html->set_registered_events( events = it_events ).

* Eventhandler registrieren
  SET HANDLER lcl_events=>on_navigate_complete FOR o_html.
  SET HANDLER lcl_events=>on_sapevent FOR o_html.

* HTML-Code mit Buttons und Forms
  DATA(it_html) = VALUE html_table( ( |<html>| )
                                    ( |  <head>| )
                                    ( |    <title>Drag & Drop Test</title>| )
                                    ( |  </head>| )
                                    ( |  <script type="text/javascript">| )
                                    ( |    function mouse_click(element)| )
                                    ( |    \{| )
                                    ( |      location.href = "SAPEVENT:" + element;| )
                                    ( |    \}| )
                                    ( |  </script>| )
                                    ( |  <body bgcolor="#AABBCC">| )
                                    ( |    <p><font size=30>Dateien mit der Maus hierher ziehen!</font></p>| )
                                    ( |    <form method="post" action="SAPEVENT:SHOW_INFO?PARAMETER1">| )
                                    ( |      <p><input type="submit" value="Klick!"></p>| )
                                    ( |    </form>| )
                                    ( |    <form method="post" action="">| )
                                    ( |      <a href="SAPEVENT:LINK_KLICK?PARAMETER2">Link</a>| )
                                    ( |    </form>| )
                                    ( |    <button onclick="mouse_click('BTN_CLICK')">Show</button>| )
                                    ( |  </body>| )
                                    ( |</html>| ) ).

* URL zu HTML holen
  DATA: lv_url TYPE swk_url.

  o_html->load_data( IMPORTING
                       assigned_url = lv_url
                     CHANGING
                       data_table   = it_html ).

* HTML anzeigen
  o_html->show_url( url = lv_url ).

[ABAP] GUI-Simple-Tree und SALV-Grid in Split-Container ohne Dynpro anzeigen, Eventhandling

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.
TYPES: ty_it_nodes TYPE STANDARD TABLE OF mtreesnode WITH DEFAULT KEY.

DATA: o_salv TYPE REF TO cl_salv_table.
DATA: it_tree_spfli TYPE STANDARD TABLE OF spfli.
DATA: it_salv_spfli TYPE STANDARD TABLE OF spfli.
DATA: it_nodes TYPE ty_it_nodes.

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
* GUI Simple Tree
    CLASS-METHODS: on_keypress FOR EVENT node_keypress OF cl_gui_simple_tree
      IMPORTING
          node_key
          key
          sender.
    CLASS-METHODS: on_selection_changed FOR EVENT selection_changed OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_expand_no_children FOR EVENT expand_no_children OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
* ALV-Events für das SALV-Grid
    CLASS-METHODS: on_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
      IMPORTING
          e_object
          sender.
    CLASS-METHODS: on_user_command FOR EVENT user_command OF cl_gui_alv_grid
      IMPORTING
          e_ucomm
          sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Tastendruck
  METHOD on_keypress.
    MESSAGE |Node: { node_key } Taste: { key }| TYPE 'S'.
  ENDMETHOD.
* Klick auf ein aktives Baumelement
  METHOD on_selection_changed.
* Element in der Nodes-Tabelle lesen
    ASSIGN it_nodes[ node_key = node_key ] TO FIELD-SYMBOL(<fs_node>).

* iTab für SALV-Table neu aufbauen
    CLEAR: it_salv_spfli.

    LOOP AT it_tree_spfli ASSIGNING FIELD-SYMBOL(<fs_line>) WHERE carrid = <fs_node>-text.
      APPEND <fs_line> TO it_salv_spfli.
    ENDLOOP.

* SALV-Table neu anzeigen
    o_salv->refresh( ).
  ENDMETHOD.
* bei Expandierung eines Baumelements ohne Unterelemente
  METHOD on_expand_no_children.
    MESSAGE |Node: { node_key }| TYPE 'S'.
  ENDMETHOD.

* Toolbar-Buttons hinzufügen:
* butn_type   Bezeichung
* 0           Button (normal)
* 1           Menü + Defaultbutton
* 2           Menü
* 3           Separator
* 4           Radiobutton
* 5           Auswahlknopf (Checkbox)
* 6           Menüeintrag
  METHOD on_toolbar.
* Separator hinzufügen
    APPEND VALUE #( butn_type = 3 ) TO e_object->mt_toolbar.
* Edit-Button hinzufügen
    APPEND VALUE #( butn_type = 5 text = 'Daten anzeigen' icon = icon_icon_list function = 'SHOW_DATA' quickinfo = 'Daten anzeigen' disabled = ' ' ) TO e_object->mt_toolbar.
  ENDMETHOD.
* Benutzerkommando (Button-Klick)
  METHOD on_user_command.
    CASE e_ucomm.
      WHEN 'SHOW_DATA'.
        DATA: lv_row TYPE i. " Zeile auf Grid
        DATA: lv_value TYPE char255. " Wert
        DATA: lv_col TYPE i. " Spalte auf Grid
        DATA: lv_row_id TYPE lvc_s_row. " Zeilen-Id
        DATA: lv_col_id TYPE lvc_s_col. " Spalten-Id
        DATA: lv_row_no TYPE lvc_s_roid. " Numerische Zeilen ID

        sender->get_current_cell( IMPORTING
                                    e_row = lv_row
                                    e_value = lv_value
                                    e_col = lv_col
                                    es_row_id = lv_row_id
                                    es_col_id = lv_col_id
                                    es_row_no = lv_row_no ).

        MESSAGE |Zeile: { lv_row }, Spalte: { lv_col }, Wert: { lv_value }, Spaltenname: { lv_col_id-fieldname }| TYPE 'S'.
    ENDCASE.
  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

  SELECT * INTO TABLE it_tree_spfli FROM spfli.

* Splitter auf screen0 erzeugen
  DATA(o_split) = NEW cl_gui_splitter_container( parent = cl_gui_container=>screen0
                                                 no_autodef_progid_dynnr = abap_true
                                                 rows = 1
                                                 columns = 2 ).

* Breite in % (linke Spalte für den Tree)
  o_split->set_column_width( id = 1 width = 15 ).

* linken und rechten Splitcontainer holen
  DATA(o_spl_left) = o_split->get_container( row = 1 column = 1 ).
  DATA(o_spl_right) = o_split->get_container( row = 1 column = 2 ).

  TRY.
* Tree-Objekt erzeugen
      DATA(o_tree) = NEW cl_gui_simple_tree( parent = o_spl_left
                                             node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single ).


* Eventtypten müssen gesondert registriert werden
      DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_simple_tree=>eventid_node_keypress
                                              appl_event = abap_true )
                                            ( eventid = cl_gui_simple_tree=>eventid_selection_changed
                                              appl_event = abap_true )
                                            ( eventid = cl_gui_simple_tree=>eventid_expand_no_children
                                              appl_event = abap_true ) ).

      o_tree->set_registered_events( events = it_events ).

      o_tree->add_key_stroke( cl_gui_simple_tree=>key_enter ).

* Events registrieren
      SET HANDLER lcl_events=>on_keypress FOR o_tree.
      SET HANDLER lcl_events=>on_selection_changed FOR o_tree.
      SET HANDLER lcl_events=>on_expand_no_children FOR o_tree.

* Root-Node einfügen
      it_nodes = VALUE #( ( node_key  = 'ROOT'           " Node-Bezeichner
                            relatship = cl_gui_simple_tree=>relat_last_child
                            disabled  = abap_true
                            isfolder  = abap_true        " Typ Ordner für Root-Element
                            n_image   = icon_folder      " Icon Ordner
                            exp_image = icon_open_folder " Icon geöffneter Ordner
                            style     = cl_gui_simple_tree=>style_default
                            text      = 'Airlines' ) ).

* Childs an Root-Node anhängen
      LOOP AT it_tree_spfli ASSIGNING FIELD-SYMBOL(<fs_line>).
* bei Änderung der carrid neue carrid als Child anhängen
        AT NEW carrid.
          APPEND VALUE #( node_key  = |NODE{ sy-tabix }| " eindeutiger Node-Bezeichner
                          relatship = cl_gui_simple_tree=>relat_last_child
                          relatkey  = 'ROOT'             " an ROOT-Element anhängen
                          style     = cl_gui_simple_tree=>style_intensified
                          text      = |{ <fs_line>-carrid }| ) TO it_nodes.
        ENDAT.
      ENDLOOP.

* Nodes im Baum einfügen
      o_tree->add_nodes( table_structure_name = 'MTREESNODE' " Typ muss gleich mit Zeilentyp von ty_it_nodes sein
                         node_table           = it_nodes ).

* Root-Nodes des Trees expandieren
      o_tree->expand_root_nodes( ).

* leeres SALV-Grid erzeugen
      cl_salv_table=>factory( EXPORTING
                                r_container    = o_spl_right
                              IMPORTING
                                r_salv_table   = o_salv
                              CHANGING
                                t_table        = it_salv_spfli ).

      o_salv->get_display_settings( )->set_striped_pattern( abap_true ).
      o_salv->get_columns( )->set_optimize( abap_true ).
      o_salv->get_functions( )->set_all( ).
      o_salv->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).
      o_salv->display( ).

* Trick: Aus dem Split-Container rechts das Grid-Objekt holen und nach cl_gui_alv_grid casten
      READ TABLE o_spl_right->children INDEX 1 ASSIGNING FIELD-SYMBOL(<child>).
      IF <child> IS ASSIGNED.
        DATA(o_alv_grid) = CAST cl_gui_alv_grid( <child> ).

* Eventhandler registrieren
        SET HANDLER lcl_events=>on_toolbar FOR o_alv_grid.
        SET HANDLER lcl_events=>on_user_command FOR o_alv_grid.
      ENDIF.

    CATCH cx_root INTO DATA(e_text).
      WRITE: / e_text->get_text( ).
  ENDTRY.

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

* cl_gui_container=>screen0 erzwingen
  WRITE space.

[ABAP] Baumstruktur mit Hilfe des cl_gui_simple_tree anzeigen, Events abfangen

* Demoprogramme
* RSDEMO_DRAG_DROP_EDIT_TREE
* RSDEMO_DRAG_DROP_TREE_MULTI
* SAPSIMPLE_TREE_CONTROL_DEMO

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.
TYPES: ty_it_nodes TYPE STANDARD TABLE OF mtreesnode WITH DEFAULT KEY.

DATA: it_nodes TYPE ty_it_nodes.

CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: on_keypress FOR EVENT node_keypress OF cl_gui_simple_tree
      IMPORTING
          node_key
          key
          sender.
    CLASS-METHODS: on_double_click FOR EVENT node_double_click OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_selection_changed FOR EVENT selection_changed OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_expand_no_children FOR EVENT expand_no_children OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
* Tastendruck, die Tasten müssen mit add_key_stroke( ) registriert worden sein
  METHOD on_keypress.
    WRITE: / |Node: { node_key } Taste: { key }|.
  ENDMETHOD.
* Doppelklick auf ein aktives Baumelement
  METHOD on_double_click.
* Text in der Nodes-Tabelle anpassen
    ASSIGN it_nodes[ node_key = node_key ] TO FIELD-SYMBOL(<fs_node>).
    <fs_node>-text = 'Schonmal geklickt.'.

* Text in der Node anpassen
    sender->node_set_text( node_key = node_key text = <fs_node>-text ).

    WRITE: / |Node: { node_key }, Text: { <fs_node>-text }|.
  ENDMETHOD.
* Klick auf ein aktives Baumelement
  METHOD on_selection_changed.
    WRITE: / |Node: { node_key }|.
  ENDMETHOD.
* bei Expandierung eines Baumelements ohne Unterelemente
  METHOD on_expand_no_children.
    WRITE: / |Node: { node_key }|.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

* Container-Objekt erzeugen
  DATA(o_dock) = NEW cl_gui_docking_container( no_autodef_progid_dynnr = abap_true
                                               side = cl_gui_docking_container=>dock_at_left
                                               ratio = 15
                                               caption = 'Datenausgabe' ).

* Tree-Objekt erzeugen
  DATA(o_tree) = NEW cl_gui_simple_tree( parent = o_dock
                                         node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single ).

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_simple_tree=>eventid_node_keypress )
*                                        ( eventid = cl_gui_simple_tree=>eventid_node_double_click )
                                        ( eventid = cl_gui_simple_tree=>eventid_selection_changed )
                                        ( eventid = cl_gui_simple_tree=>eventid_expand_no_children
                                          appl_event = abap_true ) ).

  o_tree->set_registered_events( events = it_events ).

* benötigte Tasten registrieren
*cl_gui_simple_tree=>key_f1: F1
*cl_gui_simple_tree=>key_f4: F4
*cl_gui_simple_tree=>key_insert: Einfügen
*cl_gui_simple_tree=>key_delete: Entfernen
*cl_gui_simple_tree=>key_enter: Enter
*cl_gui_simple_tree=>key_cut: Strg+X
*cl_gui_simple_tree=>key_copy: Strg+C
*cl_gui_simple_tree=>key_paste: Strg+V

  o_tree->add_key_stroke( cl_gui_simple_tree=>key_enter ).
  o_tree->add_key_stroke( cl_gui_simple_tree=>key_f1 ).
  o_tree->add_key_stroke( cl_gui_simple_tree=>key_delete ).

* Events registrieren, on_double_click und on_selection_changed
* dürfen nicht gleichzeitig registriert sein, sonst Exception
  SET HANDLER lcl_event=>on_keypress FOR o_tree.
*  SET HANDLER lcl_event=>on_double_click FOR o_tree.
  SET HANDLER lcl_event=>on_selection_changed FOR o_tree.
  SET HANDLER lcl_event=>on_expand_no_children FOR o_tree.

* Tree-Nodes einfügen -> die Bezeichner müssen eindeutig sein
  it_nodes = VALUE #( ( node_key  = 'FLDR1'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        disabled  = abap_true
                        isfolder  = abap_true
                        n_image   = icon_folder
                        exp_image = icon_open_folder
                        style     = cl_gui_simple_tree=>style_default
                        text      = 'Ordner' )

                      ( node_key  = 'NODE1'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        disabled  = abap_true
                        isfolder  = abap_true
                        relatkey  = 'FLDR1'
                        n_image   = icon_folder
                        exp_image = icon_open_folder
                        style     = cl_gui_simple_tree=>style_intensified
                        text      = 'Datensatz 1' )

                      ( node_key  = 'NODE1_1'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        isfolder  = abap_false
                        relatkey  = 'NODE1'
                        n_image   = icon_led_yellow
                        style     = cl_gui_simple_tree=>style_intensified
                        text      = 'Datensatz 1_1' )

                      ( node_key  = 'NODE2'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        isfolder  = abap_false
                        relatkey  = 'FLDR1'
                        n_image   = icon_led_green
                        style     = cl_gui_simple_tree=>style_default
                        text      = 'Datensatz 2' )

                      ( node_key  = 'NODE3'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        isfolder  = abap_false
                        relatkey  = 'FLDR1'
                        disabled  = abap_true
                        n_image   = icon_led_inactive
                        style     = cl_gui_simple_tree=>style_inactive
                        text      = 'Datensatz 3 (inaktiv)' )

                      ( node_key  = 'NODE4'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        isfolder  = abap_false
                        relatkey  = 'FLDR1'
                        disabled  = abap_false
                        n_image   = icon_led_red
                        style     = cl_gui_simple_tree=>style_intensifd_critical
                        text      = 'Datensatz 4' ) ).

  o_tree->add_nodes( table_structure_name = 'MTREESNODE' " Typ muss gleich mit Zeilentyp von ty_it_nodes sein
                     node_table           = it_nodes ).

* Root-Nodes des Trees expandieren
  o_tree->expand_root_nodes( ).

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

  WRITE space. " wichtig für Erzwingung der Listenausgabe und Anzeige des Trees

Weiterführende Infos: Link und Link