Skip to content

Commit

Permalink
Sortable: Introduces option containmentElasticity to allow for items …
Browse files Browse the repository at this point in the history
…to move a few pixels outside their containment when dragging; By no means a perfect fix but a possible first stab. Tries fixing #5620 - Sortable along y-axis with parent containment fails to put large item at the bottom of list when dragging
  • Loading branch information
marcusf committed May 24, 2010
1 parent 956f48a commit dc5c4b3
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 5 deletions.
37 changes: 37 additions & 0 deletions tests/visual/sortable/sortable_ticket_5620.html
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Sortable Visual Test : Sortable ticket #5620</title>
<link rel="stylesheet" href="../visual.css" type="text/css" />
<link rel="stylesheet" href="../../../themes/base/jquery.ui.all.css" type="text/css">
<script type="text/javascript" src="../../../jquery-1.4.2.js"></script>
<script type="text/javascript" src="../../../ui/jquery.ui.core.js"></script>
<script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script>
<script type="text/javascript" src="../../../ui/jquery.ui.mouse.js"></script>
<script type="text/javascript" src="../../../ui/jquery.ui.draggable.js"></script>
<script type="text/javascript" src="../../../ui/jquery.ui.droppable.js"></script>
<script type="text/javascript" src="../../../ui/jquery.ui.sortable.js"></script>

<style>
#list div {
width: 100px;
font-size: 12px;
}
</style>

<script type="text/javascript">
jQuery(document).ready(function() { $("#list").sortable({axis: 'y', containment: 'parent', containmentElasticity: true }); });
</script>
</head>
<body>
<div id="list">
<div>Element 1</div>
<div>Element 2</div>
<div>Element 3</div>
<div>Element 4</div>
<div>Very long text Very long text Very long text Very long text Very long text Very long text Very long text Very long text Very long text Very long text Very long text Very long text Very long text Very long text Very long textVery long text</div>
<div>Element 5</div>
</div>
</body>
</html>
32 changes: 27 additions & 5 deletions ui/jquery.ui.sortable.js
Expand Up @@ -21,6 +21,7 @@ $.widget("ui.sortable", $.ui.mouse, {
axis: false,
connectWith: false,
containment: false,
containmentElasticity: false,
cursor: 'auto',
cursorAt: false,
dropOnEmpty: true,
Expand Down Expand Up @@ -183,10 +184,14 @@ $.widget("ui.sortable", $.ui.mouse, {

//Create the placeholder
this._createPlaceholder();

// Clear and reset previous elasticity settings
this._setElasticity();

//Set a containment if given in the options
if(o.containment)
if(o.containment) {
this._setContainment();
}

if(o.cursor) { // cursor option
if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
Expand Down Expand Up @@ -333,6 +338,8 @@ $.widget("ui.sortable", $.ui.mouse, {
//If we are using droppables, inform the manager about the drop
if ($.ui.ddmanager && !this.options.dropBehaviour)
$.ui.ddmanager.drop(this, event);

this._clearElasticity();

if(this.options.revert) {
var self = this;
Expand Down Expand Up @@ -839,6 +846,20 @@ $.widget("ui.sortable", $.ui.mouse, {
height: this.helper.outerHeight()
};
},

_setElasticity: function() {
this._clearElasticity();
var o = this.options;
if (o.containment != 'document' && o.containment != 'window' && o.containmentElasticity) {
var ABSOLUTE_FUDGE = 10;
this._elasticity.x = this.currentItem.width() + ABSOLUTE_FUDGE;
this._elasticity.y = this.currentItem.height() + ABSOLUTE_FUDGE;
}
},

_clearElasticity: function() {
this._elasticity = { x: 0, y: 0 };
},

_setContainment: function() {

Expand Down Expand Up @@ -912,10 +933,11 @@ $.widget("ui.sortable", $.ui.mouse, {
if(this.originalPosition) { //If we are not dragging yet, we won't check for options

if(this.containment) {
if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;

if(event.pageX - this.offset.click.left < this.containment[0] - this._elasticity.x) pageX = this.containment[0] + this.offset.click.left + this._elasticity.x;
if(event.pageY - this.offset.click.top < (this.containment[1] - this._elasticity.y)) pageY = this.containment[1] + this.offset.click.top - this._elasticity.y;
if(event.pageX - this.offset.click.left > this.containment[2] + this._elasticity.x) pageX = this.containment[2] + this.offset.click.left - this._elasticity.x;
if(event.pageY - this.offset.click.top > (this.containment[3] + this._elasticity.y)) pageY = this.containment[3] + this.offset.click.top + this._elasticity.y;
}

if(o.grid) {
Expand Down

2 comments on commit dc5c4b3

@scottgonzalez
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sortable, and all other interaction plugins, are about to undergo a complete rewrite which will remove the majority of their options. At this point we cannot accept a commit that will add another option which will not be included in the rewrite. If you have ideas for how this would ideally work, we'd love to capture that information on the planning wiki (http://wiki.jqueryui.com/Sortable) so we can account for it during the new development.

@marcusf
Copy link
Owner

@marcusf marcusf commented on dc5c4b3 Jun 3, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, basically, how I want it to work is that when I drag an entry to the bottom, it ends up there, regardless of its size relative its peers. I could add that, but it really feels like a bug, and I've supplied a reduced test case and all. This was just my stab at providing a workaround.

Please sign in to comment.