#5920 closed bug (notabug)
oversize draggable
Reported by: | rotkiw | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | 1.9.0 |
Component: | ui.draggable | Version: | 1.8.4 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
If the draggable is bigger than the holder, the draggable is just snap to the edges of the holder.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>draggable test</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.min.js"></script> <script type="text/javascript"> $(document).ready(function() { $('#drag').draggable({ containment: 'parent', //grid: [20, 20] }); }); </script> <style type="text/css"> #holder { width:200px; height: 200px; overflow:hidden; background-color:#CF0; } #drag { width:400px; height: 400px; overflow:hidden; background-color: #C00; } #content { width:390px; height:390px; margin: 5px; background-color:#09F; } </style> </head> <body> <div id="holder"> <div id="drag"> <div id="content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur enim. Nullam id ligula in nisl tincidunt feugiat. Curabitur eu magna porttitor ligula bibendum rhoncus. Etiam dignissim. Duis lobortis porta risus. Quisque velit metus, dignissim in, rhoncus at, congue quis, mi. Praesent vel lorem. Suspendisse ut dolor at justo tristique dapibus. Morbi erat mi, rutrum a, aliquam nec, mattis semper, leo. Maecenas blandit risus vitae quam. Vivamus ut odio. Pellentesque mollis arcu nec metus. Nullam bibendum scelerisque turpis. Aliquam erat volutpat.</div> </div> </div> </body> </html>
solution:
_generatePosition: function(event) { var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); var pageX = event.pageX; var pageY = event.pageY; var flagX = false; var flagY = false; /* * - Position constraining - * Constrain the position to a mix of grid, containment. */ if(this.originalPosition) { //If we are not dragging yet, we won't check for options if(this.containment) { if (((this.containment[2] < 0) && (this.offset.click.left - event.pageX < this.containment[0])) || ((this.containment[2] >= 0) && (event.pageX - this.offset.click.left < this.containment[0]))) { pageX = this.containment[0] + this.offset.click.left; flagX = true; // Prevent jump at oversized draggable element (cursor offset > dragabble width - holder width) } if (((this.containment[3] < 0) && (this.offset.click.top - event.pageY < this.containment[1])) || ((this.containment[3] >= 0) && (event.pageY - this.offset.click.top < this.containment[1]))) { pageY = this.containment[1] + this.offset.click.top; flagY = true; } if ((!flagX && (Math.abs(event.pageX - this.offset.click.left) > Math.abs(this.containment[2]))) || ((this.containment[2] >= 0) && (event.pageX - this.offset.click.left > this.containment[2]))) pageX = this.containment[2] + this.offset.click.left; if ((!flagY && (Math.abs(event.pageY - this.offset.click.top) > Math.abs(this.containment[3]))) || ((this.containment[3] >= 0) && (event.pageY - this.offset.click.top > this.containment[3]))) pageY = this.containment[3] + this.offset.click.top; } if(o.grid) { var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; pageY = this.containment ? (!(Math.abs(top - this.offset.click.top) < this.containment[1] || top - this.offset.click.top > Math.abs(this.containment[3])) ? top : (!(Math.abs(top - this.offset.click.top) < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; pageX = this.containment ? (!(Math.abs(left - this.offset.click.left) < this.containment[0] || left - this.offset.click.left > Math.abs(this.containment[2])) ? left : (!(Math.abs(left - this.offset.click.left) < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; } } return { top: ( pageY // The absolute mouse position - this.offset.click.top // Click offset (relative to the element) - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top // The offsetParent's offset without borders (offset + border) + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) ), left: ( pageX // The absolute mouse position - this.offset.click.left // Click offset (relative to the element) - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left // The offsetParent's offset without borders (offset + border) + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) ) }; },
Attachments (1)
Change History (8)
Changed 12 years ago by
Attachment: | jquery.ui.draggable.js added |
---|
comment:1 Changed 12 years ago by
Resolution: | → invalid |
---|---|
Status: | new → closed |
Containing a draggable inside something that's smaller than the draggable itself doesn't make sense.
comment:2 Changed 12 years ago by
Hi there,
I don't agree with scott's comment - I'm currently encountering this problem as well where my draggable contents is larger than the container element. This happens because I'm creating something with a google maps effect where the user can drag a large div inside a smaller viewport.
I do hope that the jquery devs will consider opening this issue again because there are situations where the draggable element is larger than its parent container (E.g. with overflow:hidden). In the meantime, I'm currently using the Mapbox plugin to circumvent this issue.
Thanks!
comment:3 Changed 12 years ago by
I also disagree with Scott's shortsighted comment--one of the first practical uses that came to mind for draggable elements, was creating a click-and-drag window similar to google maps. Thanks Krazedout for the Mapbox reference, seeing as I will probably use that as well for now.
+1 for Jquery UI devs addressing this ticket in a future release...
comment:4 Changed 12 years ago by
I also disagree with Scott's comment. This seems like a big oversight for 'draggable'. If I have a place where I'm letting someone view a large image in a small area and I want them to be able to drag it around to see the whole image, then I need draggable to be able to support the dragging of a large element inside a small container.
It's the same situation if you open an image in Photoshop, make its window smaller than the image, then use the hand tool to drag the image inside that window. The image is contained within that window.
I think this would be solvable if instead of defining a container box, I would be defining min/max values for the top and left properties. Then I could say that the max left position is "0" (so that I would never be able to move the image towards the right past its left edge).
comment:5 Changed 11 years ago by
Containment smaller than draggable really doesn't make sense. You are talking about "viewport" smaller than draggable. Create helper "containment" block, give this block width = (2 * draggable_width – viewport_width), the same with height, and center this block relative to viewport. Then attach this helper block as "containment". It works OK for me.
However, simplifying setting "min" and "max" coordinates directly via Draggable API properties, not using containment as proxy should be nice.
comment:5 Changed 11 years ago by
Containment smaller than draggable really doesn't make sense. You are talking about "viewport" smaller than draggable. Create helper "containment" block, give this block width = (2 * draggable_width – viewport_width), the same with height and center this block relative to viewport. Then attach this helper block as "containment". It works OK for me.
However, simplifying setting "min" and "max" coordinates directly via Draggable API properties, not using containment as proxy should be nice.
comment:6 Changed 10 years ago by
Milestone: | 1.next → 1.9.0 |
---|
improved draggable