Have an issue with dragging large items to top-most or bottom-most positions.
Demo: http://jsfiddle.net/vladimir_ze/b2Q9b/17/
Before sorting (on start
event) I decrease element size to make sorting large elements easy, but it seems that the calculation still done with element original height (before I set it to smaller size).
Any ideas how to solve that?
Updated
I came across an interesting link (jQuery UI : Before start draggable) recently while searching for if I can change element height before start
event, and it turns out it possible to extend sortable with beforeStart event.
var oldMouseStart = $.ui.sortable.prototype._mouseStart;
$.ui.sortable.prototype._mouseStart = function (event, overrideHandle, noActivation) {
this._trigger('beforeStart', event, this._uiHash());
oldMouseStart.apply(this, [event, overrideHandle, noActivation]);
};
When beforeStart
fires I apply class to minimize the item and also make a call to .sortable('refresh')
.
Here's the result: http://jsfiddle.net/vladimir_ze/b2Q9b/18/ It still a bit buggy but it works good if you start dragging from the top edge.
This seems to be a bug in jquery which is already logged.
Fix for it will be available in the version 1.12. Meanwhile you can add the below code to your script as proposed in this link.Working fiddle.
$.widget("ui.sortable", $.extend({}, $.ui.sortable.prototype, {
_mouseDrag: function(event) {
var i, item, itemElement, intersection,
o = this.options,
scrolled = false,
touchingEdge;
//Compute the helpers position
this.position = this._generatePosition(event);
this.positionAbs = this._convertPositionTo("absolute");
if (!this.lastPositionAbs) {
this.lastPositionAbs = this.positionAbs;
}
//Do scrolling
if(this.options.scroll) {
if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
}
if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
}
} else {
if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
}
if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
}
}
if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
$.ui.ddmanager.prepareOffsets(this, event);
}
}
//Regenerate the absolute position used for position checks
this.positionAbs = this._convertPositionTo("absolute");
//Set the helper position
if(!this.options.axis || this.options.axis !== "y") {
this.helper[0].style.left = this.position.left+"px";
}
if(!this.options.axis || this.options.axis !== "x") {
this.helper[0].style.top = this.position.top+"px";
}
// Check if the helper is touching the edges of the containment.
if(this.containment) {
if((this.positionAbs.left === this.containment[0] || this.options.axis === "y") &&
(this.positionAbs.top === this.containment[1] || this.options.axis === "x")) {
touchingEdge = 0;
this.direction = "down";
}
else if((this.positionAbs.left === this.containment[2] || this.options.axis === "y") &&
(this.positionAbs.top === this.containment[3] || this.options.axis === "x")) {
touchingEdge = this.items.length - 1;
this.direction = "up";
}
}
if(touchingEdge !== undefined && this.helper[0] !== this.items[touchingEdge].item[0]) {
// Rearrange, if the helper is touching the edge of the containment and not
// already the item at the edge.
this._rearrange(event, this.items[touchingEdge], false);
this._trigger("change", event, this._uiHash());
} else {
//Rearrange
for (i = this.items.length - 1; i >= 0; i--) {
//Cache variables and intersection, continue if no intersection
item = this.items[i];
itemElement = item.item[0];
intersection = this._intersectsWithPointer(item);
if (!intersection) {
continue;
}
// Only put the placeholder inside the current Container, skip all
// items from other containers. This works because when moving
// an item from one container to another the
// currentContainer is switched before the placeholder is moved.
//
// Without this, moving items in "sub-sortables" can cause
// the placeholder to jitter beetween the outer and inner container.
if (item.instance !== this.currentContainer) {
continue;
}
// cannot intersect with itself
// no useless actions that have been done before
// no action if the item moved is the parent of the item checked
if (itemElement !== this.currentItem[0] &&
this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
!$.contains(this.placeholder[0], itemElement) &&
(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
) {
this.direction = intersection === 1 ? "down" : "up";
if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
this._rearrange(event, item);
} else {
break;
}
this._trigger("change", event, this._uiHash());
break;
}
}
}
//Post events to containers
this._contactContainers(event);
//Interconnect with droppables
if($.ui.ddmanager) {
$.ui.ddmanager.drag(this, event);
}
//Call callbacks
this._trigger("sort", event, this._uiHash());
this.lastPositionAbs = this.positionAbs;
return false;
}
}));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With