how to auto scroll a listbox when dragging a listtiem??
Hi nitishamraji,
Please refer to the sample below:
index.zul
<zk>
<script type="text/javascript"><![CDATA[
var oldUpdateDrag = zk.Draggable.prototype._updateDrag;
zk.afterLoad("zk", function () {
zk.Draggable.prototype._updateDrag = function (pt, evt) {
oldUpdateDrag.apply(this, arguments);
var control = this.control,
node = this.node;
if (control.$instanceof(zul.sel.Listitem)) {
var listbox = control.getListbox(),
dir;
if (dir = shouldScroll(node, listbox))
startScroll(dir, listbox);
else
clearScroll(listbox);
}
}
});
function shouldScroll (node, listbox) {
var $listbox = jq(listbox.$n('body')),
$node = jq(node),
top = $listbox.offset().top,
itemTop = $node.offset().top;
if (itemTop < top)
return 'up';
else {
var bottom = top + $listbox.height(),
itemBottom = itemTop + $node.height();
return itemBottom > bottom? 'down' : null;
}
}
function startScroll (dir, listbox) {
if (!listbox._scrollStarted)
listbox._scrollStarted = setInterval(function () {
var body = listbox.$n('body'),
oldValue = body.scrollTop;
body.scrollTop += dir == 'down'? 20 : (-20);
// can not scroll any more
if (body.scrollTop == oldValue)
clearScroll(listbox);
}, 50);
}
function clearScroll(listbox) {
if (listbox._scrollStarted) {
clearInterval(listbox._scrollStarted);
listbox._scrollStarted = null;
}
}
]]></script>
<window title="scroll while drag" border="normal">
<listbox id="left" height="150px" width="200px" onDrop="move(event.dragged)" droppable="true"
oddRowSclass="non-odd">
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK Forge" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK Mobile" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK GWT" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK JSF" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK JSP" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK Spring" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK Studio" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK Jquery" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK JS" />
</listitem>
</listbox>
<separator />
</window>
<zscript>
void move(Component dragged) {
if (self instanceof Listitem) {
self.parent.insertBefore(dragged, self.getNextSibling());
} else {
self.appendChild(dragged);
}
}
</zscript>
<button label="test" draggable="true" />
</zk>
Regards,
ben
Edit:
Code fragment with description
ZK Custom Component - Listbox Auto-scroll while Dragging
hi ben,
thank you so much... I was struggling to implement this since few days... this is what I was looking for..
Thanks.
hi benbai,
I am trying to build application similar to the example shown in this link http://www.zkoss.org/zkdemo/effects/drag_n_drop
I have two listboxes where I drag a listitem from the left listbox and drop it in the right listbox... autoscroll works fine when I drag and drop a listitem within the same listbox...
can the right listbox be automatically scrolled while I try to drag and drop a listitem from the left Listbox??
Hi
You can assign both listbox an ID, and check which one should scroll by the position of dragging item.
Please refer to the sample below
index.zul
<zk>
<script type="text/javascript"><![CDATA[
var oldUpdateDrag = zk.Draggable.prototype._updateDrag;
zk.afterLoad("zk", function () {
zk.Draggable.prototype._updateDrag = function (pt, evt) {
// call original _updateDrag method
oldUpdateDrag.apply(this, arguments);var node = this.node; // cloned listitem, the drag node
if (this.control.$instanceof(zul.sel.Listitem)) {
// get original listbox
var $node = jq(node),
listbox = getEffectListbox($node),
dir;
// start scroll if has a direction,
// or clear the scroll timer
if (dir = shouldScroll($node, jq(listbox)))
startScroll(dir, listbox);
else
clearScroll(listbox);
}
}
});
// return the scroll direction if have to scroll,
// return null otherwise.
function shouldScroll ($node, $listbox) {
var top = $listbox.offset().top,
itemTop = $node.offset().top;
if (itemTop < top)
return 'up';
else {
var bottom = top + $listbox.height(),
itemBottom = itemTop + $node.height();
return itemBottom > bottom? 'down' : null;
}
}
// create scroll timer with the specified direction
function startScroll (dir, listbox) {
if (!listbox._scrollStarted)
listbox._scrollStarted = setInterval(function () {
var body = listbox.$n('body'),
oldValue = body.scrollTop;
body.scrollTop += dir == 'down'? 20 : (-20);
// can not scroll any more
if (body.scrollTop == oldValue)
clearScroll(listbox);
}, 50);
}
// clear scroll timer
function clearScroll(listbox) {
if (listbox._scrollStarted) {
clearInterval(listbox._scrollStarted);
listbox._scrollStarted = null;
}
}
function getEffectListbox($node) {
var left = $node.offset().left,
$lbOne = jq('$lbOne'); // get root element of listbox by assigned ID
if (left < $lbOne.offset().left + $lbOne.width()) {
// get the zk widgeth by its root element
// clear the scroll of another listbox first
clearScroll(zk.Widget.$(jq('$lbTwo')[0]));
return zk.Widget.$($lbOne[0]);
}
clearScroll(zk.Widget.$(jq('$lbOne')[0]));
return zk.Widget.$(jq('$lbTwo')[0]);
}
]]></script>
<div height="15px" />
<hbox>
<listbox id="lbOne" height="120px" width="200px" droppable="true">
<listitem draggable="true" droppable="true">
<listcell label="Item 1" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 2" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 3" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 4" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 5" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 6" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 7" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 8" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 9" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 10" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 11" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 12" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 13" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 14" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 15" />
</listitem>
</listbox>
<listbox id="lbTwo" height="120px" width="200px" droppable="true">
<listitem draggable="true" droppable="true">
<listcell label="Item 1" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 2" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 3" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 4" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 5" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 6" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 7" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 8" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 9" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 10" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 11" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 12" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 13" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 14" />
</listitem>
<listitem draggable="true" droppable="true">
<listcell label="Item 15" />
</listitem>
</listbox>
</hbox>
</zk>
Regards,
ben
ZK - Open Source Ajax Java Framework
I have a listbox with drag and drop enabled to the list tiems... when I would like to darg and drop a listitem outside the view of listbox, the scrollbar does not automatically scroll.... is there any way to make auto scrolling when you want to drag and drop a listIem??... here is my code
<zk>
<hbox>
<listbox id="left" height="150px" width="200px" onDrop="move(event.dragged)" droppable="true"
oddRowSclass="non-odd">
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK Forge" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK Mobile" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK GWT" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK JSF" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK JSP" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK Spring" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK Studio" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK Jquery" />
</listitem>
<listitem draggable="true" droppable="true" onDrop="move(event.dragged)">
<listcell label="ZK JS" />
</listitem>
</listbox>
<separator />
</hbox>
<zscript>
void move(Component dragged) {
if (self instanceof Listitem) {
self.parent.insertBefore(dragged, self.getNextSibling());
} else {
self.appendChild(dragged);
}
}
</zscript>
</zk>