Drag-And-Drop - Ajax Patterns

Drag-And-Drop

From Ajax Patterns

Revision as of 21:45, 4 June 2007; view current revision
←Older revision | Newer revision→

Evidence: 2/3

Tags: Drag Move Pull Rearrange


Contents

In A Blink

Diagram: Dragging a portal


<math>Insert formula here</math><math>Insert formula here</math>= Goal Story =

Stuart is performing a multiple-choice exam online. Question 1 provides a list of historical event and requires them to be placed in chronological order. To declare his answer, he drags the items up and down until the list is ordered.

right -Manish

Problem

How can users rearrange objects on the page?


Forces

  • Objects relationships are important and the user's task often involves changing those relationships.
  • Ajaxian applications often represent object relationships visually.
  • Rearranging the visual structure from a separate form is messy - trying to map between the form and the visual structure is confusing and error-prone. It's easiest if users can directly manipulate the visual structure.


Solution

Provide a drag-and-drop mechanism to let users directly rearrange elements around the page. Drag-and-drop has proven itself as a powerful control mechanism in conventional desktop applications, and is certainly achievable using standard web technologies. The basics are straightforward: the user holds down the mouse button while the mouse hovers over a page element, and the user then moves the mouse with the button still depressed. The element follows the mouse around until the user finally releases it.

Constraints are sometimes applied on the extent of movement. Sometimes, an element can only move in one direction, or within a bounding box. Also, the element might move permanently upon mouse release, or flip back to its original position. Another variable is exactly which part of the element must be dragged. Sometimes, it's better to define a "handle" region, which is the only place where the element can be "picked up" for dragging. The main benefit is that the user can click elsewhere in the region.

Among the applications:

  • Rearranging lists. This seemingly simple task has ridiculously complex on the web. Some websites require an entire page reload each time you move an object up and down. Others have implemented the buttons in Javascript, but you still have to click Up or Down repeatedly just to place a single item. Drag-And-Drop is a natural fit - just pick up the list items and drop them where you want them.
  • Rearranging items in a geometric space. Again, this is a natural application: pick up the objects and drag them where you want them to go.
  • Building up a collection. For example, you could let users drag products into a shopping cart.
  • Expressing an action. Perhaps the most famous use of drag-and-drop was Apple's original deletion mechanism, where you delete something by dragging it into the trashcan. The basic idea is to visually represent a command, and let the user drag data to be processed by the command.

There are a few ways to implement drag-and-drop:

  • Reuse an existing library. These are becoming increasingly powerful and portable, and it's likely those available will do the job for you.
  • Leverage built-in Drag-And-Drop. Unfortunately, this isn't much of an option because only Windows IE supports Drag-And-Drop explicitly.
  • Roll your own Drag-And-Drop. Again, this is not recommended due to portability issues.

Here are a few drag-and-drop libraries, all with good cross-browser support and online demos:

  • Scriptaculous. Among many other features, Scriptaculous provides a general-purpose, portable, Drag-And-Drop library.
  • wzDragDrop A drag-and-drop library which also includes resize capability.
  • DOM-Drag A lightweight Drag-And-Drop library.
  • Tim Taylor's Drag-And-Drop Sortable Lists A library specifically for list manipulation, supporting Drag-And-Drop based reordering.

The basic approach used for drag-and-drop is as follows:

  • Event handlers inspect the incoming event to determine the element being dragged.
  • A mousedown handler saves the starting co-ordinates, sets the zIndex so that the element appears in front during the drag, changes some other style settings to indicate a drag has begun, and performs other initialisation.
  • A mousemove handler inspects the mouse's co-ordinates and moves the element accordingly using its left and top properties. Here's where cross-browser support gets nasty - mouse co-ordinates in the event object are seriously platform-specific.
  • A mouseup handler restores normal style settings and performs any other cleaning up.


What constraints will apply to the drag operation?

You will need to decide in which directions the element can move, and how far it can move. Generally, this should be fairly obvious from the visual representation being manipulated. Often, there is a container where similar objects live inside, and this should be the bounding box for dragging operations.


Real-World Examples

Backbase Portal

The Backbase Portal show various Portlets in a 3-column structure. Users can easily rearrange the portlets to suit their own taste, using a Drag-And-Drop mechanism. Google's Personalized Home page and Microsoft's Start.com follow a similar approach.

Magnetic Poetry

Magnetic Poetry is a fun application that simulates dragging magnetic tiles around a fridge.

A9 Maps

A9 Maps offers photographs of map locations. A draggable magnifying glass appears on the map, and you can move it to different regions of the map to see what the area looks like in real life.

Currently not showing maps.

Code Examples

Magnetic Poetry

Magnetic Poetry uses the DOM-Drag library to support dragging. On initialisation, Drag.init is passed each tile successively. The tiles may only be dragged within the board region, so the container's dimensions are passed in during the initialisation sequence.

 for(i=1; i<=numWords; i++){
   var currentTile = document.getElementById("word_" + i);
   
   var x1 = parseInt(document.getElementById("board").style.left);
   var x2 = parseInt(document.getElementById("board").style.width) - parseInt(currentTile.style.width) - 6;
   var y1 = parseInt(document.getElementById("board").style.top);
   var y2 = parseInt(document.getElementById("board").style.height) - parseInt(currentTile.style.height) - 6;
   the last 4 args restrict the area that the tile can be dragged in
   Drag.init(currentTile, null, x1, x2, y1, y2);
 }

The initialisation is all you need to provide dragging. With the code above, the tiles can now be happily moved around the board space. However, the application does a little more than that: (a) the currently dragged tile is tracked, and (b) an XMLHttpRequest Call saves the position once dragging is finished. To that end, onDragStart and onDragEnd handlers are registered on each of the tiles. (The Javascript is outputted from a PHP script.)

 echo 'document.getElementById("word_' . $i . '").onDragStart = 
   function(x, y) { dragStart("word_' . $i . '", x, y); };';
 echo 'document.getElementById("word_' . $i . '").onDragEnd = 
   function(x, y) { dragEnd("word_' . $i . '", x, y); };';


Alternatives

Separate Editing Interface

The conventional solution has been to provide a visual representation in one region and controls in another. This is often cumbersome and error-prone.


Related Patterns

Sprite

Drag-And-Drop is often the mechanism used to move Sprites around.

Portlet

A portal can be personalised by letting the user drag Portlets around.

Slider

A Slider is a special case of Drag-And-Drop, where the value indicator is dragged along the slider axis.


Visual Metaphor

The magnetic poetry demo suggests a nice visual metaphor: dragging magnetic tiles around a fridge door.

asdfasdasdfasdff

asdfasdf

Want to Know More?

Bold text want to know more