Skip to Content

Purpose

I hear many questions about drag & drop. I know that there are plans in the product roadmap to introduce the drag and drop functionality, but in the meantime I tried to figure out if this would be possible in a generic way on SDK basis. And the answer is yes!

How to do that?

Basically I use SAPIU5 for SDK components, so the question was how to bind drag & drop on UI5 basis. I have found some common implementations in web on how to drag drop DIV elements on the screen. From those I understood that it is easy by attaching events on dom objects. Luckily SAPUI5 has functions for that –


oDrop.onAfterRendering = function () {
...
}

here we can access already the dom object and use jQuery to place some additional events. Now, how to pass all the values between drag & drop events. Again some search on web, I have found many points, and one which works… I use a library “jquery.ndd.js (web site here)” which handles better the events. I do not know if this is the best way, but I stopped search once I had something which works.

Now, I attached this library in contribution.xml:

<jsInclude>res/dda/jquery.ndd.js</jsInclude>

and then using the onAfterRendering method I could attach the events. This is my method.

Adding Corresponding Events

Object which handles “DROP”:


oDrop.onAfterRendering = function () {
  var jqThis = this.$();
  jqThis.bind('dragover', function(evt) {
   oDrop.addStyleClass("scn-pack-DragDropArea-DropEffect");
       evt.preventDefault();
    })
    .bind('dragleave',function(evt) {
   oDrop.removeStyleClass("scn-pack-DragDropArea-DropEffect");
  
       evt.preventDefault();
    })
    .bind('dragenter',function(evt) {
       evt.preventDefault();
    })
    /** process drop event **/
    .bind('drop',function(evt) {
   var id = evt.dataTransfer.getData('id');
       var key = evt.dataTransfer.getData('key');
       var context = evt.dataTransfer.getData('context');
       that.setDropId(id);
       that.setDropKey(key);
       that.setDropContext(context);
       that.setDropAfterKey(oDrop.dropAfterKey);
       that.setDropIndex(oDrop.dropIndex);
     
       that.fireDesignStudioPropertiesChanged(["dropId"]);
       that.fireDesignStudioPropertiesChanged(["dropKey"]);
       that.fireDesignStudioPropertiesChanged(["dropContext"]);
     
       that.fireDesignStudioPropertiesChanged(["dropAfterKey"]);
       that.fireDesignStudioPropertiesChanged(["dropIndex"]);
     
   that.fireDesignStudioEvent("onDrop");
     
           evt.stopPropagation();
     
       return false;
        });
  };

Object which handles “DRAG”:


oDrag.onAfterRendering = function () {
  var jqThis = this.$();
  jqThis.attr("draggable", "true");
  jqThis.bind('dragstart', function(evt) {
  evt.dataTransfer.setData('id', oImage.internalKey);
  evt.dataTransfer.setData('key', that.getDragKey());
  evt.dataTransfer.setData('context', that.getDragContext());
  });
};

The Heart of Drop

The “evt.dataTransfer” property is available by the jQuery extension – I could not get this run w/o the extension. The biggest implementation is in drop event, there all possible properties can be collected and the drop event can be triggered.

I thought, as this is a generic idea, I will pass always two parameters “context” and “key” to be able to handle different object types.

What is currently not in my implementation is to show any fancy icons on drop, and block the drop if the contexts are different… But this is room for improvement later.

What Next?

Now, I try to finalize my generic DragDropArea – perhaps in 2 hours there will be something in a downloadable package as preview (just to check what the community think about it)

I am wondering how this can be used in different contexts…

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply