Ingo Biermann
24. November 2013

Drag & Drop Operationen in einer Tabelle mit Web Dynpro ABAP

In diesem How To werden Ihnen die verschiedenen Möglichkeiten der Drag & Drop-Operationen für das Web Dynpro ABAP UI-Element “Table” vorgestellt. Anhand einer Web Dynpro Anwendungen werden verschiedene Szenarien präsentiert und die Vorgehensweise erklärt.

Drag & Drop bezeichnet eine Benutzeraktion, in der der Nutzer ein Element aus einer Quelle auf ein Zielelement zieht und dort platziert. Dies geschieht typischer Weise mit der Maus.

In Web Dynpro ABAP kann man diese Funktionalität ebenfalls umsetzen. Hierfür eignen sich fast alle UI-Elemente und selbst solche, die ungeeignet erscheinen, können mit Hilfe des sogenannten DropTarget UI-Element “Drag&Drop-fähig” gemacht werden. In diesem Beispiel wird jedoch nur auf das UI-Element Table eingegangen.

Die Tabelle bietet folgende Drag & Drop-Operationen an:

  • Einfügen von neuen Zeilen
  • Verschieben von Zeilen in der Tabelle
  • Zeilen-Drop, sprich es wird ein “Drop” auf eine Zeile ermöglicht

Wichtig ist zwischen Ziel und Quelle zu unterscheiden. Die Quelle definiert eine sogenannte DragSourceInfo. Diese ermöglicht über die Eigenschaft data Daten an das Ziel der Drag & Drop-Operation zu übergeben. Das Ziel-Element definiert eine DropTargetInfo, welche das Event onDrop auslöst, wenn ein Element auf das Ziel fallen gelassen wird.
Ziel und Quelle werden über die Eigenschaft tag verbunden, indem dort dieselben Bezeichner gepflegt werden.

In dem ersten Beispiel wird eine Tabelle implementiert, welche die Quelle der Drag & Drop-Operation darstellt. Das Ziel der Operation ist eine Form, welche sich abhängig von der Tabellenzeile, die auf die Form fallen gelassen wird, füllt.

An diesem Punkt wird angenommen, dass Sie sich mit der grundlegenden Architektur eines Web Dynpros auskennen.

Sie haben eine Web Dynpro Anwendung mit einer Tabelle und einer Form. In meinem Fall ist es, um das Beispiel so simpel wie möglich zu halten die Tabelle SFLIGHT, also die Flugtabelle vom SAP IDES.

Flugtabelle vom SAP IDES

Flugtabelle vom SAP IDES

Der Context ist im Component-Controller gepflegt? Wurde dieser mit der View gemappt und mit den entsprechenden UI-Elementen gebunden? Dann kann es jetzt losgehen.

Mein Context sieht folgendermaßen aus:

Context

Context

Um die Tabelle als Quelle einer Drag & Drop-Operation zu definieren gehen Sie in die View und selektieren mit Rechtsklick auf das Table-Element Drag-Source einfügen

 Drag-Source einfügen selektieren

Drag-Source einfügen selektieren

Nun können sie die Eigenschaften der DragSourceInfo pflegen. In meinem Beispiel übergebe ich die eindeutige Flugnummer über die Eigenschaft data und als tag benutze ich “TABLE”. Dieser tag wird genutzt um Quelle und Ziel miteinander zu verbinden.

Quelle und Ziel per Tag miteinander verbinden

Quelle und Ziel per Tag miteinander verbinden

Als nächsten Schritt legen sie ein DropTarget-Element
an um Ihre Form als Ziel für Ihre Drag-&-Drop-Operation festzulegen.

Form als Ziel für Ihre Drag-&-Drop-Operation

Form als Ziel für Ihre Drag-&-Drop-Operation

DropTarget-Element anlegen

DropTarget-Element anlegen

Dieses UI-Element verfügt über das Ereignis onDrop. Sie können einen Ereignisbehandler implementieren, welcher ausgelöst wird, wenn ein Element auf dieses DropTarget fallen gelassen wird.

Ereignisbehandler implementieren

Ereignisbehandler implementieren

In dieses DropTarget fügen Sie nun eine Form ein. Das Element kann nur ein UI-Element enthalten aber dies kann ja mit Hilfe eines Transparent-Container umgangen werden.

Form in DropTarget einfügen

Form in DropTarget einfügen

Im nächsten Schritt wird dieses DropTarget mit einem DropTargetInfo
versehen, in dem die Eigenschaften für das Ziel der Drag & Drop-Operation definiert werden.

Ziel der Drag & Drop-Operation definieren

Ziel der Drag & Drop-Operation definieren

Der tag muss identisch zu dem aus der Quelle sein. Es kann auch ein Teil des Namens verwendet werden, da mit Wildcards (*) gearbeitet werden kann.

Tag muss identisch zu dem aus der Quelle sein

Tag muss identisch zu dem aus der Quelle sein

Als letzter Schritt muss nun die Logik für den onDrop-Eventhandler implementiert werden.

METHOD onactionflight_dropped .

DATA lo_nd_flight_number TYPE REF TO if_wd_context_node.
DATA ls_flights TYPE sflight.
DATA lv_free_seats TYPE sflightseatsocc.
DATA lo_el_flight_number TYPE REF TO if_wd_context_element.
DATA ls_flight_number TYPE wd_this->element_flight_number.
DATA lv_connid TYPE wd_this->element_flight_numberconnid.
DATA lo_nd_flight_info TYPE REF TO if_wd_context_node.
DATA lo_el_flight_info TYPE REF TO if_wd_context_element.
DATA ls_flight_info TYPE wd_this->element_flight_info.

lv_connid data.
lo_nd_flight_number wd_context->get_child_nodename wd_this->wdctx_flight_number ).
lo_el_flight_number lo_nd_flight_number->get_element( ).

lo_el_flight_number->set_attribute(
name =  `CONNID`
value lv_connid ).

SELECT SINGLE seatsmax seatsocc FROM sflight INTO CORRESPONDING FIELDS OF ls_flights
WHERE connid data.

lv_free_seats ls_flightsseatsmax – ls_flightsseatsocc.
lo_nd_flight_info wd_context->get_child_nodename wd_this->wdctx_flight_info ).
lo_el_flight_info lo_nd_flight_info->get_element( ).
ls_flight_infoseatsmax ls_flightsseatsmax.
ls_flight_infoseatsocc lv_free_seats.
lo_el_flight_info->set_static_attributes(
static_attributes ls_flight_info ).

ENDMETHOD.

Die freien Plätze werden mit der übergebenen Flugnummer berechnet und damit die Attribute der Forn im Context gesetzt.
Nachdem Sie eine Web Dynpro Anwendung erstellt haben, können Sie die Funktionalität im Browser testen. Hiermit wäre der erste Fall abgeschlossen.
Im nächsten Fallbeispiel wird auf die Unterschiede zu dem vorherigen Drag & Drop-Beispiel eingegangen.

 

Startbildschirm

Startbildschirm

 

Web Dynpro drag and drop der Tabellenzeile

Web Dynpro drag and drop der Tabellenzeile

Die Felder der Form füllen sich.

Formfelder

Formfelder

Im nächsten Fall implementieren wir das Einfügen neuer Zeilen in einer Tabelle und das Verschieben vorhandener Zeilen in zugehörigen Tabelle.

Hierfür wird der bestehenden Logik eine neue Tabelle hinzugefügt. Hier wird die Tabelle SBOOK als Vorbild genommen. Sie müssen im Context einen neuen Knoten anlegen und diesen mit der View mappen.

Neuen Knoten anlegen und diesen mit der View mappen

Neuen Knoten anlegen und diesen mit der View mappen

Diese Tabelle soll nun Einträge der ersten Tabelle aufnehmen können und auch ermöglichen, eigene Zeilen zu verschieben oder umzusortieren.

Hierfür müssen Sie folgende Schritte ausführen:

  1. DragSourceInfo hinzufügen
  2. DropTargetInfo hinzufügen
  3. Die tags für die entsprechenden Tabellen richtig pflegen, d.h. für das target den tag von der ersten Tabelle also “TABLE” und für den DropOnRowTargetInfos einen eigenen tag, welcher dann auch für den DragSourceInfo verwendet wird.
  4. Das onDrop Event behandeln
DragSourceInfo hinzufügen

DragSourceInfo hinzufügen

 

DropTargetInfo hinzufügen

DropTargetInfo hinzufügen

 

Die tags für die entsprechenden Tabellen richtig pflegen

Die tags für die entsprechenden Tabellen richtig pflegen

In der Methode kann über den tag, welcher ein Import-Parameter ist, abgefragt werden, welche DragSource gerade das Event ausgelöst hat. Daher ist es wichtig diese eindeutig zu vergeben, damit man in Fällen wie diesem, wo mehrere DragSourceInfos auf die Tabelle verweisen, unterscheiden kann, welche Ereignisbehandlung aufgerufen werden soll.

Es bietet sich an, Konstanten für die Tags anzulegen. Da es sich hier nur um ein kleines Beispiel handelt, werden sie direkt in den Code geschrieben.

Fügen Sie den Code in Ihren Ereignisbehandler ein, um das Beispiel abzuschließen.

METHOD onactiontable_drop .

DATA lo_nd_booking_table TYPE REF TO if_wd_context_node.
DATA lo_lead_selection TYPE REF TO IF_WD_CONTEXT_ELEMENT.
DATA lt_booking_table TYPE wd_this->elements_booking_table.
DATA ls_booking TYPE wd_this->element_booking_table.
DATA ls_selected_entry TYPE wd_this->element_booking_table.
DATA ls_spfli TYPE spfli.
DATA lv_index TYPE i.

IF tags ‘TABLE’.

SELECT SINGLE FROM spfli INTO CORRESPONDING FIELDS OF ls_booking WHERE connid data.
APPEND ls_booking TO lt_booking_table.
lo_nd_booking_table wd_context->get_child_nodename wd_this->wdctx_booking_table ).
lo_nd_booking_table->bind_tablenew_items lt_booking_table set_initial_elements abap_false ).

ELSEIF tags ‘ROW’.

lo_nd_booking_table wd_context->get_child_nodename wd_this->wdctx_booking_table ).
lo_nd_booking_table->get_static_attributesIMPORTING static_attributes ls_selected_entry ).
lo_nd_booking_table->get_static_attributes_tableIMPORTING table lt_booking_table ).
lo_lead_selection lo_nd_booking_table->get_lead_selection( ).
lv_index lo_lead_selection->get_index( ).
IF lv_index 0.
lv_index 1.
ENDIF.
DELETE lt_booking_table INDEX lv_index.
lv_index row_element->get_index( ).
INSERT ls_selected_entry INTO lt_booking_table INDEX lv_index.
lo_nd_booking_table->bind_tablenew_items lt_booking_table set_initial_elements abap_true ).
lo_nd_booking_table->move_toindex lv_index ).

ENDIF.
ENDMETHOD.

Erklärung des Codings:

Über den Import Parameter ROW_ELEMENT wird eine Referenz auf die Zeile, auf die man die ausgewählte Tabellenzeile “fallen gelassen” hat, übergeben. Über die Methode get_index( ) liefert die aktuelle Position der Zeile in der Tabelle. Die lead_selection wird ausgelesen, dies ist die selektierte Zeile in der Tabelle, die bewegt werden soll. Diese werden aus der Tabelle gelöscht, und wieder an dem neuen Index eingefügt. Zuletzt wird die neue Lead Selection der Tabelle mit der Methode move_to( ) an den neuen Index verschoben. Diese Methode stellt das Interface IF_WD_CONTEXT_NODE, also in diesem Fall die Referenz auf den Context-Knoten der zweiten Tabelle.

Das Ergebnis der Erweiterungen sieht so aus:

Erweiterungsergebnis

Erweiterungsergebnis

 

 

Zeile hinzugefügt

Zeile hinzugefügt

Vorgang mit anderen Zeilen wiederholen

Wiederholen des Vorgangs

Wiederholen des Vorgangs

Nun unterste Zeile nach oben ziehen

Unterste Zeile nach oben

Unterste Zeile nach oben

Ergebnis

Ergebnis der Verschiebung

Ergebnis der Verschiebung

Ich hoffe Ihnen hat dieses How To gefallen und Sie haben lernen können, wie die Drag & Drop-Operationen für das Web Dynpro UI-Element Table umzusetzen sind. Falls es Sie noch interessiert, wie ein Drag & Drop auf eine Zeile umzusetzen ist, nutzen Sie unsere Kommentarfunktion, wir helfen Ihnen gerne weiter

Für Fragen rund um das Thema dieses Blogbeitrages stehe ich Ihnen gerne zur Verfügung.

Ingo Biermann

Ingo Biermann

Als Management- und Technologieberater unterstütze ich seit mehr als 15 Jahren große und mittelständische Unternehmen in Fragen der IT-Strategie und bin unterwegs in unterschiedlichen SAP-Themen wie SAP S/4HANA, User Experience und SAP Entwicklung.

Sie haben Fragen? Kontaktieren Sie mich!



Das könnte Sie auch interessieren

Wenn ein Anwender über die Universal Worklist (UWL) einen Eintrag bearbeiten möchte, kann er diesen normalerweise über einen Absprung in die Browseranwendung des zugrunde liegenden Systems oder direkt in der […]

weiterlesen

Der Begriff FBI hat im SAP Umfeld nichts mit der amerikanischen Behörde zu tun. Er steht für die Floorplan Manager BOPF Integration, also einem Framework für die Verknüpfung des Floorplan […]

weiterlesen

Ziel der Internationalisierung einer Anwendung ist die Bereitstellung einer Grundlage, um das Programm mehrsprachig zu gestalten, ohne das Design oder den Quellcode im Nachhinein zu verändern. Sobald der Benutzer seine […]

weiterlesen

6 Kommentare zu "Drag & Drop Operationen in einer Tabelle mit Web Dynpro ABAP"

Martin Tilenius - 3. April 2014 | 17:39

Hallo Herr Bianchini!

Vielen Dank für die Informationen zu Drag & Drop. Ich suche nach einer Möglichkeit einen Drop in eine Tabellenspalte zu realisieren, komme da aber nicht wirklich voran. Haben Sie vielleicht eine Idee dazu?

Mit freundlichen Grüßen
Martin Tilenius

Antworten
Sebastian Bianchini - 4. April 2014 | 13:24

Hallo Herr Tilenius,

sehr gerne! Danke für Ihr Interesse an dem Artikel.
Also von Haus aus bietet SAP einige Optionen für die Manipulation von Tabellen durch Drag & Drop Tabellen.

1. Das Einfügen neuer Zeilen zwischen bereits vorhandenen Tabellenzeilen

2. Einfügen an erster oder letzter Position innerhalb der aufgelisteten Zeilen

3. Auf eine bereits existierende Zeile

Option 3 ist für Sie interessant.
Ich werde Ihnen nun kurz beschreiben, wie Sie vorgehen sollten, um in eine bestehende Zeile zu “droppen”.

Benötigte Schritte:
Es verhält sich eigentlich relativ ähnlich wie das Einfügen neuer Zeilen zu einer Tabelle.

Öffnen Sie via Rechtsklick das Kontextmenü Ihrer betreffenden Tabelle. Dort befindet sich der Eintrag “INSERT DROP_ROW_TRG_INF (dropOnRowTargetInfos). Bitte wählen Sie diesen aus. (Durch diesen Schritt wird eine DropTargetInfo erstellt.) Alternativ kann hier auch eine bestehende DropTargetInfo verwendet werden.

Füllen Sie für das neue Element bitte die nötigen Informationen aus. Die Eigenschaft “name” wird in einem späteren Schritt wieder benötigt, also bitte einen Wert pflegen.

In Ihrer Tabelle gibt es eine Eigenschaft “dropOnRowName”, hier geben Sie den Name der zuvor definierten DropTargetInfo an.

Nun können Sie in dem Ereignis “onDrop” die nötige Logik implementieren um das Element, was Sie per Drag&Drop auf die Zeile gezogen haben einer Spalte hinzuzufügen.
Die Einfügeposition können Sie mit Hilfe der Methode “get_index” des Interfaces IF_WD_CONTEXT_ELEMENT und dem OFFSET-Attribut ermitteln. Das OFFSET-Attribut wird in dem Ereignis onDrop übergeben.

Ich hoffe ich konnte Ihnen helfen, damit Sie Ihr Problem lösen können.

Mit freundlichen Grüßen
Sebastian Bianchini

Antworten
Ramy El-Arnaouty - 28. Juli 2014 | 23:52

Hallo Herr Bianchini,
interessanter Beitrag!
Ich habe eben bei google nach “web dynpro abap table drag and drop” gesucht und habe Ihren Beitrag auf Platz 1 gelistet bekommen – Respekt!

Antworten
Ramy El-Arnaouty - 28. Juli 2014 | 23:55

Eigentlich ist für meine aktuelle Aufgabenstellung, nur das Verschieben von Zeilen innerhalb einer Tabelle von Bedeutung. Daher habe ich mir nur Methode “onactiontable_drop” genauer angesehen. Funktioniert prima!

Antworten
Ramy El-Arnaouty - 29. Juli 2014 | 00:22

Aufgabe von “onactiontable_drop( )” ist es doch, ein Element des Knotens von einem Index auf einen anderen zu verschieben. Also interessieren uns die Daten der Elemente gar nicht:
[…]
ELSEIF tags = ‘ROW’.

lo_nd_booking_table = wd_context->get_child_node( … ).

lo_nd_booking_table->move_element( from = lo_nd_booking_table->get_element( )->get_index( ) to = row_element->get_index( ) ).

ENDIF.
[…]

Antworten
Sebastian Bianchini - 30. Juli 2014 | 18:36

Hallo Herr El-Arnaouty,

vielen Dank für Ihr Lob und es freut mich, dass Ihre Aufgabe durch den Blogbeitrag gelöst werden konnte.

In meinem Beispiel lese ich die Tabelle aus dem Kontext aus, verändere den Inhalt, binde Sie wieder an den Kontextknoten und setze die Leadselection neu um.

Viele Grüße und weiterhin viel Erfolg,

Sebastian Bianchini

Antworten

Schreiben Sie einen Kommentar

Bitte füllen Sie alle mit * gekennzeichneten Felder aus. Ihre E-Mail Adresse wird nicht veröffentlicht.





Kontaktieren Sie uns!
Alexander Koessner-Maier
Alexander Kössner-Maier Kundenservice