Jquery实现父子类复选框,选择父类子类全选,选择子类父类显示中间状态,并传值到java后台

父子类复选框,选择父类子类全选,选择子类父类显示中间状态。先看一下图片效果是不是各位想要的,下面的方法我会从选择样式以及判断选择了那些值传入java后台,以及修改时的回显。包括html代码,css代码,js代码。Jquery实现父子类复选框,选择父类子类全选,选择子类父类显示中间状态,并传值到java后台

上图是做的一个二级的权限功能,左边为一级父类,右边为二级子类。

先看在新增时的页面代码(我新增和修改的写的并不是一样的,因为修改的时候毕竟代码会复杂点影响效率,而且新增和修改的页面也不是一样的,所以就分开写了)

html代码如下:

                         <div class="bottom_list">
                                <div class="list_header">权限列表</div>
                                <div class="list_content">
                                    <c:forEach var="permAll" items="${permTree}" varStatus="psatrt" >
                                        <div class="list_content_item"><!-- style="width:400px; float: left; -->
                                            <div class="list_content_left">
                                                <li>
                                                    <input type="checkbox" value="${permAll.premId}" id="p_${psatrt.index}"
                                                         onclick="pchange(${psatrt.index})">
                                                    </input>
                                                         <span>${permAll.premName}</span>
                                                </li>
                                            </div>
                                            <div class="list_content_right">
                                                <ul>
                                                    <c:if test="${not empty permAll.childrenList}">
                                                          <c:forEach var="permChild" items="${permAll.childrenList}" varStatus="csatrt" >
                                                                  <li>
                                                                   <input type="checkbox" name="pc_${psatrt.index}" value="${permChild.premId}"
                                                                       id="${psatrt.index}_c_${csatrt.index}" onclick="cchange(${psatrt.index})">
                                                                   </input>
                                                                   <span>${permChild.premName}</span>
                                                               </li>
                                                        </c:forEach>
                                                    </c:if>
                                                </ul>
                                            </div>
                                        </div>
                                     </c:forEach>  
                                </div>
                            </div>

                           <input type="hidden" id="permIds" name="permIds"/>

id="permIds"是隐藏域,为了给后台传值用的;

${permTree}为权限树集合

${permAll.premId}为权限id

${permAll.premName}为


js代码如下:

下面的这个方法,对于父类复选全种子类全选子类也全选,父类取消选中子类也是全部取消选中,代码比较简洁、简单、时效,还是不错的,很值得借鉴。

function pchange(index){
      var pid = "p_"+index;
      var cid = "pc_"+index;
      var cname = "input[name="+cid+"]:checkbox";
      if($("#"+pid).is(':checked')) {
          $(cname).prop("checked", true);
      }else{
          $(cname).prop("checked", false);
      }
  }

考虑到父类的中间状态,就是子类选择了一部分,但还有一部分未选中,所以父类不是对勾状的,而是正方形状的。这样在子类每去点击一次复选框都需要去判断父类是需要不选还是全选还是中间的状态

  function cchange(index){
         var pid = "p_"+index;
         <c:forEach var="permAll" items="${permTree}" varStatus="psatrt" >
            if(index == "${psatrt.index}"){
                var i = 0;
                var j = 0;
                   <c:forEach var="permChild" items="${permAll.childrenList}" varStatus="csatrt" >
                           if($("#${psatrt.index}_c_${csatrt.index}").is(':checked')){
                              i++;
                     }
                           j = ${csatrt.count};
                </c:forEach>
                if(i == j){
                    $("#p_${psatrt.index}").prop("indeterminate", false);
                    $("#p_${psatrt.index}").prop("checked", true);
                }else if(i>0){
                    $("#p_${psatrt.index}").prop("checked", false);
                    $("#p_${psatrt.index}").prop("indeterminate", true);
                }else{
                    $("#p_${psatrt.index}").prop("checked", false);
                    $("#p_${psatrt.index}").prop("indeterminate", false);
                }
            }
        </c:forEach>
     }

  接下来是提交时如果判断或是选取复选框所选的值,我们需要是,只要子类有一个或是以上的选中,那么父类的值也要保存到数据库中。

var perIdStr = "";
         <c:forEach var="permAll" items="${permTree}" varStatus="psatrt" >
             if($("#p_${psatrt.index}").is(':checked')){
                 perIdStr = perIdStr + $("#p_${psatrt.index}").val() + "_";
             }
            if("${permAll.childrenList != null}" != "false"){
                      <c:forEach var="permChild" items="${permAll.childrenList}" varStatus="csatrt" >
                           if($("#${psatrt.index}_c_${csatrt.index}").is(':checked')){
                         perIdStr = perIdStr + $("#${psatrt.index}_c_${csatrt.index}").val() + "_";
                         if(perIdStr.indexOf($("#p_${psatrt.index}").val())==-1){
                             perIdStr = perIdStr + $("#p_${psatrt.index}").val() + "_";
                         }
                     }
                </c:forEach>
            }
        </c:forEach>
        var  perIdStr = $.trim(perIdStr);
        perIdStr = perIdStr.substr(0,perIdStr.length-1);
        $("#permIds").val(perIdStr);

此处是将选中复选框的id作为字符串以“,”逗号去拼接的,有特殊需要的也可以组装js数组等。

css代码如下(放入.css文件中):

.content .shouzhi .shouzhi-top .content .bottom_list {
  margin-left: 30px;
  height: 497px;
  width: 1036px;
  border: 1px solid #d7d7d7;
  border-bottom: none;
}
.content .shouzhi .shouzhi-top .content .bottom_list .list_header {
  height: 42px;
  line-height: 42px;
  background-color: #f2f2f2;
  padding-left: 12px;
  border-bottom: 1px solid #d7d7d7;
}
.content .shouzhi .shouzhi-top .content .bottom_list .list_content {
  background-color: #ffffff;
}
.content .shouzhi .shouzhi-top .content .bottom_list .list_content input {
  width: 16px;
  height: 16px;
}
.content .shouzhi .shouzhi-top .content .bottom_list .list_content .list_content_item .list_content_left {
  height: 68px;
  width: 186px;
  border-right: 2px solid #d7d7d7;
  float: left;
  border-bottom: 1px solid #d7d7d7;
}
.content .shouzhi .shouzhi-top .content .bottom_list .list_content .list_content_item .list_content_left li {
  padding-left: 18px;
  padding-top: 24px;
}
.content .shouzhi .shouzhi-top .content .bottom_list .list_content .list_content_item .list_content_right {
  float: right;
  width: 848px;
  height: 68px;
  border-bottom: 1px solid #d7d7d7;
}
.content .shouzhi .shouzhi-top .content .bottom_list .list_content .list_content_item .list_content_right ul li {
  display: inline-block;
  padding-left: 20px;
  padding-top: 24px;
}
.content .shouzhi .shouzhi-top .content .bottom_list .list_content .list_content_item:nth-child(1) .list_content_left {
  height: 108px;
  width: 186px;
  border-right: 2px solid #d7d7d7;
  float: left;
  border-bottom: 1px solid #d7d7d7;
}
.content .shouzhi .shouzhi-top .content .bottom_list .list_content .list_content_item:nth-child(1) .list_content_left li {
  padding-left: 18px;
  padding-top: 44px;
}
.content .shouzhi .shouzhi-top .content .bottom_list .list_content .list_content_item:nth-child(1) .list_content_right {
  float: right;
  width: 848px;
  height: 108px;
  border-bottom: 1px solid #d7d7d7;
}
.content .shouzhi .shouzhi-top .content .bottom_list .list_content .list_content_item:nth-child(1) .list_content_right ul {
  padding-top: 20px;
}
.content .shouzhi .shouzhi-top .content .bottom_list .list_content .list_content_item:nth-child(1) .list_content_right ul li {
  display: inline-block;
  padding: 10px  20px;
}

接下来再看一下修改时,复选框是如何回显的:

html代码如下:

                                    <c:forEach var="permAll" items="${permTree}" varStatus="psatrt" >
                                        <div class="list_content_item"><!-- style="width:400px; float: left; -->
                                            <div class="list_content_left">
                                                <li>
                                                    <input type="checkbox" name="parePerm" value="${permAll.premId}" id="p_${psatrt.index}"
                                                        onclick="pchange(${psatrt.index})">
                                                    </input>
                                                         <span>${permAll.premName}</span>
                                                </li>
                                            </div>
                                            <div class="list_content_right">
                                                <ul>
                                                    <c:if test="${not empty permAll.childrenList}">
                                                          <c:forEach var="permChild" items="${permAll.childrenList}" varStatus="csatrt" >
                                                                  <li>
                                                                   <input type="checkbox" name="p_${psatrt.index}" value="${permChild.premId}"
                                                                       id="${psatrt.index}_c_${csatrt.index}" onclick="cchange(${psatrt.index})">
                                                                   </input>
                                                                   <span>${permChild.premName}</span>
                                                               </li>
                                                        </c:forEach>
                                                    </c:if>
                                                </ul>
                                            </div>
                                        </div>
                                     </c:forEach> 

js代码如下:

 $(function(){
     var permTreeStr = $("#permTreeStr").val();
     <c:forEach var="permAll" items="${permTree}" varStatus="psatrt" >
        if("${not empty permAll.childrenList}" != "false"){
            var i = 0;
            var j = 0;
               <c:forEach var="permChild" items="${permAll.childrenList}" varStatus="csatrt" >
                       var permChildv = ${permChild.premId};
                       if(permTreeStr.indexOf(permChildv) > 0){
                          $("#${psatrt.index}_c_${csatrt.index}").prop("checked", true);
                          i++;
                 }
                       j = ${csatrt.count};
            </c:forEach>
            if(i == j){
                $("#p_${psatrt.index}").prop("indeterminate", false);
                $("#p_${psatrt.index}").prop("checked", true);
            }else if(i>0){
                $("#p_${psatrt.index}").prop("checked", false);
                $("#p_${psatrt.index}").prop("indeterminate", true);
            }
        }
    </c:forEach>
  })

初始化方法,其实这里最主要的就是,复选框当有值的时候是选中的还是未确定的状态?这里是需要特殊去判断的。

做这个还是需要多自己尝试一下,其实挺简单的。

如果有哪位朋友发现更好的方法,不妨提供一下,谢谢了!