实现CheckBox的三种选中状态(全选、半选、不选)在GridView中模拟树形的功能

度娘了很多帖子,只说三种状态要用图片替换来做,但没找到有用的例子,被逼自己写了一个

三方控件肯定是很多的,如jstree,可以直接用

由于公司的UDS限制,不能上传图片,只能文字说明了。

就是要在gridview中实现如下效果:一级、二级因为三级没有全部选中而显示半选状态

▣一级
   ▣二级
      三级1
       三级2

 

 

 

 

js↓

$(function(){

        BindCheckNode();

        $("span[name^='lblCheck']").click(checkBoxClick);

     });



function checkBoxClick()

     {

        var isChecked = $(this).attr("class") == "default" ? "checked"  : "default";

        $(this).attr("class",isChecked);

        //同步checkbox

        $(this).next().children().eq(0).attr("checked",isChecked!="default");  

        var trNode = $(this).parent().parent();

        

        childChange(trNode,isChecked);

        parentChange(trNode,isChecked); 

     }



//数据绑定时,对选中状态的节点做变更,如果有一个子节点没有选中,则为半选中状态

       function BindCheckNode()

       {

           //判断选中状态的节点的子节点是否全部选中,

           $("span[name^='lblCheck']").each(function(){

                if($(this).attr("class")=="checked")

                {

                    var curNode = this.parentNode.parentNode;

                    if(!CheckAll(curNode))

                    {

                        $(this).attr("class","checkHalf");

                    } 

                }

            });

       }    

          

       //选中状态判断

       function CheckAll(curNode) 

       {

         var level = parseInt($(curNode).attr("level"));

         var id = $(curNode).attr("id");

         var nextNode = $(curNode).next();

         while (nextNode != null && parseInt($(nextNode).attr("level")) > level) {

            //每个节点都要循环它的所有子节点,判断是否选择

             var nextCheck=$(nextNode).children().eq(0).children("span").eq(1); 

             if ($(nextCheck).attr("class") == "default") {

                 return false;   

             }

             nextNode = $(nextNode).next();

         }

         return true; 

     }

     

     //checkbox点击后影响子节点

     function childChange(curNode,className)

     {

        var level = parseInt($(curNode).attr("level"));

        var nextNode = $(curNode).next();

        

        //循环子节点

        while(nextNode!=null && parseInt($(nextNode).attr("level") ) > level)

        {

            var nextCheck=$(nextNode).children().eq(0).children("span:eq(1)"); 

            $(nextCheck).attr("class",className);

            $(nextCheck).next().children().eq(0).attr("checked",className!="default");   

            nextNode=$(nextNode).next();  

        } 

     }

     

     //checkbox点击后影响父节点

     function parentChange(curNode, className)

     {

        var pid = $(curNode).attr("pid");

        var parentNode = $("#"+pid);

        if(!$(parentNode).attr("pid"))

            return false;

        

        var parentSpanCheck=$(parentNode).children().eq(0).children("span").eq(1);

        var childList = $("tr[pid='"+pid+"']");

        var flag = false;

        var tempNode;

        $.each(childList, function(i,item){

            tempNode = $(item).children().eq(0).children("span").eq(1);

            if($(tempNode).attr("class") != className)

           {

                flag = true; 

                return;

           }

        });

        if(flag)

        {

            $(parentSpanCheck).attr("class", "checkHalf");

        } 

        else if(!flag && className == "checked")

        {

             $(parentSpanCheck).attr("class", "checked");

        }

        else

        {

             $(parentSpanCheck).attr("class", "default");

        }

        var parentSpanCheckClass=$(parentSpanCheck).attr("class");

        $(parentSpanCheck).next().children().eq(0).attr("checked",parentSpanCheckClass!="default");   

        if(pid != "0")

            changeParentState(parentNode, className);

     }
View Code

css↓  主要是背景图的移动,图片排列方式为 [全选][未选][半选]

 <style type="text/css">

        .checked {background-position-x: 0px;}

        .checkHalf{background-position-x: 23px;}

        .default{background-position-x: 46px;}

    </style>
View Code

C#前台 ↓  已将多余的东西删掉,gridview中只有一列,跟上面的table相似,lbl_Space用来增加缩进的,保留原始的checkbox,因为在保存的时候需要遍历整个gridview,不管是后台还是js中修改span的class属性,遍历gridview的时候是获取不到的

<asp:GridView ID="dgResource" OnRowDataBound="dgResource_RowDataBound" DataKeyNames="ResourceID" runat="server" AutoGenerateColumns="False">

                        <Columns>



                            <asp:TemplateField>

                                <HeaderStyle Wrap="False"></HeaderStyle>

                                <ItemStyle Wrap="False"></ItemStyle>

                                <ItemTemplate>

                                    <asp:Label runat="server" ID="lbl_Space" ForeColor="#f5fbff" Text='<%# GetSpaceNameFromLevel(DataBinder.Eval(Container, "DataItem.NameValues[Level]").ToString()) %>'>

                                    </asp:Label>

                                    <span id="lblCheck" name="lblCheck" runat="server" class="default" style="width: 23px;

                                        height: 25px; background-image: url(../../Common/Images/Icons/checkboxButton.jpg);">

                                    </span>

                                   <div style="display:none;">

                                    <asp:CheckBox runat="server" ID="chk_Query"></asp:CheckBox>

                                   </div>  

                                    <asp:Label runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.ResourceName") %>'></asp:Label>

                                    <asp:HiddenField ID="hfdPID" runat="server" Value='<%# Eval("ParentResourceID") %>' />

                <asp:HiddenField ID="hfdLevel" runat="server" Value='<%# Eval("NameValues[Level]") %>' />

                                </ItemTemplate>

                            </asp:TemplateField>

                        </Columns>

                    </asp:GridView>
View Code

 

.net ↓

protected void dgResource_RowDataBound(object sender, GridViewRowEventArgs e)

        {

            if (e.Row.RowType == DataControlRowType.DataRow)

            {

                string id = ParamUtil.getstring(dgResource.DataKeys[e.Row.RowIndex]["ResourceID"]);

                string pid = (e.Row.FindControl("hfdPID") as HiddenField).Value;

                string level = (e.Row.FindControl("hfdLevel") as HiddenField).Value;

                string application = (e.Row.FindControl("hfdApplication") as HiddenField).Value;

                //增加节点的属性

                e.Row.Attributes.Add("id", id);

                e.Row.Attributes.Add("pid", pid);

                e.Row.Attributes.Add("level", level);

        }

}





//点击保存时

for (int i = 0; i < dgResource.Rows.Count; i++)

{

    CheckBox chkQuery = (CheckBox)dgResource.Rows[i].FindControl("chk_Query");

    //根据chkQuery的Checked即可获取是否选中,注:半选也算选中

}
View Code

 

你可能感兴趣的:(checkbox)