MooTools Drag.Ghost

Version 1.01
Ghosting draggable extension for Drag.Move
Show me some demo's

License

You can freely use this work - but some rights are reserved.

Downloads

There are two downloads available, the original source file and a minified version ready for deployment. Most likely you will just want to use the script without looking at its internals - get the minified version.
» Minified (for production)
» Source code (for development)

Usage

Instance
new Drag.Ghost(element [, options]);
Element function
Element.makeGhostDraggable([options]);

Styling

Be aware that the original Drag class from MooTools will default to position: absolute and a certain left and right when not set. This might result in undesired rendering of your draggables, so you're recommended to set these styles for draggables. I've just set them to:
position: relative;
top: 0;
left: 0;

Options

OptionDefault valueDescription
opacity0.65a value between 0 and 1 defining the opacity of the dragging ghost

in addition to all Drag and Drag.Move options.

Requirements

  • MooTools Core v1.2.x
  • Drag and Drag.Move classes from MooTools More

Examples

Simple


Drag Me #1
Drag Me #2
Drag Me #3
Drag Me #4
Drag Me #5
Drag the blue boxes onto the pink droppables:
Droppable #1
Droppable #2
Droppable #3
Dragging should work perfectly as intended.

» view code

Javascript

window.addEvent('load', function() {
	$$('.drag').makeGhostDraggable({
		droppables: $$('.drop'),
		onDrop: function(element, droppable) {
			if (droppable) {
				droppable.set('html',
					droppable.get('html')
					+ '<br/>' 
					+ element.get('html')
				);
			}
		}
	});
});

HTML

<div class='drag'>Drag Me #1</div>
<div class='drag'>Drag Me #2</div>
<div class='drag'>Drag Me #3</div>
<div class='drag'>Drag Me #4</div>
<div class='drag'>Drag Me #5</div>

<div class='clear'>Drag the blue boxes onto the pink droppables:</div>

<div class='drop'>Droppable #1</div>
<div class='drop'>Droppable #2</div>
<div class='drop'>Droppable #3</div>

<div class='clear'>Dragging should work perfectly as intended.</div>

CSS

.drag {
	position: relative;
	top: 0px;
	left: 0px;
	float: left;
	background: #0af;
	border: 1px solid #000;
	padding: 10px;
	cursor: move;
	width: 50px;
	text-align: center;
	margin: 0 20px 0 0;
}

.drop {
	float: left;
	background: #f0a;
	border: 1px solid #000;
	padding: 10px;
	color: #fff;
	text-align: center;
	margin: 0 20px 0 0;
}

.clear {
	clear: both;
	padding: 15px 0;
}
 

Add comment

Comments (13)

19-03-2009, 12:02
Theo
The drag function doens't work in IE. Am I doing something wrong? Your version works perfect, but when I copy -> paste it all went wrong.
19-03-2009, 16:18
Monkey
Can you be more specific? What went wrong? Pay attention to the section above dealing with "Styling", maybe that helps?
24-04-2009, 15:20
stdu
Hi,
I'm trying to use your class work fine but I need to drag img with href
Is it possible to add a delay to allow the click to open the current link ?
Sorry, I tried but I don't know enough mootools.
Big Thx
24-04-2009, 23:25
Monkey
A link is for clicking, a draggable for dragging. The two mouse-actions should not go together. I'd say you increase the size of you draggable to have plenty of space outside the link to drag it by.
09-06-2009, 02:33
lbljeffmo
@Monkey: At first it seems complicated or highly error-prone to attempt to distinguish between a link-click and a drag-click...but I found that it's actually not so difficult to accomplish:

In the onDrop method, just check the overall distance of the drag. If the distance is greater than a (very small...1-2px) margin of error, dragging events are fired and the onClick action returns false (preventing the linking action in the browser). Otherwise the custom onDrop event is not fired...and instead returns true to execute the browser linking action.

So the margin of error accounts for any accidental drag on the part of the user when clicking the link. (In fact, while testing things out myself, I found that I almost never had ANY accidental drag...but its always a good idea to account for all the coffee addicts and grandmas of the net)

Anyway this gave me a very intuitive draggable links feature with zero false-positives (during testing atleast) in my mootools imp, so I thought I'd throw it out there.
26-10-2009, 21:11
Brian
Thanks for posting this. I'd been struggling with mootools drag setting position to 'absolute' and didn't think I could solve it until I saw this page.
28-11-2009, 17:41
damine
It's magical, excellent work !
thanks a lot for that code :)
09-12-2009, 00:43
Crispijn
Great class! I've used this solution in a project I'm working on several weeks ago but I've done it manually. I'll review my code and try to implement this sweet little class!

Great job!
05-02-2010, 15:54
kburn
hi,
your script is awsum and it works like a charm, but
I found out that if you place the draggable list into a container that has the overflow:scroll property, it turns out that when you try to drag the elements down in the scroll position, the ghost clone is created in the wrong place, I found the solution, and here is the code:

ghost: function() {
this.element = this.element.clone()
.setStyles({
'opacity': this.options.opacity,
'position': 'absolute',
'z-index': 1000,
'top': ((e.page.y)-(this.element.getStyle('height').toInt()/2)), //this.element.getCoordinates()['top'],
'left': ((e.page.x)-(this.element.getStyle('width').toInt()/2)) //this.element.getCoordinates()['left']
})
.inject(document.body)
.store('parent', this.element);
},


-----


the main changes are into the ghost function.
hope this could be useful to others that encountered this issue.

cheerz

-k-
05-02-2010, 15:57
kburn
sorry, I posted the wrong code,
this is the right one. basically you have to pass the event to the this.gost() function @ line 22, that becomes
this.ghost(event);

and then this:

ghost: function() {
this.element = this.element.clone()
.setStyles({
'opacity': this.options.opacity,
'position': 'absolute',
'z-index': 1000,
'top': ((e.page.y)-(this.element.getStyle('height').toInt()/2)), //this.element.getCoordinates()['top'],
'left': ((e.page.x)-(this.element.getStyle('width').toInt()/2)) //this.element.getCoordinates()['left']
})
.inject(document.body)
.store('parent', this.element);
},

05-02-2010, 15:59
kburn
I\'m deeply sorry I still had the wrong code in my clipboard (fail!)

ghost: function(e) {
this.element = this.element.clone()
.setStyles({
\'opacity\': this.options.opacity,
\'position\': \'absolute\',
\'z-index\': 1000,
\'top\': ((e.page.y)-(this.element.getStyle(\'height\').toInt()/2)), //this.element.getCoordinates()[\'top\'],
\'left\': ((e.page.x)-(this.element.getStyle(\'width\').toInt()/2)) //this.element.getCoordinates()[\'left\']
})
.inject(document.body)
.store(\'parent\', this.element);
},
08-02-2010, 21:18
nate
How can I make it so if I drag an item into one of the boxes it will delete the other item that was in there. Currently it adds it. So if you drag \"Drag Me #1\" into the first box and then drag \"Drag Me #2\" in the first box, \"Drag Me #1\" is removed.

Thanks in advance,

Nate
09-02-2010, 04:41
Gregg
Your examples don't work correctly in ie8 the blue box doesn't drag just the text inside the blue box