/**
* A DragDrop implementation where the linked element follows the
* mouse cursor during a drag.
* @class DD
* @extends YAHOO.util.DragDrop
* @constructor
* @param {String} id the id of the linked element
* @param {String} sGroup the group of related DragDrop items
* @param {object} config an object containing configurable attributes
* Valid properties for DD:
* scroll
*/
YAHOO.util.DD = function(id, sGroup, config) {
if (id) {
this.init(id, sGroup, config);
}
};
YAHOO.extend(YAHOO.util.DD, YAHOO.util.DragDrop, {
/**
* When set to true, the utility automatically tries to scroll the browser
* window when a drag and drop element is dragged near the viewport boundary.
* Defaults to true.
* @property scroll
* @type boolean
*/
scroll: true,
/**
* Sets the pointer offset to the distance between the linked element's top
* left corner and the location the element was clicked
* @method autoOffset
* @param {int} iPageX the X coordinate of the click
* @param {int} iPageY the Y coordinate of the click
*/
autoOffset: function(iPageX, iPageY) {
var x = iPageX - this.startPageX;
var y = iPageY - this.startPageY;
this.setDelta(x, y);
// this.logger.log("autoOffset el pos: " + aCoord + ", delta: " + x + "," + y);
},
/**
* Sets the pointer offset. You can call this directly to force the
* offset to be in a particular location (e.g., pass in 0,0 to set it
* to the center of the object, as done in YAHOO.widget.Slider)
* @method setDelta
* @param {int} iDeltaX the distance from the left
* @param {int} iDeltaY the distance from the top
*/
setDelta: function(iDeltaX, iDeltaY) {
this.deltaX = iDeltaX;
this.deltaY = iDeltaY;
this.logger.log("deltaX:" + this.deltaX + ", deltaY:" + this.deltaY);
},
/**
* Sets the drag element to the location of the mousedown or click event,
* maintaining the cursor location relative to the location on the element
* that was clicked. Override this if you want to place the element in a
* location other than where the cursor is.
* @method setDragElPos
* @param {int} iPageX the X coordinate of the mousedown or drag event
* @param {int} iPageY the Y coordinate of the mousedown or drag event
*/
setDragElPos: function(iPageX, iPageY) {
// the first time we do this, we are going to check to make sure
// the element has css positioning
var el = this.getDragEl();
this.alignElWithMouse(el, iPageX, iPageY);
},
/**
* Sets the element to the location of the mousedown or click event,
* maintaining the cursor location relative to the location on the element
* that was clicked. Override this if you want to place the element in a
* location other than where the cursor is.
* @method alignElWithMouse
* @param {HTMLElement} el the element to move
* @param {int} iPageX the X coordinate of the mousedown or drag event
* @param {int} iPageY the Y coordinate of the mousedown or drag event
*/
alignElWithMouse: function(el, iPageX, iPageY) {
var oCoord = this.getTargetCoord(iPageX, iPageY);
// this.logger.log("****alignElWithMouse : " + el.id + ", " + aCoord + ", " + el.style.display);
if (!this.deltaSetXY) {
var aCoord = [oCoord.x, oCoord.y];
YAHOO.util.Dom.setXY(el, aCoord);
var newLeft = parseInt( YAHOO.util.Dom.getStyle(el, "left"), 10 );
var newTop = parseInt( YAHOO.util.Dom.getStyle(el, "top" ), 10 );
this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
} else {
YAHOO.util.Dom.setStyle(el, "left", (oCoord.x + this.deltaSetXY[0]) + "px");
YAHOO.util.Dom.setStyle(el, "top", (oCoord.y + this.deltaSetXY[1]) + "px");
}
this.cachePosition(oCoord.x, oCoord.y);
var self = this;
setTimeout(function() {
self.autoScroll.call(self, oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
}, 0);
},
/**
* Saves the most recent position so that we can reset the constraints and
* tick marks on-demand. We need to know this so that we can calculate the
* number of pixels the element is offset from its original position.
* @method cachePosition
* @param iPageX the current x position (optional, this just makes it so we
* don't have to look it up again)
* @param iPageY the current y position (optional, this just makes it so we
* don't have to look it up again)
*/
cachePosition: function(iPageX, iPageY) {
if (iPageX) {
this.lastPageX = iPageX;
this.lastPageY = iPageY;
} else {
var aCoord = YAHOO.util.Dom.getXY(this.getEl());
this.lastPageX = aCoord[0];
this.lastPageY = aCoord[1];
}
},
/**
* Auto-scroll the window if the dragged object has been moved beyond the
* visible window boundary.
* @method autoScroll
* @param {int} x the drag element's x position
* @param {int} y the drag element's y position
* @param {int} h the height of the drag element
* @param {int} w the width of the drag element
* @private
*/
autoScroll: function(x, y, h, w) {
if (this.scroll) {
// The client height
var clientH = this.DDM.getClientHeight();
// The client width
var clientW = this.DDM.getClientWidth();
// The amt scrolled down
var st = this.DDM.getScrollTop();
// The amt scrolled right
var sl = this.DDM.getScrollLeft();
// Location of the bottom of the element
var bot = h + y;
// Location of the right of the element
var right = w + x;
// The distance from the cursor to the bottom of the visible area,
// adjusted so that we don't scroll if the cursor is beyond the
// element drag constraints
var toBot = (clientH + st - y - this.deltaY);
// The distance from the cursor to the right of the visible area
var toRight = (clientW + sl - x - this.deltaX);
// this.logger.log( " x: " + x + " y: " + y + " h: " + h +
// " clientH: " + clientH + " clientW: " + clientW +
// " st: " + st + " sl: " + sl + " bot: " + bot +
// " right: " + right + " toBot: " + toBot + " toRight: " + toRight);
// How close to the edge the cursor must be before we scroll
// var thresh = (document.all) ? 100 : 40;
var thresh = 40;
// How many pixels to scroll per autoscroll op. This helps to reduce
// clunky scrolling. IE is more sensitive about this ... it needs this
// value to be higher.
var scrAmt = (document.all) ? 80 : 30;
// Scroll down if we are near the bottom of the visible page and the
// obj extends below the crease
if ( bot > clientH && toBot < thresh ) {
window.scrollTo(sl, st + scrAmt);
}
// Scroll up if the window is scrolled down and the top of the object
// goes above the top border
if ( y < st && st > 0 && y - st < thresh ) {
window.scrollTo(sl, st - scrAmt);
}
// Scroll right if the obj is beyond the right border and the cursor is
// near the border.
if ( right > clientW && toRight < thresh ) {
window.scrollTo(sl + scrAmt, st);
}
// Scroll left if the window has been scrolled to the right and the obj
// extends past the left border
if ( x < sl && sl > 0 && x - sl < thresh ) {
window.scrollTo(sl - scrAmt, st);
}
}
},
/*
* Sets up config options specific to this class. Overrides
* YAHOO.util.DragDrop, but all versions of this method through the
* inheritance chain are called
*/
applyConfig: function() {
YAHOO.util.DD.superclass.applyConfig.call(this);
this.scroll = (this.config.scroll !== false);
},
/*
* Event that fires prior to the onMouseDown event. Overrides
* YAHOO.util.DragDrop.
*/
b4MouseDown: function(e) {
this.setStartPosition();
// this.resetConstraints();
this.autoOffset(YAHOO.util.Event.getPageX(e),
YAHOO.util.Event.getPageY(e));
},
/*
* Event that fires prior to the onDrag event. Overrides
* YAHOO.util.DragDrop.
*/
b4Drag: function(e) {
this.setDragElPos(YAHOO.util.Event.getPageX(e),
YAHOO.util.Event.getPageY(e));
},
toString: function() {
return ("DD " + this.id);
}
//////////////////////////////////////////////////////////////////////////
// Debugging ygDragDrop events that can be overridden
//////////////////////////////////////////////////////////////////////////
/*
startDrag: function(x, y) {
this.logger.log(this.id.toString() + " startDrag");
},
onDrag: function(e) {
this.logger.log(this.id.toString() + " onDrag");
},
onDragEnter: function(e, id) {
this.logger.log(this.id.toString() + " onDragEnter: " + id);
},
onDragOver: function(e, id) {
this.logger.log(this.id.toString() + " onDragOver: " + id);
},
onDragOut: function(e, id) {
this.logger.log(this.id.toString() + " onDragOut: " + id);
},
onDragDrop: function(e, id) {
this.logger.log(this.id.toString() + " onDragDrop: " + id);
},
endDrag: function(e) {
this.logger.log(this.id.toString() + " endDrag");
}
*/
/**
* @event mouseDownEvent
* @description Provides access to the mousedown event. The mousedown does not always result in a drag operation.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event b4MouseDownEvent
* @description Provides access to the mousedown event, before the mouseDownEvent gets fired. Returning false will cancel the drag.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event mouseUpEvent
* @description Fired from inside DragDropMgr when the drag operation is finished.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event b4StartDragEvent
* @description Fires before the startDragEvent, returning false will cancel the startDrag Event.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event startDragEvent
* @description Occurs after a mouse down and the drag threshold has been met. The drag threshold default is either 3 pixels of mouse movement or 1 full second of holding the mousedown.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event b4EndDragEvent
* @description Fires before the endDragEvent. Returning false will cancel.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event endDragEvent
* @description Fires on the mouseup event after a drag has been initiated (startDrag fired).
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event dragEvent
* @description Occurs every mousemove event while dragging.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event b4DragEvent
* @description Fires before the dragEvent.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event invalidDropEvent
* @description Fires when the dragged objects is dropped in a location that contains no drop targets.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event b4DragOutEvent
* @description Fires before the dragOutEvent
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event dragOutEvent
* @description Fires when a dragged object is no longer over an object that had the onDragEnter fire.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event dragEnterEvent
* @description Occurs when the dragged object first interacts with another targettable drag and drop object.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event b4DragOverEvent
* @description Fires before the dragOverEvent.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event dragOverEvent
* @description Fires every mousemove event while over a drag and drop object.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event b4DragDropEvent
* @description Fires before the dragDropEvent
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
/**
* @event dragDropEvent
* @description Fires when the dragged objects is dropped on another.
* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
*/
});