Logo  

CS479/579 - Web Programming II

Displaying ./code/ES/move.html

<!-- A comment -->
<!DOCTYPE html>
<html onmouseup='drop();' onmousemove='move(event);'>
<head>
 <title>  </title>
 <meta charset='utf-8'>
<!--
 <link rel='stylesheet' src='styles.css' type='text/css' />
-->
 <style>
 table { margin-left: 1in; margin-top: .5in; }
 #container {
   width: 200px; height: 300px; border: 1px solid red;
 }
 .item { width: 198px; height: 50px; border: 1px solid black;
      background-color: white;
 }
 .spacer { width: 200px; height: 52px; }
 </style>
 <script>
 var obj = null;
 var spacer = null;
 var spacerpos = 0;

 function offsets(e) {
   var xo = 0, yo = 0;
   do {
     xo += e.offsetLeft;
     yo += e.offsetTop;
   } while (e = e.offsetParent);
   return {xo : xo, yo : yo};
 }

 /**
  * When an element in the class 'item' is clicked on, we remove it from the
  * parent and add it to the document body (so it can be moved outside of the
  * parent element,) as an absolutely positioned element. We create a "spacer"
  * element to replace it and remember where we put the spacer.
  */
 function grab(ev) {
   if (ev.target == undefined) return;
   if (ev.target.className != "item") return;
   // Prevents the copy-paste drag event on the element we're dragging:
   ev.preventDefault();

   // Create the spacer:
   spacer = document.createElement("div");
   spacer.className = "spacer";
   spacer.innerHTML = " This space intentionally left blank";

   // Compute offsets for the target element:
   var off = offsets(ev.target);
   obj = { e: ev.target, xo: ev.clientX - off.xo, yo: ev.clientY - off.yo };
   // c == the parent element:
   var c = obj.e.parentNode;
   // Insert the spacer, then remove the dragged element:
   c.insertBefore(spacer, obj.e);
   c.removeChild(obj.e);

   // Compute the spacers index location in the parent's child node-list:
   for(spacerpos = 0; spacerpos < c.childNodes.length && c.childNodes[spacerpos] != spacer; spacerpos++);

   // Add the removed element to the document.body.  It must be in the DOM
   // somewhere in order to be displayed.
   document.body.appendChild(obj.e);
   obj.e.style.position = "absolute";
   obj.e.style.top = (ev.clientY-obj.yo) + "px";
   obj.e.style.left = (ev.clientX-obj.xo) + "px";
 }

 function drop() {
   if (obj == null) return;
   // Set back to normal static positioning:
   obj.e.style.position = "static";
   obj.e.style.top = "initial";
   obj.e.style.left = "initial";
   var c = document.getElementById("container");
   // Insert before the spacer, then remove the spacer:
   c.insertBefore(obj.e,spacer);
   spacer.parentNode.removeChild(spacer);
   spacer = null;
   obj = null;
 }

 /**
  * We cannot use a mousemove on the container itself as it is blocked by the
  * element we're moving, so we have to do the work in a global move handler.
  */
 function move(ev) {
   if (obj == null) return;
   obj.e.style.top = (ev.clientY-obj.yo) + "px";
   obj.e.style.left = (ev.clientX-obj.xo) + "px";

   // Check if the y mouse coordinate is inside the container:
   var c = document.getElementById("container");
   var off = offsets(c);
   var y = ev.clientY - off.yo;
   // Should probably use the clientHeight for the container rather than 300:
   if (y < 0 || y > 300) return;

   // Find the child node index the mouse is "over":
   for(var yp = 50, i = 0; i < c.childNodes.length && yp < y; i++, yp+=50);

   // If we've gone past the number of nodes:
   if (i == c.childNodes.length) {
     if (c.lastChild != spacer) {
       spacerpos = i-1;
       c.appendChild(spacer);
     }
     return;
   }
   y -= (yp-50);
   // Just put the spacer under the cursor as much as possible:
   if (c.childNodes[i] == spacer) return;
   else {
     console.log(y, yp, i);
     if (i < c.childNodes.length-1) {
       // We use spacerpos to determine if the spacer is above or below this
       // node and adjust the insertion accordingly.
       if (spacerpos > i) c.insertBefore(spacer,c.childNodes[i]);
       else c.insertBefore(spacer,c.childNodes[i+1]);
     } else c.appendChild(spacer);
     spacerpos = i;
   }
 }

 function additem() {
   var item = document.createElement("div");
   item.className = "item";
   item.innerHTML = document.getElementById("name").value;
   document.getElementById("container").appendChild(item);
 }
 </script>
</head>
<body>
<table>
<tr><td>
<!-- Make sure there are no text nodes (i.e. any whitespace, etc,) in the 'container' -->
<div id='container' onmousedown='grab(event);' ><div class='item'> Item 1</div><div class='item'> Item 10</div><div class='item'> Item 5</div></div>
<tr><td>
<!-- Input and button to add more item elements to the container: -->
<input type='text' id='name'><br>
<button onclick='additem();'> Add something </button>
</table>
</body>
</html>