制作一个带三态CheckBox的Tree

 
网上有很多树的例子,感觉都是不太尽如人意。俗话说,自己动手丰衣足食,自己来做一个吧。
         首先三态节点树必须是带有 CheckBox 的树,这里简单说明一下所做的三态树。所谓三态是指:选中状态,半选中状态,未选中状态。选中状态:节点的 CheckBox 打勾;半选中状态:节点的 CheckBox 打勾,但为灰色;未选中状态: CheckBox 不打勾。
        其次,子节点全选中,父节点选中;子节点全不选中,父节点不选中;子节点选中但未全部选中,父节点半选中;子节点半选中,父节点半选中;父节点选中子节点全选中,父节点取消,子节点全取消。
代码如下:客户端( JAVASCRIPT
< script type = " text/jscript "  language = " javascript " >    
    
function  ShowLegend(ControlID,LegendInfo)
{
    alert(LegendInfo);
    
var para = "LegendInfo="+LegendInfo + "&Visible=" + document.all(ControlID).checked;
    
var myAjax = new Ajax.Request('../ajax/WebFormChangeLegendVisible.aspx',{method: 'get', parameters:para, onComplete: RefreshMap});
}


function  RefreshMap(request)
{
    
var content = request.responseText;
    parent.mapview.document.forms[
0].submit();
}


function  OnTreeNodeChecked() 

    
var element = window.event.srcElement; 
    
if (!IsCheckBox(element)) 
        
return
    
    
var isChecked = element.checked; 
    
var isIndeterminate = element.Indeterminate;
    
var tree = TV2_GetTreeById("TreeView1"); 
    
var node = TV2_GetNode(tree,element); 

    TV2_SetChildNodesCheckState(node,isChecked); 
    
//alert(element.id);

    
var parent = TV2_GetParentNode(tree,node); 
    TV2_NodeOnChildNodeCheckedChanged(tree,parent,isChecked); 
    
    
//document.all("txtSelectID").value = "";
    var aCheckBox = document.getElementsByTagName("input");
    
for (var i=0;i<aCheckBox.length;i++)
    
{
        
if(aCheckBox[i].type == "checkbox"
        
{
            
if(aCheckBox[i].checked)
            
{
                
var sID = aCheckBox[i].id;
                sID 
= sID.substring(0,sID.indexOf("CheckBox")); 
                
var obja = document.getElementById(sID.replace('n','t'));            
                
var sSelectID = obja.href.replace("javascript:__doPostBack('TreeView1','s')","")
                sSelectID 
= sSelectID.replace("')","")
                var aSelectID = sSelectID.split("/")
            }

        }

    }


}
 

// 设置子节点CheckBox的状态
function  TV2_SetChildNodesCheckState(node,isChecked) 

    
var childNodes = TV2i_GetChildNodesDiv(node); 
    
if(childNodes == null
        
return

    
var inputs = WebForm_GetElementsByTagName(childNodes,"INPUT"); 
    
if(inputs == null || inputs.length == 0
        
return

    
for(var i = 0; i < inputs.length; i++
    

        
if(IsCheckBox(inputs[i])) 
            inputs[i].checked 
= isChecked; 
            inputs[i].indeterminate 
= false//父结点改变状态,子节点灰色消失
            
    }
 
}
 


// 当子节点CheckBox状态改变引发的父结点状态改变
function  TV2_NodeOnChildNodeCheckedChanged(tree,node,isChecked,isIndeterminate) 

    
if(node == null
        
return

    
var childNodes = TV2_GetChildNodes(tree,node); 

    
if(childNodes == null || childNodes.length == 0
        
return

    
var isAllSame = true
    
var Nodegray = isIndeterminate;  //节点的灰色
    for(var i = 0; i < childNodes.length; i++)  //循环子节点
    
        
var item = childNodes[i];               //获取一个子节点
        var value = TV2_NodeGetChecked(item);   //获取子节点的checked状态
        var value2 = TV2_NodeGetindeterminate(item);   //获取子节点的isIndeterminate状态
        if(isChecked != value)       //如果checkbox的选中状态不相同
        
            isAllSame 
= false
            Nodegray 
= true;
            
break
        }
 
        
if(value2)
        
{
            Nodegray 
= true;
        }

    }
 

    
var parent = TV2_GetParentNode(tree,node); 
    
if(isAllSame)   //为真:即checkbox的选中状态相同
    
        TV2_NodeSetChecked(tree,node,isChecked,Nodegray);  
//设置当前节点状态
        TV2_NodeOnChildNodeCheckedChanged(tree,parent,isChecked,Nodegray);   //向父结点递归
    }
 
    
else            //为假,即checkbox的选中状态不相同,或出于灰色状态
    
        TV2_NodeSetChecked(tree,node,
true,Nodegray); //设置当前节点状态
        TV2_NodeOnChildNodeCheckedChanged(tree,parent,true,Nodegray);         //向父结点递归
    }
 
}
 


// get node relative element(etc. checkbox) 
function  TV2_GetNode(tree,element) 

    
var id = element.id.replace(tree.id,""); 
    id 
= id.toLowerCase().replace(element.type,""); 
    id 
= tree.id + id; 

    
var node = document.getElementById(id); 
    
if(node == null//leaf node, no "A" node 
        return element; 
    
return node; 
}
 

// get parent node 
function  TV2_GetParentNode(tree,node) 

    
var div = WebForm_GetParentByTagName(node,"DIV"); 

    var table = div.previousSibling; 
    
if(table == null
        
return null

    
return TV2i_GetNodeInElement(tree,table); 
}
 

// get child nodes array 
function  TV2_GetChildNodes(tree,node) 

    
if(TV2_NodeIsLeaf(node)) 
        
return null

    
var children = new Array(); 
    
var div = TV2i_GetChildNodesDiv(node); 
    
var index = 0

    
for(var i = 0; i < div.childNodes.length; i++
    

        
var element = div.childNodes[i]; 
        
if(element.tagName != "TABLE"
        
continue

        
var child = TV2i_GetNodeInElement(tree,element); 
        
if(child != null
            children[index
++= child; 
    }
 
    
return children; 
}
 

function  TV2_NodeIsLeaf(node) 

    
return !(node.tagName == "A"); //Todo 
}
 

// 读取结点的Checked状态
function  TV2_NodeGetChecked(node) 

    
var checkbox = TV2i_NodeGetCheckBox(node); 
    
return checkbox.checked; 
}
 

// 读取节点的indeterminate状态
function  TV2_NodeGetindeterminate(node) 

    
var checkbox = TV2i_NodeGetCheckBox(node); 
    
return checkbox.Indeterminate; 
}
 

// 判断:只要该节点有一个子节点被选中,则该节点一定被选中,若有一个子节点为灰色,则该节点为灰色 
function  TV2_NodeSetChecked(tree,node,isChecked,isIndeterminate) 

    
var checkbox = TV2i_NodeGetCheckBox(node); 
    
if(checkbox != null
    

        
var childNodes = TV2_GetChildNodes(tree,node);  //获取子节点的集合
        for(var i = 0; i < childNodes.length; i++
        

            
var item = childNodes[i];               //获取一个子节点
            var value = TV2_NodeGetChecked(item);   //子节点的选中状态
            var value2 = TV2_NodeGetindeterminate(item); //子节点的灰色状态
            if(value)     
            

                isChecked 
= true ;  
                
break
            }
 
            
if(value2)//子节点为灰色
            {
            isInDeterminate
=true;
            
break;
            }

        }
 
        checkbox.checked 
= isChecked;   //结点选中状态
        checkbox.indeterminate = isIndeterminate; //结点是否灰色
    }
 
}
 

function  IsCheckBox(element) 

    
if(element == null
        
return false
    
return (element.tagName == "INPUT" && element.type.toLowerCase() == "checkbox"); 
}
 

// get tree 
function  TV2_GetTreeById(id) 

    
return document.getElementById(id); 
}
 


// get div contains child nodes 
function  TV2i_GetChildNodesDiv(node) 

    
if(TV2_NodeIsLeaf(node)) 
        
return null

    
var childNodsDivId = node.id + "Nodes"
    
return document.getElementById( childNodsDivId ); 
}
 

    
// find node in element 
function  TV2i_GetNodeInElement(tree,element) 

    
var node = TV2i_GetNodeInElementA(tree,element); 
    
if(node == null
    

        node 
= TV2i_GetNodeInElementInput(tree,element); 
    }
 
    
return node; 
}
 

// find "A" node 
function  TV2i_GetNodeInElementA(tree,element) 

    
var as = WebForm_GetElementsByTagName(element,"A"); 
    
if(as== null || as.length == 0
        
return null

    
var regexp = new RegExp("^" + tree.id + "n/d+$"); 

    
for(var i = 0; i < as.length; i++
    

        
if(as[i].id.match(regexp)) 
        

            
return as[i]; 
        }
 
    }
 
    
return null
}
 

// find "INPUT" node 
function  TV2i_GetNodeInElementInput(tree,element) 

    
var as = WebForm_GetElementsByTagName(element,"INPUT"); 
    
if(as== null || as.length == 0
        
return null

    
var regexp = new RegExp("^" + tree.id + "n/d+"); 
    
for(var i = 0; i < as.length; i++
    

        
if(as[i].id.match(regexp)) 
        

            
return as[i]; 
        }
 
    }
 
    
return null
}
 

// get checkbox of node 
function  TV2i_NodeGetCheckBox(node) 

    
if(IsCheckBox(node)) 
        
return node; 

    
var id = node.id + "CheckBox"
    
return document.getElementById(id); 
}
        

function  showtab(m,n,count) {
    
var strPic1='url(../image/1.bmp)';
    
var strPic2='url(../image/2.bmp)';
    
if (m==8{
    strPic1
='url(../image/switch03_1.gif)';
    strPic2
='url(../image/switch03_2.gif)';    }


    
for(var i=1;i<=count;i++){
        
if (i==n){            
            getObject(m
+'_'+i).style.background=strPic1;
            getObject(
'tab_'+m+'_'+i).style.display='';            
            }

        
else {
            getObject(m
+'_'+i).style.background=strPic2;
            getObject(
'tab_'+m+'_'+i).style.display='none';
            }

    }

}

function  getObject(objectId)  {
    
if(document.getElementById && document.getElementById(objectId)) {
    
// W3C DOM
    return document.getElementById(objectId);
    }
 else if (document.all && document.all(objectId)) {
    
// MSIE 4 DOM
    return document.all(objectId);
    }
 else if (document.layers && document.layers[objectId]) {
    
// NN 4 DOM.. note: this won't find nested layers
    return document.layers[objectId];
    }
 else {
    
return false;
    }

}
  //  getObject

function  Init()
{
    
//var w = document.body.scrollWidth;
    var w = document.body.clientWidth;
    
//var h = document.body.scrollHeight;
    var h = document.body.clientHeight;
    
    getObject(
"tabTree").style.height = h-90;    
    getObject(
"divHRTree").style.height=h-100;
}


    
</ script >
当然,仅有客户端的代码是不够的。我们还需要在服务器端构造一棵树。最简单的方法就是从工具箱——〉导航 中将一个TreeView控件拖到页面上。在TreeView的属性——〉行为中的“ShowCheckBox”一项改为“all”,这样,一个带有CheckBox的树就构造成功了。在服务器端的Page_Load下加入代码:
             if  ( ! Page.IsPostBack)
            
{
                
//转入前台的 OnTreeNodeChecked()
                TreeView1.Attributes.Add("onclick""OnTreeNodeChecked()");
             }
       当然,树中的节点是用户自己添加还是从数据库中读取出来的还是从域中读取出来的这都不是我们讨论的问题,现在,我们的三态树已经大功告成了。你可以手动为树添加几个节点测试一个,代码不需要做修改,按以上步骤 COPE 到自己页面上就可以用,唯一要改的就是你创建的 TreeView 的名字,我的代码中的 TreeView 的名字为 TreeView1 。有什么问题可以给我留言大家一起讨论。 ^ ^
 
 
 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值