Learn ASP.NET Core 2 and Angular 6 in October 2018. Instructor-led online courses by Bipin Joshi. Read more...
Instructor-led Online Courses by Bipin Joshi : ASP.NET Core | Angular | Design Patterns
Registration open for October 2018 batches. Read more here.

Untitled 1

Tricky issue with HTML5 drag and drop

Recently a reader asked about a tricky issue with HTML5 drag and drop. The issue is this:

HTML5 supports native drag and drop through draggable property and several events such as dragstart, drag, dragenter, dragleave, dragover and drop. Normally dragstart event handler is where you set the data that is to be transferred between the drag source and drop target. The drop event handler is where you handle the drop of a drag source, access the data transferred and process it further. Now, in this particular case he had handled only the dragstart and drop events. And the drop event handler never used to get called. In other words dragging operation was successful but dropping operation was not.

To understand the problem and the solution clearly, let's quickly recreate the problem in a simple web form. Consider the following HTML markup:

<form id="form1" runat="server">
   <div id="div1" style="width:300px;height:300px;border:2px solid red" draggable="true"></div>
   <div id="div2" style="width:300px;height:300px;border:2px solid red"></div>
</form>

As you can see there are two <div> elements. The first element - div1 - is draggable as indicated by the draggable attribute. The second div - div2 - acts as the drop target.

Now, consider the following jQuery code that handles the dragstart and drop events:

$(document).ready(function () {
     var div1 = $("#div1").get(0);
     var div2 = $("#div2").get(0);

     div1.addEventListener("dragstart", function (e) {
       $("#div1").html('drag started...');
       e.dataTransfer.setData('text/html', 'hello world');
     }, false);

       div2.addEventListener("drop", function (e) {
         e.stopPropagation();
         e.preventDefault();
         $("#div2").html(e.dataTransfer.getData('text/html'));
         return false;
   }, false);
});

The dragstart event handler sets the HTML of div1 to 'drag started...' and sets data to be transferred to 'hello world'. The drop event handler calls stopPropagation() and preventDefault(), and sets the HTML of div2 to the data passed via dataTransfer object. When you drag div1 and drop onto div2, you would expect div2 to display 'hello world'.

Now the tricky thing is that if you run the above code (Chrome or Firefox) it won't fire the drop event at all. The solution is to handle dragover event also. The default handler for dragover doesn't allow drop. This design ensures that something can be dropped only on a developer defined valid target and that all elements don't act as a valid drop targets by default. So, even if you don't want to do anything specific in dragover event handler add one as shown below:

div2.addEventListener("dragover", function (e) {
  e.preventDefault();
}, false);

After adding dragover event handler, run the web form and now the drag-n-drop should work as expected.

 


Bipin Joshi is a software consultant, trainer, author and spiritual yoga mentor having 23+ years of experience in software development. He teaches private online courses in ASP.NET Core and Angular to individuals and small groups. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Ajapa Yoga to interested individuals. To know more about him click here.

He will be teaching ASP.NET Core 2.1 and Angular 6.1 in October 2018. Click here for his online course schedule and more details.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 21 May 2013


Tags : ASP.NET HTML5