Dojo drag and drop gotcha in IE

Michael Wynholds ·

I have been working on a web app for one of our clients that includes a pretty interactive AJAX / Web 2.0 component within it. This component is essentially a simplified drag-and-drop book publishing tool, which allows users to upload images and then to arrange them on predefined templates in order to create a book.

We chose to use the Dojo Toolkit (version 0.4.2) for both the AJAX (ie: remote calls to the server) and the Widegtry side of the Web 2.0 style. It’s been working fairly well. Dojo has a lot of functionality, but also has a few areas that still need some refinement. The most interesting / infuriating to me so far has to do with Dojo drag-and-drop functionality within IE.

Dojo’s facility for drag-and-drop is essentially composed of three components:

  • Drag-and-Drop Manager
  • Drag Sources
  • Drop Targets

It intuitively makes a lot of sense. You create drag sources and drop targets and out of the box they actually work pretty well. Dojo uses a form of JavaScript inheritance to allow you to create drag copy sources or drag move sources, each of which have different behaviors. You can also reassign specific functions on your drag sources or drop targets in order to customize their behaviors.

I developed and debugged the app in Firefox and Firebug, as we all do. But when it came time to check that everything works in IE, I ran in to one bug in particular that stumped me for two entire days, and frustrated me to no end. At a certain point in using the app, my ability to drop objects on their drop targets was broken. It only happened in IE (I was using IE 6 for Windows), and the error I got was the always helpful “Unexpected error”.

What I found was that the following code, which creates a drop target, also registers the drop target with the Drag and Drop Manager.

var imageTarget = new dojo.dnd.HtmlDropTarget(imageDiv, ['galleryImages']);
imageDiv.imageTarget = imageTarget;

As a matter of fact, the Drag and Drop Manager, which is a global singleton, keeps a registry of all drag sources and drop targets created. Later on in the flow of my application, some of these drop targets need to be re-rendered, and to do so I actually delete the DOM node and re-create it, using the following code:

dojo.dom.destroyNode(pageContainerDiv);

The destroyNode() function is supposed to be memory-leak-friendly. But after I have done that, and created a new drop target where that one once was, when I try to drop another drag source on to it, I get the “Unexpected error” exception in JavaScript. And again, this only happens in IE. Firefox works fine. I finally realized that, even though the drop targets are automatically (and outside my knowledge for a long time) being registered with the Drag and Drop Manager, they must be explicitly unregistered before they are destroyed, otherwise this error occurs. I added the following code to do so.

dojo.dnd.dragManager.unregisterDropTarget(imageDiv.imageTarget);

And now everything works perfectly!