/*
Script: Drag.Move.js
A Drag extension that provides support for the constraining of draggables to containers and droppables.
License:
MIT-style license.
*/
Drag.Move = new Class({
Extends: Drag,
options: {
droppables: [],
container: false
},
initialize: function(element, options){
this.parent(element, options);
this.droppables = $$(this.options.droppables);
this.container = $(this.options.container);
if (this.container && $type(this.container) != 'element') this.container = $(this.container.getDocument().body);
element = this.element;
var current = element.getStyle('position');
var position = (current != 'static') ? current : 'absolute';
if (element.getStyle('left') == 'auto' || element.getStyle('top') == 'auto') element.position(element.getPosition(element.offsetParent));
element.setStyle('position', position);
this.addEvent('start', function(){
this.checkDroppables();
}, true);
},
start: function(event){
if (this.container){
var el = this.element, cont = this.container, ccoo = cont.getCoordinates(el.offsetParent), cps = {}, ems = {};
['top', 'right', 'bottom', 'left'].each(function(pad){
cps[pad] = cont.getStyle('padding-' + pad).toInt();
ems[pad] = el.getStyle('margin-' + pad).toInt();
}, this);
var width = el.offsetWidth + ems.left + ems.right, height = el.offsetHeight + ems.top + ems.bottom;
var x = [ccoo.left + cps.left, ccoo.right - cps.right - width];
var y = [ccoo.top + cps.top, ccoo.bottom - cps.bottom - height];
this.options.limit = {x: x, y: y};
}
this.parent(event);
},
checkAgainst: function(el){
el = el.getCoordinates();
var now = this.mouse.now;
return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top);
},
checkDroppables: function(){
var overed = this.droppables.filter(this.checkAgainst, this).getLast();
if (this.overed != overed){
if (this.overed) this.fireEvent('leave', [this.element, this.overed]);
if (overed){
this.overed = overed;
this.fireEvent('enter', [this.element, overed]);
} else {
this.overed = null;
}
}
},
drag: function(event){
this.parent(event);
if (this.droppables.length) this.checkDroppables();
},
stop: function(event){
this.checkDroppables();
this.fireEvent('drop', [this.element, this.overed]);
this.overed = null;
return this.parent(event);
}
});
Element.implement({
makeDraggable: function(options){
return new Drag.Move(this, options);
}
});