JQuery实现全选、全不选和反选功能 JQuery实现全选、全不选和反选功能

JQuery实现全选、全不选和反选功能

        项目中需要做一个全选、全不选和反选的功能。刚接到这个需求的时候,心想很简单的一个功能,几行代码就能搞定,然而事实并非如此。下面就把我的思路说一下:


1、当点击'全选'按钮时,页面中所有的复选框都应该为选中状态,

       1.1、当再次点击'全选'按钮时,所有的复选框应该是非选中状态。

       1.2、当点击子复选框时,'全选'按钮应该是非选中状态。

2、当选中当前页面的所有子复选框时,'全选'按钮应该是'选中'状态。

3、点点击'全不选'按钮时,当前页面的所有复选框置为非选中状态。

4、当点击'反选'按钮时,当前页面选中状态的复选框置为未选中状态,未选中状态的复选框置为选中状态。


在网上看到的一些博客中,很多都是有bug的,下面挑选出了一个存在bug的demo。

还有一个要注意的地方:就是JQuery中空格的问题,如

[javascript]  view plain  copy
  1. $("#checkBoxList :checkbox").attr("checked"true);改行代码里':'前有一个空格(若空格在后,好像函数也不能执行),而且是必须的  

[javascript]  view plain  copy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>  
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  3. <html>  
  4.     <head>  
  5.         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  6.         <title>Insert title here</title>  
  7.         <script type="text/javascript" src="js/jquery-1.8.3.js"></script>  
  8.         <script type="text/javascript">  
  9.             $(function() {  
  10.                 $("#selectAll").click(function(){  
  11.                     $("#checkBoxList :checkbox").attr("checked"true);  
  12.                 });  
  13.                 $("#unSelect").click(function(){  
  14.                     $("#checkBoxList :checkbox").attr("checked"false);  
  15.                 });  
  16.                 $("#reverseSelect").click(function(){  
  17.                     $("#checkBoxList :checkbox").each(function(){  
  18.                         $(this).attr("checked", !$(this).attr("checked"));  
  19.                     });  
  20.                 });  
  21.             });  
  22.         </script>  
  23.     </head>  
  24.     <body>  
  25.         <div id="checkBoxList">  
  26.             <input type="checkbox" value="项羽"/>项羽<br>  
  27.             <input type="checkbox" value="范增"/>范增<br>  
  28.             <input type="checkbox" value="龙且"/>龙且<br>  
  29.             <input type="checkbox" value="刘邦"/>刘邦<br>  
  30.             <input type="checkbox" value="萧何"/>萧何<br>  
  31.             <input type="checkbox" value="韩信"/>韩信<br>  
  32.         </div>  
  33.         <input type="checkbox" value="全选" id="selectAll"/>全选  
  34.         <input type="checkbox" value="全不选" id="unSelect"/>全不选  
  35.         <input type="checkbox" value="反选" id="reverseSelect"/>反选  
  36.     </body>  
  37. </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页面代码:

[html]  view plain  copy
  1. <form:form id="xxxId" action="xxxAction">  
  2.    <input id="idString" type="hidden" name="idString"/>  
  3.    <input id="idStrings" name="idStrings"  value="${idStrings }"/>  
  4.    <input id="checkedFlagId" name="checkedFlag" value="${checkedFlag }"/>  
  5.    <table id="contentTable" class="table table-striped table-bordered table-condensed">  
  6.       <thead>  
  7.          <tr>  
  8.         <th>序号</th>  
  9.         <th><input type="checkbox" name="checkboxbutton" value="all" id="checkboxall" onclick="funcCheckAll()">全选</th>  
  10.             <th>编号</th>  
  11.          </tr>  
  12.       </thead>  
  13.       <tbody>  
  14.          <c:forEach items="${page.list}" var="item" varStatus="status">  
  15.             <tr>  
  16.                <td>${status.index + 1}</td>  
  17.                <td>  
  18.                   <c:choose>  
  19.                      <c:when test="${fn:contains(listStringIds, item.bid) }">  
  20.                         <input type="checkbox" name="ids" checked="checked" value="${item.bid}" id="subcheck" onclick="checkReturn(this)">  
  21.                      </c:when>  
  22.                      <c:otherwise>  
  23.                 <input type="checkbox" name="ids" value="${item.bid}" id="subcheck" onclick="checkReturn(this)">  
  24.                      </c:otherwise>  
  25.                   </c:choose>  
  26.                </td>  
  27.                <td>${item.bid}</td>  
  28.             </tr>  
  29.          </c:forEach>  
  30.       </tbody>  
  31.    </table>  
  32. </form:form>  


JS代码如下:

此段代码,是进入该页面就加载的函数,防止全选按钮第一次是失效的(测试当中发现,只有点两次全选按钮时,才会真正选中)

[javascript]  view plain  copy
  1. $(document).ready(function () {  
  2.    //获取subcheck的个数  
  3.    var chsub = $("input[type='checkbox'][id='subcheck']").length;  
  4.    //获取选中的subcheck的个数   
  5.    var checkedsub = $("input[type='checkbox'][id='subcheck']:checked").length;  
  6.    if (checkedsub == 0) {  
  7.       $("#checkedFlagId").val('false');  
  8.    }  
  9.    if (checkedsub == chsub) {  
  10.       $("#checkboxall").attr("checked"true);  
  11.    }  
  12. });  

[javascript]  view plain  copy
  1. function checkReturn(obj) {  
  2.    var objIds = obj.value;  
  3.    var rt = false;  
  4.    // 中间变量,用于给$("#idStrings").val()赋值  
  5.    var idArray = "";   
  6.    // 传到后台的值(已选中的单选框的id)  
  7.    var idStrings = $("#idStrings").val();   
  8.    var checkedFlag = $("#checkedFlagId").val();  
  9.    if (idStrings == "") {  
  10.       idArray = objIds;  
  11.    } else { // 说明已有单选框被选中  
  12.       var idsArrays = "";  
  13.       // 已选的id里包含上传的objIds,说明是取消选中该id,则把该id从idStrings里删除  
  14.       if (idStrings.indexOf(objIds) >= 0) {   
  15.          var splitArray = idStrings.split(objIds);  
  16.          // 重新拼装所有已选中的单选框的值(可能会有多余的',')  
  17.          idsArrays = splitArray[0] + splitArray[1];   
  18.       } else { // 已选的id里不包含上传的objIds,说明是选中该id,则把该id添加到idStrings里  
  19.          idArray = idStrings + "," + objIds;  
  20.          var checkDelete = document.getElementsByName("ids");  
  21.          for(var i=0; i<checkDelete.length; i++) {  
  22.             if(checkDelete[i].type == "checkbox" && checkDelete[i].checked) {  
  23.                flag = true;  
  24.             }  
  25.          }  
  26.          if (checkedFlag && flag) {  
  27.             // 控制全选按钮的选中  
  28.             $("#checkboxall").attr('checked''checked');  
  29.          }  
  30.       }  
  31.       // 把idsArrays里多余的','去掉  
  32.       var idsString = idsArrays.split(",");  
  33.       for (var j=0; j<idsString.length; j++) {  
  34.          if (idsString[j] != "") {  
  35.             if (idArray == "") {  
  36.                idArray = idsString[j];  
  37.             } else {  
  38.                idArray = idArray + "," +idsString[j];  
  39.             }  
  40.          }  
  41.       }  
  42.    }  
  43.    $("#idStrings").val(idArray);  
  44.    //当没有选中某个子复选框时,checkboxall取消选中  
  45.    if (!$("#subcheck").checked) {  
  46.       $("#checkboxall").attr("checked"false);  
  47.    }  
  48.    // 获取subcheck的个数  
  49.    var chsub = $("input[type='checkbox'][id='subcheck']").length;  
  50.    // 获取选中的subcheck的个数   
  51.    var checkedsub = $("input[type='checkbox'][id='subcheck']:checked").length;  
  52.    if (checkedsub == 0) {  
  53.       $("#checkedFlagId").val('false');  
  54.    }  
  55.    if (checkedsub == chsub) {  
  56.       // 控制全选按钮的选中  
  57.       $("#checkboxall").attr("checked"true);   
  58.    }  
  59. }  
  60.           
  61. function funcCheckAll() {  
  62.    var checkedFlag = $("#checkedFlagId").val();   
  63.    var flag = false;  
  64.    // 传到后台的值(已选中的单选框的id),并且将字符串中的[和]替换掉,方便翻页之后继续拼装传到后台的值  
  65.    var idStrings = $("#idStrings").val().replace(/\[/g,"").replace(/\]/g,"");   
  66.    var idString = "";  
  67.    var checkDelete = document.getElementsByName("ids");  
  68.    // 判断全选按钮是否是已选中状态  
  69.    // $("#checkboxall").prop("checked")说明已选中  
  70.    // JQuery版本不同,if条件不同  
  71.    if ($("#checkboxall").prop("checked")) {  
  72.       // 循环遍历各个子单选按钮,并把他们值拼接到idString  
  73.       for(var i=0; i<checkDelete.length; i++) {  
  74.          if (idString == "") {  
  75.             idString = checkDelete[i].value;  
  76.          } else {  
  77.             idString = idString + "," + checkDelete[i].value;  
  78.          }  
  79.       }  
  80.       // 将各个子单选按钮设为选中状态  
  81.       $('input[name=ids]').attr('checked''checked');  
  82.       checkedFlag = true;  
  83.       $("#checkedFlagId").val(checkedFlag);  
  84.       // 若传到后台的各个单选框的id不为空,将他们拼装  
  85.       if (idStrings != "") {  
  86.          idString = idString + "," + idStrings;  
  87.       }  
  88.    } else { // 此时全选按钮起到反选作用  
  89.       for(var i=0; i<checkDelete.length; i++) {  
  90.          // 单选框是选中状态的  
  91.          if(checkDelete[i].type == "checkbox" && checkDelete[i].checked) {  
  92.             // 此处不能单纯的把选中状态的id清空,因为有可能是多页都是选中的,只能清空本页的id  
  93.             // 只能从所有idStrings里把本页的id去除  
  94.             var objId = checkDelete[i].value;  
  95.             if (idStrings.indexOf(objId) >= 0) {  
  96.                var splitArray = idStrings.split(objId);  
  97.                // 重新拼装所有已选中的单选框的值(可能会有多余的',')  
  98.                idStrings = splitArray[0] + splitArray[1];  
  99.             }  
  100.          }  
  101.       }  
  102.       // 把idsArrays里多余的','去掉  
  103.       var idsString = idStrings.split(",");  
  104.       for (var j=0; j<idsString.length; j++) {   
  105.          if (idsString[j] != "") {  
  106.             if (idString == "") {  
  107.                idString = idsString[j];  
  108.             } else {  
  109.                idString = idString + "," +idsString[j];  
  110.             }  
  111.          }  
  112.       }  
  113.       // 将选中状态改为非选中  
  114.       $('input[name=ids]').removeAttr('checked');  
  115.       checkedFlag = false;  
  116.       $("#checkedFlagId").val(checkedFlag);  
  117.    }  
  118.    // 去除重复的id begin  
  119.    // 把字符串分割成数组  
  120.    var strArr = idString.split(",");  
  121.    var tempString = "";  
  122.    for (var i in strArr) {  
  123.       if (tempString == "") {  
  124.          tempString = strArr[i];  
  125.       } else if (!(tempString.indexOf(strArr[i]) >= 0)) { // 可以去重  
  126.          tempString = tempString + "," + strArr[i];  
  127.       }  
  128.    }  
  129.    // 去除重复的id end  
  130.    $("#idStrings").val(tempString);  
  131.    // 将所有选中的id赋值,用于传给后台  
  132.    //$("#idStrings").val(idString);  
  133.    var checkDelete = document.getElementsByName("ids");  
  134.    for(var i=0; i<checkDelete.length; i++) {  
  135.       if(checkDelete[i].type == "checkbox" && checkDelete[i].checked) {  
  136.          flag = true;  
  137.       }  
  138.    }  
  139.    if (checkedFlag && flag) {  
  140.       // 控制全选按钮的选中  
  141.       $("#checkboxall").attr('checked''checked');  
  142.    }  
  143. }  

后台JAVA代码:

[java]  view plain  copy
  1. String idStrings = request.getParameter("idStrings");  
  2. String checkedFlag = request.getParameter("checkedFlag");  
  3. if (null != idStrings && !"".equals(idStrings)) {  
  4.    String ids[] = idStrings.split(",");  
  5.    Set<String> setString = new HashSet<String>();  
  6.    for (String id: ids) {  
  7.       setString.add(id);  
  8.    }  
  9.    assetView.setSetString(setString);  
  10.    Set<String> stringTemp = assetView.getSetString();  
  11.    String idsString = "";  
  12.    // 拼装成后台需要的数据格式:xx,xx,..  
  13.    for (String tempString : stringTemp) {  
  14.       if ("".equals(idsString)) {  
  15.          idsString = tempString;  
  16.       } else {  
  17.          idsString = idsString + "," + tempString;  
  18.       }  
  19.    }  
  20.    model.addAttribute("idStrings", idsString);  
  21. }  
  22. model.addAttribute("checkedFlag", checkedFlag);  

猜你喜欢

转载自blog.csdn.net/qq_32444825/article/details/80332079