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