-
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 nitishamraji,
Please refer to the sample below:
<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 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
<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
@roya
For which version of ZK?
Please refer to the working sample below:
test.zul
<zk>
<!-- tested with ZK 6.5.3 -->
<script><![CDATA[
zk.afterLoad("zul.sel", function () {
var _tWgt = {},
_tiWgt = {};
zk.override(zul.sel.Treeitem.prototype, _tiWgt, {
getDragOptions_: function (map) {
var copy = map.constructor(),
wgt = this;
// clone map
for (var attr in map) {
if (map.hasOwnProperty(attr)) copy[attr] = map[attr];
}
// change functions as needed
var oldChange = copy.change,
oldEnd = copy.endeffect;
copy.change = function (drag, pt, evt) {
var tree = wgt.getTree();
oldChange(drag, pt, evt);
tree.triggerAutoScroll(evt.pageX, evt.pageY);
};
copy.endeffect = function (drag, evt) {
var tree = wgt.getTree();
oldEnd(drag, evt);
tree.stopAutoScroll();
}
return copy;
}
});
zk.override(zul.sel.Tree.prototype, _tWgt, {
scrollValue: 50,
scrollDelay: 50,
triggerAutoScroll: function (x, y) {
var $n = jq(this.$n()),
offset = $n.offset(),
top = offset.top + (this.$n('head')? 30 : 0),
bottom = top + $n.outerHeight(true);
if (y < top)
this.startScrollToTop();
else if (y > bottom)
this.startScrollToBottom();
else
this.stopAutoScroll();
},
stopAutoScroll: function () {
this.clearScrollToTopTimer();
this.clearScrollToBottomTimer();
},
startScrollToTop: function () {
var wgt = this;
this.clearScrollToBottomTimer();
if (!this._scrollToTopTimer) {
this._scrollToTopTimer = setInterval(function () {
wgt.$n('body').scrollTop -= wgt.scrollValue;
}, this.scrollDelay);
}
},
startScrollToBottom: function () {
var wgt = this;
this.clearScrollToTopTimer();
if (!this._scrollToBottomTimer) {
this._scrollToBottomTimer = setInterval(function () {
wgt.$n('body').scrollTop += wgt.scrollValue;
}, this.scrollDelay);
}
},
clearScrollToTopTimer: function () {
var timer = this._scrollToTopTimer;
if (timer)
clearInterval(timer);
this._scrollToTopTimer = null;
},
clearScrollToBottomTimer: function () {
var timer = this._scrollToBottomTimer;
if (timer)
clearInterval(timer);
this._scrollToBottomTimer = null;
}
});
});
]]></script>
<window apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('test.TestVM')">
<tree id="tree" model="@bind(vm.model)"
width="600px" height="200px">
<treecols>
<treecol label="data" />
</treecols>
<template name="model" var="node">
<treeitem draggable="true" droppable="true">
<treerow>
<treecell label="@bind(node.data)" />
</treerow>
</treeitem>
</template>
</tree>
</window>
</zk>
TestVM.java
package test;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.zkoss.zul.DefaultTreeModel;
import org.zkoss.zul.DefaultTreeNode;
import org.zkoss.zul.TreeModel;
/**
* tested with ZK 6.5.3
*
* @author benbai
*
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class TestVM {
File file = new File("C:" + File.separator + "Program Files");
DefaultTreeModel _model;
DefaultTreeNode _selectedNode;
String _valueToAdd;
String _valueToUpdate;
public TreeModel<DefaultTreeNode<String>> getModel () {
List<DefaultTreeNode> l = new ArrayList<DefaultTreeNode>();
for (int i = 0; i < 300; i++) {
l.add(new DefaultTreeNode("chile " + i, (List)null));
}
DefaultTreeNode root = new DefaultTreeNode(null,
new DefaultTreeNode[] {new DefaultTreeNode("aaa", l)
});
if (_model == null) {
_model = new DefaultTreeModel<String>(root);
}
return _model;
}
}
Hi Ben,
Great work done. It works for auto scroll within a tree. But in my case there are more than one tree available at user screen and the user can drag a node from any tree and drop it on any other tree. how can this code be modified to auto scroll any tree on user screen.
To scroll between multiple trees you can try the updated zul page below, this version the cursor should keep inside a tree to scroll it:
<zk>
<!-- tested with ZK 6.5.3 -->
<script><![CDATA[
zk.afterLoad("zul.sel", function () {
var _tWgt = {},
_tiWgt = {};
zk.override(zul.sel.Treeitem.prototype, _tiWgt, {
getDragOptions_: function (map) {
var copy = map.constructor(),
wgt = this;
// clone map
for (var attr in map) {
if (map.hasOwnProperty(attr)) copy[attr] = map[attr];
}
// change functions as needed
var oldChange = copy.change,
oldEnd = copy.endeffect;
copy.change = function (drag, pt, evt) {
var tree = wgt.findTargetTree(evt.pageX, evt.pageY),
oldTree = wgt.oldTree;
oldChange(drag, pt, evt);
if (oldTree
&& oldTree != tree)
oldTree.stopAutoScroll();
wgt.oldTree = tree;
if (tree)
tree.triggerAutoScroll(evt.pageX, evt.pageY);
};
copy.endeffect = function (drag, evt) {
var tree = wgt.oldTree;
oldEnd(drag, evt);
if (tree)
tree.stopAutoScroll();
}
return copy;
},
findTargetTree: function (pageX, pageY) {
var trees = jq('.z-tree'),
len = trees.length,
i = 0,
wgt;
for ( ; i < len; i++) {
var $tree = jq(trees[i]),
offset = $tree.offset(),
left = offset.left,
right = left + $tree.width(),
top = offset.top,
bottom = top + $tree.height();
if (pageX >= left
&& pageX <= right
&& pageY >= top
&& pageY <= bottom) {
wgt = zk.Widget.$('#' + trees[i].id);
break;
}
}
return wgt;
}
});
zk.override(zul.sel.Tree.prototype, _tWgt, {
scrollValue: 50,
scrollDelay: 50,
triggerAutoScroll: function (x, y) {
var $n = jq(this.$n()),
offset = $n.offset(),
top = offset.top + (this.$n('head')? 30 : 0),
bottom = top + $n.outerHeight(true),
diff = bottom - top;
top = top + diff*0.3;
bottom = bottom - diff*0.3;
if (y < top)
this.startScrollToTop();
else if (y > bottom)
this.startScrollToBottom();
else
this.stopAutoScroll();
},
stopAutoScroll: function () {
this.clearScrollToTopTimer();
this.clearScrollToBottomTimer();
},
startScrollToTop: function () {
var wgt = this;
this.clearScrollToBottomTimer();
if (!this._scrollToTopTimer) {
this._scrollToTopTimer = setInterval(function () {
wgt.$n('body').scrollTop -= wgt.scrollValue;
}, this.scrollDelay);
}
},
startScrollToBottom: function () {
var wgt = this;
this.clearScrollToTopTimer();
if (!this._scrollToBottomTimer) {
this._scrollToBottomTimer = setInterval(function () {
wgt.$n('body').scrollTop += wgt.scrollValue;
}, this.scrollDelay);
}
},
clearScrollToTopTimer: function () {
var timer = this._scrollToTopTimer;
if (timer)
clearInterval(timer);
this._scrollToTopTimer = null;
},
clearScrollToBottomTimer: function () {
var timer = this._scrollToBottomTimer;
if (timer)
clearInterval(timer);
this._scrollToBottomTimer = null;
}
});
});
]]></script>
<window apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('test.TestVM')">
<tree id="tree" model="@bind(vm.model)"
width="600px" height="200px">
<treecols>
<treecol label="data" />
</treecols>
<template name="model" var="node">
<treeitem draggable="true" droppable="true">
<treerow>
<treecell label="@bind(node.data)" />
</treerow>
</treeitem>
</template>
</tree>
<tree id="tree2" model="@bind(vm.model)"
width="600px" height="200px">
<treecols>
<treecol label="data" />
</treecols>
<template name="model" var="node">
<treeitem draggable="true" droppable="true">
<treerow>
<treecell label="@bind(node.data)" />
</treerow>
</treeitem>
</template>
</tree>
</window>
</zk>
To scroll between multiple trees you can try the updated zul page below, this version the cursor should keep inside a tree to scroll it:
<zk>
<!-- tested with ZK 6.5.3 -->
<script><![CDATA[
zk.afterLoad("zul.sel", function () {
var _tWgt = {},
_tiWgt = {};
function clearDragOverStyles() {
jq('.z-drag-over').each(function () {
jq(this).removeClass('z-drag-over');
});
}
zk.override(zul.sel.Treeitem.prototype, _tiWgt, {
getDragOptions_: function (map) {
var copy = map.constructor(),
wgt = this;
// clone map
for (var attr in map) {
if (map.hasOwnProperty(attr)) copy[attr] = map[attr];
}
// change functions as needed
var oldChange = copy.change,
oldEnd = copy.endeffect;
copy.change = function (drag, pt, evt) {
var tree = wgt.findTargetTree(evt.pageX, evt.pageY),
oldTree = wgt.oldTree;
oldChange(drag, pt, evt);
if (oldTree
&& oldTree != tree)
oldTree.stopAutoScroll();
wgt.oldTree = tree;
if (tree)
tree.triggerAutoScroll(evt.pageX, evt.pageY);
};
copy.endeffect = function (drag, evt) {
var tree = wgt.oldTree;
oldEnd(drag, evt);
if (tree)
tree.stopAutoScroll();
jq('.z-drag-over').each(function () {
jq(this).removeClass('z-drag-over');
});
}
return copy;
},
findTargetTree: function (pageX, pageY) {
var trees = jq('.z-tree'),
len = trees.length,
i = 0,
wgt;
for ( ; i < len; i++) {
var $tree = jq(trees[i]),
offset = $tree.offset(),
left = offset.left,
right = left + $tree.width(),
top = offset.top,
bottom = top + $tree.height();
if (pageX >= left
&& pageX <= right
&& pageY >= top
&& pageY <= bottom) {
wgt = zk.Widget.$('#' + trees[i].id);
break;
}
}
return wgt;
}
});
zk.override(zul.sel.Tree.prototype, _tWgt, {
scrollValue: 22,
scrollDelay: 200,
topDiff: 90,
bottomDiff: 90,
scrollSpeedRatio: 1,
triggerAutoScroll: function (x, y) {
var $n = jq(this.$n()),
offset = $n.offset(),
top = offset.top + (this.$n('head')? 30 : 0),
bottom = offset.top + $n.outerHeight(true);
top = top + this.topDiff;
bottom = bottom - this.bottomDiff;
if (y < top) {
this.scrollSpeedRatio = (top - y)/this.topDiff*2;
this.startScrollToTop();
} else if (y > bottom) {
this.scrollSpeedRatio = (y - bottom)/this.bottomDiff*2;
this.startScrollToBottom();
}
else
this.stopAutoScroll();
},
stopAutoScroll: function () {
this.clearScrollToTopTimer();
this.clearScrollToBottomTimer();
},
startScrollToTop: function () {
var wgt = this;
wgt._oldDropped = null;
this.clearScrollToBottomTimer();
if (!this._scrollToTopTimer) {
this._scrollToTopTimer = setInterval(function () {
wgt.$n('body').scrollTop -= (wgt.scrollValue * wgt.scrollSpeedRatio);
var $n = jq(wgt.$n()),
dragged = $n.find('.z-dragged')[0],
oldDropped = wgt._oldDropped || dragged || $n.find('.z-drag-over')[0],
top = jq('.z-drop-ghost').offset().top,
$oldDropped;
if (!oldDropped) return;
if (oldDropped == dragged) {
oldDropped = oldDropped.previousSibling;
}
while(oldDropped) {
$oldDropped = jq(oldDropped);
if ($oldDropped.offset().top < top) {
$n.find('.z-drag-over').removeClass('z-drag-over');
$oldDropped.addClass('z-drag-over');
wgt._oldDropped = $oldDropped[0];
break;
}
oldDropped = oldDropped.previousSibling;
}
}, this.scrollDelay);
}
},
startScrollToBottom: function () {
var wgt = this;
wgt._oldDropped = null;
this.clearScrollToTopTimer();
if (!this._scrollToBottomTimer) {
this._scrollToBottomTimer = setInterval(function () {
wgt.$n('body').scrollTop += (wgt.scrollValue * wgt.scrollSpeedRatio);
var $n = jq(wgt.$n()),
dragged = $n.find('.z-dragged')[0],
oldDropped = wgt._oldDropped || dragged || $n.find('.z-drag-over')[0],
top = jq('.z-drop-ghost').offset().top,
$oldDropped;
if (!oldDropped) return;
if (oldDropped == dragged) {
oldDropped = oldDropped.previousSibling;
}
while(oldDropped) {
$oldDropped = jq(oldDropped);
if ($oldDropped.offset().top+$oldDropped.height() > top) {
$n.find('.z-drag-over').removeClass('z-drag-over');
$oldDropped.addClass('z-drag-over');
wgt._oldDropped = $oldDropped[0];
break;
}
oldDropped = oldDropped.nextSibling;
}
}, this.scrollDelay);
}
},
clearScrollToTopTimer: function () {
var timer = this._scrollToTopTimer;
if (timer) {
clearInterval(timer);
clearDragOverStyles();
}
this._scrollToTopTimer = null;
},
clearScrollToBottomTimer: function () {
var timer = this._scrollToBottomTimer;
if (timer) {
clearInterval(timer);
clearDragOverStyles();
}
this._scrollToBottomTimer = null;
}
});
});
]]></script>
<window apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('test.TestVM')">
<tree id="tree" model="@bind(vm.model)"
width="600px" height="300px">
<treecols>
<treecol label="data" />
</treecols>
<template name="model" var="node">
<treeitem draggable="true" droppable="true">
<treerow>
<treecell label="@bind(node.data)" />
</treerow>
</treeitem>
</template>
</tree>
<tree id="tree2" model="@bind(vm.model)"
width="600px" height="300px">
<treecols>
<treecol label="data" />
</treecols>
<template name="model" var="node">
<treeitem draggable="true" droppable="true">
<treerow>
<treecell label="@bind(node.data)" />
</treerow>
</treeitem>
</template>
</tree>
</window>
</zk>
Asked: 2012-01-10 15:27:53 +0800
Seen: 907 times
Last updated: Sep 02 '14