Ext JS Examples: Drag n’ Drop buttons on a panel

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:

Positioning Issue

Have fun,

Totti

4 thoughts on “Ext JS Examples: Drag n’ Drop buttons on a panel”

  1. Hi, I was playing with some custom drag drop implementations and was wondering how to make the source element persist after it’s dragged. I have a panel with some buttons on it, but I want them to be able to be dragged more than once… in my current implementation, once they are dragged into a new panel, the source element disappears.

    Any thoughts?

    1. @Kasapo: To make the source element persist (not removing it from the original position) please modify the method
      onNodeDrop : function(target, dd, e, data) above.

      In onNodeDrop what we do is actually remove the source element from the original position and put it in the new position.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>