dragdrop.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /**********************************************************
  2. Adapted from the sortable lists example by Tim Taylor
  3. http://tool-man.org/examples/sorting.html
  4. Modified by Tom Westcott : http://www.cyberdummy.co.uk
  5. **********************************************************/
  6. var DragDrop = {
  7. firstContainer : null,
  8. lastContainer : null,
  9. parent_id : null,
  10. parent_group : null,
  11. makeListContainer : function(list, group) {
  12. // each container becomes a linked list node
  13. if (this.firstContainer == null) {
  14. this.firstContainer = this.lastContainer = list;
  15. list.previousContainer = null;
  16. list.nextContainer = null;
  17. } else {
  18. list.previousContainer = this.lastContainer;
  19. list.nextContainer = null;
  20. this.lastContainer.nextContainer = list;
  21. this.lastContainer = list;
  22. }
  23. // these functions are called when an item is draged over
  24. // a container or out of a container bounds. onDragOut
  25. // is also called when the drag ends with an item having
  26. // been added to the container
  27. list.onDragOver = new Function();
  28. list.onDragOut = new Function();
  29. list.onDragDrop = new Function();
  30. list.group = group;
  31. var items = list.getElementsByTagName( "li" );
  32. for (var i = 0; i < items.length; i++) {
  33. DragDrop.makeItemDragable(items[i]);
  34. }
  35. },
  36. serData : function ( group, theid ) {
  37. var container = DragDrop.firstContainer;
  38. var j = 0;
  39. var string = "";
  40. while (container != null) {
  41. if(theid != null && container.id != theid)
  42. {
  43. container = container.nextContainer;
  44. continue;
  45. }
  46. if(group != null && container.group != group)
  47. {
  48. container = container.nextContainer;
  49. continue;
  50. }
  51. j ++;
  52. if(j > 1)
  53. {
  54. string += ":";
  55. }
  56. string += container.id;
  57. var items = container.getElementsByTagName( "li" );
  58. string += "(";
  59. for (var i = 0; i < items.length; i++) {
  60. if(i > 0)
  61. {
  62. string += ",";
  63. }
  64. string += items[i].id;
  65. }
  66. string += ")";
  67. container = container.nextContainer;
  68. }
  69. return string;
  70. },
  71. makeItemDragable : function(item) {
  72. Drag.makeDraggable(item);
  73. item.setDragThreshold(5);
  74. // tracks if the item is currently outside all containers
  75. item.isOutside = false;
  76. item.onDragStart = DragDrop.onDragStart;
  77. item.onDrag = DragDrop.onDrag;
  78. item.onDragEnd = DragDrop.onDragEnd;
  79. },
  80. onDragStart : function(nwPosition, sePosition, nwOffset, seOffset) {
  81. // update all container bounds, since they may have changed
  82. // on a previous drag
  83. //
  84. // could be more smart about when to do this
  85. var container = DragDrop.firstContainer;
  86. while (container != null) {
  87. container.northwest = Coordinates.northwestOffset( container, true );
  88. container.southeast = Coordinates.southeastOffset( container, true );
  89. container = container.nextContainer;
  90. }
  91. // item starts out over current parent
  92. this.parentNode.onDragOver();
  93. parent_id = this.parentNode.id;
  94. parent_group = this.parentNode.group;
  95. },
  96. onDrag : function(nwPosition, sePosition, nwOffset, seOffset) {
  97. // check if we were nowhere
  98. if (this.isOutside) {
  99. // check each container to see if in its bounds
  100. var container = DragDrop.firstContainer;
  101. while (container != null) {
  102. if ((nwOffset.inside( container.northwest, container.southeast ) ||
  103. seOffset.inside( container.northwest, container.southeast )) && container.group == parent_group) {
  104. // we're inside this one
  105. container.onDragOver();
  106. this.isOutside = false;
  107. // since isOutside was true, the current parent is a
  108. // temporary clone of some previous container node and
  109. // it needs to be removed from the document
  110. var tempParent = this.parentNode;
  111. tempParent.removeChild( this );
  112. container.appendChild( this );
  113. tempParent.parentNode.removeChild( tempParent );
  114. break;
  115. }
  116. container = container.nextContainer;
  117. }
  118. // we're still not inside the bounds of any container
  119. if (this.isOutside)
  120. return;
  121. // check if we're outside our parent's bounds
  122. } else if (!(nwOffset.inside( this.parentNode.northwest, this.parentNode.southeast ) ||
  123. seOffset.inside( this.parentNode.northwest, this.parentNode.southeast ))) {
  124. this.parentNode.onDragOut();
  125. this.isOutside = true;
  126. // check if we're inside a new container's bounds
  127. var container = DragDrop.firstContainer;
  128. while (container != null) {
  129. if ((nwOffset.inside( container.northwest, container.southeast ) ||
  130. seOffset.inside( container.northwest, container.southeast )) && container.group == parent_group) {
  131. // we're inside this one
  132. container.onDragOver();
  133. this.isOutside = false;
  134. this.parentNode.removeChild( this );
  135. container.appendChild( this );
  136. break;
  137. }
  138. container = container.nextContainer;
  139. }
  140. // if we're not in any container now, make a temporary clone of
  141. // the previous container node and add it to the document
  142. if (this.isOutside) {
  143. var tempParent = this.parentNode.cloneNode( false );
  144. this.parentNode.removeChild( this );
  145. tempParent.appendChild( this );
  146. // body puts a border or item at bottom of page if do not have this
  147. tempParent.style.border = 0;
  148. document.getElementsByTagName( "body" ).item(0).appendChild( tempParent );
  149. return;
  150. }
  151. }
  152. // if we get here, we're inside some container bounds, so we do
  153. // everything the original dragsort script did to swap us into the
  154. // correct position
  155. var parent = this.parentNode;
  156. var item = this;
  157. var next = DragUtils.nextItem(item);
  158. while (next != null && this.offsetTop >= next.offsetTop - 2) {
  159. var item = next;
  160. var next = DragUtils.nextItem(item);
  161. }
  162. if (this != item) {
  163. DragUtils.swap(this, next);
  164. return;
  165. }
  166. var item = this;
  167. var previous = DragUtils.previousItem(item);
  168. while (previous != null && this.offsetTop <= previous.offsetTop + 2) {
  169. var item = previous;
  170. var previous = DragUtils.previousItem(item);
  171. }
  172. if (this != item) {
  173. DragUtils.swap(this, item);
  174. return;
  175. }
  176. },
  177. onDragEnd : function(nwPosition, sePosition, nwOffset, seOffset) {
  178. // if the drag ends and we're still outside all containers
  179. // it's time to remove ourselves from the document or add
  180. // to the trash bin
  181. if (this.isOutside) {
  182. var container = DragDrop.firstContainer;
  183. while (container != null) {
  184. if(container.id == parent_id)
  185. {
  186. break;
  187. }
  188. container = container.nextContainer;
  189. }
  190. this.isOutside = false;
  191. this.parentNode.removeChild( this );
  192. container.appendChild( this );
  193. this.style["top"] = "0px";
  194. this.style["left"] = "0px";
  195. //var container = DragDrop.firstContainer;
  196. //container.appendChild( this );
  197. return;
  198. }
  199. this.parentNode.onDragOut();
  200. this.parentNode.onDragDrop();
  201. this.style["top"] = "0px";
  202. this.style["left"] = "0px";
  203. }
  204. };
  205. var DragUtils = {
  206. swap : function(item1, item2) {
  207. var parent = item1.parentNode;
  208. parent.removeChild(item1);
  209. parent.insertBefore(item1, item2);
  210. item1.style["top"] = "0px";
  211. item1.style["left"] = "0px";
  212. },
  213. nextItem : function(item) {
  214. var sibling = item.nextSibling;
  215. while (sibling != null) {
  216. if (sibling.nodeName == item.nodeName) return sibling;
  217. sibling = sibling.nextSibling;
  218. }
  219. return null;
  220. },
  221. previousItem : function(item) {
  222. var sibling = item.previousSibling;
  223. while (sibling != null) {
  224. if (sibling.nodeName == item.nodeName) return sibling;
  225. sibling = sibling.previousSibling;
  226. }
  227. return null;
  228. }
  229. };