Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / examples / docs / source / Portal.html
1 <html>
2 <head>
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
4   <title>The source code</title>
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 </head>
8 <body  onload="prettyPrint();">
9     <pre class="prettyprint lang-js">/*!
10  * Ext JS Library 3.3.1
11  * Copyright(c) 2006-2010 Sencha Inc.
12  * licensing@sencha.com
13  * http://www.sencha.com/license
14  */
15 Ext.ux.Portal = Ext.extend(Ext.Panel, {
16     layout : 'column',
17     autoScroll : true,
18     cls : 'x-portal',
19     defaultType : 'portalcolumn',
20     
21     initComponent : function(){
22         Ext.ux.Portal.superclass.initComponent.call(this);
23         this.addEvents({
24             validatedrop:true,
25             beforedragover:true,
26             dragover:true,
27             beforedrop:true,
28             drop:true
29         });
30     },
31
32     initEvents : function(){
33         Ext.ux.Portal.superclass.initEvents.call(this);
34         this.dd = new Ext.ux.Portal.DropZone(this, this.dropConfig);
35     },
36     
37     beforeDestroy : function() {
38         if(this.dd){
39             this.dd.unreg();
40         }
41         Ext.ux.Portal.superclass.beforeDestroy.call(this);
42     }
43 });
44
45 Ext.reg('portal', Ext.ux.Portal);
46
47 Ext.ux.Portal.DropZone = Ext.extend(Ext.dd.DropTarget, {
48     
49     constructor : function(portal, cfg){
50         this.portal = portal;
51         Ext.dd.ScrollManager.register(portal.body);
52         Ext.ux.Portal.DropZone.superclass.constructor.call(this, portal.bwrap.dom, cfg);
53         portal.body.ddScrollConfig = this.ddScrollConfig;
54     },
55     
56     ddScrollConfig : {
57         vthresh: 50,
58         hthresh: -1,
59         animate: true,
60         increment: 200
61     },
62
63     createEvent : function(dd, e, data, col, c, pos){
64         return {
65             portal: this.portal,
66             panel: data.panel,
67             columnIndex: col,
68             column: c,
69             position: pos,
70             data: data,
71             source: dd,
72             rawEvent: e,
73             status: this.dropAllowed
74         };
75     },
76
77     notifyOver : function(dd, e, data){
78         var xy = e.getXY(), portal = this.portal, px = dd.proxy;
79
80         // case column widths
81         if(!this.grid){
82             this.grid = this.getGrid();
83         }
84
85         // handle case scroll where scrollbars appear during drag
86         var cw = portal.body.dom.clientWidth;
87         if(!this.lastCW){
88             this.lastCW = cw;
89         }else if(this.lastCW != cw){
90             this.lastCW = cw;
91             portal.doLayout();
92             this.grid = this.getGrid();
93         }
94
95         // determine column
96         var col = 0, xs = this.grid.columnX, cmatch = false;
97         for(var len = xs.length; col < len; col++){
98             if(xy[0] < (xs[col].x + xs[col].w)){
99                 cmatch = true;
100                 break;
101             }
102         }
103         // no match, fix last index
104         if(!cmatch){
105             col--;
106         }
107
108         // find insert position
109         var p, match = false, pos = 0,
110             c = portal.items.itemAt(col),
111             items = c.items.items, overSelf = false;
112
113         for(var len = items.length; pos < len; pos++){
114             p = items[pos];
115             var h = p.el.getHeight();
116             if(h === 0){
117                 overSelf = true;
118             }
119             else if((p.el.getY()+(h/2)) > xy[1]){
120                 match = true;
121                 break;
122             }
123         }
124
125         pos = (match && p ? pos : c.items.getCount()) + (overSelf ? -1 : 0);
126         var overEvent = this.createEvent(dd, e, data, col, c, pos);
127
128         if(portal.fireEvent('validatedrop', overEvent) !== false &&
129            portal.fireEvent('beforedragover', overEvent) !== false){
130
131             // make sure proxy width is fluid
132             px.getProxy().setWidth('auto');
133
134             if(p){
135                 px.moveProxy(p.el.dom.parentNode, match ? p.el.dom : null);
136             }else{
137                 px.moveProxy(c.el.dom, null);
138             }
139
140             this.lastPos = {c: c, col: col, p: overSelf || (match && p) ? pos : false};
141             this.scrollPos = portal.body.getScroll();
142
143             portal.fireEvent('dragover', overEvent);
144
145             return overEvent.status;
146         }else{
147             return overEvent.status;
148         }
149
150     },
151
152     notifyOut : function(){
153         delete this.grid;
154     },
155
156     notifyDrop : function(dd, e, data){
157         delete this.grid;
158         if(!this.lastPos){
159             return;
160         }
161         var c = this.lastPos.c, 
162             col = this.lastPos.col, 
163             pos = this.lastPos.p,
164             panel = dd.panel,
165             dropEvent = this.createEvent(dd, e, data, col, c,
166                 pos !== false ? pos : c.items.getCount());
167
168         if(this.portal.fireEvent('validatedrop', dropEvent) !== false &&
169            this.portal.fireEvent('beforedrop', dropEvent) !== false){
170
171             dd.proxy.getProxy().remove();
172             panel.el.dom.parentNode.removeChild(dd.panel.el.dom);
173             
174             if(pos !== false){
175                 c.insert(pos, panel);
176             }else{
177                 c.add(panel);
178             }
179             
180             c.doLayout();
181
182             this.portal.fireEvent('drop', dropEvent);
183
184             // scroll position is lost on drop, fix it
185             var st = this.scrollPos.top;
186             if(st){
187                 var d = this.portal.body.dom;
188                 setTimeout(function(){
189                     d.scrollTop = st;
190                 }, 10);
191             }
192
193         }
194         delete this.lastPos;
195     },
196
197     // internal cache of body and column coords
198     getGrid : function(){
199         var box = this.portal.bwrap.getBox();
200         box.columnX = [];
201         this.portal.items.each(function(c){
202              box.columnX.push({x: c.el.getX(), w: c.el.getWidth()});
203         });
204         return box;
205     },
206
207     // unregister the dropzone from ScrollManager
208     unreg: function() {
209         Ext.dd.ScrollManager.unregister(this.portal.body);
210         Ext.ux.Portal.DropZone.superclass.unreg.call(this);
211     }
212 });
213 </pre>    
214 </body>
215 </html>