Saturday, December 17, 2011

HTML5 Native Drag ‘n’ Drop

HTML5 does not only mean a whole new world of tags (video, audio, header, footer, article, section etc.) and revolutionary technologies like Geolocation, Application cache, Canvas, Web Workers etc. but it also brings along a rich set of JavaScript API to developers.

Today, we witness one of the interesting feature that it provides; the capability of dragging and dropping elements natively without using any JS framework. The HTML5 spec defines the new events that we should catch in order to handle operations like

  1. Start of drag operation ( dragstart )
  2. Dragging content over another element ( dragover )
  3. Entering the drag area of another element ( dragenter )
  4. End of Drag operation ( drop )

If you have worked with a RIA-friendly language such as ActionScript, then you will found this to be very similar. Having said that, providing this drag and drop support in the browser itself is the reason behind the fame of HTML5.

Coming back, lets see some code in action. We have some images in our page which we want to drag and drop in div container. These images are tagged with class “dragMe” (so that we can attach event listeners to them). Similarly, we have a div container in which we are going to drop these images with an id of “dropOnMe”.

htmlCode

Things to note

  • draggable=true  -  By default, images and links are draggable in nature but I have added this attribute just to convey that any HTML5 element can be selected, dragged and dropped if you add this attribute to it. Also add following CSS to make it work across different browsers

draggableTrueCss

  • Custom data-* attributes  -  Again something, HTML5-blessed. It provides us the capability to define custom data-attributes on any element. Here we use it to define properties of individual images. More on custom data-attributes here.

Next, we add some event handlers to handle drag n drop related events we defined above:

1. Adding Drag Handlers

dragStart

We took a hold of all the elements that are to be dragged and attach to each, a drag handler which will be called whenever you click and try to drag that elements. In the handler, we update the event’s dataTransfer object and set custom properties in the JavaScript object, which we defined in the markup  (yes you guessed it right, we are going to use them in the drop handler)

2. Adding Drop Handlers

dropHandler

Note that we use both e.preventDefault() and return false in the function, to make it work across different browsers; this is needed to make sure that we cancel the default action that the browser will normally take, like surfing to that location (in case of a link). Apart from that, the code just retrieves the data set in dataTransfer object and display that using innerHTML of the div.

3. Adding handlers for dragover & dragenter

dragOverEnterHandlers

Again for making the code work across different browsers (tested on Firefox, IE and Chrome), we need to use both preventDefault() and also return false from the handler in order to inform the browser that you can drop and release the dragged item on this element for which the function is called.

A Lot More…

..can be achieved like customizing the drag icon and even drag and drop across different instances of same browser or even dragging from one browser and dropping in another browser. Stay tuned or check out the spec for more details.

Final Demo Looks like

Too bad that I don’t have a proper hosting solution, so you have to do with images, until you are passionate enough to write the above code yourself.

Initial Screen

image

Dragging an Item

image

Dropped it !!

image

We can add more spice to the tut by adding CSS and some other effects but in the hope that it would overshadow the concept, I emphasize on the minimal code needed for it.

Any suggestions, improvements or bugs are welcome as comments.