beginDrag()
The beginDrag() method is defined as follows.
function beginDrag(obj) {
if(window.event.button == 1) {
document.onmousemove = function anonymous() { dragControl.move(obj) };
this.origin = obj.parentNode;
this.entity = obj;
this.beginX = window.event.x;
this.beginY = window.event.y;
window.event.cancelBubble = true;
}
}
This method is attached to our entities within our XSL Transformations (XSLT) style sheet.

Figure 1. beginDrag() method placement
This method first checks to ensure that the left mouse button fired the event, instead of the right (which is used for context menus). It then sets the proper property values and cancels the bubbling of events within the client browser.
endDrag()
The endDrag() method is defined follows:
function endDrag() {
if(this.entity != null) {
this.entity.style.position = "static";
this.entity.style.left = null;
this.entity.style.top = null;
this.entity = this.entity.removeNode(true);
if(this.target != null) {
dragControl.target.appendChild(this.entity);
if(this.target.open != "true") {
clickOnEntity(this.target);
}
}
else {
this.origin.appendChild(this.entity);
}
document.onmousemove = null;
document.onmouseup = null;
this.entity = null;
this.target = null;
this.enabled = false;
}
}
This method first ensures that there is an entity selected. Depending on whether or not the user currently has a target selected, it either returns the entity to its origin (given no target) or moves the entity to its new location (given a target).
This method is attached to our entities within our XSLT style sheet.

Figure 2. endDrag() method placement
setTarget()
The setTarget() method is defined as follows:
function setTarget(obj) {
if(this.entity != null && this.entity != obj) {
this.target = obj;
}
window.event.cancelBubble = true;
}
This method first ensures that there is a current entity and that the selected entity is not the entity being moved over. It then proceeds to set the target property of the DragControl, after which it cancels the bubbling of events within the client browser.
This method is attached to our entities within our XSLT style sheet.

Figure 3. setTarget() method placement
setPosition()
The setPosition() method is defined as follows:
function setPosition() {
this.entity.style.left = window.event.x;
this.entity.style.top = window.event.y - 10;
}
This method simply sets the selected entity's X and Y coordinates to the current mouse event's X and Y coordinates. This method is called from within the move() method.
This method is attached to our entities within our tree.js file.

Figure 4. setPosition() method placement
move()
The move() method is defined as follows.
function move(obj) {
if(window.event.x < this.beginX - 5 || window.event.x > this.beginX + 5 ||
window.event.y < this.beginY -5 || window.event.y > this.beginY + 5 &&
this.enabled == false) {
obj.style.position = "absolute";
obj.style.filter = "alpha(opacity='60')";
this.setPosition();
this.enabled = true;
obj = obj.removeNode(true);
document.body.appendChild(obj);
document.onmouseup = function anonymous() { dragControl.endDrag() };
}
else if(this.enabled == true) {
this.setPosition();
}
}
This method ensures that the user is actually dragging the entity by at least 5 pixels in any direction whether X, Y, positive, or negative. It then moves the entity out of the current tree and into the body of the document. It is continuously called via the "onmousemove" event of the document object and ensures that the entity is always displayed next to the mouse cursor.
This method is attached to our entities within the tree.js file.

Figure 5. move() method placement
reset()
The reset() method is defined as follows:
function reset() {
document.onmouseup = null;
document.onmousemove = null;
this.entity = null;
this.origin = null;
this.target = null;
}
This method simply cleans up the document and the DragControl object. It
is called whenever a drag and drop is completed or canceled.
This method is attached to our entities within our XSLT style sheet.

Figure 6. reset() method placement
View a live demo of the folder tree drag-and-drop control. For demonstrations purposes I have created two trees and placed entities titled numerically "One" to "Six" beneath them. Try dragging them so that "Two" is nested beneath "One," "Three" is nested beneath "Two," and so on. Below is a screen shot of the entity named "One" being dragged from Tree 1 into Tree 2 after all numbers have been logically ordered (nested) beneath one another by the user.

Figure 7. Dragging and dropping from one tree to another
Download complete source code.
View a live demo