4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-grid-header-DropZone'>/**
19 </span> * @class Ext.grid.header.DropZone
20 * @extends Ext.dd.DropZone
23 Ext.define('Ext.grid.header.DropZone', {
24 extend: 'Ext.dd.DropZone',
25 colHeaderCls: Ext.baseCSSPrefix + 'column-header',
26 proxyOffsets: [-4, -9],
28 constructor: function(headerCt){
29 this.headerCt = headerCt;
30 this.ddGroup = this.getDDGroup();
31 this.callParent([headerCt.el]);
34 getDDGroup: function() {
35 return 'header-dd-zone-' + this.headerCt.up('[scrollerOwner]').id;
38 getTargetFromEvent : function(e){
39 return e.getTarget('.' + this.colHeaderCls);
42 getTopIndicator: function() {
43 if (!this.topIndicator) {
44 this.topIndicator = Ext.core.DomHelper.append(Ext.getBody(), {
45 cls: "col-move-top",
46 html: "&#160;"
49 return this.topIndicator;
52 getBottomIndicator: function() {
53 if (!this.bottomIndicator) {
54 this.bottomIndicator = Ext.core.DomHelper.append(Ext.getBody(), {
55 cls: "col-move-bottom",
56 html: "&#160;"
59 return this.bottomIndicator;
62 getLocation: function(e, t) {
64 region = Ext.fly(t).getRegion(),
67 if ((region.right - x) <= (region.right - region.left) / 2) {
68 pos = "after";
70 pos = "before";
74 header: Ext.getCmp(t.id),
79 positionIndicator: function(draggedHeader, node, e){
80 var location = this.getLocation(e, node),
81 header = location.header,
83 nextHd = draggedHeader.nextSibling('gridcolumn:not([hidden])'),
84 prevHd = draggedHeader.previousSibling('gridcolumn:not([hidden])'),
85 region, topIndicator, bottomIndicator, topAnchor, bottomAnchor,
86 topXY, bottomXY, headerCtEl, minX, maxX;
88 // Cannot drag beyond non-draggable start column
89 if (!header.draggable && header.getIndex() == 0) {
93 this.lastLocation = location;
95 if ((draggedHeader !== header) &&
96 ((pos === "before" && nextHd !== header) ||
97 (pos === "after" && prevHd !== header)) &&
98 !header.isDescendantOf(draggedHeader)) {
100 // As we move in between different DropZones that are in the same
101 // group (such as the case when in a locked grid), invalidateDrop
102 // on the other dropZones.
103 var allDropZones = Ext.dd.DragDropManager.getRelated(this),
104 ln = allDropZones.length,
108 for (; i < ln; i++) {
109 dropZone = allDropZones[i];
110 if (dropZone !== this && dropZone.invalidateDrop) {
111 dropZone.invalidateDrop();
117 topIndicator = this.getTopIndicator();
118 bottomIndicator = this.getBottomIndicator();
119 if (pos === 'before') {
126 topXY = header.el.getAnchorXY(topAnchor);
127 bottomXY = header.el.getAnchorXY(bottomAnchor);
129 // constrain the indicators to the viewable section
130 headerCtEl = this.headerCt.el;
131 minX = headerCtEl.getLeft();
132 maxX = headerCtEl.getRight();
134 topXY[0] = Ext.Number.constrain(topXY[0], minX, maxX);
135 bottomXY[0] = Ext.Number.constrain(bottomXY[0], minX, maxX);
137 // adjust by offsets, this is to center the arrows so that they point
138 // at the split point
143 // position and show indicators
144 topIndicator.setXY(topXY);
145 bottomIndicator.setXY(bottomXY);
147 bottomIndicator.show();
148 // invalidate drop operation and hide indicators
150 this.invalidateDrop();
154 invalidateDrop: function() {
156 this.hideIndicators();
159 onNodeOver: function(node, dragZone, e, data) {
160 if (data.header.el.dom !== node) {
161 this.positionIndicator(data.header, node, e);
163 return this.valid ? this.dropAllowed : this.dropNotAllowed;
166 hideIndicators: function() {
167 this.getTopIndicator().hide();
168 this.getBottomIndicator().hide();
171 onNodeOut: function() {
172 this.hideIndicators();
175 onNodeDrop: function(node, dragZone, e, data) {
177 this.invalidateDrop();
178 var hd = data.header,
179 lastLocation = this.lastLocation,
181 fromIdx = fromCt.items.indexOf(hd), // Container.items is a MixedCollection
182 toCt = lastLocation.header.ownerCt,
183 toIdx = toCt.items.indexOf(lastLocation.header),
184 headerCt = this.headerCt,
188 if (lastLocation.pos === 'after') {
192 // If we are dragging in between two HeaderContainers that have had the lockable
193 // mixin injected we will lock/unlock headers in between sections. Note that lockable
194 // does NOT currently support grouped headers.
195 if (fromCt !== toCt && fromCt.lockableInjected && toCt.lockableInjected && toCt.lockedCt) {
196 scrollerOwner = fromCt.up('[scrollerOwner]');
197 scrollerOwner.lock(hd, toIdx);
198 } else if (fromCt !== toCt && fromCt.lockableInjected && toCt.lockableInjected && fromCt.lockedCt) {
199 scrollerOwner = fromCt.up('[scrollerOwner]');
200 scrollerOwner.unlock(hd, toIdx);
202 // If dragging rightwards, then after removal, the insertion index will be one less when moving
203 // in between the same container.
204 if ((fromCt === toCt) && (toIdx > fromCt.items.indexOf(hd))) {
208 // Remove dragged header from where it was without destroying it or relaying its Container
209 if (fromCt !== toCt) {
210 fromCt.suspendLayout = true;
211 fromCt.remove(hd, false);
212 fromCt.suspendLayout = false;
215 // Dragged the last header out of the fromCt group... The fromCt group must die
216 if (fromCt.isGroupHeader) {
217 if (!fromCt.items.getCount()) {
218 groupCt = fromCt.ownerCt;
219 groupCt.suspendLayout = true;
220 groupCt.remove(fromCt, false);
221 fromCt.el.dom.parentNode.removeChild(fromCt.el.dom);
222 groupCt.suspendLayout = false;
224 fromCt.minWidth = fromCt.getWidth() - hd.getWidth();
225 fromCt.setWidth(fromCt.minWidth);
229 // Move dragged header into its drop position
230 toCt.suspendLayout = true;
231 if (fromCt === toCt) {
232 toCt.move(fromIdx, toIdx);
234 toCt.insert(toIdx, hd);
236 toCt.suspendLayout = false;
238 // Group headers acquire the aggregate width of their child headers
239 // Therefore a child header may not flex; it must contribute a fixed width.
240 // But we restore the flex value when moving back into the main header container
241 if (toCt.isGroupHeader) {
242 hd.savedFlex = hd.flex;
244 hd.width = hd.getWidth();
245 // When there was previously a flex, we need to ensure we don't count for the
247 toCt.minWidth = toCt.getWidth() + hd.getWidth() - (hd.savedFlex ? 1 : 0);
248 toCt.setWidth(toCt.minWidth);
251 hd.flex = hd.savedFlex;
257 // Refresh columns cache in case we remove an emptied group column
258 headerCt.purgeCache();
260 headerCt.onHeaderMoved(hd, fromIdx, toIdx);
261 // Emptied group header can only be destroyed after the header and grid have been refreshed
262 if (!fromCt.items.getCount()) {