我目前在zk中使用动态树。代码如下:
<tree id="treeview" multiple="true" width="330px" model="@load(vm.treeModel)"
style="border: 1px solid #9D9D9D;" vflex="1" rows="14" >
<treecols sizable="true">
<treecol />
</treecols>
<template name="model">
<treeitem>
<treerow>
<treecell><checkbox label="@load(each.data.name)" checked="true"/></treecell>
</treerow>
</treeitem>
</template>
</tree>
我希望如果我取消选中父复选框,则必须取消选中所有子项。 反之亦然,即如果我检查父复选框,则必须检查所有子项。
zk中是否有可用于树标记的属性来执行此操作? 如果没有,还有其他方法吗?
答案 0 :(得分:0)
我遇到了同样的问题,并提出了一个仅限客户端的解决方案,它可以快速准确地引发正确的选择事件。
要启用它,请在树项呈示器中添加此小部件侦听器:
treeitem.setWidgetListener(Events.ON_CLICK, "selectSubTreesOnItemClick(this, event);");
在你的情况下(模板),这样做:
<tree xmlns:w="client">
...
<treeitem w:onClick="selectSubTreesOnItemClick(this, event)">
然后,导入以下js文件(在您的zul中,在某处添加<script src="/js/treeselection.js" />
):
function selectSubTreesOnItemClick(item, event) {
// if clicked outside of check box, reset selection
if (!jq(event.target).is('.z-treerow')) {
item.getTree().clearSelection();
// re-select clicked node
item.setSelected(true);
}
privateSelectDescendants(item);
privateSelectParentIfAllDescendantsSelected(item);
// update selection
item.getTree().fireOnSelect(item);
// prevent interference of the tree's default click behavior (like selection of the clicked node ;) ).
event.stop();
}
/**
* @param parent if selected, selects all children (and grand-children and so on), otherwise
* removes them from selection.
*/
function privateSelectDescendants(parent) {
var items = parent.getTree().itemIterator();
// find all descendants of parent
while (items.hasNext() && items.next() !== parent) {}
var stopAt = privateGetFirstNonDescendant(parent);
// check descendants
while (items.hasNext()) {
var descendant = items.next();
if (descendant === stopAt) {
break;
} else {
descendant.setSelected(parent.isSelected());
}
}
}
/**
* @param item parent will be selected if item and all its siblings are selected, otherwise
* unselected. Repeated for grandparents, great-grandparents, and so on.
*/
function privateSelectParentIfAllDescendantsSelected(item) {
if (item.getParentItem() != null) {
var parent = item.getParentItem();
// find all descendants of parent
var items = parent.getTree().itemIterator();
while (items.hasNext()) {
if (items.next() === parent){
break;
}
}
var stopAt = privateGetFirstNonDescendant(parent);
// check descendants
var allDescendantsSelected = true;
while (items.hasNext()) {
var child = items.next();
if (child === stopAt) {
break;
} else if (!child.isSelected()) {
allDescendantsSelected = false;
break;
}
}
parent.setSelected(allDescendantsSelected);
// continue with grandparents
privateSelectParentIfAllDescendantsSelected(parent);
}
}
/**
* @param item
* @returns the next item that is on the same or a higher level as item.
* Undefined if item is the last node or only followed by children.
*/
function privateGetFirstNonDescendant(item) {
var result = item.nextSibling;
while (!result && item.getParentItem() != null) {
item = item.getParentItem();
result = item.nextSibling;
}
return result;
}
(Un)选择树节点也将(un)选择其后代。此外,如果选择了所有节点的兄弟节点,则将选择父节点,否则将取消选择(这将一直到根节点)。
答案 1 :(得分:0)
您可以将Zscript用于您的目的,通过onclick
事件,您可以链接到函数并将Treeitem作为参数传递。该函数评估是否有子代,在子代之间循环并根据是否选择父代进行设置。如果有很多嵌套嵌套,则可以使用递归函数。
<zscript><![CDATA[
public void selectItemsChildren(Treeitem item){
item.setOpen(true);
if(!item.isEmpty())
for(Treeitem p : item.getTreechildren().getItems()){
p.setSelected(item.isSelected());
}
}
]]>
</zscript>
<tree id="treeAccess" width="100%" model="@bind(vm.treeModel)">
<treecols>
<treecol hflex="1" label="Description"/>
</treecols>
<template name="model">
<treeitem onClick="selectItemsChildren(self)">
<treerow>
<treecell label="@load(each...any)"/>
</treerow>
</treeitem>
</template>
</tree>