0

how to auto scroll a listbox when dragging a listtiem?? nitishamraji

asked 2012-01-11 17:18:31 +0800

nitishamraji gravatar image nitishamraji
39

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>

delete flag offensive retag edit

3 Replies

Sort by ยป oldest newest

answered 2014-09-02 06:46:35 +0800

ajaidka gravatar image ajaidka
196 4

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.

link publish delete flag offensive edit

answered 2012-01-12 16:18:55 +0800

nitishamraji gravatar image nitishamraji
39

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

link publish delete flag offensive edit

answered 2012-01-12 03:13:27 +0800

ashishd gravatar image ashishd flag of Taiwan
1972 6

Hi Nitish, I'm afraid this is not supported yet. Could you register a feature request for this? (you can create it in our Issue Tracker here)

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2012-01-11 17:18:31 +0800

Seen: 124 times

Last updated: Sep 02 '14

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More