在实际应用中,经常遇到需要在表格中选定一条或多条记录进行操作的情况。
- 使用ADF RichTable提供的Multiple RowSelect功能
- 在RichTable中增加列,使用基于VO的Checkbox进行RichTable的行多选
- 在RichTable中增加列,不基于VO进行RichTable的行多选
1.使用ADF RichTable提供的Multiple RowSelect
优点:RichTable原生支持,稳定快速,代码简单
缺点:只能按住键盘Ctrl键或Shift键通过鼠标进行多选,用户操作不直观
步骤:设置RichTable的属性,将RowSelection设为multiple,并将SelectedRowKeys设为空,即可在后台通过如下代码获得选定行的RowKey,进而可以通过在VO上通过对应RowKey得到对应行。
补充:为什么将SelectedRowKeys置为空
修改之前SelectedRowKeys值为#{bindings.EmployeesVO1.collectionModel.selectedRow},该EL表达式表明之前该Table的SelectedRowKeys绑定到了对应VO的selectedRow,但client端的状态改变并不能实时的提交到Server端,以至于当此绑定存在时,取到的是Server端存储的selectedRow而非client端当前的selectedrow。
2.在RichTable中增加列,使用基于VO的Checkbox进行RichTable的行多选
优点:使用checkbox的方式提供选择,代码复杂度中等
缺点:必须修改每一个需要使用该多选方式的RichTable对应的VO
步骤:
3.在RichTable中增加列,不基于VO进行RichTable的行多选
优点:使用checkbox的方式提供选择,不必修改VO
缺点:代码复杂度较高
步骤:
缺点:只能按住键盘Ctrl键或Shift键通过鼠标进行多选,用户操作不直观
步骤:设置RichTable的属性,将RowSelection设为multiple,并将SelectedRowKeys设为空,即可在后台通过如下代码获得选定行的RowKey,进而可以通过在VO上通过对应RowKey得到对应行。
public Boolean getIsChecked() {
//return (Boolean) getAttributeInternal(ISCHECKED);
return getAttributeInternal(ISCHECKED) == null ? false :
(Boolean)getAttributeInternal(ISCHECKED);
}
补充:为什么将SelectedRowKeys置为空
修改之前SelectedRowKeys值为#{bindings.EmployeesVO1.collectionModel.selectedRow},该EL表达式表明之前该Table的SelectedRowKeys绑定到了对应VO的selectedRow,但client端的状态改变并不能实时的提交到Server端,以至于当此绑定存在时,取到的是Server端存储的selectedRow而非client端当前的selectedrow。
2.在RichTable中增加列,使用基于VO的Checkbox进行RichTable的行多选
优点:使用checkbox的方式提供选择,代码复杂度中等
缺点:必须修改每一个需要使用该多选方式的RichTable对应的VO
步骤:
- 在VO添加非数据库项IsChecked,设置其Type为Boolean,Updateable为Always
- 为该VO生成ViewRowImpl.java,并修改IsChecked的get方法
public Boolean getIsChecked() {
//return (Boolean) getAttributeInternal(ISCHECKED);
return getAttributeInternal(ISCHECKED) == null ? false :
(Boolean)getAttributeInternal(ISCHECKED);
} - 将VO拖入页面创建RichTable,修改IsChecked列,将标签改为<af:selectBooleanCheckbox>,并将其Autosubmit/Immediate属性设为true,并在header中拖入另一个SelectBooleanCheckbox
- header里的Checkbox不能添加ValueChangeListener,如果已经添加,需要将ValueChangeListener重置为Default(空)。为Header里的Checkbox创建ClientListener和ServerListener,分别设置属性如下:
ClientListener
method: mainClientCall
type: click
ServerListener
method: callMBmainmethod
type: onSelectedOrDeselected()
完成后如下 - 在页面转入Source模式,在标签 <af:document... 与 <af:messages... 间加入如下代码
<script type="text/javascript">
<![CDATA[function mainClientCall (event)
{
var currcheckbox = event.getSource();
var selectstatus = currcheckbox.getValue();
//call method in manage bean
AdfCustomEvent.queue(currcheckbox, "callMBmainmethod",{params:selectstatus}, true);
}
]]>
</script>
在页面backingbean中修改onSelectedOrDeselected方法,添加以下代码以实现全选功能。注意修改this.getTable()为你的目标表。public void onSelectedOrDeselected(ClientEvent clientEvent) {
boolean isSelected =
(Boolean)clientEvent.getParameters().get("params");
RichTable rt = this.getTable1();
for (int i = 0; i < rt.getRowCount(); i++) {
JUCtrlHierNodeBinding rowData =
(JUCtrlHierNodeBinding)rt.getRowData(i);
Row row = rowData.getRow();
if (isSelected) {
row.setAttribute("IsChecked", true);
} else {
row.setAttribute("IsChecked", false);
}
}
// Refresh target table state
AdfFacesContext adfContext = AdfFacesContext.getCurrentInstance();
UIComponent refreshComponent = this.getTable1();
if (refreshComponent != null) {
adfContext.addPartialTarget(refreshComponent);
}
}- 可以在AppModel或ManageBean中通过遍历VO判断IsChecked的状态来取出选定行。
3.在RichTable中增加列,不基于VO进行RichTable的行多选
优点:使用checkbox的方式提供选择,不必修改VO
缺点:代码复杂度较高
步骤:
- 在RichTable中插入列,设置宽度(width)为13,RowHeader属性为true,Align属性为Center;在列及列header中分别拖入SelectBooleanCheckBox,设置checkbox的simple属性为true,删除其Text属性中的值。将全选checkbox的ID设置为maincheckbox,单选的checkbox
ID设置为subcheckbox:(参考2.3) - 分别为两个Checkbox创建一组ClientListener/ServerListener,属性设置如下(参考2.4)
MainCheckbox
clientListener
Method: mainClientCall
Type: click
serverListener
Type: callMBmainmethod
Method: mainCheckBoxChecked()
SubCheckbox
clientListener
Method: subClientCall
Type: click
serverListener
Type: callMBsubmethod
Method: subCheckBoxChecked()
在页面转入source模式,复制如下代码至<af: document ...与<af: messages ...标签之间(参考2.5)<script type="text/javascript">
<![CDATA[function mainClientCall (event)
{
var currcheckbox = event.getSource();
var selectstatus = currcheckbox.getValue();
//call method in manage bean
AdfCustomEvent.queue(currcheckbox, "callMBmainmethod",{params:selectstatus}, true);
}
function subClientCall (event)
{
var currcheckbox = event.getSource();
var selectstatus = currcheckbox.getValue();
//call method in manage bean
AdfCustomEvent.queue(currcheckbox, "callMBsubmethod",{params:selectstatus}, true);
}
]]>
</script>- 修改页面对应Manage
bean中的方法,修改mainCheckBoxChecked(),subCheckBoxChecked()方法,添加如下代码public void getSelectedRows(ActionEvent actionEvent) {
System.out.println("Selected Rows"); //debug
System.out.println("******************************************"); //debug
RowKeySet selectedRowsList = this.getMultipleCheckBoxProcess().getSelectedRowsList(this.getResId1());
if (selectedRowsList != null && selectedRowsList.size() != 0) {
for (Object temp : selectedRowsList)
System.out.println("Get Row : " + temp);
}
System.out.println("******************************************"); //debug
}
public void CleanUpStatus(ActionEvent actionEvent) {
this.getMultipleCheckBoxProcess().CleanUpStatus(this.getResId1(), "maincheckbox", "subcheckbox");
}
public void mainCheckBoxChecked(ClientEvent clientEvent) {
Boolean currstatus = (Boolean)clientEvent.getParameters().get("params");
this.getMultipleCheckBoxProcess().mainCheckBoxChecked(this.getResId1(), "subcheckbox", currstatus);
}
public void subCheckBoxChecked(ClientEvent clientEvent) {
Boolean currstatus = (Boolean)clientEvent.getParameters().get("params");
this.getMultipleCheckBoxProcess().subCheckBoxChecked(this.getResId1(), currstatus);
}
public MultipleCheckBox getMultipleCheckBoxProcess(){
FacesContext ctx = FacesContext.getCurrentInstance();
Application app = ctx.getApplication();
MultipleCheckBox curr = (MultipleCheckBox)app.evaluateExpressionGet(ctx, "#{ viewScope.view_MultipleCheckbox}", Object.class);
return curr;
} - 复制MultipleCheckbox.java至目标位置(在Demo中可以找到),在当前所使用的TaskFlow中添加Manage Bean名为view_MultipleCheckbox,Scope为view级别的Bean,指向MultipleCheckbox.java,修改MultipleCheckbox.java中的Package,使其与实际路径相符。
- 注意在适当的时候调用MultipleCheckbox的CleanUpStatus方法,一般在RichTable中数据发生改变时需要调用,如页面存在Query,则需在Query中调用MultipleCheckbox的CleanUpStatus方法。
补充:类MultipleCheckBox中方法说明
- public RowKeySet
getSelectedRowsList(RichTable tartab);
输入参数1:使用多选择Checkbox的RichTable对象
返回参数:选中的行的RowKey - public void setSelectedRowsList(RowKeySet
selectedRowsList, RichTable tartab);
输入参数1:选中行的RowKey
输入参数2:使用多选择Checkbox的RichTable对象 - public void subCheckBoxChecked(RichTable
tartab, Boolean checkStatus);
输入参数1:使用多选择Checkbox的RichTable对象
输入参数2:当前Checkbox的状态
该方法应在多Checkbox RichTable中某行前的Checkbox被选中/反选时调用 - public void mainCheckBoxChecked(RichTable
tartab, String subcheckboxid, Boolean newstatus);
输入参数1:使用多选择Checkbox的RichTable对象
输入参数2:每行前Checkbox的id
输入参数3:当前全选Checkbox的状态
该方法应在全选Checkbox被选中/反选时调用 - public void CleanUpStatus(RichTable
tartab, String maincheckboxid, String subcheckboxid);
输入参数1:使用多选择Checkbox的RichTable对象
输入参数2:全选Checkbox的id
输入参数3:每行前Checkbox的id
该方法用于清除Checkbox的被选状态,通常需要执行查询前均需调用
Demo:
MultipleRowSelect1.rar
MultipleRowSelect2.rar
MultipleRowSelect3.rar
0 评论:
发表评论