This blog entry was written following a question of an user in ExtJS forum: How to drag n’ drop a button on a panel ?
ExtJs people tend to just focus on the grid-to-grid, grid-to-listview.. sort of drag and drop, and forgot to include in their documentation a typical example of ‘drag and drop’ of a simple element like a button on a panel. Below is my implementation:
ExtJS: 3.x
Demo: Drag and Drop a button
index.html
<pre class="brush:html"><html>
<head>
<title>ExtJS – Drag n’ Drop Demo</title>
<link rel="stylesheet" type="text/css" href="../resources/css/ext-all.css" />
<script src="js/ext-base.js" type="text/javascript"></script>
<script src="js/ext-all.js" type="text/javascript"></script>
<script src="js/dd_button.js" type="text/javascript"></script>
</head>
<body>
<div id="canvas">
</div>
</body>
</html>
dd_button.js
[/javascript]
Ext.onReady(function(){
// Make the button Draggable inside tag
var initDragZone = function(v) {
v.dragZone = new Ext.dd.DragZone(Ext.getBody(), {
getDragData: function(e) {
// .button-draggable == class of the button you want to drag around
if(sourceEl = e.getTarget('.button-draggable')) {
d = sourceEl.cloneNode(true);
d.id = Ext.id();
return v.dragData = {
sourceEl: sourceEl,
repairXY: Ext.fly(sourceEl).getXY(),
ddel: d
}
}
},
onDrag: function(e) {
// !Important: manually fix the default position of Ext-generated proxy element
// Uncomment these line to see the Ext issue
var proxy = Ext.DomQuery.select('*', this.getDragEl());
proxy[2].style.position = '';
},
getRepairXY: function() {
return this.dragData.repairXY;
}
});
};
// Make the panel droppable to the button
var initDropZone = function(g) {
g.dropZone = new Ext.dd.DropZone(g.body, {
getTargetFromEvent: function(e) {
return e.getTarget('#canvas');
},
onNodeOver : function(target, dd, e, data){
return Ext.dd.DropZone.prototype.dropAllowed;
},
onNodeDrop : function(target, dd, e, data) {
// !Important: We assign the dragged element to be set to new drop position
if(dragEl = Ext.get(data.sourceEl)) {
dragEl.setXY([e.getPageX(),e.getPageY()]);
}
return true;
}
});
};
// Make the Panel Droppable
var myPanel = new Ext.Panel({
width: 500,
height: 300,
renderTo: 'canvas',
bodyStyle: { background: 'yellow' },
html: 'Drop your button here',
listeners: {
render: initDropZone
}
});
var myButton = new Ext.Button({
width: 30,
height: 20,
cls: 'button-draggable',
text: "Drag me",
renderTo: Ext.getBody(),
listeners: {
render: initDragZone
}
});
});
The important point of this implementation is the onDrag method
onDrag: function(e) {
// !Important: manually fix the default position of Ext-generated proxy element
// Uncomment these line to see the Ext issue
var proxy = Ext.DomQuery.select('*', this.getDragEl());
proxy[2].style.position = '';
},
Try removing the function onDrag above, you’ll see this positioning issue:

Have fun,
Totti