不論是自己實作拖放效果,或是使用 JavaScript 函式庫,都需要花點心思才能做出,如果不熟 JavaScript 的人還是挺麻煩。ZK 所有元件都內建拖放效果,只要啟用即可。而拖放之後實際要產生什麼行為仍可以 Java 實作。
例如我要讓一個表格中的每一列可以被拖放改變順序。
啟用完後,滑鼠拖拉元件就會看到如上的元件被拖動的殘影效果。
<listbox width="40%" apply="quickstart.DragDropComposer">
...
<listitem draggable="true" droppable="true" >
<listcell label="United States"/>
<listcell label="5,093"/>
<listcell label="19.39%"/>
</listitem>
<listitem>
上都設定 draggable="true"
,啟用該元件可以被拖拉droppable="true"
讓使用者可以把元件「拖放」到 <listitem>
上。但光是啟用只是擁有瀏覽器上可以看到的拖放視覺效果,實際上並不會改變每列順序,這必須要透過 Java 來控制元件來改變順序
public class DragDropComposer extends SelectorComposer<Component> {
@Listen("onDrop = listitem")
public void move(DropEvent event){
Listitem listitem = (Listitem)event.getTarget();
listitem.getParent().insertBefore(event.getDragged(), listitem);
}
}
<listitem>
上時,會發出 onDrop
事件,因此我要註冊對應的傾聽器來變更順序event.getTarget()
傳回事件發生的元件,也就是丟下去的目的元件。例如我把 France 拖放到 Germany,那 target 就是 Gerymany。 event.getDragged()
就是被拖的元件,也就是 France。insertBefore()
: 我把 France 插入到 Germany 前面來改變順序。可以啟用 Listbox 的多選功能來達到一次拖拉多個元件的效果
<listbox multiple="true" width="50%">
<listitem draggable="true" label="Matthew"/>
<listitem draggable="true" label="Mark"/>
<listitem draggable="true" label="Lucas"/>
<listitem draggable="true" label="John"/>
</listbox>
<div droppable="true" sclass="box" height="150px" onDrop="onDrop(event)">
丟到此區
</div>
multiple="true"
啟用多選功能public void onDrop(DropEvent evt) {
Listitem li = (Listitem)evt.getDragged();
if (li.isSelected()) {
Set selected = ((Listitem)evt.getDragged()).getListbox().getSelectedItems();
//處理整批
} else {
li.setSelected(true);
//處理單一個
}
Clients.showNotification("select " + selected.size());
}
getSelectedItems()
)有時我希望能指定拖放特定的元件,例如一個區域只能放 email,另一個區域只能放入 contact:
在 draggable
上自定一個字串作為其「類別」
<listbox multiple="true" width="50%">
<listitem draggable="email" label="Email 1"/>
<listitem draggable="email" label="Email 2"/>
<listitem draggable="contact" label="Contact 1"/>
<listitem draggable="contact" label="Contact 2"/>
</listbox>
然後 droppable 指定同樣的「類別」。如果你拖放的元件類別不同,ZK 會顯示像上圖那樣的「禁止」圖示,告知使用者無法放入,即便你拖放了,也不會產生 onDrop 事件。
<div sclass="box" height="50px" droppable="email" onDrop="accept(event)" >
只接受 email
</div>
以上介紹拖拉的基本用法,如果對 JavaScript 熟悉的人甚至可以客製化拖拉效果,請參考 ZK Client-side Reference。