js树结构--带复选框--c#(递归)

导读:
  
  在项目中,有一个通讯录组以及通讯录的功能,通讯录组要求无限分级,树状结构显示 ,经过研究,完整地实现了树结构,效果如下还可以实时添加,修改,删除,使用ajax实现,客户端不会刷新
  下面先讲怎样在服务端实现这个树结构,首先,数据库设计至少三个字段,主建,名称,父节点(记录父节点主键),由于本项目中树结构较多,所以我用一个实体类来表示TreeEntity.cs
  using System;using System.Collections.Generic;using System.Text;namespace SmsSystem.Model{
  public class TreeEntity
  {
  public TreeEntity() { } public TreeEntity(int id, string name, int parentId) {
  this.id = id;
  this.name = name;
  this.parentId = parentId;
  } private int id;
  private string name;
  private int parentId;
  public int Id
  {
  get { return id; } set { id = value ; } } public string Name
  {
  get { return name; } set { name = value ; } } public int ParentId
  {
  get { return parentId; } set { parentId = value; } } }}
  
  数据库访问层我在一篇文件中曾经提到过http://blog.csdn.net/cleverfoxloving/archive/2006/09/15/1226956.aspx具体实现不详述了,我用一个类返回一个IList (没接触过C#的泛型的这里可能不明白,请参阅相关资料)
  /// /// 获得数据列表返回ArrayList ///
  public IList GetList(int companyRkey)
  {
  IList list = new List ();
  DataSet ds = this.GetDatasetList(" company_Rkey = " + companyRkey);
  if (ds.Tables[0].Rows.Count > 0)
  {
  foreach (DataRow dr in ds.Tables[0].Rows)
  {
  TreeEntity tree = new TreeEntity();
  tree.Id = int.Parse(dr["Rkey"].ToString());
  tree.Name = dr["Groupname"].ToString();
  tree.ParentId = int.Parse(dr["Parent_rkey"].ToString());
  list.Add(tree);
  } } return list;
  }
  接下来要写一个通用的方法,由list递归生成xml,GetTreeXML.cs
  using System;using System.Data;using System.Collections.Generic;using System.Xml;using System.IO;using SmsSystem.Model;namespace SmsSystem.Utility{
  public class GetTreeXML
  {
  public GetTreeXML() {
  
  }
  public void addDataXml(XmlDocument xmlDoc, XmlElement xmlRootNode, IList list)
  {
  foreach(TreeEntity treeEntity in list){
  if (treeEntity.ParentId == int.Parse(xmlRootNode.GetAttribute("mid")))
  {
  XmlElement xmlNewElemene = xmlDoc.CreateElement("subject");
  
  xmlNewElemene.SetAttribute("mid", treeEntity.Id.ToString());
  xmlNewElemene.SetAttribute("name", treeEntity.Name);
  xmlNewElemene.SetAttribute("value", treeEntity.ParentId.ToString());
  xmlRootNode.AppendChild(xmlNewElemene);
  addDataXml(xmlDoc, xmlNewElemene, list);
  } } } public XmlDocument getGroupTree(IList list)
  {
  XmlDocument xmlDoc = new XmlDocument();
  XmlDeclaration objXmlDeclare = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", "yes");
  xmlDoc.InsertBefore(objXmlDeclare, xmlDoc.DocumentElement);
  XmlElement xmlRootElem = xmlDoc.CreateElement("subject");
  xmlRootElem.SetAttribute("mid", "0");
  xmlRootElem.SetAttribute("name", "通讯录组群");
  xmlDoc.AppendChild(xmlRootElem);
  addDataXml(xmlDoc, xmlRootElem, list);
  return xmlDoc;
  } public string getGruopTreeStr(IList list)
  {
  return this.XmlDocumentToString(this.getGroupTree(list));
  } ///………………(其它树结构)
  public string XmlDocumentToString(XmlDocument doc)
  {
  MemoryStream stream = new MemoryStream();
  XmlTextWriter writer = new XmlTextWriter(stream, null);
  //writer.Formatting = Formatting.Indented; doc.Save(writer);
  StreamReader sr = new StreamReader(stream, System.Text.Encoding.UTF8);
  stream.Position = 0 string xmlString = sr.ReadToEnd();
  sr.Close();
  stream.Close();
  return xmlString;
  } }}
  
  这上面的四个方法是主要的核心方法,接下来就是客户端采用Ajax调用,以及有JS生成树结构显示了,只列出部分重要代码,首先简单说一个Ajax调用,采用AjaxPro.dll框架,具体用法参考相关资料,代码如下
  protected void Page_Load(object sender, EventArgs e)
  {
  AjaxPro.Utility.RegisterTypeForAjax(typeof(Address_AddressManage));
  
  
  } [AjaxPro.AjaxMethod]
  public string GetAddressGruopStr() {
  if (null != Session["userInfo"])
  {
  bool isAll = (((SmsSystem.BO.UserInfo)Session["userInfo"]).PopedomType == "1") ? true : false int userRkey = ((SmsSystem.BO.UserInfo)Session["userInfo"]).CustEmployee_Rkey;
  SmsSystem.BLL.AddressGroup addressGroupBll = new SmsSystem.BLL.AddressGroup();
  return addressGroupBll.getGroupTreeStr(userRkey, isAll);
  
  } else {
  Response.Redirect("Default.aspx");
  return null }
  } [AjaxPro.AjaxMethod]
  public DataSet GetAddressList(int AddressGroupRkey)
  {
  if (null != Session["userInfo"])
  {
  bool isAll = (((SmsSystem.BO.UserInfo)Session["userInfo"]).PopedomType == "1") ? true : false int userRkey = ((SmsSystem.BO.UserInfo)Session["userInfo"]).CustEmployee_Rkey;
  SmsSystem.BLL.AddressList AddressListBll = new SmsSystem.BLL.AddressList();
  return AddressListBll.GetDatasetList(userRkey, isAll, AddressGroupRkey);
  } else {
  Response.Redirect("Default.aspx");
  return null } }
  
  首先在Page_Load要注册Ajax框架,然后是两个供Ajax调用的方法,返回字符串,在客户端
  function swapClass(obj, cls) {
  obj.className = cls;
  }var TreeForm = document.getElementById("TreeForm");function SelChkBox(para){
  
  var bTrue=false with(TreeForm)
  for(i=0i
  {
  if ((document.forms[0].elements[i].name=="chkbutton") && (document.forms[0].elements[i].value==para))
  {
  bTrue=!document.forms[0].elements[i].checked;
  document.forms[0].elements[i].checked=bTrue;
  break } } if (para=='All')
  {
  with(TreeForm)
  for (i=0i
  {
  if(document.forms[0].elements[i].name=="chkbutton")
  {
  document.forms[0].elements[i].checked=bTrue;
  } } } else {
  SelectAllNode(para,bTrue);
  }}//点击一个节点的复选框function SelChkBoxSingle(para){
  var bTrue=false with(TreeForm)
  for(i=0i
  {
  if ((document.forms[0].elements[i].name=="chkbutton") && (document.forms[0].elements[i].value==para))
  {
  bTrue=!document.forms[0].elements[i].checked;
  } else {
  document.forms[0].elements[i].checked = false } }}//选择一个节点function SelChkBoxSingle1(para){
  var bTrue=false with(TreeForm)
  for(i=0i
  {
  if ((document.forms[0].elements[i].name=="chkbutton") && (document.forms[0].elements[i].value==para))
  {
  bTrue=!document.forms[0].elements[i].checked;
  document.forms[0].elements[i].checked=bTrue;
  } } else {
  if (document.forms[0].elements[i].checked) document.forms[0].elements[i].checked = !document.forms[0].elements[i].checked;
  } }}// checkbox onclickfunction SelChkBox1(para){
  var bTrue=false with(TreeForm)
  for(i=0i
  {
  if ((document.forms[0].elements[i].name=="chkbutton") && (document.forms[0].elements[i].value==para))
  {
  bTrue=document.forms[0].elements[i].checked;
  break } } if (para=='All')
  {
  with(TreeForm)
  for(i=0i
  {
  if(document.forms[0].elements[i].name=="chkbutton")
  {
  document.forms[0].elements[i].checked=bTrue;
  } } } else {
  SelectAllNode(para,bTrue);
  }}function SelectAllNode(sMidValue,bTrue){
  var xmlDoc1 = new ActiveXObject("MSXML.DOMDocument")
  xmlDoc1.async = false xmlDoc1.loadXML(xmlSSS)
  return SelectNode(xmlDoc1.documentElement,sMidValue,bTrue)
  }function SelectNode(oElem,sMidValue,bTrue){
  var retStr="" var oNodeList = oElem.childNodes
  if (GetAttributes(oElem,"mid")==sMidValue)
  {
  SelectChildNode(oElem,bTrue);
  if (bTrue)
  SelectParentNode(oElem,bTrue);
  else IsParentChecked(oElem);
  return } else {
  for (var i=0i<=oNodeList.length-1i++)
  {
  SelectNode(oNodeList.item(i),sMidValue,bTrue)
  } }}function SelectChildNode(oElem,bTrue){
  var oNodeList = oElem.childNodes
  for (var i=0i<=oNodeList.length-1i++)
  {
  ClickNode(GetAttributes(oNodeList.item(i),"mid"),bTrue);
  SelectChildNode(oNodeList.item(i),bTrue)
  }}//检查当前节点的父节点的子节点是否有被选中的。//如故没有,则父节点的CheckBox的checked=false;function IsParentChecked(oElem){
  var bExist=false do {
  if (GetAttributes(oElem,"mid")=="")
  break else {
  var pNode = oElem.parentNode
  var oNodeList = pNode.childNodes;
  for (var i=0i<=oNodeList.length-1i++)
  {
  if (IsNodeChecked(GetAttributes(oNodeList.item(i),"mid")))
  {
  bExist = true break } } if (bExist) break ClickNode(GetAttributes(pNode,"mid"),false);
  oElem=pNode;
  } } while(true);
  }//选中所有的父节点function SelectParentNode(oElem,bTrue){
  do {
  if (GetAttributes(oElem,"mid")=="")
  break else {
  var pNode=oElem.parentNode;
  ClickNode(GetAttributes(pNode,"mid"),bTrue);
  oElem=pNode;
  } } while(true);
  }//判断某一节点是否被选中。function IsNodeChecked(sMidValue){
  var bChecked=false with(TreeForm)
  for(i=0i
  {
  if ((document.forms[0].elements[i].name=="chkbutton") && (document.forms[0].elements[i].value==sMidValue))
  {
  bChecked=document.forms[0].elements[i].checked;
  break } } return bChecked;
  }function ClickNode(sMidValue,bTrue){
  with(TreeForm)
  for(i=0i
  {
  if ((document.forms[0].elements[i].name=="chkbutton") && (document.forms[0].elements[i].value==sMidValue))
  {
  document.forms[0].elements[i].checked=bTrue;
  break } }}var bAll=truebAll=trueif (bAll){
  sAllChecked=""}var tree = new WebFXTree('通讯录组',sAllChecked,"0","javascript:void(0);");
  tree.setBehavior('classic');function AddNode(oElem,oTreeNode){
  var oNewNode;
  if (oTreeNode==null)
  {
  oNewNode = tree;
  } else {
  var sChecked="" //if (GetAttributes(oElem,"value")=="1") // sChecked="checked"; if (GetAttributes(oElem,"type")=="subject")
  var oNewNode = new WebFXTreeItem(GetAttributes(oElem,"name"),sChecked,GetAttributes(oElem,"mid"),"javascript:SelChkBoxSingle('"+GetAttributes(oElem,"mid")+"')");
  else var oNewNode = new WebFXTreeItem(GetAttributes(oElem,"name"),sChecked,GetAttributes(oElem,"mid"),"javascript:GetResultXml('"+GetAttributes(oElem,"mid")+"')");
  oTreeNode.add(oNewNode);
  } var oNodeList = oElem.childNodes
  for (var i=0i<=oNodeList.length-1i++)
  {
  if (oElem.nodeType==1){
  AddNode(oNodeList.item(i),oNewNode)
  } }}function GetAttributes(oElm,AttrName){
  var sAttr="" for (var i=0i<=oElm.attributes.length-1i++)
  {
  if (oElm.attributes.item(i).nodeName==AttrName)
  {
  sAttr = oElm.attributes.item(i).nodeValue;
  break } } return sAttr
  }function LoadXmlResult(){
  document.getElementById("showAderessGroupTree").innerHTML="通讯录树正在载入……" SmsSystem.Address_AddressManage.GetAddressGruopStr(LoadXmlResult_callback);
  }function LoadXmlResult_callback(response){
  if(response.value == null){
  alert("没有任何数据!");
  return } xmlString = response.value;
  createTree("showAderessGroupTree",xmlString);
  
  }function createTree(treeDivId,xmlString){
  if (document.getElementById) {
  var xmlDoc = new ActiveXObject("MSXML.DOMDocument")
  xmlDoc.async = false xmlDoc.loadXML(xmlString)
  AddNode(xmlDoc.documentElement)
  
  document.getElementById(treeDivId).innerHTML=tree;
  //document.write(tree); // tree.expandAll() }}//添加资源function addGroup(){
  var str="" var name=""
  for(var i=0i
  if(document.forms[0].chkbutton[i].checked==true){
  str=document.forms[0].chkbutton[i].value;
  name = document.forms[0].chkbutton[i].label;
  break
  }
  }
  if(str=='){
  alert('请选择待修改类别名称!');
  return false } document.all["addGroupDiv"].style.left=120 document.all["addGroupDiv"].style.top=140 document.all["addGroupDiv"].style.display="" document.getElementById("groupName").value=name;
  }function modifyGroup(){
  (修改的代码,省略…………)}function cancalAdd(divID){
  document.all[divID].style.display="none"}function GetResultXml(mid){
  SmsSystem.Address_AddressManage.GetAddressList(mid,GetResult_callback);
  
  }function GetResult_callback(response){
  
  if(response.value == null){
  alert("没有任何数据!");//可以自行添加对于无数据的处理流程 return }
  var dt = response.value.Tables[0];
  
  if (dt.Rows.length>0){
  
  fillContent(dt)
  }else{
  removeContent();
  var showAddressListt = document.getElementById("showAddressListt");
  var row=document.createElement('tr');
  row.setAttribute("height","26");
  row.setAttribute("bgColor","#FFFFFF");
  var cell=createCellth('没有记录,清先添加记录!');
  cell.setAttribute("width","380");
  row.appendChild(cell);
  showAddressListt.appendChild(row);
  return }
  }function removeContent(){
  var showAddressListt = document.getElementById("showAddressListt");
  while(showAddressListt.childNodes.length>0)
  {
  showAddressListt.removeChild(showAddressListt.childNodes[0]);
  }}function fillContent(dt){
  
  
  
  removeContent();
  if (dt){
  document.getElementById("addressListtTable").style.width="800px" //var showResult = document.getElementById("showResult"); var showAddressListt = document.getElementById("showAddressListt");
  //var tableContent = document.createElement("table"); //tableContent.setAttribute("bgColor","#FF0000"); //tableContent.setAttribute("width","300"); //增加一行,设置标题 var row=document.createElement('tr');
  row.setAttribute("height","26");
  row.setAttribute("bgColor","#FFFFFF");
  
  var cell=createCellth(');
  cell.setAttribute("width","30");
  row.appendChild(cell);
  cell=createCellth('序号');
  cell.setAttribute("width","60");
  row.appendChild(cell);
  cell=createCellth('姓名');
  cell.setAttribute("width","120");
  row.appendChild(cell);
  cell=createCellth('性别');
  cell.setAttribute("width","120");
  row.appendChild(cell);
  cell=createCellth('手机号');
  cell.setAttribute("width","120");
  row.appendChild(cell);
  cell=createCellth('生日');
  cell.setAttribute("width","200");
  row.appendChild(cell);
  cell=createCellth('公司名称');
  cell.setAttribute("width","120");
  row.appendChild(cell);
  cell=createCellth('公司电话');
  cell.setAttribute("width","120");
  row.appendChild(cell);
  cell=createCellth('公司传真');
  cell.setAttribute("width","120");
  row.appendChild(cell);
  cell=createCellth('职务');
  cell.setAttribute("width","100");
  row.appendChild(cell);
  cell=createCellth('备注');
  cell.setAttribute("width","100");
  row.appendChild(cell);
  cell=createCellth('创建日期');
  cell.setAttribute("width","140");
  row.appendChild(cell);
  
  showAddressListt.appendChild(row);
  //设置标题结束 //循环处理填充表格 for(var i=0i
  
  
  
  var row=document.createElement('tr');
  row.setAttribute("height","23");
  if(i%2==0){
  row.setAttribute("bgColor","#FFFFFF");
  }else{
  row.setAttribute("bgColor","#F5F5F5");
  } var cell=createCheckbox(dt.Rows[i].Rkey);
  
  row.appendChild(cell);
  
  cell=createCelltd((i+1));
  row.appendChild(cell);
  cell=createCelltd(dt.Rows[i].Name);
  row.appendChild(cell);
  var sex = "男" if(dt.Rows[i].Sex == '1'){
  sex = "女" } cell=createCelltd(sex);
  row.appendChild(cell);
  cell=createCelltd(dt.Rows[i].MobileNo);
  row.appendChild(cell);
  var tempBirthday = new Date(dt.Rows[i].Birthday);
  cell=createCelltd(tempBirthday.toLocaleDateString());
  row.appendChild(cell);
  cell=createCelltd(dt.Rows[i].ComName);
  row.appendChild(cell);
  cell=createCelltd(dt.Rows[i].ComTel);
  row.appendChild(cell);
  cell=createCelltd(dt.Rows[i].ComFax);
  row.appendChild(cell);
  cell=createCelltd(dt.Rows[i].Duty);
  row.appendChild(cell);
  cell=createCelltd(dt.Rows[i].Remark);
  row.appendChild(cell);
  var tempFileDate = new Date(dt.Rows[i].FileDate);
  
  cell=createCelltd(tempFileDate.toLocaleDateString());
  row.appendChild(cell);
  //生成操作链接 //row.appendChild(addLink(smsID,smsContent));
  
  showAddressListt.appendChild(row);
  }
  //showResult.appendChild(tableContent); }}function createCellth(text){
  var cell=document.createElement('th');
  var textNode=document.createTextNode(text);
  cell.appendChild(textNode);
  return cell;
  }function createCelltd(text){
  var cell=document.createElement('td');
  cell.style.background ="#FFFFFF" //cell.setAttribute("bgcolor","#FFFFFF"); var textNode=document.createTextNode(text);
  cell.appendChild(textNode);
  return cell;
  }function createCheckbox(id){
  var cell=document.createElement('td');
  cell.style.background ="#FFFFFF" var input=document.createElement('input');
  input.setAttribute("id","selectId");
  input.setAttribute("name","id");
  input.setAttribute("type","checkbox");
  
  cell.appendChild(input);
  return cell;
  }
  
  以上是初步实现的部分js脚本,在未重构之前显得有些凌乱,还用到了一个WebFXTree的js树,是前辈高人写的,内容太多了,这里不便列出,页面上部分代码下如
  

>  
  • 通讯录组群
  • 通讯录

  •   
      
      

  •   
    通讯录联系人员

  
<script type="text/javascript" defer="defer">var dw=new slcDragWindow("addGroupDiv","frmTitle","closeFrame");
  LoadXmlResult();</script>
  最下面这个LoadXmlResult()便是采用Ajax调用,当然,这里实际上没怎么体现Ajax的优势,只有点了某个节点,去取出此节点下对应的通讯录联系人员,才是真正的Ajax应用,在上面的js中GetResultXml(mid)才是。
  刚初步实现了效果,没有重构,样式也没有整理,所以html和js的代码较凌散,还有部分未给出(实在是太多了),而且还有一些功能没有实现,比如全选,批量删除,把一个组中的的联系人员转到另一组中,对某条记录点右键菜单中列出复制,粘贴,剪贴,发送短信,编辑,删除等,有待日后完善,努力把web程序做的跟C/S可蓖美的用户体验,我今天所做只希望能起到抛砖引玉的作用,如果确实需要参考全部代码,可以用cleverfoxloving@gmail.com跟我联系,夜太深了,写的有些乱,请多包涵:)晚安。
  Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1298167

本文转自
http://blog.csdn.net/cleverfoxloving/archive/2006/09/28/1298167.aspx
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值