>>>在阅读本文之前请先优先参考《Display tag 的使用》
本文场景描述:使用display tag标签在做列表的情况下,前置复选框选择功能,在勾选时记住勾选复选框勾选状态,在分页后的复选框状态仍然保持。
目的:数据实现分页显示,不是查询所有的数据,而是每次取固定的条数。而且在每页选中的数据ID都可以保存,一起提交选中的数据,做相应的操作。比如第一 页选中2条,第二页选中3条,提交时是5条,如果返回第一页,这也显示选中的数据,回到第二页,也会显示选中的数据,以此类推,取消选中,翻页几次,无任 何问题;总之,无论选中还是取消,翻页都没有bug;
实现方法:
1、首先进入的是你分页显示数据的页面,在这个action,或者servlet里创建一个session,名字自定义。因为每次翻页都是经 过这个action的,大多都是这样吧,所以要做下判断,第一次进入的时候创建session,而翻页的时候就不在new(新建)了。然后从 session里取出来的map把它循环组成字符串传回页面,放到隐藏域中,做判断用。
代码:
//初始化Table所选项
private void initCheckedItems(HttpServletRequest request,HttpServletResponse response, Model model){
boolean isFirstEnter=true;
if(request.getQueryString()!=null && !"".equals(request.getQueryString())){
if(request.getQueryString().contains("-p")){
isFirstEnter=false;
}
}
if(isFirstEnter){//判断是否第一次进入该页面[在未点击分页情况下]
//创建map,用于存放选中的checkbox
Map ck_map = new HashMap();
//存放session,命名为jld_session,注意:每个模块定义用于存放checkbox的session的名字必须不同
request.getSession().setAttribute("chkd_session", ck_map);
}
if(request.getSession().getAttribute("chkd_session")!=null){
//获取名字为当前模块的session,把session中的值取出来,返回到页面,用于判断哪个checkbox选中了
Map map = (Map)request.getSession().getAttribute("chkd_session");
String ckIds = "";
if(map !=null){
Iterator it = map.entrySet().iterator();
while(it.hasNext()){
Map.Entry entry = (Map.Entry) it.next();
String value = (String)entry.getValue();
if(ckIds.equals("")){
ckIds = value;
}else{
ckIds = ckIds +";"+value;
}
}
}
model.addAttribute("ckIds", ckIds);
}
}
在list所在的action中加入initCheckedItems(request, response, model);方法。
2、全选和单选操作,每次点击checkbox的时候,都触发一个js函数,把id传到后台,后台根据前台判断的是选中还是选中之后取消来做相应的 操作,是添加到map中,还是从map中移除,该方法里创建个map,把ID作为键值,ID作为value值,然后循环这个map,把所有ID组成字符串 用“;”分割,ajax返回值就是这个字符串,然后document.getElementById().value=...把这个字符串设在隐藏域 中 代码如下:
//全选时触发 function checkAll(){ if ($("#chkAll:checked").length > 0){ $("[name=sonChecklist]").attr("checked", "checked"); $("[name=sonChecklist]").each(function(){ var id=$(this).attr("id"); chkSonClick(id); }); }else{ $("[name=sonChecklist]").removeAttr("checked"); } } //单选时触发 function chkSonClick(id){ var check = document.getElementById(id); var a = 1; if(check.checked){ a = 1;//添加 }else{ a = 0;//取消 } var b = 0; $.ajax({ async: false, type: "POST", url: "setSubIds.do", data:"&id="+id+"&done="+a, success: function(msg){ document.getElementById("ckIds").value = msg;//存到页面隐藏域中 b = 1; } }); if(a==1&&b==1){ document.getElementById(id).checked =true; }else if(a==0&&b==1){ document.getElementById(id).checked =false; } }
3、后台处理传过来的数据,每次处理好数据之后都把数据设在页面的隐藏域中。
@RequestMapping("/setSubIds")
public String setSubIds(HttpServletRequest request,
HttpServletResponse response, RedirectAttributes attribute)
throws Exception {
System.out.println("----Ajax保存所选的checkbox进入----");
String id = request.getParameter("id"); //点击checkbox的value值
String done = request.getParameter("done"); //判断操作,是选中,还是选中之后取消
//获得此模块所存的用于存储选中id的session,此模块命名为chkd_session,不同模块sessionid不同
Map map = (Map)request.getSession().getAttribute("chkd_session");
if(done.equals("1")){
map.put(id, id);//插入map操作,id作为主键,id作为值,用户覆盖相同的值
}else if(done.equals("0")){
map.remove(id);//从map中移除操作
}
System.out.println("Map里存的值:"+map.size());
//覆盖名为chkd_session的session
request.getSession().setAttribute("chkd_session", map);
//以下用于ajax返回值操作
try{
String ids = "";//要返回页面的字符串
if(map !=null){
//把map遍历成字符串
Iterator it = map.entrySet().iterator();
while(it.hasNext()){
Map.Entry entry = (Map.Entry) it.next();
String value = (String)entry.getValue();
//循环第一遍
if(ids.equals("")){
ids = value;
}else{
ids = ids +";"+value;
}
}
}
//创建servlet
response.setContentType("text ml;charset=gb2312");
PrintWriter outs = response.getWriter();
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
outs.print(ids);//打印返回值
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
4、在提交的时候获取这个隐藏域的内容,每次翻页都会发这些ID藏在隐藏域中
判断是否选中:在页面加载之后最后执行:
//初始化选中项 initCheckedItems(); function initCheckedItems(){ var idd = document.getElementsByName("sonChecklist");//checkbox的name名称,自己定义 var ids = document.getElementById("ckIds").value;//隐藏域里的所有选中的id,字符串 var arr = ids.split(";"); for(var i=0;i<idd.length;i++){ for(var n=0;n<arr.length;n++){ if(idd[i].value==arr[n]){ idd[i].checked = true;//如果有匹配的就选中 } } } }
5、如何在display tag标签中嵌入checkbox可供选择。
<display:table id="item" name="${itemList}" size="${itemCount}" pagesize="${itemSize}"
class="table table-bordered table-striped table-hover"
requestURI="/system/list.do" partialList="true">
<display:column title="<input id='chkAll' type='checkbox' name='chkAll' οnclick='checkAll()'/>" class="nowrap">
<input type='checkbox' id="${item.id}" name='sonChecklist' value="${item.id}" οnclick='chkSonClick(${item.id})'/>
</display:column>
<display:column title="名称" property="title" sortable="true"/>
</display:table>
总结:实现了自己的需求。
缺点:可能会慢,如果网络不好,因为每次都有请求。