JQuery实现全选、全不选和反选功能
2016-12-12 16:01
701 查看
项目中需要做一个全选、全不选和反选的功能。刚接到这个需求的时候,心想很简单的一个功能,几行代码就能搞定,然而事实并非如此。下面就把我的思路说一下:
1、当点击'全选'按钮时,页面中所有的复选框都应该为选中状态,
1.1、当再次点击'全选'按钮时,所有的复选框应该是非选中状态。
1.2、当点击子复选框时,'全选'按钮应该是非选中状态。
2、当选中当前页面的所有子复选框时,'全选'按钮应该是'选中'状态。
3、点点击'全不选'按钮时,当前页面的所有复选框置为非选中状态。
4、当点击'反选'按钮时,当前页面选中状态的复选框置为未选中状态,未选中状态的复选框置为选中状态。
在网上看到的一些博客中,很多都是有bug的,下面挑选出了一个存在bug的demo。
还有一个要注意的地方:就是JQuery中空格的问题,如
效果图如下:
现给出我的demo效果图,
图1,注意'全选'按钮的选中状态
图2,注意全选、全不选、反选按钮的选中状态
给出我的demo源码
问题到此为止,其实这篇博文最想记录的是后续加的一个需求,
背景介绍:
随着数据量的增加,业务方要求,在不同的页面实现复选框的选中,即第一页选中全部或某几个,第二页继续选中,第三页也有可能选中,然后一并提交到后台处理。
刚开始接到这个需求的时候,顿时懵逼,博主心想哪有在不同页面处理的,翻页的时候就已经刷新了,这怎么可能处理嘛。但是既然业务有这个需求,就得做了。下班坐地铁的时候想了想这个问题。
解决方案:
当选中第一页的某些复选框时,翻页时,肯定是又提交了一次表单,重新到数据库查询第二页数据,在这个过程中,可以把第一页选中的那些复选框的值随着表单一起提交,后台接收放到model中(springmvc框架)或者cookie中,第二页用EL表达式取出这些值,当返回第一页数据时,再把之前model中的数据回显到页面中即可。大体思路即是如此了。既然思路有了,就要付诸实践,进行研发和测试。
单元测试中遇到的问题:
1、测试效果图1如下:
由此图可知,编号重复了,这是一个bug,仔细想想,其实也不算是什么问题,完全可以交给后台来处理的,后台用set集合处理即可。
2、测试效果图2如下
由此图可知,当'全选'按钮实现清除功能时,会把前几页的数据都清空掉,这个bug很严重。
以上所说都是全选按钮的测试,还有子复选框的测试,博主就不在贴出效果图了,简单的把测试案例阐述一下
1、当把当前页所有的复选框选中时,全选按钮也要选中。
2、当多次选中某个复选框时,要判断此复选框是否已经选中,大家可以看到效果图里有一个textarea标签,本标签就是为了可视化的展示哪些按钮已选中
首先要取到textarea里的值(idStrings),当textarea标签里没有编号时(idStrings为空字符串),选中某个复选框,则idStrings不为空,当在选中其它按钮时,动态将此按钮的id值拼装到idStrings里,若选中的某个复选框的值已存在于idStrings字符串里,应该将此按钮的id值从idStrings里剔除。
博主就讨论这些了,测试的情况有很多种,就不一一阐述了。
现给出核心代码:
JSP页面代码:
<form:form id="xxxId" action="xxxAction">
<input id="idString" type="hidden" name="idString"/>
<input id="idStrings" name="idStrings" value="${idStrings }"/>
<input id="checkedFlagId" name="checkedFlag" value="${checkedFlag }"/>
<table id="contentTable" class="table table-striped table-bordered table-condensed">
<thead>
<tr>
<th>序号</th>
<th><input type="checkbox" name="checkboxbutton" value="all" id="checkboxall" onclick="funcCheckAll()">全选</th>
<th>编号</th>
</tr>
</thead>
4000
<tbody>
<c:forEach items="${page.list}" var="item" varStatus="status">
<tr>
<td>${status.index + 1}</td>
<td>
<c:choose>
<c:when test="${fn:contains(listStringIds, item.bid) }">
<input type="checkbox" name="ids" checked="checked" value="${item.bid}" id="subcheck" onclick="checkReturn(this)">
</c:when>
<c:otherwise>
<input type="checkbox" name="ids" value="${item.bid}" id="subcheck" onclick="checkReturn(this)">
</c:otherwise>
</c:choose>
</td>
<td>${item.bid}</td>
</tr>
</c:forEach>
</tbody>
</table>
</form:form>
JS代码如下:
此段代码,是进入该页面就加载的函数,防止全选按钮第一次是失效的(测试当中发现,只有点两次全选按钮时,才会真正选中)
$(document).ready(function () {
//获取subcheck的个数
var chsub = $("input[type='checkbox'][id='subcheck']").length;
//获取选中的subcheck的个数
var checkedsub = $("input[type='checkbox'][id='subcheck']:checked").length;
if (checkedsub == 0) {
$("#checkedFlagId").val('false');
}
if (checkedsub == chsub) {
$("#checkboxall").attr("checked", true);
}
});
后台JAVA代码:
String idStrings = request.getParameter("idStrings");
String checkedFlag = request.getParameter("checkedFlag");
if (null != idStrings && !"".equals(idStrings)) {
String ids[] = idStrings.split(",");
Set<String> setString = new HashSet<String>();
for (String id: ids) {
setString.add(id);
}
assetView.setSetString(setString);
Set<String> stringTemp = assetView.getSetString();
String idsString = "";
// 拼装成后台需要的数据格式:xx,xx,..
for (String tempString : stringTemp) {
if ("".equals(idsString)) {
idsString = tempString;
} else {
idsString = idsString + "," + tempString;
}
}
model.addAttribute("idStrings", idsString);
}
model.addAttribute("checkedFlag", checkedFlag);
1、当点击'全选'按钮时,页面中所有的复选框都应该为选中状态,
1.1、当再次点击'全选'按钮时,所有的复选框应该是非选中状态。
1.2、当点击子复选框时,'全选'按钮应该是非选中状态。
2、当选中当前页面的所有子复选框时,'全选'按钮应该是'选中'状态。
3、点点击'全不选'按钮时,当前页面的所有复选框置为非选中状态。
4、当点击'反选'按钮时,当前页面选中状态的复选框置为未选中状态,未选中状态的复选框置为选中状态。
在网上看到的一些博客中,很多都是有bug的,下面挑选出了一个存在bug的demo。
还有一个要注意的地方:就是JQuery中空格的问题,如
$("#checkBoxList :checkbox").attr("checked", true);改行代码里':'前有一个空格(若空格在后,好像函数也不能执行),而且是必须的
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript" src="js/jquery-1.8.3.js"></script> <script type="text/javascript"> $(function() { $("#selectAll").click(function(){ $("#checkBoxList :checkbox").attr("checked", true); }); $("#unSelect").click(function(){ $("#checkBoxList :checkbox").attr("checked", false); }); $("#reverseSelect").click(function(){ $("#checkBoxList :checkbox").each(function(){ $(this).attr("checked", !$(this).attr("checked")); }); }); }); </script> </head> <body> <div id="checkBoxList"> <input type="checkbox" value="项羽"/>项羽<br> <input type="checkbox" value="范增"/>范增<br> <input type="checkbox" value="龙且"/>龙且<br> <input type="checkbox" value="刘邦"/>刘邦<br> <input type="checkbox" value="萧何"/>萧何<br> <input type="checkbox" value="韩信"/>韩信<br> </div> <input type="checkbox" value="全选" id="selectAll"/>全选 <input type="checkbox" value="全不选" id="unSelect"/>全不选 <input type="checkbox" value="反选" id="reverseSelect"/>反选 </body> </html>
效果图如下:
现给出我的demo效果图,
图1,注意'全选'按钮的选中状态
图2,注意全选、全不选、反选按钮的选中状态
给出我的demo源码
问题到此为止,其实这篇博文最想记录的是后续加的一个需求,
背景介绍:
随着数据量的增加,业务方要求,在不同的页面实现复选框的选中,即第一页选中全部或某几个,第二页继续选中,第三页也有可能选中,然后一并提交到后台处理。
刚开始接到这个需求的时候,顿时懵逼,博主心想哪有在不同页面处理的,翻页的时候就已经刷新了,这怎么可能处理嘛。但是既然业务有这个需求,就得做了。下班坐地铁的时候想了想这个问题。
解决方案:
当选中第一页的某些复选框时,翻页时,肯定是又提交了一次表单,重新到数据库查询第二页数据,在这个过程中,可以把第一页选中的那些复选框的值随着表单一起提交,后台接收放到model中(springmvc框架)或者cookie中,第二页用EL表达式取出这些值,当返回第一页数据时,再把之前model中的数据回显到页面中即可。大体思路即是如此了。既然思路有了,就要付诸实践,进行研发和测试。
单元测试中遇到的问题:
1、测试效果图1如下:
由此图可知,编号重复了,这是一个bug,仔细想想,其实也不算是什么问题,完全可以交给后台来处理的,后台用set集合处理即可。
2、测试效果图2如下
由此图可知,当'全选'按钮实现清除功能时,会把前几页的数据都清空掉,这个bug很严重。
以上所说都是全选按钮的测试,还有子复选框的测试,博主就不在贴出效果图了,简单的把测试案例阐述一下
1、当把当前页所有的复选框选中时,全选按钮也要选中。
2、当多次选中某个复选框时,要判断此复选框是否已经选中,大家可以看到效果图里有一个textarea标签,本标签就是为了可视化的展示哪些按钮已选中
首先要取到textarea里的值(idStrings),当textarea标签里没有编号时(idStrings为空字符串),选中某个复选框,则idStrings不为空,当在选中其它按钮时,动态将此按钮的id值拼装到idStrings里,若选中的某个复选框的值已存在于idStrings字符串里,应该将此按钮的id值从idStrings里剔除。
博主就讨论这些了,测试的情况有很多种,就不一一阐述了。
现给出核心代码:
JSP页面代码:
<form:form id="xxxId" action="xxxAction">
<input id="idString" type="hidden" name="idString"/>
<input id="idStrings" name="idStrings" value="${idStrings }"/>
<input id="checkedFlagId" name="checkedFlag" value="${checkedFlag }"/>
<table id="contentTable" class="table table-striped table-bordered table-condensed">
<thead>
<tr>
<th>序号</th>
<th><input type="checkbox" name="checkboxbutton" value="all" id="checkboxall" onclick="funcCheckAll()">全选</th>
<th>编号</th>
</tr>
</thead>
4000
<tbody>
<c:forEach items="${page.list}" var="item" varStatus="status">
<tr>
<td>${status.index + 1}</td>
<td>
<c:choose>
<c:when test="${fn:contains(listStringIds, item.bid) }">
<input type="checkbox" name="ids" checked="checked" value="${item.bid}" id="subcheck" onclick="checkReturn(this)">
</c:when>
<c:otherwise>
<input type="checkbox" name="ids" value="${item.bid}" id="subcheck" onclick="checkReturn(this)">
</c:otherwise>
</c:choose>
</td>
<td>${item.bid}</td>
</tr>
</c:forEach>
</tbody>
</table>
</form:form>
JS代码如下:
此段代码,是进入该页面就加载的函数,防止全选按钮第一次是失效的(测试当中发现,只有点两次全选按钮时,才会真正选中)
$(document).ready(function () {
//获取subcheck的个数
var chsub = $("input[type='checkbox'][id='subcheck']").length;
//获取选中的subcheck的个数
var checkedsub = $("input[type='checkbox'][id='subcheck']:checked").length;
if (checkedsub == 0) {
$("#checkedFlagId").val('false');
}
if (checkedsub == chsub) {
$("#checkboxall").attr("checked", true);
}
});
function checkReturn(obj) { var objIds = obj.value; var rt = false; // 中间变量,用于给$("#idStrings").val()赋值 var idArray = ""; // 传到后台的值(已选中的单选框的id) var idStrings = $("#idStrings").val(); var checkedFlag = $("#checkedFlagId").val(); if (idStrings == "") { idArray = objIds; } else { // 说明已有单选框被选中 var idsArrays = ""; // 已选的id里包含上传的objIds,说明是取消选中该id,则把该id从idStrings里删除 if (idStrings.indexOf(objIds) >= 0) { var splitArray = idStrings.split(objIds); // 重新拼装所有已选中的单选框的值(可能会有多余的',') idsArrays = splitArray[0] + splitArray[1]; } else { // 已选的id里不包含上传的objIds,说明是选中该id,则把该id添加到idStrings里 idArray = idStrings + "," + objIds; var checkDelete = document.getElementsByName("ids"); for(var i=0; i<checkDelete.length; i++) { if(checkDelete[i].type == "checkbox" && checkDelete[i].checked) { flag = true; } } if (checkedFlag && flag) { // 控制全选按钮的选中 $("#checkboxall").attr('checked', 'checked'); } } // 把idsArrays里多余的','去掉 var idsString = idsArrays.split(","); for (var j=0; j<idsString.length; j++) { if (idsString[j] != "") { if (idArray == "") { idArray = idsString[j]; } else { idArray = idArray + "," +idsString[j]; } } } } $("#idStrings").val(idArray); //当没有选中某个子复选框时,checkboxall取消选中 if (!$("#subcheck").checked) { $("#checkboxall").attr("checked", false); } // 获取subcheck的个数 var chsub = $("input[type='checkbox'][id='subcheck']").length; // 获取选中的subcheck的个数 var checkedsub = $("input[type='checkbox'][id='subcheck']:checked").length; if (checkedsub == 0) { $("#checkedFlagId").val('false'); } if (checkedsub == chsub) { // 控制全选按钮的选中 $("#checkboxall").attr("checked", true); } } function funcCheckAll() { var checkedFlag = $("#checkedFlagId").val(); var flag = false; // 传到后台的值(已选中的单选框的id),并且将字符串中的[和]替换掉,方便翻页之后继续拼装传到后台的值 var idStrings = $("#idStrings").val().replace(/\[/g,"").replace(/\]/g,""); var idString = ""; var checkDelete = document.getElementsByName("ids"); // 判断全选按钮是否是已选中状态 // $("#checkboxall").prop("checked")说明已选中 // JQuery版本不同,if条件不同 if ($("#checkboxall").prop("checked")) { // 循环遍历各个子单选按钮,并把他们值拼接到idString for(var i=0; i<checkDelete.length; i++) { if (idString == "") { idString = checkDelete[i].value; } else { idString = idString + "," + checkDelete[i].value; } } // 将各个子单选按钮设为选中状态 $('input[name=ids]').attr('checked', 'checked'); checkedFlag = true; $("#checkedFlagId").val(checkedFlag); // 若传到后台的各个单选框的id不为空,将他们拼装 if (idStrings != "") { idString = idString + "," + idStrings; } } else { // 此时全选按钮起到反选作用 for(var i=0; i<checkDelete.length; i++) { // 单选框是选中状态的 if(checkDelete[i].type == "checkbox" && checkDelete[i].checked) { // 此处不能单纯的把选中状态的id清空,因为有可能是多页都是选中的,只能清空本页的id // 只能从所有idStrings里把本页的id去除 var objId = checkDelete[i].value; if (idStrings.indexOf(objId) >= 0) { var splitArray = idStrings.split(objId); // 重新拼装所有已选中的单选框的值(可能会有多余的',') idStrings = splitArray[0] + splitArray[1]; } } } // 把idsArrays里多余的','去掉 var idsString = idStrings.split(","); for (var j=0; j<idsString.length; j++) { if (idsString[j] != "") { if (idString == "") { idString = idsString[j]; } else { idString = idString + "," +idsString[j]; } } } // 将选中状态改为非选中 $('input[name=ids]').removeAttr('checked'); checkedFlag = false; $("#checkedFlagId").val(checkedFlag); } // 去除重复的id begin // 把字符串分割成数组 var strArr = idString.split(","); var tempString = ""; for (var i in strArr) { if (tempString == "") { tempString = strArr[i]; } else if (!(tempString.indexOf(strArr[i]) >= 0)) { // 可以去重 tempString = tempString + "," + strArr[i]; } } // 去除重复的id end $("#idStrings").val(tempString); // 将所有选中的id赋值,用于传给后台 //$("#idStrings").val(idString); var checkDelete = document.getElementsByName("ids"); for(var i=0; i<checkDelete.length; i++) { if(checkDelete[i].type == "checkbox" && checkDelete[i].checked) { flag = true; } } if (checkedFlag && flag) { // 控制全选按钮的选中 $("#checkboxall").attr('checked', 'checked'); } }
后台JAVA代码:
String idStrings = request.getParameter("idStrings");
String checkedFlag = request.getParameter("checkedFlag");
if (null != idStrings && !"".equals(idStrings)) {
String ids[] = idStrings.split(",");
Set<String> setString = new HashSet<String>();
for (String id: ids) {
setString.add(id);
}
assetView.setSetString(setString);
Set<String> stringTemp = assetView.getSetString();
String idsString = "";
// 拼装成后台需要的数据格式:xx,xx,..
for (String tempString : stringTemp) {
if ("".equals(idsString)) {
idsString = tempString;
} else {
idsString = idsString + "," + tempString;
}
}
model.addAttribute("idStrings", idsString);
}
model.addAttribute("checkedFlag", checkedFlag);
相关文章推荐
- 基于jQuery实现复选框的全选 全不选 反选功能
- jquery实现全选反选功能
- JQuery实现列表中复选框全选反选功能封装
- Jquery之实现全选反选功能
- 功能选中jquery实现全选反选功能
- JQuery实现列表中复选框全选反选功能封装(推荐)
- jquery实现全选/反选功能
- JQuery 中 实现复选框全选/全不选/反选功能 案例
- JQuery实现全选,不选,反选功能
- Jquery 实现全选反选功能
- jquery实现简单的全选和反选功能
- jquery实现全选反选功能---兰
- JQuery学习(4)全选反选功能的实现
- Jquery实现全选反选功能
- jquery实现简单的全选和反选功能
- 基于jQuery实现复选框的全选 全不选 反选功能
- jquery实现全选、全消、反选功能
- js, jQuery实现全选、反选功能
- jQuery实现checkbox列表的全选、反选功能
- JQuery实现列表中复选框全选反选功能封装