Tutorial:Custom Drag and Drop Part 1 (Legacy)

This version of our Learning Center is unmaintained.
This article may be out-of-date or contain incorrect information.
Please visit the new Sencha Learning Center for up-to-date material.

Go to the new Sencha Learning Center

From Sencha - Learn

Jump to: navigation, search
Summary: Custom Drag & Drop Basics - Part 1
Author: Jozef Sakalos
Published: September 8, 2007
Ext Version: 1.1+ / 2.0+
Languages: en.png English

Being with Ext for a couple of months, searching for help and helping on forums I have realized that there are a lot of questions on the subject of Drag & Drop and that there is lack of examples. So comes this tutorial...

Contents

Preface

There is a lot of ways how to code D&D and I don't want to say that the methods described in this tutorial are the only ones. Take them as examples of one way of tackling the D&D. Also, if standard tree or grid D&D is what you want and need this tutorial is not for you.

On the other hand, if you need some specialty, custom looking drag proxies, D&D items reordering or custom actions on drop and you don't know where to start, then read on.

Let's get our hands dirty

dd.html

First of all we need a markup. We start with this one:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link rel="stylesheet" type="text/css" href="../extjs/resources/css/ext-all.css">
    <link rel="stylesheet" type="text/css" href="Ext.ux.IconCombo.css">
    <script type="text/javascript" src="../extjs/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="../extjs/ext-all-debug.js"></script>
    <script type="text/javascript" src="dd.js"></script>
    <!-- A Localization Script File comes here -->
    <script type="text/javascript">Ext.onReady(Tutorial.dd.init, Tutorial.dd);</script>
    <title>Custom Drag &amp; Drop Tutorial</title>
    <style type="text/css">
    body {
        font-size: 11px;
    }
    .dd-ct {
        position:absolute;
        border: 1px solid silver;
        width: 180px;
        height: 180px;
        top: 32px;
        background-color: #ffffc0;
    }
    #dd1-ct {
        left: 64px;
    }
    #dd2-ct {
        left: 256px;
    }
    .dd-item {
        height: 18px;
        border: 1px solid #a0a0a0;
        background-color: #c4d0ff;
        vertical-align: middle;
        cursor: move;
        padding: 2px;
        z-index: 1000;
    }
    .dd-ct .dd-item {
        margin: 2px;
    }
    .dd-proxy {
        opacity: 0.4;
        -moz-opacity: 0.4;
        filter: alpha(opacity=40);
    }
    .dd-over {
        background-color: #ffff60;
    }
    </style>
</head>
<body>
<div class="dd-ct" id="dd1-ct">
    <div class="dd-item" id="dd1-item1">Item 1.1</div>
    <div class="dd-item" id="dd1-item2">Item 1.2</div>
    <div class="dd-item" id="dd1-item3">Item 1.3</div>
</div>
</body>
</html>

We define one container div dd1-ct that we will use later and three divs to have something to drag. For simplicity, I have used the embedded style sheets.

dd.js

What a surprise, we need javascript file too:

/**
  * Custom Drag & Drop Tutorial
  * by Jozef Sakalos, aka Saki
  * http://extjs.com/learn/Tutorial:Custom_Drag_and_Drop_Part_1
  */
 
// reference local blank image
Ext.BLANK_IMAGE_URL = '../extjs/resources/images/default/s.gif';
 
Ext.namespace('Tutorial');
 
// create application
Tutorial.dd = function() {
 
    // private space
 
 
    return {
 
        // public methods
        init: function() {
 
            var dd11 = Ext.get('dd1-item1');
            dd11.dd = new Ext.dd.DDProxy('dd1-item1', 'group');
 
            var dd12 = Ext.get('dd1-item2');
            dd12.dd = new Ext.dd.DDProxy('dd1-item2', 'group');
 
            var dd13 = Ext.get('dd1-item3');
            dd13.dd = new Ext.dd.DDProxy('dd1-item3', 'group');
 
        }
    };
}(); // end of app
 
// end of file

The dd application uses standard application layout and during execution of the init function it creates DDProxy for each item. This should already work, shouldn't it?

Test it

Navigate to dd.html and try to drag items. Works, yeah? Well, it works but we just drag empty rectangles with ugly thick borders. It would look much better if the element we drag, the proxy, would look exactly like it's source probably with some transparency.

Let's do it.

Override function startDrag

Insert the following code just after the initial comment into the file dd.js:

Ext.override(Ext.dd.DDProxy, {
    startDrag: function(x, y) {
        var dragEl = Ext.get(this.getDragEl());
        var el = Ext.get(this.getEl());
 
        dragEl.applyStyles({border:'','z-index':2000});
        dragEl.update(el.dom.innerHTML);
        dragEl.addClass(el.dom.className + ' dd-proxy');
    }
});

We override default function startDrag defined in Ext.dd.DDProxy. This function is called by the DD core upon starting a drag. We first get dragEl (i.e. the proxy element being dragged) and el (i.e. the original source element we initiated the dragging from).

Then we cancel the ugly border and set z-index high enough.

Next, we copy content of source element to content of the proxy. Content of our items is very simple but in real application you would also need to handle ids of elements contained in items we drag because with this simple copy we would create elements with duplicate ids which would lead to an unpredictable behavior.

Last, we copy class from the original to the proxy and we add dd-proxy class for transparency.

Test it again

Reload dd.html and try to drag items. Looks much better, doesn't it?

We have learnt here how to make an element draggable and how to create custom looking proxies. We will add some more functionality in next part(s).

This page was last modified on 16 September 2009, at 02:19. This page has been accessed 120,601 times.