Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #3860 (reopened defect)

Opened 2 years ago

Last modified 9 months ago

Drag & Drop Drag Position is getting corrupted in DIV

Reported by: gkupps@yahoo.com Assigned to: thomas@fesch.at
Priority: high Milestone: 2.x
Component: script.aculo.us Version:
Severity: minor Keywords: dragdrop
Cc:

Description

I have a div with a table inside it.

<DIV STYLE="padding-left: 50pt;">
<DIV STYLE="overflow: auto; width: 250; height: 100;
            border: 1px gray solid;
            padding:0px; margin: 0px;">
<table id="t1" class="sortable mytable">

I'm trying to Drag from this table, it works fine. But if i scroll, the drag does not work. It often shows up below the table. If i scroll a little, the drag is offset(below the table) by a little, if i scroll a lot the drag is offset by a lot. This issue exists in Firefox/IE and Safari.

I'm attaching a sample.


<html>
<head>
<title>Drag &amp; Drop</title>

<style type="text/css">

td
{
 width: 10em;
 text-align: center;
}

table.mytable {
	list-style-type: none;
	padding: 4px 4px 0 4px;
	margin: 0px;
	font-size: 13px;
	font-family: Arial, sans-serif;
}

table.mytable tr {
	margin-bottom: 4px;
	padding: 2px 2px;
	border: 1px solid #c00;
	background-color: #eee;
}

div.draggable {
  cursor:move;
  padding:2px;
  background-color: #BBCCDD;
}

div.dropsite {
  padding:2px;
  background-color: #DDBB99;
}

div.hoverclass123
{
	border:1px solid red;
}

</style>

<script language="JavaScript" type="text/javascript" src="javascripts/prototype.js"></script>
<script language="JavaScript" type="text/javascript" src="javascripts/scriptaculous.js"></script>
<script language="JavaScript" type="text/javascript">

window.onload = function()
{
	var t1 = document.getElementById("t1");
	add_divs(t1, 'td', 'draggable');
	var trs = t1.getElementsByTagName("tr");
	for (var i = 0; i < trs.length; i++)
	{
		var divs = document.getElementsByClassName("draggable", trs[i]);
		var drag_text = divs[2].innerHTML;
		for (var j = 0; j < divs.length; ++j)
		{
			new Draggable(divs[j], {ghosting:true, revert:true});
		}
	}

	var t2 = document.getElementById("t2");
	add_divs(t2, 'td', 'dropsite');
	var divs = document.getElementsByClassName("dropsite", t2);
	for (var j = 0; j < divs.length; ++j)
	{
		Droppables.add(divs[j], {accept:'draggable',
									 hoverclass:'hoverclass123',
									 onDrop:function(element, dropon, event)
										 { debug("dropped " + element.innerHTML + " on "
													+ dropon.innerHTML + "\n")}});
	}
};

function debug(text)
{
   document.getElementById('debug').innerHTML
       = "<pre>" + text + "</pre>";
}

function add_divs(table, tag, classname)
{
	var items = table.getElementsByTagName(tag);
	for (var i = 0; i < items.length; i++)
		items[i].innerHTML =
			"<div class='" + classname + "'>" + items[i].innerHTML + "</div>";
}


</script>
</head>
<body>

<p>Drag from this table:</p>
<DIV STYLE="padding-left: 50pt;">
<DIV STYLE="overflow: auto; width: 250; height: 100;
            border: 1px gray solid;
            padding:0px; margin: 0px;">
<table id="t1" class="sortable mytable">
    <tr><td>one</td><td>1</td><td>uno</td></tr>
    <tr><td>two</td><td>2</td><td>dos</td></tr>
    <tr><td>three</td><td>3</td><td>tres</td></tr>
    <tr><td>four</td><td>4</td><td>quatro</td></tr>
    <tr><td>five</td><td>5</td><td>cinco</td></tr>
    <tr><td>six</td><td>6</td><td>seis</td></tr>
    <tr><td>seven</td><td>7</td><td>siete</td></tr>
    <tr><td>eight</td><td>8</td><td>ocho</td></tr>
    <tr><td>nine</td><td>9</td><td>nueve</td></tr>
    <tr><td>ten</td><td>10</td><td>diez</td></tr>
</table>
</DIV>
</DIV>
<p>
<p>Drop on this table:</p>
<DIV STYLE="padding-left: 50pt;">
<DIV STYLE="overflow: auto; width: 250; height: 100;
            border: 1px gray solid;
            padding:0px; margin: 0px;">
<table id="t2" class="sortable mytable">
    <tr><td>eleven</td><td>11</td><td>once</td></tr>
    <tr><td>twelve</td><td>12</td><td>doce</td></tr>
    <tr><td>thirteen</td><td>13</td><td>trece</td></tr>
    <tr><td>fourteen</td><td>14</td><td>catorce</td></tr>
    <tr><td>fifteen</td><td>15</td><td>quince</td></tr>
    <tr><td>sixteen</td><td>16</td><td>dieciseis</td></tr>
    <tr><td>seventeen</td><td>17</td><td>diecisiete</td></tr>
    <tr><td>eightteen</td><td>18</td><td>dieciocho</td></tr>
    <tr><td>nineteen</td><td>19</td><td>diecinueve</td></tr>
    <tr><td>twenty</td><td>20</td><td>veinte</td></tr>
</table>
</DIV>
</DIV>
<p>
<div id="debug"></div>
</p>
</body>
</html>


   

Attachments

dragdrop_3860.patch (0.6 kB) - added by kennelbound on 05/23/07 17:00:59.

Change History

02/26/06 18:49:38 changed by karsten@oneslistening.com

I've had similar issues when using Sortables and a mixture of fixed position divs and relative position divs. If the page hasn't been scrolled, everything works just dandy. But, once page scolling occurs (fixed position divs stay put; relative move with the page), sortables get shifted on loss of the source div's class. The shift is equal to the amount of page scroll.

05/05/06 18:24:16 changed by andrew.martinez@paetec.com

I *think* this can easily be fixed by calculating the dragged item's total scroll offset to obtain it's true scrolled position durinng the drag routine. I am going to be taking a stab at implementing the drag and drop multiple. If I can see a way to add this in, I will take ownership of this defect and post the patch ASAP.

05/12/06 11:21:23 changed by anonymous

see #5059.

06/27/06 05:49:48 changed by tsukue@gmail.com

The fix described in #5059 does not work on Firefox & Safari, for this particular example. The reason is this:

Somewhere around line 300, dragdrop.js absolutizes the element which is about to be dragged, and then inserts it into its original parent node again.

   if(this.options.ghosting) {
      this._clone = this.element.cloneNode(true);
      Position.absolutize(this.element);
      this.element.parentNode.insertBefore(this._clone, this.element);
    }

But for this example, absolutize() calculates the element's offset (positionedOffset) according to the element's offsetParent (<body>), which is different from "this.element.parentNode" (<td>), which the absolutized element is going to be attached. And as Firefox does not calculate absolute position from its window top-left, the re-inserted element "shifts" by its parentNode's scrolling amount.

This may not be something which dragdrop.js should take care of. May be you should avoid using tables when using sortables with scrolling divs.

07/31/06 13:39:02 changed by anonymous

comment

08/19/06 00:12:55 changed by tomg@byu.net

  • keywords set to dragdrop.

Is this solved by #5017? It appears to be similar.

08/20/06 20:02:13 changed by madrobby

  • status changed from new to closed.
  • resolution set to fixed.

(In [4797]) Fix an issue with redrawing ghosted draggables that are inside a scrolled container, fixes #3860 [thx gkupps, tsukue]

08/22/06 23:13:16 changed by Ian Young

  • status changed from closed to reopened.
  • resolution deleted.
  • severity changed from major to minor.
  • milestone set to 1.x.

Is it just me or does this patch not make any difference on IE 6, but works fine on Firefox / Camino and Safari.

08/23/06 17:03:35 changed by anonymous

draw: function(point) {
    var pos = Position.cumulativeOffset(this.element);
    if(this.options.ghosting) {
      Position.prepare();
      var r   = Position.realOffset(this.element);      
      window.status = r.inspect();
            
      //this is what breaks offset on IE      
      pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
      
    }

(follow-up: ↓ 11 ) 08/23/06 17:07:25 changed by madrobby

We probably need an ugly "if" for IE -- can anyone patch this, and test on IE6 and IE7?

(in reply to: ↑ 10 ) 09/20/06 12:10:10 changed by Metamorph

Replying to Thomas Fuchs <t.fuchs@wollzelle.com>:

We probably need an ugly "if" for IE -- can anyone patch this, and test on IE6 and IE7?

Still not working. IE 6.0.2900

05/23/07 17:00:59 changed by kennelbound

  • attachment dragdrop_3860.patch added.

05/23/07 17:02:03 changed by kennelbound

Attached a fix patch.

Basically the problem is that IE6 requires the use of pageYOffset and pageXOffset if you want to include the scroll in its location.

Patch addresses this.

07/20/07 14:15:54 changed by sokrat3s

It doesn't even work in FF.

09/03/07 21:00:25 changed by danmayer

This is still failing for me in FF 2.0.0.6 on mac and windows.

It fails if your in a scrolling DIV by adding the offset of the scroll onto the position of the element being dragged. After a little bit of scrolling this makes it nearly impossible to place items on the bottom of a list and very confusing to drag and drop the elements.

Has anyone been looking the the scrolling div issue, or have people just been recommending that drag and drop not be used inside of scrollable divs?