DropZone3.html 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js"><span id='Ext-view-DropZone'>/**
  19. </span> * @private
  20. */
  21. Ext.define('Ext.view.DropZone', {
  22. extend: 'Ext.dd.DropZone',
  23. indicatorHtml: '&lt;div class=&quot;' + Ext.baseCSSPrefix + 'grid-drop-indicator-left&quot;&gt;&lt;/div&gt;&lt;div class=&quot;' + Ext.baseCSSPrefix + 'grid-drop-indicator-right&quot;&gt;&lt;/div&gt;',
  24. indicatorCls: Ext.baseCSSPrefix + 'grid-drop-indicator',
  25. constructor: function(config) {
  26. var me = this;
  27. Ext.apply(me, config);
  28. // Create a ddGroup unless one has been configured.
  29. // User configuration of ddGroups allows users to specify which
  30. // DD instances can interact with each other. Using one
  31. // based on the id of the View would isolate it and mean it can only
  32. // interact with a DragZone on the same View also using a generated ID.
  33. if (!me.ddGroup) {
  34. me.ddGroup = 'view-dd-zone-' + me.view.id;
  35. }
  36. // The DropZone's encapsulating element is the View's main element. It must be this because drop gestures
  37. // may require scrolling on hover near a scrolling boundary. In Ext 4.x two DD instances may not use the
  38. // same element, so a DragZone on this same View must use the View's parent element as its element.
  39. me.callParent([me.view.el]);
  40. },
  41. // Fire an event through the client DataView. Lock this DropZone during the event processing so that
  42. // its data does not become corrupted by processing mouse events.
  43. fireViewEvent: function() {
  44. var me = this,
  45. result;
  46. me.lock();
  47. result = me.view.fireEvent.apply(me.view, arguments);
  48. me.unlock();
  49. return result;
  50. },
  51. getTargetFromEvent : function(e) {
  52. var node = e.getTarget(this.view.getItemSelector()),
  53. mouseY, nodeList, testNode, i, len, box;
  54. // Not over a row node: The content may be narrower than the View's encapsulating element, so return the closest.
  55. // If we fall through because the mouse is below the nodes (or there are no nodes), we'll get an onContainerOver call.
  56. if (!node) {
  57. mouseY = e.getPageY();
  58. for (i = 0, nodeList = this.view.getNodes(), len = nodeList.length; i &lt; len; i++) {
  59. testNode = nodeList[i];
  60. box = Ext.fly(testNode).getBox();
  61. if (mouseY &lt;= box.bottom) {
  62. return testNode;
  63. }
  64. }
  65. }
  66. return node;
  67. },
  68. getIndicator: function() {
  69. var me = this;
  70. if (!me.indicator) {
  71. me.indicator = new Ext.Component({
  72. html: me.indicatorHtml,
  73. cls: me.indicatorCls,
  74. ownerCt: me.view,
  75. floating: true,
  76. shadow: false
  77. });
  78. }
  79. return me.indicator;
  80. },
  81. getPosition: function(e, node) {
  82. var y = e.getXY()[1],
  83. region = Ext.fly(node).getRegion(),
  84. pos;
  85. if ((region.bottom - y) &gt;= (region.bottom - region.top) / 2) {
  86. pos = &quot;before&quot;;
  87. } else {
  88. pos = &quot;after&quot;;
  89. }
  90. return pos;
  91. },
  92. <span id='Ext-view-DropZone-method-containsRecordAtOffset'> /**
  93. </span> * @private Determines whether the record at the specified offset from the passed record
  94. * is in the drag payload.
  95. * @param records
  96. * @param record
  97. * @param offset
  98. * @returns {Boolean} True if the targeted record is in the drag payload
  99. */
  100. containsRecordAtOffset: function(records, record, offset) {
  101. if (!record) {
  102. return false;
  103. }
  104. var view = this.view,
  105. recordIndex = view.indexOf(record),
  106. nodeBefore = view.getNode(recordIndex + offset),
  107. recordBefore = nodeBefore ? view.getRecord(nodeBefore) : null;
  108. return recordBefore &amp;&amp; Ext.Array.contains(records, recordBefore);
  109. },
  110. positionIndicator: function(node, data, e) {
  111. var me = this,
  112. view = me.view,
  113. pos = me.getPosition(e, node),
  114. overRecord = view.getRecord(node),
  115. draggingRecords = data.records,
  116. indicatorY;
  117. if (!Ext.Array.contains(draggingRecords, overRecord) &amp;&amp; (
  118. pos == 'before' &amp;&amp; !me.containsRecordAtOffset(draggingRecords, overRecord, -1) ||
  119. pos == 'after' &amp;&amp; !me.containsRecordAtOffset(draggingRecords, overRecord, 1)
  120. )) {
  121. me.valid = true;
  122. if (me.overRecord != overRecord || me.currentPosition != pos) {
  123. indicatorY = Ext.fly(node).getY() - view.el.getY() - 1;
  124. if (pos == 'after') {
  125. indicatorY += Ext.fly(node).getHeight();
  126. }
  127. me.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, indicatorY);
  128. // Cache the overRecord and the 'before' or 'after' indicator.
  129. me.overRecord = overRecord;
  130. me.currentPosition = pos;
  131. }
  132. } else {
  133. me.invalidateDrop();
  134. }
  135. },
  136. invalidateDrop: function() {
  137. if (this.valid) {
  138. this.valid = false;
  139. this.getIndicator().hide();
  140. }
  141. },
  142. // The mouse is over a View node
  143. onNodeOver: function(node, dragZone, e, data) {
  144. var me = this;
  145. if (!Ext.Array.contains(data.records, me.view.getRecord(node))) {
  146. me.positionIndicator(node, data, e);
  147. }
  148. return me.valid ? me.dropAllowed : me.dropNotAllowed;
  149. },
  150. // Moved out of the DropZone without dropping.
  151. // Remove drop position indicator
  152. notifyOut: function(node, dragZone, e, data) {
  153. var me = this;
  154. me.callParent(arguments);
  155. delete me.overRecord;
  156. delete me.currentPosition;
  157. if (me.indicator) {
  158. me.indicator.hide();
  159. }
  160. },
  161. // The mouse is past the end of all nodes (or there are no nodes)
  162. onContainerOver : function(dd, e, data) {
  163. var me = this,
  164. view = me.view,
  165. count = view.store.getCount();
  166. // There are records, so position after the last one
  167. if (count) {
  168. me.positionIndicator(view.getNode(count - 1), data, e);
  169. }
  170. // No records, position the indicator at the top
  171. else {
  172. delete me.overRecord;
  173. delete me.currentPosition;
  174. me.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, 0);
  175. me.valid = true;
  176. }
  177. return me.dropAllowed;
  178. },
  179. onContainerDrop : function(dd, e, data) {
  180. return this.onNodeDrop(dd, null, e, data);
  181. },
  182. onNodeDrop: function(node, dragZone, e, data) {
  183. var me = this,
  184. dropHandled = false,
  185. // Create a closure to perform the operation which the event handler may use.
  186. // Users may now set the wait parameter in the beforedrop handler, and perform any kind
  187. // of asynchronous processing such as an Ext.Msg.confirm, or an Ajax request,
  188. // and complete the drop gesture at some point in the future by calling either the
  189. // processDrop or cancelDrop methods.
  190. dropHandlers = {
  191. wait: false,
  192. processDrop: function () {
  193. me.invalidateDrop();
  194. me.handleNodeDrop(data, me.overRecord, me.currentPosition);
  195. dropHandled = true;
  196. me.fireViewEvent('drop', node, data, me.overRecord, me.currentPosition);
  197. },
  198. cancelDrop: function() {
  199. me.invalidateDrop();
  200. dropHandled = true;
  201. }
  202. },
  203. performOperation = false;
  204. if (me.valid) {
  205. performOperation = me.fireViewEvent('beforedrop', node, data, me.overRecord, me.currentPosition, dropHandlers);
  206. if (dropHandlers.wait) {
  207. return;
  208. }
  209. if (performOperation !== false) {
  210. // If either of the drop handlers were called in the event handler, do not do it again.
  211. if (!dropHandled) {
  212. dropHandlers.processDrop();
  213. }
  214. }
  215. }
  216. return performOperation;
  217. },
  218. destroy: function(){
  219. Ext.destroy(this.indicator);
  220. delete this.indicator;
  221. this.callParent();
  222. }
  223. });
  224. </pre>
  225. </body>
  226. </html>