Upgrade to ExtJS 3.2.1 - Released 04/27/2010
[extjs.git] / examples / dd / dragdropzones.js
1 /*!
2  * Ext JS Library 3.2.1
3  * Copyright(c) 2006-2010 Ext JS, Inc.
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 Ext.onReady(function() {
8
9     var patients = [{
10         insuranceCode: '11111',
11         name: 'Fred Bloggs',
12         address: 'Main Street',
13         telephone: '555 1234 123'
14     }, {
15         insuranceCode: '22222',
16         name: 'Fred West',
17         address: 'Cromwell Street',
18         telephone: '666 666 666'
19     }, {
20         insuranceCode: '33333',
21         name: 'Fred Mercury',
22         address: 'Over The Rainbow',
23         telephone: '555 321 0987'
24     }, {
25         insuranceCode: '44444',
26         name: 'Fred Forsyth',
27         address: 'Blimp Street',
28         telephone: '555 111 2222'
29     }, {
30         insuranceCode: '55555',
31         name: 'Fred Douglass',
32         address: 'Talbot County, Maryland',
33         telephone: 'N/A'
34     }];
35
36     var PatientRecord = Ext.data.Record.create([{
37         name: 'name'
38     }, {
39         name: 'address'
40     }, {
41         name: 'telephone'
42     }]);
43
44     var patientStore = new Ext.data.Store({
45         data: patients,
46         reader: new Ext.data.JsonReader({
47             id: 'insuranceCode'
48         }, PatientRecord)
49     });
50
51     var hospitals = [{
52         code: 'AAAAA',
53         name: 'Saint Thomas',
54         address: 'Westminster Bridge Road, SE1 7EH',
55         telephone: '020 7188 7188'
56     }, {
57         code: 'BBBBB',
58         name: 'Queen\'s Medical Centre',
59         address: 'Derby Road, NG7 2UH',
60         telephone: '0115 924 9924'
61     }, {
62         code: 'CCCCC',
63         name: 'Saint Bartholomew',
64         address: 'West Smithfield, EC1A 7BE',
65         telephone: '020 7377 7000'
66     }, {
67         code: 'DDDDD',
68         name: 'Royal London',
69         address: 'Whitechapel, E1 1BB',
70         telephone: '020 7377 7000'
71     }];
72     
73     var HospitalRecord = Ext.data.Record.create([{
74         name: 'name'
75     }, {
76         name: 'address'
77     }, {
78         name: 'telephone'
79     }]);
80
81     var hospitalStore = new Ext.data.Store({
82         data: hospitals,
83         reader: new Ext.data.JsonReader({
84             id: 'code'
85         }, HospitalRecord)
86     });
87     
88     var patientView = new Ext.DataView({
89         cls: 'patient-view',
90         tpl: '<tpl for=".">' +
91                 '<div class="patient-source"><table><tbody>' +
92                     '<tr><td class="patient-label">Name</td><td class="patient-name">{name}</td></tr>' +
93                     '<tr><td class="patient-label">Address</td><td class="patient-name">{address}</td></tr>' +
94                     '<tr><td class="patient-label">Telephone</td><td class="patient-name">{telephone}</td></tr>' +
95                 '</tbody></table></div>' +
96              '</tpl>',
97         itemSelector: 'div.patient-source',
98         overClass: 'patient-over',
99         selectedClass: 'patient-selected',
100         singleSelect: true,
101         store: patientStore,
102         listeners: {
103             render: initializePatientDragZone
104         }
105     });
106
107     var helpWindow = new Ext.Window({
108         title: 'Source code',
109         width: 920,
110         height: 500,
111         closeAction: 'hide',
112         bodyCfg: {tag: 'textarea', readonly: true},
113         bodyStyle: {
114             backgroundColor: 'white',
115             margin: '0px',
116             border: '0px none'
117         },
118         listeners: {
119             render: function(w) {
120                 Ext.Ajax.request({
121                     url: 'dragdropzones.js',
122                     success: function(r) {
123                         w.body.dom.value = r.responseText;
124                     }
125                 });
126             }
127         }
128     });
129
130     var hospitalGrid = new Ext.grid.GridPanel({
131         title: 'Hospitals',
132         region: 'center',
133         margins: '0 5 5 0',
134         bbar: [{
135             text: 'View Source',
136             handler: function() {
137                 helpWindow.show();
138             }
139         }],
140         columns: [{
141             dataIndex: 'name',
142             header: 'Name',
143             width: 200
144         }, {
145             dataIndex: 'address',
146             header: 'Address',
147             width: 300
148         }, {
149             dataIndex: 'telephone',
150             header: 'Telephone',
151             width: 100
152         }],
153         viewConfig: {
154             tpl: new Ext.XTemplate('<div class="hospital-target">Drop Patient Here</div>'),
155             enableRowBody: true,
156             getRowClass: function(rec, idx, p, store) {
157                 p.body = this.tpl.apply(rec.data);
158             }
159         },
160         store: hospitalStore,
161         listeners: {
162             render: initializeHospitalDropZone
163         }
164     });
165
166     new Ext.Viewport({
167         layout: 'border',
168         items: [{
169             cls: 'app-header',
170             region: 'north',
171             height: 30,
172             html: '<h1>Patient Hospital Assignment</h1>',
173             margins: '5 5 5 5'
174         }, {
175             title: 'Patients',
176             region: 'west',
177             width: 300,
178             margins: '0 5 5 5',
179             items: patientView
180         }, hospitalGrid ]
181     });
182 });
183
184 /*
185  * Here is where we "activate" the DataView.
186  * We have decided that each node with the class "patient-source" encapsulates a single draggable
187  * object.
188  *
189  * So we inject code into the DragZone which, when passed a mousedown event, interrogates
190  * the event to see if it was within an element with the class "patient-source". If so, we
191  * return non-null drag data.
192  *
193  * Returning non-null drag data indicates that the mousedown event has begun a dragging process.
194  * The data must contain a property called "ddel" which is a DOM element which provides an image
195  * of the data being dragged. The actual node clicked on is not dragged, a proxy element is dragged.
196  * We can insert any other data into the data object, and this will be used by a cooperating DropZone
197  * to perform the drop operation.
198  */
199 function initializePatientDragZone(v) {
200     v.dragZone = new Ext.dd.DragZone(v.getEl(), {
201
202 //      On receipt of a mousedown event, see if it is within a draggable element.
203 //      Return a drag data object if so. The data object can contain arbitrary application
204 //      data, but it should also contain a DOM element in the ddel property to provide
205 //      a proxy to drag.
206         getDragData: function(e) {
207             var sourceEl = e.getTarget(v.itemSelector, 10);
208             if (sourceEl) {
209                 d = sourceEl.cloneNode(true);
210                 d.id = Ext.id();
211                 return v.dragData = {
212                     sourceEl: sourceEl,
213                     repairXY: Ext.fly(sourceEl).getXY(),
214                     ddel: d,
215                     patientData: v.getRecord(sourceEl).data
216                 }
217             }
218         },
219
220 //      Provide coordinates for the proxy to slide back to on failed drag.
221 //      This is the original XY coordinates of the draggable element.
222         getRepairXY: function() {
223             return this.dragData.repairXY;
224         }
225     });
226 }
227
228 /*
229  * Here is where we "activate" the GridPanel.
230  * We have decided that the element with class "hospital-target" is the element which can receieve
231  * drop gestures. So we inject a method "getTargetFromEvent" into the DropZone. This is constantly called
232  * while the mouse is moving over the DropZone, and it returns the target DOM element if it detects that
233  * the mouse if over an element which can receieve drop gestures.
234  *
235  * Once the DropZone has been informed by getTargetFromEvent that it is over a target, it will then
236  * call several "onNodeXXXX" methods at various points. These include:
237  *
238  * onNodeEnter
239  * onNodeOut
240  * onNodeOver
241  * onNodeDrop
242  *
243  * We provide implementations of each of these to provide behaviour for these events.
244  */
245 function initializeHospitalDropZone(g) {
246     g.dropZone = new Ext.dd.DropZone(g.getView().scroller, {
247
248 //      If the mouse is over a target node, return that node. This is
249 //      provided as the "target" parameter in all "onNodeXXXX" node event handling functions
250         getTargetFromEvent: function(e) {
251             return e.getTarget('.hospital-target');
252         },
253
254 //      On entry into a target node, highlight that node.
255         onNodeEnter : function(target, dd, e, data){ 
256             Ext.fly(target).addClass('hospital-target-hover');
257         },
258
259 //      On exit from a target node, unhighlight that node.
260         onNodeOut : function(target, dd, e, data){ 
261             Ext.fly(target).removeClass('hospital-target-hover');
262         },
263
264 //      While over a target node, return the default drop allowed class which
265 //      places a "tick" icon into the drag proxy.
266         onNodeOver : function(target, dd, e, data){ 
267             return Ext.dd.DropZone.prototype.dropAllowed;
268         },
269
270 //      On node drop, we can interrogate the target node to find the underlying
271 //      application object that is the real target of the dragged data.
272 //      In this case, it is a Record in the GridPanel's Store.
273 //      We can use the data set up by the DragZone's getDragData method to read
274 //      any data we decided to attach.
275         onNodeDrop : function(target, dd, e, data){
276             var rowIndex = g.getView().findRowIndex(target);
277             var h = g.getStore().getAt(rowIndex);
278             var targetEl = Ext.get(target);
279             targetEl.update(data.patientData.name+', '+targetEl.dom.innerHTML);
280             Ext.Msg.alert('Drop gesture', 'Dropped patient ' + data.patientData.name +
281                 ' on hospital ' + h.data.name);
282             return true;
283         }
284     });
285 }