Avg. Rating 4.5

Problem

You want to allow users to drag files, images, text, and other data types into and out of HTML based AIR applications.

Solution

By using Adobe AIR's Drag and Drop implementation in JavaScript, developers can react to drag and drop operations that occur on HTML DOM objects.

Detailed explanation

NOTE: Adobe AIR's support for drag and drop within HTML content is based on the WebKit implementation. You can find more information on this at http://developer.apple.com/documentation/AppleApplications/Conceptual/SafariJSProgTopics/Tasks/draganddrop.html.

One of the benefits of developing for the desktop is providing users with a more integrated experience when interacting with multiple applications. One of the most frequently used user gestures is to drag and drop files, data, and other elements between applications and the desktop and between the applications themselves.

This example will demonstrate how you can accept text being dragged items into your application as well as support dragging elements out. It will also show you how to modify the drag effect to demonstrate for the user what type of drag operations he can perform with the element he is dragging as well as the ability to modify the drag image.

Two flows are important to consider when using drag and drop operations in HTML.

First, we will examine the flow for HTML elements that are drag enabled:

  1. The element specifies that it is available for drag operations
  2. The user selects the element and starts to drag it.
  3. The element receives an ondragstart event and sets the data which will be transferred, as well as specifies which drag operations are supported. It can also specify a custom drag image at this time.
  4. The element receives ondrag events while it is being dragged.
  5. The user drops the element being dragged and receives an ondragend event.

The typical flow for HTML elements that want to receive drop operations is as follows:

  1. The user drags an item over the element listening for drop events.
  2. The element receives an ondragenter event and specifies which drop operations are allowed.
  3. The element receives ondragover operations continuously as the item is being dragged over.
  4. The user drops the item and the receiving element receives an ondrop event.

Alternatively, if the user moves the dragged item outside the boundaries of the listening element, it will receive an ondragleave event.

Linked text and highlighted text elements are dragenabled by default. To disable this functionality, use the -khtml-userdrag:none style. Conversely, to enable other HTML elements to be dragenabled, use the -khtml-user-drag:element style.

To manipulate the data that is being transferred as part of the drag operation, listen for the ondragstaroperation and use the dataTransfer object that is attached to the event object. The dataTransfer object has two data modification methods: getData and setData. The setData method takes two parameters: the MIME type and the string of data that conforms to that type. You can call the setData method multiple times, and it allows you to store multiple data types. For example, if you wanted to specify a text/plain type and a text/uri-list type, you would do the following:

function dropStartListener( event )
{
    event.dataTransfer.setData( "text/plain", "Adobe" );
    event.dataTransfer.setData( "text/uri-list", "http://www.adobe.com" );
}

If setData is called for a MIME type that already exists on the element being dragged, that data will be overwritten. Retrieving data from an element that is being dragged can occur only within an ondrop event handler. The getData method takes a MIME type as its only parameter and returns the value of the MIME type if it exists on the element being dragged. For example:

function dropListener( event )
{
    alert( event.dataTransfer.getData( "text/plain" ) );    // Adobe
}

AIR supports the following MIME types:

  • Text "text/plain"
  • HTML "text/html"
  • URL "text/uri-list"
  • Bitmap "image/x-vnd.adobe.air.bitmap"
  • File list "application/x-vnd.adobe.air.filelist"

When a user is dragging data from one application to another, or from one location in your application to another, you may want to indicate to the user which operations (copy, link, or move) are available. By using the effectAllowed and dropEffect properties of the dataTransfer object, you can specify which operations are allowed. You can see the list of available values for these properties by reading the WebKit documentation referenced earlier.

The effectAllowed property tells the system what operations the source element supports. The dropEffect property specifies the single operation that the current target receiving the drag event supports. The operating system then uses this information regarding which effects the source and destination targets support, and allows the user to make that choice. Generally, the user chooses by using the system's standard keyboard modifiers.

To modify the drag image that is displayed to the user as she is dragging the item, use the setDragImage method of the data Transfer object. This method takes three arguments. The first argument is a JavaScript Image object which references the image that will appear to the user. The second and third arguments are the respective X and Y offsets that will modify the position of that image relative to the cursor's X and Y positions onscreen.

Assume that we had the following HTML element in our document. Notice that we explicitly specify that this element is draggable using the -khtml-user-drag:element style:

<div id="box" style="-khtml-user-drag:element" ondragstart="onBoxDragStart(event)"></div>

We can then change the image by listening for the ondrag start event and modify the image using the setDragImage method:

// First create a reference to our drag image in the
// main document scope.

var dragImage = new Image();
dragImage.src = "app:/images/dragImage.png";

// This method gets called when a drag starts
// on our 'box' element.

function onBoxDragStart( event )
{
    // Set the data we would like to be transferred.
    event.dataTransfer.setData("text/plain", "This is a red box!");

    // Modify the drag image to use the reference // we created above.
    event.dataTransfer.setDragImage( dragImage, 0, 0 );
}

This cookbook example was originally posted in the Adobe AIR for JavaScript Developers Pocketguide, which can currently be found at toString.org.

 

htmldragdropexample.zip
[Full HTML Drag and Drop Example]

+
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

Report abuse

Related recipes