Introduction
In today’s World of upcoming new technologies, interoperability and the power of SAP’s strategic UI technology – web dynpro it is easy to forget about some of the earlier but equally usable technologies. The ABAP control framework is one such technology that offers a powerful alternative to web dynpro or BSP. This is a point well made in previous blogs such as that by David Halisky:
Yea though I walk through the valley of the shadow of WDA/WDJ, I have taken BC412
Yea though I walk through the valley of the shadow of WDA/WDJ, I have taken BC412
As part of a recent project in the automotive industry a customer required a new transaction to maintain vehicle model accessory data at a “higher” and easier central level to that provided as standard. The customer’s legacy system allowed the user to easily move data around the screen via drag and drop and maintain many records at any one time. Web access to the transaction (which was to be effectively one screen) was not required and the volume of data was comparatively low.
From a conceptual point of a view my first thoughts were to provide a solution something similar to the layout of SE80 with the following sections:
· Vehicle model selection criteria (top left hand corner)
· Hierarchical vehicle model data – tree control (bottom left hand corner)
· Vehicle accessory data ALV grid (right hand side)
A new table would be created which would store the accessory master data records at the central level and this would represent a 1: many relationship with the standard accessory table records. An ALV grid would be used to maintain the new table and the user would be able to assign the records to the standard vehicle model master data records. The assignment would be performed via drag & drop.
It was at this point at which I started to think about the options to do this technically. The project was a predominately ABAP biased Netweaver 7 environment and drag and drop technology is not currently supported in ABAP Web Dynpro. Aside from BSP technology the ABAP control framework seemed almost the only choice for this development.
What I came up with was the following transaction:
This is an attempt to highlight some of the key elements of this transaction within the ABAP control framework – namely:
· ALV models
· Tree controls
· Use of HTML
· Drag and drop between an ALV grid and tree control
The basics
There is a wealth of information available on all the things that are required for this development but I found only a few limited attempts ‘to chain it all together’. Some good sources of information include:
BC412: ABAP Dialog Programming Using EnjoySAP Controls SAP delivered course
http://www.sap.com/services/education/course.epx?context=%5B%5B%7CBC412%7C%7C%7C%7C%5D%5D%7C
User Interface Development in ABAP / GUI Controls
Control framework help
http://help.sap.com/saphelp_nw2004s/helpdata/en/d2/147a36c70d2354e10000009b38f839/frameset.htm
OO ABAP and Design Patterns 3: Docking Containers' Controller
OO ABAP and Design Patterns 3: Docking Containers' Controller
SAP delivered examples:
· See transaction DWDM – Enjoy SAP demos
· For OO ALV see ABAP programs prefixed with SALV or package SLIS (or programs prefix BCALV) for ALV grid examples
· Programs RSDEMO_DRAG_DROP_TREE_MULTI / RSDEMO_DRAG_DROP_EDIT_TREE
…plus of course the ABAP controls technology book (with the ‘infamous’ crazy painting on the cover!) if you can get hold of a copy. A newer SAP Controls Workshop book does exist:
http://www.sappressbooks.com/product.cfm?account=&product=H1913
Choice of ALV Model
The ABAP List Viewer has been around for some time now and has developed significantly since its initial 4.6 days. As a developer you are presented with a raft of different ways in which to use ALV from the calling of function modules to the new simple “factory” method for example:
Type | Type | Release | Comment |
ALV list/hierarchical list | Function Modules | Generally 4.6 onwards (some are available in earlier releases) | See function modules REUSE_ALV_LIST_DISPLAY or REUSE_ALV_HIERSEQ_LIST_DISPLAY |
Fullscreen grid | See function module REUSE_ALV_GRID_DISPLAY | ||
ALV grid or tree control | Class | See class CL_GUI_ALV_GRID or CL_GUI_ALV_TREE | |
OO ALV wrapper to grid control e.g. “factory” method | From basis release 6.40 | See class CL_SALV_TABLE, CL_SALV_HIERSEQ_TABLE or CL_SALV_TREE |
My advice here is to ensure you know how the ALV is to be used and decide up-front what you want to do in the ALV as you may find that the approach you choose will not support what you want to do. As my transaction used controls for example that automatically meant I needed to use one of the OO approaches to ALV. If you have any doubt or just wish to check then I would strongly recommend reading the following:
Note 551605 - ALV FAQ - General information
https://service.sap.com/sap/support/notes/551605
ALV Grid control
http://help.sap.com/saphelp_nw04/helpdata/en/0a/b552f7d30911d2b467006094192fe3/frameset.htm
By far the most important point to make here is that currently the new object model of the SAP List Viewer (CL_SALV_TABLE) does not support editable ALV. This is stated in a few places but unless you do your homework it is easy to miss. Whilst there have been solutions offered to overcome this restriction for example:
Power of ABAP Objects: Overcome the Restrictions of SALV Model
Power of ABAP Objects: Overcome the Restrictions of SALV Model
I decided I would use CL_GUI_ALV_GRID for my vehicle accessory data – this offered the user the ability to fully edit data in the grid, display icons and also supported drag & drop functionality.
Choice of Tree control
In a similar vain to ALV the developer is also presented with different techniques for displaying data in a hierarchical tree format. There are two approaches – SAP tree and SAP tree model and within these three types of tree control. Essentially SAP tree model retains data itself within an instance which means it is better for actions such as searching, requiring less network communication than SAP tree. SAP tree is however available in earlier (pre 4.6C) releases to SAP tree model and has different environment restrictions.
The three types of tree control; simple, column and list appear as follows:
Initially I found this quite confusing and there to be some overlap in functionality between all 3 types. In short, as with ALV’s, do your homework and decide what you want to do and then use that to determine your type of tree control. There are limitations with certain types such as functionality that is not available in certain environments or different behaviour from one environment to another. The standard help is very good once you’ve digested the different approaches and got your head around nodes, branches and leaves…
SAP Tree and Tree Model
http://help.sap.com/saphelp_nw04/helpdata/en/34/2a90d6b42d11d2bd7a080009b4534c/frameset.htm
I decided I would use CL_GUI_LIST_TREE for my vehicle model data – a choice that was driven by the need to have icons and a checkbox for user input in my tree. If you wish to have a checkbox then you need to choose either the column or list tree approach from SAP tree and not an approach from the SAP tree model. Aside from this the SAP tree model provides some functionality that is not available in the SAP tree such as printing and searching and is the recommended approach.
Selection criteria fields using HTML
In my transaction the vehicle accessory data is driven entirely by the vehicle models that are displayed on the left hand side of the screen. There was no requirement to restrict this data however the user had requested the ability to be able to change the vehicle model data that was displayed thus influencing what vehicle accessories were displayed.
I wanted to present my user with all the data and tools to use the transaction on one screen. To do this, in keeping with my ‘SE80’ mindset I opted to use HTML to place a small number of fields available for input in the top left hand corner. To put this into context:
SE80 HTML section | My transaction – HTML section |
The HTML section proved to be fairly straightforward to do however did have limitations which I was not normally used to - for me these were namely:
· Single value entry only. Multiple selections can be coded but its much more work!
· No F4 search help provision. You can code your own (as in SE80) but you would need to do it for every field which is potentially a lot of work. List boxes are very good however!
· No automatic dictionary validation e.g. foreign key checks, conversion exits etc
· Button appearance – the aesthetics can appear slightly different to those used elsewhere in the system
There were 5 principal objects that I used:
Class | Methods | Description |
CL_DD_DOCUMENT | ADD_FORM MERGE_DOCUMENT DISPLAY_DOCUMENT | Instantiate CL_DD_FORM_AREA |
CL_DD_FORM_AREA | LINE_WITH_LAYOUT ADD_TEXT ADD_GAP ADD_SELECT_ELEMENT ADD_BUTTON ADD_INPUT_ELEMENT | Screen field control & formatting |
CL_DD_BUTTON_ELEMENT | - | Button object handling |
CL_DD_SELECT_ELEMENT | - | List box object handling |
CL_DD_INPUT_ELEMENT | - | Screen field object handling |
A handler is created for every user input – each input field or button then had its own corresponding input element object which could be used when the handler event was triggered e.g. data input or a button being pressed.
The use of HTML in the SAP control framework is referred to as dynamic documents and there is some help available in the system at:
http://help.sap.com/saphelp_nw04/helpdata/en/b6/ab3a8103ac11d4a73f0000e83dd863/frameset.htm
Drag & drop
Having discussed the approach and structure to this transaction I now want to focus on one particular element of it, namely drag & drop. When I first discussed this development with a colleague the initial reaction was one of excitement but also caution as to how long such a piece of work would take. The reality of it was however that the drag & drop component of the work proved to be no worse than other aspects of the development so don’t be put off! Whilst my transaction only utilised one-way drag & drop I found the example programs such as RSDEMO_DRAG_DROP_TREE_MULTI of great use and the code/concept relatively easy to grasp. I am conscious that a lot can be written in this area – this is just an overview and will hopefully give you an idea of what can be done and how to do it.
The requirements
· Drag a vehicle accessory from the ALV grid on the right hand side of the screen on to a node in a tree control on the left hand side of the screen. This is effectively a move and copy operation.
· Update the tree control display, showing the accessory(s) that had been assigned to the vehicle model(s) as a result of the drop
· Update the ALV display by changing the type of icon on the accessory line(s) that had been assigned asa result of the drag
The solution
I’ll keep this simple and break it down into two sections broadly showing what you need to do “up front” and then what happens/to do upon the drag & drop event occurring:
1) Preparation
· Create a new local drag & drop class in the public section of your class. This will store information about the dragged object and so needs to include any information you wish to “pass across” from one object to another. There are no methods to this class it is merely used to transfer data. My class looked as follows:
class lcl_dragdropobj definition.
public section.
* The node_key is needed to decide which function shall& nbsp;be performed:
data: node_key_at_drop type string,
t_node_key_and_text type treemnotab,
source(5) type c,
node_table &n bsp; type treemcnota,
item_table &n bsp; type treemcitac.
data: sel_lines type zvsg_t_model_line,
lv_index ; type i.
endclass. ; "lcl_dragdropobj DEFINITION
· Create separate objects to define the drag & drop behaviour and global variables to easily identify the object handles – in this case the tree and ALV grid:
· Define the behaviour of the drag & drop using the objects GO_BEHAVIOUR_LEFT and GO_BEHAVIOUR_RIGHT. Using method ADD this means you need to define the source, target, flavor and effect for each object. In my example this means:
| GO_BEHAVIOUR_LEFT | GO_BEHAVIOUR_RIGHT |
FLAVOR | Line | Line |
SOURCE | NO | YES |
TARGET | YES | NO |
EFFECT | CL_DRAGDROP=>MOVE + CL_DRAGDROP=>COPY |
I was initially unsure of the “flavor” however it is merely a description for the type of drag & drop operation. In my example there is just one way drag and drop however it is possible to have multiple operations and these are identified by the flavor.
· After defining the behaviour you should use method GET_HANDLE in order to uniquely identify each object
· Upon creating the ALV layout (i.e. the ALV grid which will display my vehicle accessory data) pass the drag and drop handle for the GO_BEHAVIOUR_RIGHT object (GV_HANDLE_ALV) into field S_DRAGDROP-ROW_DDID
· When creating the node and item table for the tree (i.e. where the vehicle models will be displayed) pass the drag and drop handle for the GO_BEHAVIOUR_LEFT object (GV_HANDLE_TREE) into the field DRAGDROPID for each node which you want to be able to “drop into” i.e. activate the drag & drop behaviour
· Register the drag & drop events for the ALV grid and tree. The exact events will depend upon the class you have used (re earlier reference to doing your homework first as there is some disparity in events between classes). In my example I used the following events:
| Class | Method |
ALV grid | CL_GUI_ALV_GRID | ONDRAG |
ONDROPCOMPLETE | ||
Tree control | CL_GUI_LIST_TREE | ON_DROP |
2) The drag & drop operation
In my example method ONDRAG is triggered when line(s) from my ALV grid are selected and dragged across to the tree control on the left hand side of the screen. When the selection is dropped on to a node method ONDROP is triggered. If this method is executed successfully method ONDRAGCOMPLETE is then triggered.
Method ONDRAG
This method is concerned with my ALV grid data and I use this method to do the following:
· Perform checks e.g. ensure it is ok for the user to perform the drag operation
· Determine the selected rows e.g. using method CL_GUI_ALV_GRID ->GET_SELECTED_ROWS
· Create a local instance of the drag & drop class (LCL_DRAGDROPOBJ)
· Add information into the class such as the line index details of selected rows
· Assign the local class to the referring event parameter E_DRAGDROPOBJ->OBJECT
Method ONDROP
This method “retrieves” information from E_DRAGDROPOBJ->OBJECT and is used to update the tree data.
· Cast the E_DRAGDROPOBJ->OBJECT into a local object (ensure you use the catch system exceptions statement
· Loop around the selected rows that have been dragged across and validate the drop
· Messages can be output from this method and you can terminate the drop operation by calling method DRAG_DROP_OBJECT->ABORT
· Update the tree nodes and items
Method ONDRAGCOMPLETE
In this example I use this method to update a status icon in my ALV grid to show that an accessory has been assigned to a vehicle model. I use the method to refresh the ALV display.
The E_DRAGDROPOBJ->OBJECT data is available from earlier.
Conclusions
This has been an attempt to provide some insight into several areas – editable ALV’s and tree controls and drag and drop functionality between them with a bit of HTML for good measure. In part this has been to try to renew interest in what is now perhaps an overlooked area but also hopefully provide a working example to what was a fairly simple problem. I haven’t gone into huge amounts of detail but hopefully provided some useful references and ‘wet’ your appetite for further inspirational development work!