1 | var Dom = YAHOO.util.Dom;
|
---|
2 | var Event = YAHOO.util.Event;
|
---|
3 | var DDM = YAHOO.util.DragDropMgr;
|
---|
4 | //var tempPlaceholderList;
|
---|
5 | //var tempPlaceholder;
|
---|
6 |
|
---|
7 | //////////////////////////////////////////////////////////////////////////////
|
---|
8 | // custom drag and drop implementation
|
---|
9 | //////////////////////////////////////////////////////////////////////////////
|
---|
10 |
|
---|
11 | YAHOO.example.DDList = function(id, sGroup, config) {
|
---|
12 |
|
---|
13 | YAHOO.example.DDList.superclass.constructor.call(this, id, sGroup, config);
|
---|
14 |
|
---|
15 | this.logger = this.logger || YAHOO;
|
---|
16 | var el = this.getDragEl();
|
---|
17 | Dom.setStyle(el, "opacity", 0.67); // The proxy is slightly transparent
|
---|
18 |
|
---|
19 | this.goingUp = false;
|
---|
20 | this.lastY = 0;
|
---|
21 | };
|
---|
22 |
|
---|
23 | YAHOO.extend(YAHOO.example.DDList, YAHOO.util.DDProxy, {
|
---|
24 |
|
---|
25 | startDrag: function(x, y) {
|
---|
26 | this.logger.log(this.id + " startDrag");
|
---|
27 |
|
---|
28 | /*
|
---|
29 | if(!tempPlaceholder)
|
---|
30 | {
|
---|
31 | tempPlaceholderList = document.createElement("UL");
|
---|
32 | tempPlaceholderList.setAttribute("class", "emptyList");
|
---|
33 | tempPlaceHolder = createPlaceholder(null, null, false);
|
---|
34 | tempPlaceholderList.appendChild(tempPlaceHolder);
|
---|
35 | }
|
---|
36 | */
|
---|
37 |
|
---|
38 | // make the proxy look like the source element
|
---|
39 | var dragEl = this.getDragEl();
|
---|
40 | var clickEl = this.getEl();
|
---|
41 |
|
---|
42 | this.sourcePrevSibling = getPrevSiblingOfType(clickEl, "li");
|
---|
43 | this.sourceNextSibling = getNextSiblingOfType(clickEl, "li");
|
---|
44 | this.sourceParentList = clickEl.parentList;
|
---|
45 |
|
---|
46 | closeAllOpenContents();
|
---|
47 |
|
---|
48 | Dom.setStyle(clickEl, "visibility", "hidden");
|
---|
49 | dragEl.innerHTML = clickEl.innerHTML;
|
---|
50 |
|
---|
51 | var child = clickEl.childList;
|
---|
52 | var contents = clickEl.textDiv;
|
---|
53 | if(child)
|
---|
54 | {
|
---|
55 | this.dragElChild = child;
|
---|
56 | Dom.setStyle(child, "display", "none");
|
---|
57 | }
|
---|
58 | else
|
---|
59 | {
|
---|
60 | this.dragElChild = null;
|
---|
61 | }
|
---|
62 |
|
---|
63 | if(contents)
|
---|
64 | {
|
---|
65 | this.contents = contents;
|
---|
66 | }
|
---|
67 | else
|
---|
68 | {
|
---|
69 | this.contents = null;
|
---|
70 | }
|
---|
71 |
|
---|
72 | Dom.setStyle(dragEl, "color", Dom.getStyle(clickEl, "color"));
|
---|
73 | Dom.setStyle(dragEl, "backgroundColor", Dom.getStyle(clickEl, "backgroundColor"));
|
---|
74 | Dom.setStyle(dragEl, "border", "2px solid gray");
|
---|
75 | },
|
---|
76 |
|
---|
77 | endDrag: function(e) {
|
---|
78 |
|
---|
79 | var srcEl = this.getEl();
|
---|
80 | var proxy = this.getDragEl();
|
---|
81 |
|
---|
82 | // Show the proxy element and animate it to the src element's location
|
---|
83 | Dom.setStyle(proxy, "visibility", "");
|
---|
84 |
|
---|
85 | var a = new YAHOO.util.Motion(
|
---|
86 | proxy, {
|
---|
87 | points: {
|
---|
88 | to: Dom.getXY(srcEl)
|
---|
89 | }
|
---|
90 | },
|
---|
91 | 0.1,
|
---|
92 | YAHOO.util.Easing.easeOut
|
---|
93 | );
|
---|
94 |
|
---|
95 | var proxyElem = proxy;
|
---|
96 | var thisElem = this;
|
---|
97 | var last = this.lastMoved;
|
---|
98 |
|
---|
99 | // Hide the proxy and show the source element when finished with the animation
|
---|
100 | a.onComplete.subscribe(function()
|
---|
101 | {
|
---|
102 | //Make the helper invisible
|
---|
103 | Dom.setStyle(proxyElem.id, "visibility", "hidden");
|
---|
104 | //Make the actual item visible again
|
---|
105 | Dom.setStyle(srcEl.id, "visibility", "");
|
---|
106 |
|
---|
107 | //Show the child list if the section has one
|
---|
108 | if(srcEl.childList)
|
---|
109 | {
|
---|
110 | Dom.setStyle(srcEl.childList, "display", "block");
|
---|
111 | insertAfter(srcEl.childList, srcEl);
|
---|
112 | }
|
---|
113 |
|
---|
114 | //Move the element's text div if it has one
|
---|
115 | if(srcEl.textDiv)
|
---|
116 | {
|
---|
117 | insertAfter(srcEl.textDiv, srcEl);
|
---|
118 | }
|
---|
119 |
|
---|
120 | var reverse = false;
|
---|
121 | var newNodeID = null;
|
---|
122 |
|
---|
123 | //Make sure we have the ID of the last section moved
|
---|
124 | if(last.nodeID)
|
---|
125 | {
|
---|
126 | newNodeID = last.nodeID;
|
---|
127 | //We only want to modify the new node ID if the two sections are at the same level in the same document
|
---|
128 | if(!srcEl.nodeID || (newNodeID.split(".").length == srcEl.nodeID.split(".").length && srcEl.nodeID.split(".")[0] == newNodeID.split(".")[0]))
|
---|
129 | {
|
---|
130 | if(thisElem.goingUp && (last.index > srcEl.index))
|
---|
131 | {
|
---|
132 | var lastDigit = parseInt(newNodeID.substring(newNodeID.lastIndexOf(".") + 1));
|
---|
133 | if(lastDigit == 1){lastDigit = 2;} //Make sure we never get 0
|
---|
134 |
|
---|
135 | newNodeID = newNodeID.replace(/\.[^\.]*$/, "." + --lastDigit);
|
---|
136 | reverse = true;
|
---|
137 | }
|
---|
138 | else if(!srcEl.nodeID || (!thisElem.goingUp && (last.index < srcEl.index)))
|
---|
139 | {
|
---|
140 | var lastDigit = parseInt(newNodeID.substring(newNodeID.lastIndexOf(".") + 1));
|
---|
141 | newNodeID = newNodeID.replace(/\.[^\.]*$/, "." + ++lastDigit);
|
---|
142 | reverse = true;
|
---|
143 | }
|
---|
144 | }
|
---|
145 | }
|
---|
146 |
|
---|
147 | var operation;
|
---|
148 | if(thisElem.goingUp)
|
---|
149 | {
|
---|
150 | operation = reverse ? "insertAfter" : "insertBefore";
|
---|
151 | }
|
---|
152 | else
|
---|
153 | {
|
---|
154 | operation = reverse ? "insertBefore" : "insertAfter";
|
---|
155 | }
|
---|
156 |
|
---|
157 | //If a new section has just been dragged in
|
---|
158 | if(srcEl.newSection)
|
---|
159 | {
|
---|
160 | srcEl.newSection = null;
|
---|
161 |
|
---|
162 | //Create a new draggable section to replace the one we just moved
|
---|
163 | createDraggableNewSection(srcEl.parent);
|
---|
164 |
|
---|
165 | //Add the normal things to the new section
|
---|
166 | var textDiv = createSectionTextDiv(null);
|
---|
167 | srcEl.textDiv = textDiv;
|
---|
168 | insertAfter(textDiv, srcEl);
|
---|
169 | textDiv.parentItem = srcEl;
|
---|
170 |
|
---|
171 | createSectionMenu(srcEl);
|
---|
172 | setMouseOverAndOutFunctions(srcEl);
|
---|
173 | srcEl.setAttribute("class", srcEl.getAttribute("class").replace(/newSection/g, ""));
|
---|
174 | srcEl.dbID = _idCounter++;
|
---|
175 | srcEl.collection = last.collection;
|
---|
176 | _allContents.push(srcEl);
|
---|
177 |
|
---|
178 | var undo = new Array();
|
---|
179 | undo.op = "del";
|
---|
180 | undo.srcElem = srcEl;
|
---|
181 | undo.removeTransaction = true;
|
---|
182 | _undoOperations.push(undo);
|
---|
183 |
|
---|
184 | saveTransaction('{"operation":"create", "subOperation":"' + operation + '", "collection":"' + last.collection + '", "oid":"' + newNodeID + '"}');
|
---|
185 | addCollectionToBuild(last.collection);
|
---|
186 | }
|
---|
187 | else
|
---|
188 | {
|
---|
189 | var needsUndo = false;
|
---|
190 | if(hasClass(last, "placeHolder"))
|
---|
191 | {
|
---|
192 | //Removed the dashed border that surrounds an empty section
|
---|
193 | if(last.parentNode)
|
---|
194 | {
|
---|
195 | removeFromParent(last);
|
---|
196 | }
|
---|
197 |
|
---|
198 | if(last.isEmptyList)
|
---|
199 | {
|
---|
200 | saveTransaction('{"operation":"move", "subOperation":"append", "collection":"' + srcEl.collection + '", "oid":"' + srcEl.nodeID + '", "newCollection":"' + last.collection + '", "newOID":"' + last.nodeID + '"}');
|
---|
201 | }
|
---|
202 | else
|
---|
203 | {
|
---|
204 | saveTransaction('{"operation":"move", "subOperation":"insertAfter", "collection":"' + srcEl.collection + '", "oid":"' + srcEl.nodeID + '", "newCollection":"' + last.collection + '", "newOID":"' + last.nodeID + '"}');
|
---|
205 | }
|
---|
206 | addCollectionToBuild(srcEl.collection);
|
---|
207 | addCollectionToBuild(last.collection);
|
---|
208 | needsUndo = true;
|
---|
209 | }
|
---|
210 | else
|
---|
211 | {
|
---|
212 | if(srcEl.collection != last.collection || srcEl.nodeID != newNodeID)
|
---|
213 | {
|
---|
214 | saveTransaction('{"operation":"move", "subOperation":"' + operation + '", "collection":"' + srcEl.collection + '", "oid":"' + srcEl.nodeID + '", "newCollection":"' + last.collection + '", "newOID":"' + newNodeID + '"}');
|
---|
215 | addCollectionToBuild(srcEl.collection);
|
---|
216 | addCollectionToBuild(last.collection);
|
---|
217 | needsUndo = true;
|
---|
218 | }
|
---|
219 | }
|
---|
220 |
|
---|
221 | //Save the undo operation if necessary
|
---|
222 | if(needsUndo)
|
---|
223 | {
|
---|
224 | var undo = new Array();
|
---|
225 | if(thisElem.sourceNextSibling)
|
---|
226 | {
|
---|
227 | undo.op = "mvb";
|
---|
228 | undo.refElem = thisElem.sourceNextSibling;
|
---|
229 | }
|
---|
230 | else if(thisElem.sourcePrevSibling)
|
---|
231 | {
|
---|
232 | undo.op = "mva";
|
---|
233 | undo.refElem = thisElem.sourcePrevSibling;
|
---|
234 | }
|
---|
235 | else
|
---|
236 | {
|
---|
237 | undo.op = "mvi";
|
---|
238 | undo.refElem = thisElem.sourceParentList;
|
---|
239 | }
|
---|
240 |
|
---|
241 | undo.srcElem = srcEl;
|
---|
242 | undo.removeTransaction = true;
|
---|
243 | _undoOperations.push(undo);
|
---|
244 | }
|
---|
245 | }
|
---|
246 |
|
---|
247 | updateFromTop();
|
---|
248 | });
|
---|
249 | a.animate();
|
---|
250 |
|
---|
251 | if(hasClass(srcEl.previousSibling, "placeHolder"))
|
---|
252 | {
|
---|
253 | removeFromParent(srcEl.previousSibling);
|
---|
254 | new YAHOO.example.DDList(srcEl.parentNode.previousSibling);
|
---|
255 | }
|
---|
256 | if(hasClass(srcEl, "topLevel"))
|
---|
257 | {
|
---|
258 | srcEl.setAttribute("class", srcEl.getAttribute("class").replace(/topLevel/g, ""));
|
---|
259 | }
|
---|
260 | },
|
---|
261 |
|
---|
262 | onDragDrop: function(e, id) {
|
---|
263 |
|
---|
264 | // If there is one drop interaction, the li was dropped either on the list,
|
---|
265 | // or it was dropped on the current location of the source element.
|
---|
266 | if (DDM.interactionInfo.drop.length === 1) {
|
---|
267 |
|
---|
268 | // The position of the cursor at the time of the drop (YAHOO.util.Point)
|
---|
269 | var pt = DDM.interactionInfo.point;
|
---|
270 |
|
---|
271 | // The region occupied by the source element at the time of the drop
|
---|
272 | var region = DDM.interactionInfo.sourceRegion;
|
---|
273 |
|
---|
274 | // Check to see if we are over the source element's location. We will
|
---|
275 | // append to the bottom of the list once we are sure it was a drop in
|
---|
276 | // the negative space (the area of the list without any list items)
|
---|
277 | if (!region.intersect(pt)) {
|
---|
278 | var destEl = Dom.get(id);
|
---|
279 | var destDD = DDM.getDDById(id);
|
---|
280 | if(hasClass(destEl, "topLevel") && hasClass(destEl, "dragList"))
|
---|
281 | {
|
---|
282 | destEl.appendChild(this.getEl());
|
---|
283 | }
|
---|
284 | destDD.isEmpty = false;
|
---|
285 | DDM.refreshCache();
|
---|
286 | }
|
---|
287 |
|
---|
288 | }
|
---|
289 | },
|
---|
290 |
|
---|
291 | onDrag: function(e) {
|
---|
292 |
|
---|
293 | // Keep track of the direction of the drag for use during onDragOver
|
---|
294 | var y = Event.getPageY(e);
|
---|
295 |
|
---|
296 | if (y < this.lastY) {
|
---|
297 | this.goingUp = true;
|
---|
298 | } else if (y > this.lastY) {
|
---|
299 | this.goingUp = false;
|
---|
300 | }
|
---|
301 |
|
---|
302 | this.lastY = y;
|
---|
303 | },
|
---|
304 |
|
---|
305 | onDragOver: function(e, id) {
|
---|
306 |
|
---|
307 | var srcEl = this.getEl();
|
---|
308 | var destEl = Dom.get(id);
|
---|
309 |
|
---|
310 | // We are only concerned with list items, we ignore the dragover
|
---|
311 | // notifications for the list.
|
---|
312 | if(destEl.nodeName.toLowerCase() == "li") {
|
---|
313 | if((hasClass(destEl, "dragItem") || hasClass(destEl, "placeHolder")) && !hasClass(destEl, "topLevel") && !hasClass(destEl, "newSection"))
|
---|
314 | {
|
---|
315 | var orig_p = srcEl.parentNode;
|
---|
316 | var p = destEl.parentNode;
|
---|
317 |
|
---|
318 | var child = destEl.childList;
|
---|
319 | var contents = destEl.textDiv;
|
---|
320 |
|
---|
321 | if (this.goingUp) {
|
---|
322 | p.insertBefore(srcEl, destEl);
|
---|
323 | } else {
|
---|
324 | p.insertBefore(srcEl, destEl.nextSibling);
|
---|
325 | }
|
---|
326 |
|
---|
327 | //This is to stop items being inserted between a section and its children
|
---|
328 | if(child)
|
---|
329 | {
|
---|
330 | insertAfter(child, destEl);
|
---|
331 | }
|
---|
332 | if(contents)
|
---|
333 | {
|
---|
334 | insertAfter(contents, destEl);
|
---|
335 | }
|
---|
336 |
|
---|
337 | this.lastMoved = destEl;
|
---|
338 |
|
---|
339 | DDM.refreshCache();
|
---|
340 | }
|
---|
341 | }
|
---|
342 | }
|
---|
343 | }); |
---|