ZK允许用户在用户界面内拖曳特定的组件。例如,将文件拖至其它的目录,或将商品拖至购物车。
若一个组件可以被拖曳则它是可拖曳的。若用户可以将一个可拖曳的组件放入到某一组件内,则称该组件是可放下的(droppable)。
注: 在放下后,ZK并不假定关于发生什么的任何行为。这由应用程序开发人员编写onDrop
事件监听器来决定。
如果应用程序什么也不做,被拖曳的组件只是简单的移回它的初始位置.
使用ZK,通过指派draggable
属性除了"false
"外的任何值,你可以使一个组件变为可拖曳的。若想禁用,则将其设为"false
"。
<image draggable="true"/>
类似的,可以将droppable属性赋值为"true
"来将一个组件变为可放下的。
<hbox droppable="true"/>
然后,用户可以拖曳一个可拖曳的组件,并将其放入一个可放下的组件。
一旦用户拖曳一个组件并将其放入可放下的另一个组件,onDrop
事件会通知用户放入组件的组件。onDrop
事件是org.zkoss.ui.event.DropEvent
的一个实例。调用getDragged
方法,你可以获取什么被拖曳(及放下)了。
注意 onDrop
事件的目标是可放下的组件,而不是被拖曳的组件。
下面是一个简单的例子,允许用户使用拖放对列表项目重新排序。
<window title="Reorder by Drag-and-Drop" border="normal"> Unique Visitors of ZK: <listbox id="src" multiple="true" width="300px"> <listhead> <listheader label="Country/Area"/> <listheader align="right" label="Visits"/> <listheader align="right" label="%"/> </listhead> <listitem draggable="true" droppable="true" onDrop="move(event.dragged)"> <listcell label="United States"/> <listcell label="5,093"/> <listcell label="19.39%"/> </listitem> <listitem draggable="true" droppable="true" onDrop="move(event.dragged)"> <listcell label="China"/> <listcell label="4,274"/> <listcell label="16.27%"/> </listitem> <listitem draggable="true" droppable="true" onDrop="move(event.dragged)"> <listcell label="France"/> <listcell label="1,892"/> <listcell label="7.20%"/> </listitem> <listitem draggable="true" droppable="true" onDrop="move(event.dragged)"> <listcell label="Germany"/> <listcell label="1,846"/> <listcell label="7.03%"/> </listitem> <listitem draggable="true" droppable="true" onDrop="move(event.dragged)"> <listcell label="(other)"/> <listcell label="13,162"/> <listcell label="50.01%"/> </listitem> <listfoot> <listfooter label="Total 132"/> <listfooter label="26,267"/> <listfooter label="100.00%"/> </listfoot> </listbox> <zscript> void move(Component dragged) { self.parent.insertBefore(dragged, self); } </zscript> </window>
当用户拖放一个列表项或tree项时,这些项目的选择状态不会改变。仅当移动拖曳项时是可视的,但是, 通过查询所有选中项的集合,你可以处理所有的选中项,如下所示。
public void onDrop(DropEvent evt) { Set selected = ((Listitem)evt.getDragged()).getListbox().getSelectedItems(); //then, you can handle the whole set at once }
注意,被拖曳项允许并未被选中。因此对于此事例,你或许更喜欢将选中项改变为拖曳项,如下所示。
Listitem li = (Listitem)evt.getDragged(); if (li.isSelected()) { Set selected = ((Listitem)evt.getDragged()).getListbox().getSelectedItems(); //then, you can handle the whole set at once } else { li.setSelected(true); //handle li only }
可放下组件不接受所有的可拖曳组件是和平常的。例如,一个e-mail文件夹只接受e-mail且拒绝联系(contacts)或其它。当调用onDrop
时,你可以默默地忽略不可接受的组件,或是发出警告消息。
为了获得更好的视觉效果,你可以使用一个标识来确定每种类型的可拖曳组件,然后将标识赋予draggable
属性。
<listitem draggable="email"/> ... <listitem draggable="contact"/>
然后,你可以为droppable
属性指定一个标识列表来限制可被放下的组件。例如,下面的图像仅接受email
和contact
。
<image src="/img/send.png" droppable="email, contact" onDrop="send(event.dragged)"/>
若想接受任何类型的组件,你可以将droppable
属性的值设为"true
"。例如,下面的图像可以接受任意类型的可拖曳组件。
<image src="/img/trash.png" droppable="true" onDrop="remove(event.dragged)"/>
另外,如果draggable
属性的值为 "true
",则意味着此组件属于匿名类型。此外,只有droppable
属性值为"true
" 的组件接受此组件。