From: Polin Wei
在Table的作業中, 常會有將所有筆數全選( Select All Rows)的需求, 在 ADF 的 Table 要實現這樣的效果卻有點難(好難搞的 ADF....) , Google 一下查到一些高手的作法, 整理如下.
前置作業:
1. 使用 Table: USERS 來作示範
CREATE TABLE "USERS"( "USERNAME" VARCHAR2(15 BYTE) NOT NULL PRIMARY KEY ENABLE , "NAME" VARCHAR2(255 BYTE) NOT NULL ENABLE, "PASSWORD" VARCHAR2(15 BYTE) NOT NULL ENABLE ) |
2. 建立一個 JavaBean: UsersTableBean
package com.wei.bean; import com.wei.utils.ADFUtils; import java.util.ArrayList; import javax.faces.event.ValueChangeEvent; import oracle.adf.model.binding.DCIteratorBinding; import oracle.adf.view.rich.component.rich.data.RichTable; import oracle.adf.view.rich.context.AdfFacesContext; import oracle.adf.view.rich.render.ClientEvent; import oracle.jbo.Row; import oracle.jbo.RowSetIterator; import org.apache.myfaces.trinidad.model.CollectionModel; import org.apache.myfaces.trinidad.model.RowKeySet; import org.apache.myfaces.trinidad.model.RowKeySetImpl; public class UsersTableBean { private RowKeySet selectedRows; private RichTable table; private static final String ITERATOR_NAME = "UsersVO1Iterator"; public UsersTableBean() { super(); } public void setSelectedRows(RowKeySet selectedRows) { this.selectedRows = selectedRows; } public RowKeySet getSelectedRows() { if (selectedRows == null) { selectedRows = new RowKeySetImpl(); CollectionModel collectionModel = (CollectionModel)getTable().getValue(); selectedRows.setCollectionModel(collectionModel); } return selectedRows; } public void setTable(RichTable table) { this.table = table; } public RichTable getTable() { return table; } public void rowSelected(ClientEvent clientEvent) { refreshSelectedRows(); AdfFacesContext.getCurrentInstance().addPartialTarget(getTable()); } public void selectAll(ValueChangeEvent valueChangeEvent) { DCIteratorBinding it = ADFUtils.findIterator(ITERATOR_NAME); RowSetIterator rit = it.getRowSetIterator(); rit.reset(); if (valueChangeEvent.getNewValue() != null) { Boolean selectAll = Boolean.parseBoolean(valueChangeEvent.getNewValue().toString()); if (rit.first() != null) { Row r = rit.first(); r.setAttribute("Selected", selectAll); } while (rit.hasNext()) { Row r = rit.next(); if (r != null) { r.setAttribute("Selected", selectAll); } } } refreshSelectedRows(); it.executeQuery(); } private void refreshSelectedRows() { getSelectedRows().clear(); DCIteratorBinding it = ADFUtils.findIterator(ITERATOR_NAME); RowSetIterator rit = it.getRowSetIterator(); rit.reset(); if (rit.first() != null) { Row r = rit.first(); if (r.getAttribute("Selected") != null) { makeRowSelected(r); } } while (rit.hasNext()) { Row r = rit.next(); if (r.getAttribute("Selected") != null) { makeRowSelected(r); } } } private void makeRowSelected(Row r) { Boolean selected = (Boolean)r.getAttribute("Selected"); if (selected) { ArrayList keyList = new ArrayList(); keyList.add(r.getKey()); getSelectedRows().add(keyList); } } } |
Step 01:
建立的 EO (Entity Objects): USERSEO 自行加入一個暫時記錄資料(transient attribute)的欄位 Selected , Type: Boolean, 因不需回寫 Table, 所以將屬性 Persistent 拿掉
Step 02: 建立一個檔案 tableCheckBoxSelect.jspx , 將 UserVO1 拖拉進來,並選轉換為ADF Table 物件
Section | Attribute | Value |
---|---|---|
Common | Id | t1 |
rowSelection | multiple | |
Behavior | partialTriggers | selectAll |
Advanced | binding | #{viewScope.UsersTableBean.table} |
selectedRowKeys | #{viewScope.UsersTableBean.selectedRows} |
Step 03: 再將 Selected 欄位 Convert To CheckBox
在作 Convert 時, 可以挑選要 Binding 的資料來源, 原則上不需變動
最後確認時, 是告知轉換成 Checkbox 時, 這兩個欄位屬性: MaximumLength、Columns會被移除
在 Headline 加入 SelectBooleanCheckbox 元件
Section | Attribute | Value |
---|---|---|
Common | Id | selectAll |
Width | 30 | |
Behavior | autoSubmit | true |
valueChangeListener | #{viewScope.UsersTableBean.selectAll} |
這是方法之一, 但第一次選擇時 Table 裡的每一個ROW 的 checkBox 卻沒有被打勾, 這未解決......
參考:
http://www.gebs.ro/blog/oracle/oracle-adf-row-selection-using-checkboxes/
http://docs.oracle.com/cd/E16764_01/web.1111/b31973/af_event.htm
http://docs.oracle.com/cd/B14099_19/web.1012/b14022/overview-summary.html
Section 5.3.1, "How to Return the Original Source of the Event.
留言列表