Example10DragFromOutside.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <template>
  2. <div>
  3. <div>
  4. <div class="layoutJSON">
  5. Displayed as <code>[x, y, w, h]</code>:
  6. <div class="columns">
  7. <div class="layoutItem" v-for="item in layout">
  8. <b>{{ item.i }}</b>: [{{ item.x }}, {{ item.y }}, {{ item.w }}, {{ item.h }}]
  9. </div>
  10. </div>
  11. </div>
  12. </div>
  13. <br/>
  14. <div @drag="drag" @dragend="dragend" class="droppable-element" draggable="true"
  15. unselectable="on">Droppable Element (Drag me!)</div>
  16. <div id="content">
  17. <grid-layout ref="gridlayout" :layout.sync="layout"
  18. :col-num="12"
  19. :row-height="30"
  20. :is-draggable="true"
  21. :is-resizable="true"
  22. :vertical-compact="true"
  23. :use-css-transforms="true"
  24. >
  25. <grid-item :key="item.i" v-for="item in layout"
  26. :x="item.x"
  27. :y="item.y"
  28. :w="item.w"
  29. :h="item.h"
  30. :i="item.i"
  31. >
  32. <span class="text">{{ item.i }}</span>
  33. </grid-item>
  34. </grid-layout>
  35. </div>
  36. </div>
  37. </template>
  38. <script>
  39. import {GridLayout, GridItem} from "vue-grid-layout"
  40. let mouseXY = {"x": null, "y": null};
  41. let DragPos = {"x": null, "y": null, "w": 1, "h": 1, "i": null};
  42. export default {
  43. components: {
  44. GridLayout,
  45. GridItem
  46. },
  47. data() {
  48. return {
  49. layout: [
  50. {"x": 0, "y": 0, "w": 2, "h": 2, "i": "0"},
  51. {"x": 2, "y": 0, "w": 2, "h": 4, "i": "1"},
  52. {"x": 4, "y": 0, "w": 2, "h": 5, "i": "2"},
  53. {"x": 6, "y": 0, "w": 2, "h": 3, "i": "3"},
  54. {"x": 8, "y": 0, "w": 2, "h": 3, "i": "4"},
  55. {"x": 10, "y": 0, "w": 2, "h": 3, "i": "5"},
  56. {"x": 0, "y": 5, "w": 2, "h": 5, "i": "6"},
  57. {"x": 2, "y": 5, "w": 2, "h": 5, "i": "7"},
  58. {"x": 4, "y": 5, "w": 2, "h": 5, "i": "8"},
  59. {"x": 5, "y": 10, "w": 4, "h": 3, "i": "9"},
  60. ],
  61. }
  62. },
  63. mounted() {
  64. document.addEventListener("dragover", function (e) {
  65. mouseXY.x = e.clientX;
  66. mouseXY.y = e.clientY;
  67. }, false);
  68. },
  69. beforeDestroy() {
  70. },
  71. methods: {
  72. drag: function (e) {
  73. let parentRect = document.getElementById('content').getBoundingClientRect();
  74. let mouseInGrid = false;
  75. if (((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right)) && ((mouseXY.y > parentRect.top) && (mouseXY.y < parentRect.bottom))) {
  76. mouseInGrid = true;
  77. }
  78. if (mouseInGrid === true && (this.layout.findIndex(item => item.i === 'drop')) === -1) {
  79. this.layout.push({
  80. x: (this.layout.length * 2) % (this.colNum || 12),
  81. y: this.layout.length + (this.colNum || 12), // puts it at the bottom
  82. w: 1,
  83. h: 1,
  84. i: 'drop',
  85. });
  86. }
  87. let index = this.layout.findIndex(item => item.i === 'drop');
  88. if (index !== -1) {
  89. try {
  90. this.$refs.gridlayout.$children[this.layout.length].$refs.item.style.display = "none";
  91. } catch {
  92. }
  93. let el = this.$refs.gridlayout.$children[index];
  94. el.dragging = {"top": mouseXY.y - parentRect.top, "left": mouseXY.x - parentRect.left};
  95. let new_pos = el.calcXY(mouseXY.y - parentRect.top, mouseXY.x - parentRect.left);
  96. if (mouseInGrid === true) {
  97. this.$refs.gridlayout.dragEvent('dragstart', 'drop', new_pos.x, new_pos.y, 1, 1);
  98. DragPos.i = String(index);
  99. DragPos.x = this.layout[index].x;
  100. DragPos.y = this.layout[index].y;
  101. }
  102. if (mouseInGrid === false) {
  103. this.$refs.gridlayout.dragEvent('dragend', 'drop', new_pos.x, new_pos.y, 1, 1);
  104. this.layout = this.layout.filter(obj => obj.i !== 'drop');
  105. }
  106. }
  107. },
  108. dragend: function (e) {
  109. let parentRect = document.getElementById('content').getBoundingClientRect();
  110. let mouseInGrid = false;
  111. if (((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right)) && ((mouseXY.y > parentRect.top) && (mouseXY.y < parentRect.bottom))) {
  112. mouseInGrid = true;
  113. }
  114. if (mouseInGrid === true) {
  115. alert(`Dropped element props:\n${JSON.stringify(DragPos, ['x', 'y', 'w', 'h'], 2)}`);
  116. this.$refs.gridlayout.dragEvent('dragend', 'drop', DragPos.x, DragPos.y, 1, 1);
  117. this.layout = this.layout.filter(obj => obj.i !== 'drop');
  118. // UNCOMMENT below if you want to add a grid-item
  119. /*
  120. this.layout.push({
  121. x: DragPos.x,
  122. y: DragPos.y,
  123. w: 1,
  124. h: 1,
  125. i: DragPos.i,
  126. });
  127. this.$refs.gridLayout.dragEvent('dragend', DragPos.i, DragPos.x,DragPos.y,1,1);
  128. try {
  129. this.$refs.gridLayout.$children[this.layout.length].$refs.item.style.display="block";
  130. } catch {
  131. }
  132. */
  133. }
  134. },
  135. }
  136. }
  137. </script>
  138. <style scoped>
  139. .droppable-element {
  140. width: 150px;
  141. text-align: center;
  142. background: #fdd;
  143. border: 1px solid black;
  144. margin: 10px 0;
  145. padding: 10px;
  146. }
  147. .vue-grid-layout {
  148. background: #eee;
  149. }
  150. .vue-grid-item:not(.vue-grid-placeholder) {
  151. background: #ccc;
  152. border: 1px solid black;
  153. }
  154. .vue-grid-item .resizing {
  155. opacity: 0.9;
  156. }
  157. .vue-grid-item .static {
  158. background: #cce;
  159. }
  160. .vue-grid-item .text {
  161. font-size: 24px;
  162. text-align: center;
  163. position: absolute;
  164. top: 0;
  165. bottom: 0;
  166. left: 0;
  167. right: 0;
  168. margin: auto;
  169. height: 100%;
  170. width: 100%;
  171. }
  172. .vue-grid-item .no-drag {
  173. height: 100%;
  174. width: 100%;
  175. }
  176. .vue-grid-item .minMax {
  177. font-size: 12px;
  178. }
  179. .vue-grid-item .add {
  180. cursor: pointer;
  181. }
  182. .vue-draggable-handle {
  183. position: absolute;
  184. width: 20px;
  185. height: 20px;
  186. top: 0;
  187. left: 0;
  188. background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><circle cx='5' cy='5' r='5' fill='#999999'/></svg>") no-repeat;
  189. background-position: bottom right;
  190. padding: 0 8px 8px 0;
  191. background-repeat: no-repeat;
  192. background-origin: content-box;
  193. box-sizing: border-box;
  194. cursor: pointer;
  195. }
  196. .layoutJSON {
  197. background: #ddd;
  198. border: 1px solid black;
  199. margin-top: 10px;
  200. padding: 10px;
  201. }
  202. .layoutJSON {
  203. background: #ddd;
  204. border: 1px solid black;
  205. margin-top: 10px;
  206. padding: 10px;
  207. }
  208. .columns {
  209. -moz-columns: 120px;
  210. -webkit-columns: 120px;
  211. columns: 120px;
  212. }
  213. </style>