-
FEATURED COMPONENTS
First time here? Check out the FAQ!
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>
hi ashish,
please refer to the following thread for the solution..
http://www.zkoss.org/forum/listComment/18391-how-to-auto-scroll-a-listbox-when-dragging-a-listtiem
Try this JS (May be you need to tweak it a little). It works for me, I have a listbox without paging/scroll, and scroll is at window level.
<script>
zk.afterLoad("zk", function() {
var oldUpdateDrag = zk.Draggable.prototype._updateDrag;
zk.Draggable.prototype._updateDrag = function(pt, evt) {
// call original _updateDrag method
try {
oldUpdateDrag.apply(this, arguments);
} catch (e) {
// 4: handle exception
}
var control = this.control, // original listitem
node = this.node; // cloned listitem, the drag node
if (control.$instanceof(zul.sel.Listitem)) {
// get original listbox
var listbox = control.getListbox(), dir;
// start scroll if has a direction,
// or clear the scroll timer
if (dir = shouldScroll(jq(node), jq(listbox)))
startScroll(dir, listbox);
else
clearScroll(listbox);
}
if (control.$instanceof(zul.sel.Listcell)) {
// get original listbox
var listbox = control.getListbox(), dir;
// start scroll if has a direction,
// or clear the scroll timer
if (dir = shouldScrollPage(jq(node), jq(listbox))) {
startScrollPage(dir, listbox);
}
} else {
// clearScroll(listbox);
}
}
/*
* else {
*
* var listbox = control.getListbox(), dir; // start scroll if has a
* direction, // or clear the scroll timer if (dir =
* shouldScrollPage(jq(node), jq(listbox))) startScrollPage(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;
}
}
function shouldScrollPage($node, $listbox) {
var dir = '';
var winmid = window.pageYOffset + 100;
var top = $listbox.offset().top, itemTop = $node.offset().top;
console.log(top);
console.log(itemTop);
if (itemTop < winmid)
dir = 'up';
else {
var bottom = window.pageYOffset, itemBottom = itemTop + $node.height();
dir = itemBottom > winmid+400 ? 'down' : null;
}
//console.log(dir);
return dir;
}
// 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);
}
function startScrollPage(dir, listbox) {
var body = $('body');
var scrollFlag = false;
if (!scrollFlag)
scrollFlag = setInterval(function() {
var oldValue = listbox.$n('body').scrollTop;
// console.log("oldValue" + oldValue);
var position = (dir == 'down' ? (body.scrollTop() + 20) : (body.scrollTop() -20));
body.scrollTop(position);
//console.log("body.scrollTop " + body.scrollTop());
//console.log("pos " + position);
// can not scroll any more
if (listbox.$n('body').scrollTop == oldValue){
clearScrollPage(body, scrollFlag);
//scrollFlag = false;
}
}, 100);
}
function clearScrollPage(body, scrollFlag) {
if (scrollFlag) {
clearInterval(scrollFlag);
}
}
// clear scroll timer
function clearScroll(listbox) {
if (listbox._scrollStarted) {
clearInterval(listbox._scrollStarted);
listbox._scrollStarted = null;
}
}
</script>
Your may have to use right component in if statement search for text "if (control.$instanceof(zul.sel.Listcell))" and use appropriate component in condition.
Asked: 2012-01-11 17:18:31 +0800
Seen: 124 times
Last updated: Sep 02 '14