http://jsfiddle.net/ujty083a/4/
$(document).ready(function(){
$(".left ul li").draggable({
refreshPosition: true,
revert: true
});
$(".right li").droppable({
drop: function(e, ui){
alert(ui.draggable.text()+" "+$(this).text());
}
});
});
I have three lists one you can drag and the other two accept drop. The right lists may or may not have a scroll bar but there will always be 2 or more.
The first problem I've found is when the top list has a scrollbar and you try to drop an item on the second list two events are triggered. One for the hidden list and one for the visible list.
The second problem is the when one of the lists has a scrollbar it does not auto scroll when the user drags an item into it.
I think you'll need to modify droppable
and modify substantially some of the behaviors this way:
droppable
should be
scrollable or not. droppable
are visible or not.jquery ui
widgets.This is not perfect but should give you some ideas:
$.widget('ui.droppable', $.ui.droppable, {
_over: function (e, ui) {
var draggable = $.ui.ddmanager.current;
if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
// this to make sure the droppable is visible
this.scrollVisible = this._isScrollIntoView();
if (this.accept.call(this.element[0], (draggable.currentItem || draggable.element)) && (!this.options.scrollable || this.scrollVisible)) {
if (this.options.hoverClass) {
this.element.addClass(this.options.hoverClass);
}
// to activate scrollable you need to change scrollParent of the draggable
// and adjust some calculations
if (this.options.scrollable) {
draggable.overflowOffset = $(this.element).scrollParent().offset();
draggable.scrollParent = $(this.element).scrollParent();
draggable.offsetParent = $(this.element).scrollParent();
draggable.offset.parent.top = $(this.element).scrollParent().scrollTop();
}
this._trigger('over', event, this.ui(draggable));
}
},
_out: function (event) {
this._super();
var draggable = $.ui.ddmanager.current;
// remove scrollable
if (this.options.scrollable) {
draggable.scrollParent = $(document);
draggable.offsetParent = $(document);
draggable.overflowOffset = $(document).offset();
draggable.offset.parent.top = $(document).scrollTop();
}
},
_drop: function (event, custom) {
var draggable = custom || $.ui.ddmanager.current;
if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
var childrenIntersection = false;
this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function () {
var inst = $.data(this, 'droppable');
if (
inst.options.greedy && !inst.options.disabled && inst.options.scope == draggable.options.scope && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && $.ui.intersect(draggable, $.extend(inst, {
offset: inst.element.offset()
}), inst.options.tolerance)) {
childrenIntersection = true;
return false;
}
});
if (childrenIntersection) return false;
// same as for over, you need to validate visibility of the element
this.scrollVisible = this._isScrollIntoView();
if (this.accept.call(this.element[0], (draggable.currentItem || draggable.element)) && (!this.options.scrollable || this.scrollVisible)) {
if (this.options.activeClass) this.element.removeClass(this.options.activeClass);
if (this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
this._trigger('drop', event, this.ui(draggable));
return this.element;
}
return false;
},
// a function to check visibility. Taken here:
//http://stackoverflow.com/questions/487073/check-if-element-is-visible-after-scrolling
_isScrollIntoView() {
var $elem = $(this.element);
var $parent = $(this.element).scrollParent();
var docViewTop = $parent.parent().scrollTop();
var docViewBottom = docViewTop + $parent.parent().height();
var elemTop = $elem.offset().top;
var elemBottom = elemTop + $elem.height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
});
$(document).ready(function () {
$(".left ul li").draggable({
refreshPosition: true,
revert: true,
});
$(".right .top li").droppable({
scrollable: true,
drop: function (e, ui) {
alert(ui.draggable.text() + " " + $(this).text());
}
});
$(".right .bottom li").droppable({
scrollable: false,
drop: function (e, ui) {
alert(ui.draggable.text() + " " + $(this).text());
}
});
});
http://jsfiddle.net/ejv32oen/4/
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