Advanced Search

Results 1 to 7 of 7

Thread: Drag and Drop Script - Problem dragging an object over scrollbar

  1. #1
    Join Date
    Jan 2006
    Posts
    6
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Drag and Drop Script - Problem dragging an object over scrollbar

    I have used your drag and drop script ... it's helpful ... I could drag and drop things already. I have a problem though, it doesn't drag over a scrollbar ... here's the scenario ... I have a 'div A' (whose style.overflow = auto) containing an item or obj to be dragged and dropped to another 'div B'. I can drag the item in 'div A' but when it comes across div A's scrollbar, I couldn't drag it anymore, hence I couldn't drop it to 'div B'. I disabled div A's vertical scrollbar by setting its overflow to blank dynamically, and I was able to drag it across and drop it in div B. But it's not the correct solution since disabling the scrollbar causes div A to expand, destroying the layer design and layout. How can I drag an object over a scrollbar? Pls. help. Thanks!

  2. #2
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    28,677
    Thanks
    43
    Thanked 3,126 Times in 3,092 Posts
    Blog Entries
    12

    Default

    I really don't think you can but, I could be wrong. If you post a link to your page and the script, I will play with it and see what might be done. One thought, instead of disabling the scrollbar by setting overflow to blank, try disabling it by setting the overflow to 'hidden'. If you can do this just temporarily, during the dragging process, it will not throw off the layout so much and in fact, any distortions to the layout could be compensated for by temporarily adding a border, margin or padding perhaps, to the division.

    Warning: Please include a link to the DD script in question in your post. See this thread for the proper posting format for asking a question.
    PLEASE: Include the URL to your problematic webpage that you want help with.

    Also, there is another drag and drop unit that might not have that problem:

    http://www.walterzorn.com/dragdrop/dragdrop_e.htm
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  3. #3
    Join Date
    Jan 2006
    Posts
    6
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Hi, thanks for replying. I have tried using 'hidden' as overflow value but it didn't work coz the scrollbar was only hidden from view. I have attached dd_drag_drop.html.txt file ... pls. remove .txt extension (the file attachment tool here doesn't consider html as valid file type). I will also try the 'walter_zorn' link and see if it works. I would really appreciate your help. Thanks again.

  4. #4
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    28,677
    Thanks
    43
    Thanked 3,126 Times in 3,092 Posts
    Blog Entries
    12

    Default

    The reason your demo has problems is twofold. In no particular order, the overflow:auto that initializes a scrollbar does cause problems for Mozilla based browsers because they then see the division as a mini page from which no element can escape. If you drag it beyond its borders, it scrolls to accommodate but the dragged item goes underneath the rest of the page. This was not a problem in IE. In both browsers however, using position absolute (or relative in tests here) for the scrolling (and/or potential destination areas) division caused problems because the dragged element was still tied to the absolutely positioned element. I found that by removing the draggable element from the document tree and appending it to the body took care of this problem but, I still cannot figure out how to initially position it at the start of drag. I'm currently using the click event's x/y coords minus half the object's width and height, respectively. This worked fairly well but, causes it to jump to a position where the pointer is at the object's center regardless of where the pointer was at drag start.

    I also have been playing with Zorn's unit and find that it works well as long as the position property on other elements on the page is not set via css style. Zorn's unit has many options that I have not fully explored yet so, there may be a way to get it to work even with other elements on the page having a position property other than static.

    Back to my method for a moment, once the element is freed from the DOM of its parent and attached to the body, it would be nice to find a way to 'dock' it to the element that it is released over. I will be looking into this and initializing its drag position more intuitively. Here is what I have so far (css position style is now set by the script so is not required in the element's tag):

    Code:
    /**************************************************
     * dom-drag.js
     * 09.25.2001
     * www.youngpup.net
     * Script featured on Dynamic Drive (http://www.dynamicdrive.com) 12.08.2005
     **************************************************
     * 10.28.2001 - fixed minor bug where events
     * sometimes fired off the handle, not the root.
     **************************************************/
    var flag=1
    var Drag = {
    
    	obj : null,
    
    	init : function(o, oRoot, minX, maxX, minY, maxY, bSwapHorzRef, bSwapVertRef, fXMapper, fYMapper)
    	{
    		o.onmousedown	= Drag.start;
    
    		o.hmode			= bSwapHorzRef ? false : true ;
    		o.vmode			= bSwapVertRef ? false : true ;
    
    		o.root = oRoot && oRoot != null ? oRoot : o ;
    
    		if (o.hmode  && isNaN(parseInt(o.root.style.left  ))) o.root.style.left   = "0px";
    		if (o.vmode  && isNaN(parseInt(o.root.style.top   ))) o.root.style.top    = "0px";
    		if (!o.hmode && isNaN(parseInt(o.root.style.right ))) o.root.style.right  = "0px";
    		if (!o.vmode && isNaN(parseInt(o.root.style.bottom))) o.root.style.bottom = "0px";
    
    		o.minX	= typeof minX != 'undefined' ? minX : null;
    		o.minY	= typeof minY != 'undefined' ? minY : null;
    		o.maxX	= typeof maxX != 'undefined' ? maxX : null;
    		o.maxY	= typeof maxY != 'undefined' ? maxY : null;
    
    		o.xMapper = fXMapper ? fXMapper : null;
    		o.yMapper = fYMapper ? fYMapper : null;
    
    		o.root.onDragStart	= new Function();
    		o.root.onDragEnd	= new Function();
    		o.root.onDrag		= new Function();
    	},
    
    	start : function(e)
    	{
    		var o = Drag.obj = this;
    		e = Drag.fixE(e);
    		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
    		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
    		o.root.onDragStart(x, y);
    
    		o.lastMouseX	= e.clientX;
    		o.lastMouseY	= e.clientY;
    
    		if (o.hmode) {
    			if (o.minX != null)	o.minMouseX	= e.clientX - x + o.minX;
    			if (o.maxX != null)	o.maxMouseX	= o.minMouseX + o.maxX - o.minX;
    		} else {
    			if (o.minX != null) o.maxMouseX = -o.minX + e.clientX + x;
    			if (o.maxX != null) o.minMouseX = -o.maxX + e.clientX + x;
    		}
    
    		if (o.vmode) {
    			if (o.minY != null)	o.minMouseY	= e.clientY - y + o.minY;
    			if (o.maxY != null)	o.maxMouseY	= o.minMouseY + o.maxY - o.minY;
    		} else {
    			if (o.minY != null) o.maxMouseY = -o.minY + e.clientY + y;
    			if (o.maxY != null) o.minMouseY = -o.maxY + e.clientY + y;
    		}
    
    		document.onmousemove	= Drag.drag;
    		document.onmouseup		= Drag.end;
    		document.onmousedown=function(e){
    		if (typeof e == 'undefined') e = window.event;
    		tempx=e.clientX
    		tempy=e.clientY
    		}
    
    		return false;
    	},
    
    	drag : function(e)
    	{
    		e = Drag.fixE(e);
    		var o = Drag.obj;
    		if (flag){
    		var tw=Math.floor(o.offsetWidth/2),
    		th=Math.floor(o.offsetHeight/2);
    		o.parentNode.removeChild(o);
    		o.style.position='absolute'
    		o.style.left=tempx-tw+'px'
    		o.style.top=tempy-th+'px'
    		document.getElementsByTagName('body')[0].appendChild(o)
    		flag=0
    		}
    
    		var ey	= e.clientY;
    		var ex	= e.clientX;
    		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
    		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
    		var nx, ny;
    
    		if (o.minX != null) ex = o.hmode ? Math.max(ex, o.minMouseX) : Math.min(ex, o.maxMouseX);
    		if (o.maxX != null) ex = o.hmode ? Math.min(ex, o.maxMouseX) : Math.max(ex, o.minMouseX);
    		if (o.minY != null) ey = o.vmode ? Math.max(ey, o.minMouseY) : Math.min(ey, o.maxMouseY);
    		if (o.maxY != null) ey = o.vmode ? Math.min(ey, o.maxMouseY) : Math.max(ey, o.minMouseY);
    
    		nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
    		ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));
    
    		if (o.xMapper)		nx = o.xMapper(y)
    		else if (o.yMapper)	ny = o.yMapper(x)
    
    		Drag.obj.root.style[o.hmode ? "left" : "right"] = nx + "px";
    		Drag.obj.root.style[o.vmode ? "top" : "bottom"] = ny + "px";
    		Drag.obj.lastMouseX	= ex;
    		Drag.obj.lastMouseY	= ey;
    
    		Drag.obj.root.onDrag(nx, ny);
    		return false;
    	},
    
    	end : function()
    	{
    		flag=1;
    		document.onmousemove = null;
    		document.onmouseup   = null;
    		Drag.obj.root.onDragEnd(	parseInt(Drag.obj.root.style[Drag.obj.hmode ? "left" : "right"]), 
    									parseInt(Drag.obj.root.style[Drag.obj.vmode ? "top" : "bottom"]));
    		Drag.obj = null;
    	},
    
    	fixE : function(e)
    	{
    		if (typeof e == 'undefined') e = window.event;
    		if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
    		if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
    		return e;
    	}
    };
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  5. #5
    Join Date
    Jan 2006
    Posts
    6
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Thanks for the explanation, John! I'm really learning a lot. I'll try attaching the draggable element to the body, and find a way as you said to 'dock' it to the element that it is released over. I'll also use the updated dom-drag script.

  6. #6
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    28,677
    Thanks
    43
    Thanked 3,126 Times in 3,092 Posts
    Blog Entries
    12

    Default

    Well, I think I've got it, at least a tailor-made solution. I simplified your markup:

    HTML Code:
    <html>
    	<head>
    		<style type="text/css">
    
    		.drag{
    		cursor:pointer;
    		z-index: 100;
    		}
    
    		</style>
    
    		<script type="text/javascript" src="dom_drag.js">
    
    		</script>
    	</head>
    	<body>
    			<div id="renderingCanvas" style="float:right;position:relative; width: 69.5%!important;width:70%; height: 344px; border: 1px solid black; background-color: gray;">
    				hello
    
    			</div>
    			<div id='folder_panel' style="position:relative; float:left; width: 30%; height: 344px; background-color: white;  border: 1px solid black; overflow: auto; " >
    				<span>Test 1</span><br>
    				<span>Test 2</span><br>
    				<span>Test 3</span><br>
    				<span>Test 4</span><br>
    				<span>Test 5</span><br>
    				<span>Test 1</span><br>
    				<span>Test 2</span><br>
    				<span>Test 3</span><br>
    				<span>Test 4</span><br>
    				<div class="drag" style="width: 100px; height: 50px; border: 1px solid black; background-color: blue; color: white; font-size: 120%">Draggable DIV 111</div>			<span>Test 5</span><br>
    				<span>Test 1</span><br>
    				<span>Test 2</span><br>
    				<span>Test 3</span><br>
    				<span>Test 4</span><br>
    				<span>Test 5</span><br>
    				<span>Test 1</span><br>
    				<span>Test 2</span><br>
    				<span>Test 3</span><br>
    				<span>Test 4</span><br>
    				<span>Test 5</span><br>
    				<div class="drag" style="width: 100px; height: 50px; border: 1px solid black; background-color: blue; color: white; font-size: 120%">Draggable DIV 222</div>
    				<div class="drag" style="width: 100px; height: 50px; border: 1px solid black; background-color: blue; color: white; font-size: 120%">Draggable DIV 333</div>
    			</div>
    			<!-- end of renderDiv -->
    
    <script type="text/javascript">
    var draggers=document.getElementsByTagName('div')
    for (var i_tem = 0; i_tem < draggers.length; i_tem++)
    if ( draggers[i_tem].className=='drag' )
    Drag.init(draggers[i_tem])
    </script>
    	</body>
    </html>
    and customized the script to it. The script will work with other markups but, the potential dock elements are currently limited to divisions:

    Code:
    /**************************************************
     * dom-drag.js
     * 09.25.2001
     * www.youngpup.net
     * Script featured on Dynamic Drive (http://www.dynamicdrive.com) 12.08.2005
     **************************************************
     * 10.28.2001 - fixed minor bug where events
     * sometimes fired off the handle, not the root.
     **************************************************/
    
    function findPosX(obj)
    {
    	var curleft = 0;
    	if (obj.offsetParent)
    	{
    		while (obj.offsetParent)
    		{
    			curleft += obj.offsetLeft
    			obj = obj.offsetParent;
    		}
    	}
    	else if (obj.x)
    		curleft += obj.x;
    	return curleft;
    }
    
    function findPosY(obj)
    {
    	var curtop = 0;
    	if (obj.offsetParent)
    	{
    		while (obj.offsetParent)
    		{
    			curtop += obj.offsetTop
    			obj = obj.offsetParent;
    		}
    	}
    	else if (obj.y)
    		curtop += obj.y;
    	return curtop;
    }
    
    var Drag = {
    
    	obj : null,
    
    	init : function(o, oRoot, minX, maxX, minY, maxY, bSwapHorzRef, bSwapVertRef, fXMapper, fYMapper)
    	{
    		o.onmousedown	= Drag.start;
    
    		o.hmode			= bSwapHorzRef ? false : true ;
    		o.vmode			= bSwapVertRef ? false : true ;
    
    		o.root = oRoot && oRoot != null ? oRoot : o ;
    
    		if (o.hmode  && isNaN(parseInt(o.root.style.left  ))) o.root.style.left   = "0px";
    		if (o.vmode  && isNaN(parseInt(o.root.style.top   ))) o.root.style.top    = "0px";
    		if (!o.hmode && isNaN(parseInt(o.root.style.right ))) o.root.style.right  = "0px";
    		if (!o.vmode && isNaN(parseInt(o.root.style.bottom))) o.root.style.bottom = "0px";
    
    		o.minX	= typeof minX != 'undefined' ? minX : null;
    		o.minY	= typeof minY != 'undefined' ? minY : null;
    		o.maxX	= typeof maxX != 'undefined' ? maxX : null;
    		o.maxY	= typeof maxY != 'undefined' ? maxY : null;
    
    		o.xMapper = fXMapper ? fXMapper : null;
    		o.yMapper = fYMapper ? fYMapper : null;
    
    		o.root.onDragStart	= new Function();
    		o.root.onDragEnd	= new Function();
    		o.root.onDrag		= new Function();
    	},
    
    	start : function(e)
    	{
    		var o = Drag.obj = this;
    		e = Drag.fixE(e);
    		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
    		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
    		o.root.onDragStart(x, y);
    
    		o.lastMouseX	= e.clientX;
    		o.lastMouseY	= e.clientY;
    
    		if (o.hmode) {
    			if (o.minX != null)	o.minMouseX	= e.clientX - x + o.minX;
    			if (o.maxX != null)	o.maxMouseX	= o.minMouseX + o.maxX - o.minX;
    		} else {
    			if (o.minX != null) o.maxMouseX = -o.minX + e.clientX + x;
    			if (o.maxX != null) o.minMouseX = -o.maxX + e.clientX + x;
    		}
    
    		if (o.vmode) {
    			if (o.minY != null)	o.minMouseY	= e.clientY - y + o.minY;
    			if (o.maxY != null)	o.maxMouseY	= o.minMouseY + o.maxY - o.minY;
    		} else {
    			if (o.minY != null) o.maxMouseY = -o.minY + e.clientY + y;
    			if (o.maxY != null) o.minMouseY = -o.maxY + e.clientY + y;
    		}
    
    		document.onmousemove	= Drag.drag;
    		document.onmouseup		= Drag.end;
    		document.onmousedown=function(e){
    		if (typeof e == 'undefined') e = window.event;
    		var targ=e.srcElement? e.srcElement : e.target
    		var hAdj=wAdj=0
    		var tp=targ
    		while(tp.parentNode){
    		if (typeof tp.parentNode.tagName!=='undefined'&&tp.parentNode.tagName.toLowerCase()=='body')
    		break;
    		if (tp.parentNode.scrollTop)
    		hAdj+=tp.parentNode.scrollTop;
    		if (tp.parentNode.scrollLeft)
    		wAdj+=tp.parentNode.scrollLeft;
    		tp=tp.parentNode;
    		}
    		tempx=findPosX(targ)-wAdj
    		tempy=findPosY(targ)-hAdj
    		}
    
    		return false;
    	},
    
    	drag : function(e)
    	{
    		e = Drag.fixE(e);
    		var o = Drag.obj;
    		if (o.style.position!=='absolute'){
    		if (o.tagName.toLowerCase()=='img') {
    		var placeHolder=document.createElement('img')
    		placeHolder.src='../transparentpixel.gif'
    		placeHolder.width=o.offsetWidth;
    		placeHolder.height=o.offsetHeight;
    		}
    		else {
    		var placeHolder=document.createElement('div')
    		placeHolder.style.width=o.offsetWidth+'px';
    		placeHolder.style.height=o.offsetHeight+'px';
    		}
    		o.parentNode.insertBefore(placeHolder, o);
    		o.parentNode.removeChild(o);
    		o.style.position='absolute'
    		o.style.left=tempx+'px'
    		o.style.top=tempy+'px'
    		document.body.appendChild(o)
    		}
    		
    		else if (o.parentNode.tagName&&o.parentNode.tagName.toLowerCase()!=='body'){
    		o.parentNode.removeChild(o);
    		o.style.left=tempx+'px'
    		o.style.top=tempy+'px'
    		document.body.appendChild(o)
    		}
    
    		var ey	= e.clientY;
    		var ex	= e.clientX;
    		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
    		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
    		var nx, ny;
    
    		if (o.minX != null) ex = o.hmode ? Math.max(ex, o.minMouseX) : Math.min(ex, o.maxMouseX);
    		if (o.maxX != null) ex = o.hmode ? Math.min(ex, o.maxMouseX) : Math.max(ex, o.minMouseX);
    		if (o.minY != null) ey = o.vmode ? Math.max(ey, o.minMouseY) : Math.min(ey, o.maxMouseY);
    		if (o.maxY != null) ey = o.vmode ? Math.min(ey, o.maxMouseY) : Math.max(ey, o.minMouseY);
    
    		nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
    		ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));
    
    		if (o.xMapper)		nx = o.xMapper(y)
    		else if (o.yMapper)	ny = o.yMapper(x)
    
    		Drag.obj.root.style[o.hmode ? "left" : "right"] = nx + "px";
    		Drag.obj.root.style[o.vmode ? "top" : "bottom"] = ny + "px";
    		Drag.obj.lastMouseX	= ex;
    		Drag.obj.lastMouseY	= ey;
    
    		Drag.obj.root.onDrag(nx, ny);
    		return false;
    	},
    
    	end : function()
    	{
    		var dockObj=0, x=findPosX(Drag.obj), y=findPosY(Drag.obj), xe=x+Drag.obj.offsetWidth, ye=y+Drag.obj.offsetHeight;
    		var dockers=document.getElementsByTagName('div')
    		for (var i_tem = 0; i_tem < dockers.length-1; i_tem++)
    		if (x>findPosX(dockers[i_tem])&&xe<findPosX(dockers[i_tem])+dockers[i_tem].offsetWidth-16&&y>findPosY(dockers[i_tem])&&ye<findPosY(dockers[i_tem])+dockers[i_tem].offsetHeight)
    		dockObj=dockers[i_tem]
    		if (dockObj){
    		document.body.removeChild(Drag.obj)
    		Drag.obj.style.left=x-findPosX(dockObj)-parseInt(dockObj.style.borderWidth)+'px'
    		Drag.obj.style.top=y-findPosY(dockObj)+dockObj.scrollTop-parseInt(dockObj.style.borderWidth)+'px'
    		dockObj.appendChild(Drag.obj)
    		}
    		document.onmousemove = null;
    		document.onmouseup   = null;
    		Drag.obj.root.onDragEnd(	parseInt(Drag.obj.root.style[Drag.obj.hmode ? "left" : "right"]), 
    									parseInt(Drag.obj.root.style[Drag.obj.vmode ? "top" : "bottom"]));
    		Drag.obj = null;
    	},
    
    	fixE : function(e)
    	{
    		if (typeof e == 'undefined') e = window.event;
    		if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
    		if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
    		return e;
    	}
    };
    Note: Acts a little oddly in Opera but not too bad, good in IE6 and modern Mozilla.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  7. #7
    Join Date
    Jan 2006
    Posts
    6
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Thanks!!!

    Hi John,

    Thanks a lot for your help, I really appreciate it. I made use of the dom-drag.js that you customized. I learned a lot from your code too.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •