Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / examples / dd / dragdropzones.js
index 7bc210f..4c87b4c 100644 (file)
-/*!
- * Ext JS Library 3.0.3
- * Copyright(c) 2006-2009 Ext JS, LLC
- * licensing@extjs.com
- * http://www.extjs.com/license
+Ext.require(['*']);
+
+Ext.onReady(function() {
+
+    var patients = [{
+        insuranceCode: '11111',
+        name: 'Fred Bloggs',
+        address: 'Main Street',
+        telephone: '555 1234 123'
+    }, {
+        insuranceCode: '22222',
+        name: 'Fred Bansod',
+        address: 'Van Ness',
+        telephone: '666 666 666'
+    }, {
+        insuranceCode: '33333',
+        name: 'Fred Mercury',
+        address: 'Over The Rainbow',
+        telephone: '555 321 0987'
+    }, {
+        insuranceCode: '44444',
+        name: 'Fred Forsyth',
+        address: 'Blimp Street',
+        telephone: '555 111 2222'
+    }, {
+        insuranceCode: '55555',
+        name: 'Fred Douglass',
+        address: 'Talbot County, Maryland',
+        telephone: 'N/A'
+    }];
+
+    Ext.define('Patient', {
+        extend: 'Ext.data.Model',
+        idProperty: 'insuranceCode',
+        fields: [{
+                name: 'name'
+            }, {
+                name: 'address'
+            }, {
+                name: 'telephone'
+            }]
+    });
+
+    var patientStore = Ext.create('Ext.data.Store', {
+        model: 'Patient',
+        data: patients
+    });
+
+    var hospitals = [{
+        code: 'AAAAA',
+        name: 'Saint Thomas',
+        address: 'Westminster Bridge Road, SE1 7EH',
+        telephone: '020 7188 7188'
+    }, {
+        code: 'BBBBB',
+        name: 'Queen\'s Medical Centre',
+        address: 'Derby Road, NG7 2UH',
+        telephone: '0115 924 9924'
+    }, {
+        code: 'CCCCC',
+        name: 'Saint Bartholomew',
+        address: 'West Smithfield, EC1A 7BE',
+        telephone: '020 7377 7000'
+    }, {
+        code: 'DDDDD',
+        name: 'Royal London',
+        address: 'Whitechapel, E1 1BB',
+        telephone: '020 7377 7000'
+    }];
+
+    Ext.define('Hospital', {
+        extend: 'Ext.data.Model',
+        idProperty: 'code',
+        fields: [{
+            name: 'name'
+        }, {
+            name: 'address'
+        }, {
+            name: 'telephone'
+        }]
+    });
+
+    var hospitalStore = Ext.create('Ext.data.Store', {
+        model: 'Hospital',
+        data: hospitals
+    });
+
+    var patientView = Ext.create('Ext.view.View', {
+        cls: 'patient-view',
+        tpl: '<tpl for=".">' +
+                '<div class="patient-source"><table><tbody>' +
+                    '<tr><td class="patient-label">Name</td><td class="patient-name">{name}</td></tr>' +
+                    '<tr><td class="patient-label">Address</td><td class="patient-name">{address}</td></tr>' +
+                    '<tr><td class="patient-label">Telephone</td><td class="patient-name">{telephone}</td></tr>' +
+                '</tbody></table></div>' +
+             '</tpl>',
+        itemSelector: 'div.patient-source',
+        overItemCls: 'patient-over',
+        selectedItemClass: 'patient-selected',
+        singleSelect: true,
+        store: patientStore,
+        listeners: {
+            render: initializePatientDragZone
+        }
+    });
+
+    var helpWindow = Ext.create('Ext.Window', {
+        title: 'Source code',
+        width: 920,
+        height: 500,
+        closeAction: 'hide',
+        renderTpl: [
+            '<textarea readonly class="{baseCls}-body<tpl if="bodyCls"> {bodyCls}</tpl><tpl if="frame"> {baseCls}-body-framed</tpl><tpl if="ui"> {baseCls}-body-{ui}</tpl>"<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>></div>'
+        ],
+        listeners: {
+            render: function(w) {
+                Ext.Ajax.request({
+                    url: 'dragdropzones.js',
+                    success: function(r) {
+                        w.body.dom.value = r.responseText;
+                    }
+                });
+            }
+        }
+    });
+
+    var hospitalGrid = Ext.create('Ext.grid.Panel', {
+        title: 'Hospitals',
+        region: 'center',
+        margins: '0 5 5 0',
+        bbar: [{
+            text: 'View Source',
+            handler: function() {
+                helpWindow.show();
+            }
+        }],
+        sortableColumns: false,
+        columns: [{
+            dataIndex: 'name',
+            header: 'Name',
+            width: 200
+        }, {
+            dataIndex: 'address',
+            header: 'Address',
+            width: 300
+        }, {
+            dataIndex: 'telephone',
+            header: 'Telephone',
+            width: 100
+        }],
+        features: [{
+            ftype:'rowbody',
+            rowBodyDivCls: 'hospital-target',
+            getAdditionalData: function() {
+                return Ext.apply(Ext.grid.feature.RowBody.prototype.getAdditionalData.apply(this, arguments), {
+                    rowBody: 'Drop Patient Here'
+                });
+            }
+        }],
+        viewConfig: {
+            listeners: {
+                render: initializeHospitalDropZone
+            }
+        },
+        store: hospitalStore
+    });
+
+    Ext.create('Ext.Viewport', {
+        layout: 'border',
+        items: [{
+            cls: 'app-header',
+            region: 'north',
+            height: 30,
+            html: '<h1>Patient Hospital Assignment</h1>',
+            margins: '5 5 5 5'
+        }, {
+            title: 'Patients',
+            region: 'west',
+            width: 300,
+            margins: '0 5 5 5',
+            items: patientView
+        }, hospitalGrid ]
+    });
+});
+
+/*
+ * Here is where we "activate" the DataView.
+ * We have decided that each node with the class "patient-source" encapsulates a single draggable
+ * object.
+ *
+ * So we inject code into the DragZone which, when passed a mousedown event, interrogates
+ * the event to see if it was within an element with the class "patient-source". If so, we
+ * return non-null drag data.
+ *
+ * Returning non-null drag data indicates that the mousedown event has begun a dragging process.
+ * The data must contain a property called "ddel" which is a DOM element which provides an image
+ * of the data being dragged. The actual node clicked on is not dragged, a proxy element is dragged.
+ * We can insert any other data into the data object, and this will be used by a cooperating DropZone
+ * to perform the drop operation.
  */
-Ext.onReady(function() {\r
-\r
-    var patients = [{\r
-        insuranceCode: '11111',\r
-        name: 'Fred Bloggs',\r
-        address: 'Main Street',\r
-        telephone: '555 1234 123'\r
-    }, {\r
-        insuranceCode: '22222',\r
-        name: 'Fred West',\r
-        address: 'Cromwell Street',\r
-        telephone: '666 666 666'\r
-    }, {\r
-        insuranceCode: '33333',\r
-        name: 'Fred Mercury',\r
-        address: 'Over The Rainbow',\r
-        telephone: '555 321 0987'\r
-    }, {\r
-        insuranceCode: '44444',\r
-        name: 'Fred Forsyth',\r
-        address: 'Blimp Street',\r
-        telephone: '555 111 2222'\r
-    }, {\r
-        insuranceCode: '55555',\r
-        name: 'Fred Douglass',\r
-        address: 'Talbot County, Maryland',\r
-        telephone: 'N/A'\r
-    }];\r
-\r
-    var PatientRecord = Ext.data.Record.create([{\r
-        name: 'name'\r
-    }, {\r
-        name: 'address'\r
-    }, {\r
-        name: 'telephone'\r
-    }]);\r
-\r
-    var patientStore = new Ext.data.Store({\r
-        data: patients,\r
-        reader: new Ext.data.JsonReader({\r
-            id: 'insuranceCode'\r
-        }, PatientRecord)\r
-    });\r
-\r
-    var hospitals = [{\r
-        code: 'AAAAA',\r
-        name: 'Saint Thomas',\r
-        address: 'Westminster Bridge Road, SE1 7EH',\r
-        telephone: '020 7188 7188'\r
-    }, {\r
-        code: 'BBBBB',\r
-        name: 'Queen\'s Medical Centre',\r
-        address: 'Derby Road, NG7 2UH',\r
-        telephone: '0115 924 9924'\r
-    }, {\r
-        code: 'CCCCC',\r
-        name: 'Saint Bartholomew',\r
-        address: 'West Smithfield, EC1A 7BE',\r
-        telephone: '020 7377 7000'\r
-    }, {\r
-        code: 'DDDDD',\r
-        name: 'Royal London',\r
-        address: 'Whitechapel, E1 1BB',\r
-        telephone: '020 7377 7000'\r
-    }];\r
-    \r
-    var HospitalRecord = Ext.data.Record.create([{\r
-        name: 'name'\r
-    }, {\r
-        name: 'address'\r
-    }, {\r
-        name: 'telephone'\r
-    }]);\r
-\r
-    var hospitalStore = new Ext.data.Store({\r
-        data: hospitals,\r
-        reader: new Ext.data.JsonReader({\r
-            id: 'code'\r
-        }, HospitalRecord)\r
-    });\r
-    \r
-    var patientView = new Ext.DataView({\r
-        cls: 'patient-view',\r
-        tpl: '<tpl for=".">' +\r
-                '<div class="patient-source"><table><tbody>' +\r
-                    '<tr><td class="patient-label">Name</td><td class="patient-name">{name}</td></tr>' +\r
-                    '<tr><td class="patient-label">Address</td><td class="patient-name">{address}</td></tr>' +\r
-                    '<tr><td class="patient-label">Telephone</td><td class="patient-name">{telephone}</td></tr>' +\r
-                '</tbody></table></div>' +\r
-             '</tpl>',\r
-        itemSelector: 'div.patient-source',\r
-        store: patientStore,\r
-        listeners: {\r
-            render: initializePatientDragZone\r
-        }\r
-    });\r
-\r
-    var helpWindow = new Ext.Window({\r
-        title: 'Source code',\r
-        width: 920,\r
-        height: 500,\r
-        closeAction: 'hide',\r
-        bodyCfg: {tag: 'textarea', readonly: true},\r
-        bodyStyle: {\r
-            backgroundColor: 'white',\r
-            margin: '0px',\r
-            border: '0px none'\r
-        },\r
-        listeners: {\r
-            render: function(w) {\r
-                Ext.Ajax.request({\r
-                    url: 'dragdropzones.js',\r
-                    success: function(r) {\r
-                        w.body.dom.value = r.responseText;\r
-                    }\r
-                });\r
-            }\r
-        }\r
-    });\r
-\r
-    var hospitalGrid = new Ext.grid.GridPanel({\r
-        title: 'Hospitals',\r
-        region: 'center',\r
-        margins: '0 5 5 0',\r
-        bbar: [{\r
-            text: 'View Source',\r
-            handler: function() {\r
-                helpWindow.show();\r
-            }\r
-        }],\r
-        columns: [{\r
-            dataIndex: 'name',\r
-            header: 'Name',\r
-            width: 200\r
-        }, {\r
-            dataIndex: 'address',\r
-            header: 'Address',\r
-            width: 300\r
-        }, {\r
-            dataIndex: 'telephone',\r
-            header: 'Telephone',\r
-            width: 100\r
-        }],\r
-        viewConfig: {\r
-            tpl: new Ext.XTemplate('<div class="hospital-target"></div>'),\r
-            enableRowBody: true,\r
-            getRowClass: function(rec, idx, p, store) {\r
-                p.body = this.tpl.apply(rec.data);\r
-            }\r
-        },\r
-        store: hospitalStore,\r
-        listeners: {\r
-            render: initializeHospitalDropZone\r
-        }\r
-    });\r
-\r
-    new Ext.Viewport({\r
-        layout: 'border',\r
-        items: [{\r
-            cls: 'app-header',\r
-            region: 'north',\r
-            height: 100,\r
-            html: '<h1>Patient Hospital Assignment</h1>',\r
-            margins: '5 5 5 5'\r
-        }, {\r
-            title: 'Patients',\r
-            region: 'west',\r
-            width: 300,\r
-            margins: '0 5 5 5',\r
-            items: patientView\r
-        }, hospitalGrid ]\r
-    });\r
-});\r
-\r
-/*\r
- * Here is where we "activate" the DataView.\r
- * We have decided that each node with the class "patient-source" encapsulates a single draggable\r
- * object.\r
- *\r
- * So we inject code into the DragZone which, when passed a mousedown event, interrogates\r
- * the event to see if it was within an element with the class "patient-source". If so, we\r
- * return non-null drag data.\r
- *\r
- * Returning non-null drag data indicates that the mousedown event has begun a dragging process.\r
- * The data must contain a property called "ddel" which is a DOM element which provides an image\r
- * of the data being dragged. The actual node clicked on is not dragged, a proxy element is dragged.\r
- * We can insert any other data into the data object, and this will be used by a cooperating DropZone\r
- * to perform the drop operation.\r
- */\r
-function initializePatientDragZone(v) {\r
-    v.dragZone = new Ext.dd.DragZone(v.getEl(), {\r
-\r
-//      On receipt of a mousedown event, see if it is within a draggable element.\r
-//      Return a drag data object if so. The data object can contain arbitrary application\r
-//      data, but it should also contain a DOM element in the ddel property to provide\r
-//      a proxy to drag.\r
-        getDragData: function(e) {\r
-            var sourceEl = e.getTarget(v.itemSelector, 10);\r
-            if (sourceEl) {\r
-                d = sourceEl.cloneNode(true);\r
-                d.id = Ext.id();\r
-                return v.dragData = {\r
-                    sourceEl: sourceEl,\r
-                    repairXY: Ext.fly(sourceEl).getXY(),\r
-                    ddel: d,\r
-                    patientData: v.getRecord(sourceEl).data\r
-                }\r
-            }\r
-        },\r
-\r
-//      Provide coordinates for the proxy to slide back to on failed drag.\r
-//      This is the original XY coordinates of the draggable element.\r
-        getRepairXY: function() {\r
-            return this.dragData.repairXY;\r
-        }\r
-    });\r
-}\r
-\r
-/*\r
- * Here is where we "activate" the GridPanel.\r
- * We have decided that the element with class "hospital-target" is the element which can receieve\r
- * drop gestures. So we inject a method "getTargetFromEvent" into the DropZone. This is constantly called\r
- * while the mouse is moving over the DropZone, and it returns the target DOM element if it detects that\r
- * the mouse if over an element which can receieve drop gestures.\r
- *\r
- * Once the DropZone has been informed by getTargetFromEvent that it is over a target, it will then\r
- * call several "onNodeXXXX" methods at various points. These include:\r
- *\r
- * onNodeEnter\r
- * onNodeOut\r
- * onNodeOver\r
- * onNodeDrop\r
- *\r
- * We provide implementations of each of these to provide behaviour for these events.\r
- */\r
-function initializeHospitalDropZone(g) {\r
-    g.dropZone = new Ext.dd.DropZone(g.getView().scroller, {\r
-\r
-//      If the mouse is over a target node, return that node. This is\r
-//      provided as the "target" parameter in all "onNodeXXXX" node event handling functions\r
-        getTargetFromEvent: function(e) {\r
-            return e.getTarget('.hospital-target');\r
-        },\r
-\r
-//      On entry into a target node, highlight that node.\r
-        onNodeEnter : function(target, dd, e, data){ \r
-            Ext.fly(target).addClass('hospital-target-hover');\r
-        },\r
-\r
-//      On exit from a target node, unhighlight that node.\r
-        onNodeOut : function(target, dd, e, data){ \r
-            Ext.fly(target).removeClass('hospital-target-hover');\r
-        },\r
-\r
-//      While over a target node, return the default drop allowed class which\r
-//      places a "tick" icon into the drag proxy.\r
-        onNodeOver : function(target, dd, e, data){ \r
-            return Ext.dd.DropZone.prototype.dropAllowed;\r
-        },\r
-\r
-//      On node drop, we can interrogate the target node to find the underlying\r
-//      application object that is the real target of the dragged data.\r
-//      In this case, it is a Record in the GridPanel's Store.\r
-//      We can use the data set up by the DragZone's getDragData method to read\r
-//      any data we decided to attach.\r
-        onNodeDrop : function(target, dd, e, data){\r
-            var rowIndex = g.getView().findRowIndex(target);\r
-            var h = g.getStore().getAt(rowIndex);\r
-            Ext.Msg.alert('Drop gesture', 'Dropped patient ' + data.patientData.name +\r
-                ' on hospital ' + h.data.name);\r
-            return true;\r
-        }\r
-    });\r
-}
\ No newline at end of file
+function initializePatientDragZone(v) {
+    v.dragZone = Ext.create('Ext.dd.DragZone', v.getEl(), {
+
+//      On receipt of a mousedown event, see if it is within a draggable element.
+//      Return a drag data object if so. The data object can contain arbitrary application
+//      data, but it should also contain a DOM element in the ddel property to provide
+//      a proxy to drag.
+        getDragData: function(e) {
+            var sourceEl = e.getTarget(v.itemSelector, 10), d;
+            if (sourceEl) {
+                d = sourceEl.cloneNode(true);
+                d.id = Ext.id();
+                return v.dragData = {
+                    sourceEl: sourceEl,
+                    repairXY: Ext.fly(sourceEl).getXY(),
+                    ddel: d,
+                    patientData: v.getRecord(sourceEl).data
+                };
+            }
+        },
+
+//      Provide coordinates for the proxy to slide back to on failed drag.
+//      This is the original XY coordinates of the draggable element.
+        getRepairXY: function() {
+            return this.dragData.repairXY;
+        }
+    });
+}
+
+/*
+ * Here is where we "activate" the GridPanel.
+ * We have decided that the element with class "hospital-target" is the element which can receieve
+ * drop gestures. So we inject a method "getTargetFromEvent" into the DropZone. This is constantly called
+ * while the mouse is moving over the DropZone, and it returns the target DOM element if it detects that
+ * the mouse if over an element which can receieve drop gestures.
+ *
+ * Once the DropZone has been informed by getTargetFromEvent that it is over a target, it will then
+ * call several "onNodeXXXX" methods at various points. These include:
+ *
+ * onNodeEnter
+ * onNodeOut
+ * onNodeOver
+ * onNodeDrop
+ *
+ * We provide implementations of each of these to provide behaviour for these events.
+ */
+function initializeHospitalDropZone(v) {
+    var gridView = v,
+        grid = gridView.up('gridpanel');
+
+    grid.dropZone = Ext.create('Ext.dd.DropZone', v.el, {
+
+//      If the mouse is over a target node, return that node. This is
+//      provided as the "target" parameter in all "onNodeXXXX" node event handling functions
+        getTargetFromEvent: function(e) {
+            return e.getTarget('.hospital-target');
+        },
+
+//      On entry into a target node, highlight that node.
+        onNodeEnter : function(target, dd, e, data){
+            Ext.fly(target).addCls('hospital-target-hover');
+        },
+
+//      On exit from a target node, unhighlight that node.
+        onNodeOut : function(target, dd, e, data){
+            Ext.fly(target).removeCls('hospital-target-hover');
+        },
+
+//      While over a target node, return the default drop allowed class which
+//      places a "tick" icon into the drag proxy.
+        onNodeOver : function(target, dd, e, data){
+            return Ext.dd.DropZone.prototype.dropAllowed;
+        },
+
+//      On node drop, we can interrogate the target node to find the underlying
+//      application object that is the real target of the dragged data.
+//      In this case, it is a Record in the GridPanel's Store.
+//      We can use the data set up by the DragZone's getDragData method to read
+//      any data we decided to attach.
+        onNodeDrop : function(target, dd, e, data){
+            var rowBody = Ext.fly(target).findParent('.x-grid-rowbody-tr', null, false),
+                mainRow = rowBody.previousSibling,
+                h = gridView.getRecord(mainRow),
+                targetEl = Ext.get(target);
+
+            targetEl.update(data.patientData.name + ', ' + targetEl.dom.innerHTML);
+            Ext.Msg.alert('Drop gesture', 'Dropped patient ' + data.patientData.name +
+                ' on hospital ' + h.data.name);
+            return true;
+        }
+    });
+}