Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

Introduction

Making processes more user-friendly is the challenge we are facing today and tomorrow. A nice way to make processes more user-friendly is by making them easier to work with, easier to understand and present everything as appealing and easy as possible to the end-user.

I stumbled upon this "hidden" feature whilst looking for a new and easy solution for Product Portfolio Management/Maintenance. I call it a hidden feature because when searching for it I found .... nothing :smile: But undocumented features aren't that exceptional and that's why SCN is here of course!

I think this is a Enhancement Pack 1 feature which might only be available when a particular business function is activated.

This behavior should also work for a TreeView but I didn't test that (yet).

Example

The example below is a very basic example with no goal, I used it of course in another context but I made the example as generic as possible. In this way it's easy reproducible and the focus is on the actual drag and drop.

We'll create one Z component containing one viewset with two views. We'll drag-and-drop some data between the SOURCE view and the TARGET view.

Create Z Component

Create ViewSet

Add a Model to your component

In order to be able to add Model Context Nodes you must specify a Model in the Rutime Repository. Since I'm working with products I'll add the PROD_ALL Model.

Create the SOURCE and TARGET View

Add two Views to your Component. I added one Model Context Node on both views called PRODUCTS which are using the Product BOL Object.

I created both views as "Table View" with the options shown above. The Configurable is usefull and speeds up the process of creating the table; the "With Toolbar" is certainly not needed in this example.

The Table View will be linked to the Context Node Products as shown in the picture.

At this moment your component should look like this:

Add ViewSet to Window and the Views to the ViewSet in the Runtime Repository

Afterwards the Runtime Repository of your component should look like this:

Create an empty Class to implement the drag-and-drop behaviour for the UI element

This class will serve as the "dragAndDropIterator" iterator that is attached to the UI element. In this class we'll tell the system how we want to implement drag-and-drop.

  • Create an empty class and add the IF_THTMLB_DRAG_N_DROP_ITERATOR Interface

    

  • This enables two methods

    

       Implement the following code in method IF_THTMLB_DRAG_N_DROP_ITERATOR~RENDER_OBJECTS_DND_BEHAVIORS

   method IF_THTMLB_DRAG_N_DROP_ITERATOR~RENDER_OBJECTS_DND_BEHAVIORS.
  DATA: ls_behavior    TYPE           CRM_THTMLB_BEHAVIOR_STRUCTURE.

        LS_BEHAVIOR-BEHAVIORID = 'B2'.                      "#EC NOTEXT
        LS_BEHAVIOR-FLAVOR     = cl_bsp_dlc_config_util=>c_dnd_default_flavor. "'F2'.                      "#EC NOTEXT
        LS_BEHAVIOR-ISSOURCE  = 'X'.                        "#EC NOTEXT
        LS_BEHAVIOR-ISTARGET   = 'X'.
        LS_BEHAVIOR-EFFECT_CROSS_CONTROL     = 'MOVE'.      "#EC NOTEXT
        LS_BEHAVIOR-EFFECT_INSIDE_CONTROL     = 'COPY'.     "#EC NOTEXT
        APPEND LS_BEHAVIOR TO EV_BEHAVIOR.
endmethod.

Prepare the SOURCE view for drag-and-drop

Make sure the table gets some data, I did a simple Query in the DO_PREPARE_OUTPUT method in the controller to fill the PRODUCTS Context Node.

  • Add the Interface IF_THTMLB_DRAG_N_DROP tot the Controller Class

    

  • This enables two methods in the class:

    

  • Implement the following code in method IF_THTMLB_DRAG_N_DROP~ON_DRAG

DATA: LR_ITERATOR     TYPE REF TO IF_BOL_BO_COL_ITERATOR,
        LR_ENTITY      
TYPE REF TO if_bol_bo_property_access,
        LR_DND_OBJ     
TYPE REF TO CL_THTMLB_TABLE_DND_OBJECT.

  LR_DND_OBJ ?= DRAG_N_DROP_OBJECT.
  LR_ITERATOR = MODEL->COLLECTION_WRAPPER->IF_BOL_BO_COL~GET_ITERATOR( ).
  LR_ENTITY ?= LR_ITERATOR->GET_BY_INDEX( IV_INDEX = LR_DND_OBJ->ROW ).
  LR_DND_OBJ->IF_THTMLB_DRAG_N_DROP_OBJECT~OBJECT = LR_ENTITY.
 
CASE EFFECT.
   
WHEN 'MOVE'.
      MODEL->COLLECTION_WRAPPER->IF_BOL_BO_COL~REMOVE( LR_ENTITY ).
   
WHEN 'COPY'.
  ENDCASE.

  • Add an Attribute to the Context Node PRODUCTS and reference it to the Class you created earlier

    

          We'll use this attribute in the View later on.

  • Override the IF_BSP_MODEL~INIT method in the Context Node PRODUCTS to initialize the Attribute

CALL METHOD SUPER->IF_BSP_MODEL~INIT
  EXPORTING
    ID     = ID
    OWNER  = OWNER
    .
  CREATE OBJECT GR_DND_ITERATOR.

  • Go to the View Layout

    

     Add the "dragAndDropIterator" (Case sensitive!) attribute to the configCellerator and reference it to the Attribute you just created in your Context Node.

Prepare the TARGET view for drag-and-drop

Basically, do exactly the same as for the SOURCE view with the only exception to implement the ON_DROP method to make sure it's able to receive dragged elements from the SOURCE view.

Implement the following in the IF_THTMLB_DRAG_N_DROP~ON_DROP method of the Controller class:

DATA: LR_ITERATOR     TYPE REF TO IF_BOL_BO_COL_ITERATOR,
      LR_ENTITY       TYPE REF TO IF_BOL_BO_PROPERTY_ACCESS,
      LV_DND_OBJ      TYPE REF TO CL_THTMLB_TABLE_DND_OBJECT.
  TRY.
      LV_DND_OBJ ?= DRAG_N_DROP_OBJECT.
      LR_ENTITY ?= LV_DND_OBJ->IF_THTMLB_DRAG_N_DROP_OBJECT~OBJECT.
      IF LV_DND_OBJ->ROW EQ 0.
        LV_DND_OBJ->ROW = 1.
      ENDIF.
      MODEL->COLLECTION_WRAPPER->INSERT( IV_BO = LR_ENTITY IV_INDEX = LV_DND_OBJ->ROW ).
    CATCH CX_ROOT.
  ENDTRY.

Test it

You should get something like in the video below:

Limitations

Unfortunately you can only drop on a table which already contains data... If the table is empty you cannot drop anything onto it.

2 Comments
Labels in this area