Sortable: Calculating item distance and direction using a more robust algorithm to better support sorting among nested sortables. Fixes #8572 - Wrong placeholder positions. Fixes #8573 - Can't drag an item out of an inner sortable. Fixes #8574 - Hard to put an item between two inner sortables.

Use the item which has the least distance between the mouse
pointer and one of its borders to rearrange, with direction being
determined by the nearest border.
Also we use this algorithm to rearrange even when currentContainer
is not changed to override the defective rearrangment in
_mouseDrag
This commit is contained in:
John Chen 2012-08-17 16:20:45 +08:00 committed by Scott González
parent 20e6064711
commit bae06d2b1e

View File

@ -734,16 +734,26 @@ $.widget("ui.sortable", $.ui.mouse, {
if(this.containers.length === 1) { if(this.containers.length === 1) {
this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
this.containers[innermostIndex].containerCache.over = 1; this.containers[innermostIndex].containerCache.over = 1;
} else if(this.currentContainer != this.containers[innermostIndex]) { } else {
//When entering a new container, we will find the item with the least distance and append our item near it //When entering a new container, we will find the item with the least distance and append our item near it
var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; var dist = 10000; var itemWithLeastDistance = null;
var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top';
var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height';
var base = this.positionAbs[posProperty] + this.offset.click[posProperty];
for (var j = this.items.length - 1; j >= 0; j--) { for (var j = this.items.length - 1; j >= 0; j--) {
if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
var cur = this.containers[innermostIndex].floating ? this.items[j].item.offset().left : this.items[j].item.offset().top; if(this.items[j].item[0] == this.currentItem[0]) continue;
var cur = this.items[j].item.offset()[posProperty];
var nearBottom = false;
if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
nearBottom = true;
cur += this.items[j][sizeProperty];
}
if(Math.abs(cur - base) < dist) { if(Math.abs(cur - base) < dist) {
dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
this.direction = (cur - base > 0) ? 'down' : 'up'; this.direction = nearBottom ? "up": "down";
} }
} }