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

Ticket #6776 (new defect)

Opened 1 year ago

Last modified 4 months ago

Broken overflow support for droppables

Reported by: dalyons Assigned to: madrobby
Priority: normal Milestone: 2.x
Component: script.aculo.us Version: edge
Severity: major Keywords: overflow div droppables dragdrop
Cc: tomg

Description

First posted on google groups Here, Thomas Fuchs said it might be a bug so i'll open a ticket.

Ive seen this posted numerous times all over the web, but noone seems to have a solution.

In short, if there are droppables inside a scrollable div (overflow auto or scroll), all the 'hidden' divs in that scroll (not viewable unless you scroll down to them) are still present as invisible drop targets. Its kind of hard to explain, heres a simple example as i dont know how to post code.

Theres a Scrolling div with height 1 line. It has 3 'lines' of divs in it. Like: <div style="overflow:auto; height: 1em">

<div id=l1> line1 </div>

<div id=l2> line2 </div> <div id=l3> line3 </div>

</div>

<div id=dragme> Drag me </div>

So when it loads only "line1" is visible. Cool so far. Then you make l1-l3 droppables and dragme a draggable.

The problem is "dragme" can be dropped onto line2 and line3, even when they are not visible, just by letting go of the draggable underneath the scrolling box. You shouldn't be able to drop onto something that isn't supposed to be there! Major problem when using d&d with a database app, as you can inadvertently move a record somewhere by accident quite easily.

I think its something to do with the isAffected method, somehow the checking to see whether the drag element is inside the drop elements' parent's scrolling viewport is not working. I dont know enough js to fix it though. I have tried replacing Position.within with Position.withinIncludingScrolloffsets Dosent seem to help, even with a Position.prepare before hand. I have like wise tried many fixes in other scrolling related d&d tickets, none help.

Attachments

test.htm (10.3 kB) - added by dalyons on 12/06/06 22:14:59.
Simplified test case
test.html (12.0 kB) - added by cowboycoder on 01/17/08 21:14:44.
More Advanced Test case with fix.
dragdrop.js (31.3 kB) - added by cowboycoder on 01/17/08 21:15:59.
New DragDrop changes to make advanced test case work.

Change History

12/06/06 22:14:59 changed by dalyons

  • attachment test.htm added.

Simplified test case

12/06/06 22:19:25 changed by dalyons

I added an attachment with a simplified example. Dunno if i've done it the right way - first RoR bug submit here :P. Just put it in the same folder as the dragdrop.js and prototype.js.

It has a scroll box with 30 divs in it labeled "line1" - "line30" that are all made drop targets.

The draggable "dragme" can be dropped on the whitespace underneath this and still register a drop, as shown by the text in the message box.

12/06/06 22:55:15 changed by tomg

  • cc set to tomg.
  • keywords changed from overflow div droppables to overflow div droppables dragdrop.

12/09/06 18:50:47 changed by madrobby

  • owner changed from sam to madrobby.
  • version changed from 1.1.6 to edge.
  • component changed from Prototype to script.aculo.us.

(in reply to: ↑ description ) 04/25/07 05:19:25 changed by woranl

Replying to dalyons:

First posted on google groups Here, Thomas Fuchs said it might be a bug so i'll open a ticket. Ive seen this posted numerous times all over the web, but noone seems to have a solution. In short, if there are droppables inside a scrollable div (overflow auto or scroll), all the 'hidden' divs in that scroll (not viewable unless you scroll down to them) are still present as invisible drop targets. Its kind of hard to explain, heres a simple example as i dont know how to post code. Theres a Scrolling div with height 1 line. It has 3 'lines' of divs in it. Like: <div style="overflow:auto; height: 1em"> <div id=l1> line1 </div> <div id=l2> line2 </div> <div id=l3> line3 </div> </div> <div id=dragme> Drag me </div> So when it loads only "line1" is visible. Cool so far. Then you make l1-l3 droppables and dragme a draggable. The problem is "dragme" can be dropped onto line2 and line3, even when they are not visible, just by letting go of the draggable underneath the scrolling box. You shouldn't be able to drop onto something that isn't supposed to be there! Major problem when using d&d with a database app, as you can inadvertently move a record somewhere by accident quite easily. I think its something to do with the isAffected method, somehow the checking to see whether the drag element is inside the drop elements' parent's scrolling viewport is not working. I dont know enough js to fix it though. I have tried replacing Position.within with Position.withinIncludingScrolloffsets Dosent seem to help, even with a Position.prepare before hand. I have like wise tried many fixes in other scrolling related d&d tickets, none help.

First of all, I'm not a good JS programer. But since I was experiencing with this bug before, I made myself a quick and dirty workaround in dragdrop.js.

isAffected: function(point, element, drop) {
	/*Start of my workaround...*/
	if (element.classNames()=="My_Draggable_Classname"){
	  var tlc = Position.cumulativeOffset($('My_Overflow_Div')); 
	  Position.within(element, tlc[0], tlc[1] + element.getDimensions().height); 
	if (Position.overlap('vertical', element)<0 | Position.overlap('horizontal', element)<0 | Position.overlap('vertical', element)>SomeOffset)
           {return false;}
	}
	/*...End of my workaround*/
	return (
      (drop.element!=element) &&
      ((!drop._containers) ||
        this.isContained(element, drop)) &&
      ((!drop.accept) ||
        (Element.classNames(element).detect( 
          function(v) { return drop.accept.include(v) } ) )) &&
      Position.within(drop.element, point[0], point[1]) );
  },

Adjust "SomeOffset" depending on your overflow div dimension. In my case I use 4.23. Anyway, I hope this can at least give a kick start toward a better fix.

01/17/08 21:13:01 changed by cowboycoder

I have written a fix for this. I am unsure on how to submit it. But I will try to get it submitted this weekend.

01/17/08 21:14:44 changed by cowboycoder

  • attachment test.html added.

More Advanced Test case with fix.

01/17/08 21:15:59 changed by cowboycoder

  • attachment dragdrop.js added.

New DragDrop changes to make advanced test case work.