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