Link to home
Start Free TrialLog in
Avatar of Morten Brockhoff
Morten Brockhoff

asked on

addeventlistener problem

Hi Experts,

I attempt to create draggable Div containers on a page using the following idea:

The div tag has an onmousedown that calls a function assigning an addeventlistener mousemove to the container
The mousemove calls another function that should get the e.pageX, e.pageY of the pointer and change the container top/left with the output (using the mousemove)
But this method only works if you embed the e.pageX, e.pageY events in the listener itself - not if you call it outside the function. Then it only fires every onmousedown and then forget mousemove.

Why is that?
 
heres the code:
function DragBox(e, Ct){ // this is called from the div onmousedown
	
	var iBox = document.getElementById('addbox'+Ct); // I need to work with multiple boxes on the page, each with a counter = Ct as identifier

		iBox.addEventListener('mousemove', MoveBox(e, iBox), false);

	}

function MoveBox(e, iBox){

	e = e || window.event;
	var Dx = e.pageX, Dy = e.pageY;

		iBox.style.left = Dx-10;
		iBox.style.top = Dy-10;
}

Open in new window


Best regards
Morten B
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

I don't understand your code - is there more to it?

Usually you have a mousedown, mousemove event.

Here is a simple example
CSS
.dragBox {
  position: absolute;
  border: 1px solid blue;
  display: inline-block;
}

Open in new window

HTML
<div class="dragBoxContainer" style="position: relative; overflow: hidden; height: 500px">
  <div class="dragBox">This is my box</div>
  <div class="dragBox" style="left: 100px">This is my other box</div>
</div>

Open in new window

jQuery to bind to draggables
$(function() {
  // Bind to the plugin
  $('.dragBox').dragBox()
});

Open in new window

jQuery Plugin code
(function($) {
  $.fn.dragBox = function() {
    this.each(function(i, e) {
      e.addEventListener('mousedown', dragging);
    });
    
    return this;
    
    function dragging(e)
    {
      // Create an object on the document to store the current
      // drag information
      // target: element being dragged
      // event: last mouse event
      
      document.dragInfo = {
        target: this,
        event: e
      }
      
      // Setup the workers
      document.addEventListener('mouseup', stopDragging);
      document.addEventListener('mousemove', dragMe);
      
    }
    
    function stopDragging(e)
    {
      // Tidy up after ourselves
      document.removeEventListener('mouseup', stopDragging);
      document.removeEventListener('mousemove', dragMe);
      document.dragInfo = null;
    }
    
    function dragMe(e)
    {
      // Get the current dragInfo out of the document
      
      var source = this.dragInfo;
      var left = source.event.clientX - e.clientX;
      var top = source.event.clientY - e.clientY;
      
      // Save the event for the next move
      source.event = e;
      
      // ensure we don't go outside the bounds (top and left) of the parent
      var newTop = source.target.offsetTop > top ? source.target.offsetTop - top : 0;
      var newLeft = source.target.offsetLeft > left ? source.target.offsetLeft - left : 0;
      
      source.target.style.top = newTop + 'px';
      source.target.style.left = newLeft + 'px';
    }
  }
}(jQuery));

Open in new window

Working sample here
Avatar of Morten Brockhoff
Morten Brockhoff

ASKER

Thanks for being with me Julian,

I am out of office till tomorrow, where I will try your suggestion and continue the question.

Best
Hi again,

the example works fine on its own, but when i attempt to implement it in my site it fails.

I append a <div class="dragBox"...></div> to a specified div (id="FloorPlan"<%=Ct%>") using the javascript below:  

function addLocaleNumbers(cX, cY){
	
	//introduce restraints on Y positions
	cY = Math.round(cY / 10) * 10
	
	//get position and size of div containing  image
	var imgX = document.getElementById('imgDivX').value
	var imgY = document.getElementById('imgDivY').value
	var imgW = document.getElementById('imgDivW').value
	var imgH = document.getElementById('imgDivH').value
		var x = parseInt(imgX) +parseInt( imgW)
		var y = parseInt(imgY) +parseInt( imgH)
		if(cX >= x){return false}
		if(cX <= imgX){return false}
		if(cY >= y){return false}
		if(cY <= imgY){return false}
		
	//get TOTAL AMOUNT OF CLICKS
	var Ct = document.getElementById('CurrentCt').value;
	var floorDiv = document.getElementById('FloorPlan'+Ct)

//CALCULATE HORISONTAL CENTERLINE OF THE IMAGECONTAINER
	var 	midLine = parseInt(imgY)+parseInt(imgH)/2
	var 	addLineTop
//	alert(midLine)
	var ouMidline
	if(cY <= midLine){ouMidline = -180; addLineTop = -180; }else{ouMidline = 80; addLineTop = 0;}
	//store variables in hidden inputs
		var clicks = document.getElementById('clicks');
		var NoClicks = parseInt(clicks.value)+1
		var posArr = []
			
			for(i=0;i<=NoClicks;i++){
			posArr.push(i)
			
			}

	document.getElementById('clicks').value = NoClicks
	document.getElementById('clickArr').value = posArr
	
	var CClass = document.getElementById('CategoryClass').value;
			
			var addBox = '\
						<div id="addInfo' + NoClicks + '" class="' + CClass + '" name="addInfo' + NoClicks + '" style="position:absolute; top:' + (imgH-y + ouMidline) + 'px; left:' + (imgW-x) + 'px; height:100px; width:100px; border:thin solid; background-color:#EFFFFF; font-size:8px;text-align:center;" onmouseover="markInfoBox(' + NoClicks + ', 2)" onclick="stopProp(event, this);" >\
						<Div id="InfoClass'+ NoClicks + '" style="font-size:8px; width:90px;">'+ CClass + '</div>\
						<input type="text" id="localeNr'+ NoClicks + '" name="localeNr'+ NoClicks + '" value="' + NoClicks + '" style="font-size:8px; width:16px;" onclick="openItems('+NoClicks+')" onblur="setInfo(' + NoClicks + ')">\
						<input type="text" id="' + CClass + 'Type'+ NoClicks + '" name="' + CClass + 'Type'+ NoClicks + '" value="' + CClass + 'type" style="font-size:8px; width:67px;">\
						<input type="text" id="' + CClass + 'Name'+ NoClicks + '" name="' + CClass + 'Name'+ NoClicks + '" value="' + CClass + 'navn" style="font-size:8px; width:90px;">\
						<input type="text" id="' + CClass + 'User'+ NoClicks + '" name="' + CClass + 'User'+ NoClicks + '" value="' + CClass + 'bruger" style="font-size:8px; width:90px;">\
						<input type="text" id="' + CClass + 'Xpos'+ NoClicks + '" name="' + CClass + 'Xpos'+ NoClicks + '" value="' + cX + '" style="font-size:8px; width:30px;">\
						<input type="text" id="' + CClass + 'Ypos'+ NoClicks + '" name="' + CClass + 'Ypos'+ NoClicks + '" value="' + cY + '" style="font-size:8px; width:30px;">\
						<img src="delete.png" id="delBox' + CClass + '" height="16px" style="position:absolute; top:90%; left:90%; cursor:pointer;" onclick="removeBox(' + NoClicks + ');" >\
						</div>\
						<div id="addLine' + NoClicks + '" name="addLine' + NoClicks + '" style="position:absolute; top:' + (imgH-y + addLineTop) + 'px; left:' + (imgW-x) + 'px; height:180px; width:1px; background-color:#333333;"></div>\
						<div class="add" id="add' + NoClicks + '" name="add' + NoClicks + '" style="position:absolute; top:' + (imgH-y) + 'px; left:' + (imgW-x) + 'px; font-size:8px;text-align:center; border:thin solid; width:16px; cursor:default;" onmouseover="markInfoBox(' + NoClicks + ', 2)" onclick="stopProp(event, this);">' + NoClicks + '</div>\
						'

					var addInputDiv = document.createElement('div');

						addInputDiv.id = 'addbox'+NoClicks;
						addInputDiv.className = 'dragBox';
						addInputDiv.style.position = 'absolute';
						addInputDiv.style.top = parseInt(cY) + 'px';
						addInputDiv.style.left = parseInt(cX) + 'px';
						addInputDiv.style.zIndex = 1;
						addInputDiv.innerHTML = addBox;
						
							floorDiv.appendChild(addInputDiv);

}

Open in new window


The dragBox appears correctly but cannot bind to the jQuery from within the Floorplan* div.
ASP/HTML-code here:
<!-- FLOOR PLAN RECORDSET -->
<% dim ct, displayed
ct = 0

	do while not rsFloors.EOF
	
	ct = ct+1
	if ct = 1 then
	displayed = "block"
	else
	displayed = "none"
	end if
	%>

	<!-- FLOOR PLAN EDITOR -->
        <div id="Del<%=ct%>"  style="position:absolute; top:<%=190+(22*ct)%>px; left:20px; padding:5px; width:400px; height:auto; background-color:#EFFFFF; visibility:hidden; z-index:2;">
        <input type="checkbox" id="delThis<%=ct%>" onClick=" PrepDel(); delPlan(<%=rsFloors("IdFloorPlans")%>);">
        <a href="#" onClick="Displayfloor(<%=ct%>);"><%=rsFloors("FPname")%></a>
        </div>
	<!-- FLOOR PLAN CLICKABLE IMAGES -->


        <div id="FloorPlan<%=ct%>" style="position:absolute; top:280px; left:250px; border:thin solid #99EEEE; display:<%=displayed%>;">
        <div style="position:absolute; top:51%; left:0px; height:1px; width:100%; background-color:#99EEEE;"></div>
        <input type="hidden" id="FloorPlanId<%=ct%>" value="<%=rsFloors("idFloorPlans")%>" />



        <p style="position:absolute; top:-230px; left:-242px; font-size:24px;">
        Bygning <%=replace(rsFloors("FPname"), ".jpg", "")%></p>
        
        <img id="floorImg<%=ct%>" src="<%=rsFloors("FPpath")%>" width="950px" style="cursor:pointer; z-index:1;" onClick="init(<%=ct%>)" />
        </div>

			<%
            rsFloors.movenext
            loop
            %>

Open in new window


I hope this makes sense.

Best Morten
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yess! thank you - it now works like a charm.

You saved my day

Best regards
Morten
Do you still reward helpful experts with points? - i cant seem to find a way to do that...
You are welcome  (seems you found the points assignment)
I did? by clicking the "best solution" maybe :)
Yup and that all worked - there is now the "accepted" green border around my post indicating that a solution has been found and points assigned.