mirror of
https://github.com/jquery/jquery-ui.git
synced 2024-11-21 11:04:24 +00:00
sortable,draggable: made connectToSortable work again, now works with multiple sortables (closes #2785)
This commit is contained in:
parent
57266e1ba4
commit
d0d8ee752d
@ -423,89 +423,115 @@
|
|||||||
|
|
||||||
$.ui.plugin.add("draggable", "connectToSortable", {
|
$.ui.plugin.add("draggable", "connectToSortable", {
|
||||||
start: function(e,ui) {
|
start: function(e,ui) {
|
||||||
|
|
||||||
var inst = $(this).data("draggable");
|
var inst = $(this).data("draggable");
|
||||||
inst.sortable = $.data($(ui.options.connectToSortable)[0], 'sortable');
|
inst.sortables = [];
|
||||||
inst.sortableOffset = inst.sortable.element.offset();
|
$(ui.options.connectToSortable).each(function() {
|
||||||
inst.sortableOuterWidth = inst.sortable.element.outerWidth();
|
if($.data(this, 'sortable')) inst.sortables.push({
|
||||||
inst.sortableOuterHeight = inst.sortable.element.outerHeight();
|
instance: $.data(this, 'sortable'),
|
||||||
if(inst.sortable.options.revert) inst.sortable.shouldRevert = true;
|
offset: $.data(this, 'sortable').element.offset(),
|
||||||
|
width: $.data(this, 'sortable').element.width(),
|
||||||
|
height: $.data(this, 'sortable').element.height(),
|
||||||
|
shouldRevert: $.data(this, 'sortable').options.revert
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
stop: function(e,ui) {
|
stop: function(e,ui) {
|
||||||
//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
|
|
||||||
var instDraggable = $(this).data("draggable");
|
|
||||||
var inst = instDraggable.sortable;
|
|
||||||
|
|
||||||
if(inst.isOver) {
|
//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
|
||||||
inst.isOver = 0;
|
var inst = $(this).data("draggable");
|
||||||
instDraggable.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
|
|
||||||
inst.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
|
$.each(inst.sortables, function() {
|
||||||
if(inst.shouldRevert) inst.options.revert = true; //revert here
|
if(this.instance.isOver) {
|
||||||
inst.stop(e);
|
this.instance.isOver = 0;
|
||||||
inst.options.helper = "original";
|
inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
|
||||||
}
|
this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
|
||||||
|
if(this.shouldRevert) this.instance.options.revert = true; //revert here
|
||||||
|
this.instance.mouseStop(e);
|
||||||
|
this.instance.options.helper = "original";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
drag: function(e,ui) {
|
drag: function(e,ui) {
|
||||||
|
|
||||||
//This is handy: We reuse the intersectsWith method for checking if the current draggable helper
|
//This is handy: We reuse the intersectsWith method for checking if the current draggable helper
|
||||||
//intersects with the sortable container
|
//intersects with the sortable container
|
||||||
var instDraggable = $(this).data("draggable");
|
var inst = $(this).data("draggable"), self = this;
|
||||||
var inst = instDraggable.sortable;
|
inst.position.absolute = ui.absolutePosition; //Sorry, this is an ugly API fix
|
||||||
instDraggable.position.absolute = ui.absolutePosition; //Sorry, this is an ugly API fix
|
|
||||||
|
|
||||||
if(inst.intersectsWith.call(instDraggable, {
|
var checkPos = function(o) {
|
||||||
left: instDraggable.sortableOffset.left, top: instDraggable.sortableOffset.top,
|
|
||||||
width: instDraggable.sortableOuterWidth, height: instDraggable.sortableOuterHeight
|
|
||||||
})) {
|
|
||||||
//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
|
|
||||||
if(!inst.isOver) {
|
|
||||||
inst.isOver = 1;
|
|
||||||
|
|
||||||
//Cache the width/height of the new helper
|
var l = o.left, r = l + o.width,
|
||||||
var height = inst.options.placeholderElement ? $(inst.options.placeholderElement, $(inst.options.items, inst.element)).innerHeight() : $(inst.options.items, inst.element).innerHeight();
|
t = o.top, b = t + o.height;
|
||||||
var width = inst.options.placeholderElement ? $(inst.options.placeholderElement, $(inst.options.items, inst.element)).innerWidth() : $(inst.options.items, inst.element).innerWidth();
|
|
||||||
|
|
||||||
//Now we fake the start of dragging for the sortable instance,
|
|
||||||
//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
|
|
||||||
//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
|
|
||||||
inst.currentItem = $(this).clone().appendTo(inst.element);
|
|
||||||
inst.options.helper = function() { return ui.helper[0]; };
|
|
||||||
inst.start(e);
|
|
||||||
|
|
||||||
//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
|
|
||||||
inst.clickOffset.top = instDraggable.offset.click.top;
|
|
||||||
inst.clickOffset.left = instDraggable.offset.click.left;
|
|
||||||
inst.offset.left -= ui.absolutePosition.left - inst.position.absolute.left;
|
|
||||||
inst.offset.top -= ui.absolutePosition.top - inst.position.absolute.top;
|
|
||||||
|
|
||||||
//Do a nifty little helper animation: Animate it to the portlet's size (just takes the first 'li' element in the sortable now)
|
|
||||||
inst.helperProportions = {width: width, height: height}; //We have to reset the helper proportions, because we are doing our animation there
|
|
||||||
ui.helper.animate({height: height, width: width}, 500);
|
|
||||||
instDraggable.propagate("toSortable", e);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
|
|
||||||
if(inst.currentItem) inst.drag(e);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
//If it doesn't intersect with the sortable, and it intersected before,
|
|
||||||
//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
|
|
||||||
if(inst.isOver) {
|
|
||||||
inst.isOver = 0;
|
|
||||||
inst.cancelHelperRemoval = true;
|
|
||||||
inst.options.revert = false; //No revert here
|
|
||||||
inst.stop(e);
|
|
||||||
inst.options.helper = "original";
|
|
||||||
|
|
||||||
//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
|
|
||||||
inst.currentItem.remove();
|
|
||||||
inst.placeholder.remove();
|
|
||||||
|
|
||||||
ui.helper.animate({ height: this.innerHeight(), width: this.innerWidth() }, 500);
|
|
||||||
instDraggable.propagate("fromSortable", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return (l < (this.position.absolute.left + this.offset.click.left) && (this.position.absolute.left + this.offset.click.left) < r
|
||||||
|
&& t < (this.position.absolute.top + this.offset.click.top) && (this.position.absolute.top + this.offset.click.top) < b);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$.each(inst.sortables, function() {
|
||||||
|
|
||||||
|
if(checkPos.call(inst, {
|
||||||
|
left: this.offset.left, top: this.offset.top,
|
||||||
|
width: this.width, height: this.height
|
||||||
|
})) {
|
||||||
|
//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
|
||||||
|
if(!this.instance.isOver) {
|
||||||
|
this.instance.isOver = 1;
|
||||||
|
|
||||||
|
//Cache the width/height of the new helper
|
||||||
|
var height = this.instance.options.placeholderElement ? $(this.instance.options.placeholderElement, $(this.instance.options.items, this.instance.element)).innerHeight() : $(this.instance.options.items, this.instance.element).innerHeight();
|
||||||
|
var width = this.instance.options.placeholderElement ? $(this.instance.options.placeholderElement, $(this.instance.options.items, this.instance.element)).innerWidth() : $(this.instance.options.items, this.instance.element).innerWidth();
|
||||||
|
|
||||||
|
//Now we fake the start of dragging for the sortable instance,
|
||||||
|
//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
|
||||||
|
//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
|
||||||
|
this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
|
||||||
|
this.instance.options.helper = function() { return ui.helper[0]; };
|
||||||
|
|
||||||
|
e.target = this.instance.currentItem[0];
|
||||||
|
this.instance.mouseStart(e, true);
|
||||||
|
|
||||||
|
//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
|
||||||
|
this.instance.clickOffset.top = inst.offset.click.top;
|
||||||
|
this.instance.clickOffset.left = inst.offset.click.left;
|
||||||
|
this.instance.offset.left -= ui.absolutePosition.left - this.instance.position.absolute.left;
|
||||||
|
this.instance.offset.top -= ui.absolutePosition.top - this.instance.position.absolute.top;
|
||||||
|
|
||||||
|
//Do a nifty little helper animation: Animate it to the portlet's size (just takes the first 'li' element in the sortable now)
|
||||||
|
this.instance.helperProportions = {width: width, height: height}; //We have to reset the helper proportions, because we are doing our animation there
|
||||||
|
ui.helper.animate({height: height, width: width}, 500);
|
||||||
|
inst.propagate("toSortable", e);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
|
||||||
|
if(this.instance.currentItem) this.instance.mouseDrag(e);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
//If it doesn't intersect with the sortable, and it intersected before,
|
||||||
|
//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
|
||||||
|
if(this.instance.isOver) {
|
||||||
|
this.instance.isOver = 0;
|
||||||
|
this.instance.cancelHelperRemoval = true;
|
||||||
|
this.instance.options.revert = false; //No revert here
|
||||||
|
this.instance.mouseStop(e);
|
||||||
|
this.instance.options.helper = "original";
|
||||||
|
|
||||||
|
//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
|
||||||
|
this.instance.currentItem.remove();
|
||||||
|
this.instance.placeholder.remove();
|
||||||
|
|
||||||
|
ui.helper.animate({ height: self.innerHeight(), width: self.innerWidth() }, 500);
|
||||||
|
inst.propagate("fromSortable", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@
|
|||||||
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mouseStart: function(e) {
|
mouseStart: function(e, overrideHandle) {
|
||||||
|
|
||||||
var o = this.options;
|
var o = this.options;
|
||||||
this.currentContainer = this;
|
this.currentContainer = this;
|
||||||
@ -297,7 +297,7 @@
|
|||||||
if($.data(e.target, 'sortable-item')) currentItem = $(e.target);
|
if($.data(e.target, 'sortable-item')) currentItem = $(e.target);
|
||||||
|
|
||||||
if(!currentItem) return false;
|
if(!currentItem) return false;
|
||||||
if(this.options.handle) {
|
if(this.options.handle && !overrideHandle) {
|
||||||
var validHandle = false;
|
var validHandle = false;
|
||||||
$(this.options.handle, currentItem).each(function() { if(this == e.target) validHandle = true; });
|
$(this.options.handle, currentItem).each(function() { if(this == e.target) validHandle = true; });
|
||||||
if(!validHandle) return false;
|
if(!validHandle) return false;
|
||||||
@ -512,14 +512,14 @@
|
|||||||
|
|
||||||
$.ui.plugin.add("sortable", "revert", {
|
$.ui.plugin.add("sortable", "revert", {
|
||||||
stop: function(e, ui) {
|
stop: function(e, ui) {
|
||||||
var self = ui.instance;
|
var self = this.data("sortable");
|
||||||
self.cancelHelperRemoval = true;
|
self.cancelHelperRemoval = true;
|
||||||
var cur = self.currentItem.offset();
|
var cur = self.currentItem.offset();
|
||||||
var op = self.helper.offsetParent().offset();
|
var op = self.helper.offsetParent().offset();
|
||||||
if(ui.instance.options.zIndex) ui.helper.css('zIndex', ui.instance.options.zIndex); //Do the zIndex again because it already was resetted by the plugin above on stop
|
if(self.options.zIndex) ui.helper.css('zIndex', self.options.zIndex); //Do the zIndex again because it already was resetted by the plugin above on stop
|
||||||
|
|
||||||
//Also animate the placeholder if we have one
|
//Also animate the placeholder if we have one
|
||||||
if(ui.instance.placeholder) ui.instance.placeholder.animate({ opacity: 'hide' }, parseInt(ui.options.revert, 10) || 500);
|
if(self.placeholder) self.placeholder.animate({ opacity: 'hide' }, parseInt(ui.options.revert, 10) || 500);
|
||||||
|
|
||||||
|
|
||||||
ui.helper.animate({
|
ui.helper.animate({
|
||||||
@ -595,35 +595,35 @@
|
|||||||
|
|
||||||
$.ui.plugin.add("sortable", "axis", {
|
$.ui.plugin.add("sortable", "axis", {
|
||||||
sort: function(e, ui) {
|
sort: function(e, ui) {
|
||||||
var o = ui.options;
|
var o = ui.options, inst = this.data("sortable");
|
||||||
if(o.constraint) o.axis = o.constraint; //Legacy check
|
if(o.constraint) o.axis = o.constraint; //Legacy check
|
||||||
o.axis == 'x' ? ui.instance.position.current.top = ui.instance.originalPosition.top : ui.instance.position.current.left = ui.instance.originalPosition.left;
|
o.axis == 'x' ? inst.position.current.top = inst.originalPosition.top : inst.position.current.left = inst.originalPosition.left;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$.ui.plugin.add("sortable", "scroll", {
|
$.ui.plugin.add("sortable", "scroll", {
|
||||||
start: function(e, ui) {
|
start: function(e, ui) {
|
||||||
var o = ui.options;
|
var o = ui.options, inst = this.data("sortable");
|
||||||
o.scrollSensitivity = o.scrollSensitivity || 20;
|
o.scrollSensitivity = o.scrollSensitivity || 20;
|
||||||
o.scrollSpeed = o.scrollSpeed || 20;
|
o.scrollSpeed = o.scrollSpeed || 20;
|
||||||
|
|
||||||
ui.instance.overflowY = function(el) {
|
inst.overflowY = function(el) {
|
||||||
do { if((/auto|scroll/).test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-y'))) return el; el = el.parent(); } while (el[0].parentNode);
|
do { if((/auto|scroll/).test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-y'))) return el; el = el.parent(); } while (el[0].parentNode);
|
||||||
return $(document);
|
return $(document);
|
||||||
}(this);
|
}(this);
|
||||||
ui.instance.overflowX = function(el) {
|
inst.overflowX = function(el) {
|
||||||
do { if((/auto|scroll/).test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-x'))) return el; el = el.parent(); } while (el[0].parentNode);
|
do { if((/auto|scroll/).test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-x'))) return el; el = el.parent(); } while (el[0].parentNode);
|
||||||
return $(document);
|
return $(document);
|
||||||
}(this);
|
}(this);
|
||||||
|
|
||||||
if(ui.instance.overflowY[0] != document && ui.instance.overflowY[0].tagName != 'HTML') ui.instance.overflowYstart = ui.instance.overflowY[0].scrollTop;
|
if(inst.overflowY[0] != document && inst.overflowY[0].tagName != 'HTML') inst.overflowYstart = inst.overflowY[0].scrollTop;
|
||||||
if(ui.instance.overflowX[0] != document && ui.instance.overflowX[0].tagName != 'HTML') ui.instance.overflowXstart = ui.instance.overflowX[0].scrollLeft;
|
if(inst.overflowX[0] != document && inst.overflowX[0].tagName != 'HTML') inst.overflowXstart = inst.overflowX[0].scrollLeft;
|
||||||
|
|
||||||
},
|
},
|
||||||
sort: function(e, ui) {
|
sort: function(e, ui) {
|
||||||
|
|
||||||
var o = ui.options;
|
var o = ui.options;
|
||||||
var i = ui.instance;
|
var i = this.data("sortable");
|
||||||
|
|
||||||
if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') {
|
if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') {
|
||||||
if(i.overflowY[0].offsetHeight - (ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity)
|
if(i.overflowY[0].offsetHeight - (ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity)
|
||||||
@ -650,7 +650,6 @@
|
|||||||
$(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
|
$(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
//ui.instance.recallOffset(e);
|
|
||||||
i.offset = {
|
i.offset = {
|
||||||
left: i.mouse.start.left - i.originalPosition.left + (i.overflowXstart !== undefined ? i.overflowXstart - i.overflowX[0].scrollLeft : 0),
|
left: i.mouse.start.left - i.originalPosition.left + (i.overflowXstart !== undefined ? i.overflowXstart - i.overflowX[0].scrollLeft : 0),
|
||||||
top: i.mouse.start.top - i.originalPosition.top + (i.overflowYstart !== undefined ? i.overflowYstart - i.overflowX[0].scrollTop : 0)
|
top: i.mouse.start.top - i.originalPosition.top + (i.overflowYstart !== undefined ? i.overflowYstart - i.overflowX[0].scrollTop : 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user