ajax+asp无限级分类树型结构(带数据库) |
IE测试通过,FF有点小BUG Cls_Leibie.asp 复制代码 代码如下: <% 数据库字段为类属性,添加、删除、修改、操作检查等函数为类的方法 Class Cls_Leibie Private nClassID,sClassName,nParentID,sParentPath,nDepth,nRootID,nChild,nOrderID,sFilePath 定义私有变量(类的属性,即数据库字段对应的变量) Private rs,sql,ErrorStr Private Sub Class_Initialize() ErrorStr="" 初始化错误信息为空 End Sub Private Sub Class_Terminate() 销毁类时关闭数据库连接 If IsObject(Conn) Then Conn.Close Set Conn = Nothing End If End Sub *******************设置各个属性****************************************************** Public Property Let ClassID(str) 获取类别ID(主键) nClassID=str call ClassProperty() 获取类别ID时调用此函数读出类的所有属性 End Property Public Property Let ClassName(str) 获取类别名称 sClassName=str End Property Public Property Get ClassName ClassName=sClassName End Property Public Property Let ParentID(str) 获取类别父ID nParentID=str End Property Public Property Get ParentID ParentID=nParentID End Property Public Property Let ParentPath(str) 获取父路径ID sParentPath=str End Property Public Property Get ParentPath ParentPath=sParentPath End Property Public Property Let Depth(str) 获取类别深度 nDepth=str End Property Public Property Get Depth Depth=nDepth End Property Public Property Let RootID(str) 获取类别根ID nRootID=str End Property Public Property Get RootID RootID=nRootID End Property Public Property Let Child(str) 子类别个数 nChild=str End Property Public Property Get Child Child=nChild End Property Public Property Let OrderID(str) 排序ID nOrderID=str End Property Public Property Get OrderID OrderID=nOrderID End Property Public Property Let FilePath(str) 类别文件根目录(生成静态文件路径,小站老杨Web技术博客用的是生成静态,故设置此字段) sFilePath=str End Property Public Property Get FilePath FilePath=sFilePath End Property ****************************************************************************** Private Sub ClassProperty() 读取类的所有属性 sql="select * from ArticleClass where ClassID="& nClassID set rs=conn.execute(sql) if not rs.eof then sClassName=trim(rs("ClassName")) nParentID=trim(rs("ParentID")) sParentPath=trim(rs("ParentPath")) nDepth=trim(rs("Depth")) nRootID=trim(rs("RootID")) nChild=trim(rs("Child")) nOrderID=trim(rs("OrderID")) sFilePath=trim(rs("FilePath")) end if set rs=nothing End Sub Public Function FAddCheck() 类别添加检查函数,结果为0表示通过检查,为1表示有错误发生,有错误发生时退出函数,将错误信息写入错误变量ErrorStr dim temprs FAddCheck=0 if sClassName="" then 类名为空 FAddCheck=1 ErrorStr="类名不能为空!" exit Function else if nParentID="" then 父id为空 FAddCheck=1 ErrorStr="父id不能为空!" exit Function else if nParentID<>0 then set temprs=conn.execute("select ClassID From ArticleClass where ClassID=" & nParentID) 父类别不存在 if temprs.eof then FAddCheck=1 ErrorStr="所属类别不存在或已经被删除!" exit Function else sql="select ClassID from ArticleClass where ClassName="& sClassName &" and ParentID="& nParentID 类名重复 set rs=conn.execute(sql) if not rs.eof then FAddCheck=1 ErrorStr="类名重复!" exit Function end if set rs=nothing end if set temprs=nothing else sql="select ClassID from ArticleClass where ClassName="& sClassName &" and ParentID="& nParentID 类名重复 set rs=conn.execute(sql) if not rs.eof then FAddCheck=1 ErrorStr="类名重复!" exit Function end if set rs=nothing end if end if end if End Function Public Sub SAdd() dim maxClassID,maxRootID set rs = conn.execute("select Max(ClassID) from ArticleClass") 查找当前数据库中最大的类别id,如果没有数据则设置为0,要插入的类别id为当前最大id加1 maxClassID=rs(0) if isnull(maxClassID) then maxClassID=0 end if set rs=nothing nClassID=maxClassID+1 set rs=conn.execute("select max(rootid) From ArticleClass") 查找当前数据库中最大的根id,如果没有数据则设置为0,要插入的根id为当前最大根id加1 maxRootID=rs(0) if isnull(maxRootID) then maxRootID=0 end if nRootID=maxRootID+1 set rs=conn.execute("select RootID,Depth,ParentPath,Child,OrderID From ArticleClass where ClassID=" & nParentID) 查找父类别相应信息 if not rs.eof then nRootID=trim(rs("Rootid")) 根id与父类别根id相同 sParentPath=trim(rs("ParentPath"))& "," &nParentID if cint(trim(nParentID))>0 then 父id大于0则有父类别,故要插入的类别的深度父类别的深度加1,父id不大于0则当前要插入的类别为根类别,则深度为0 nDepth=cint(trim(rs("Depth")))+1 else nDepth=0 end if if cint(trim(rs("Child")))>0 then dim rsPrevOrderID 得到与本栏目同级的最后一个栏目的OrderID set rsPrevOrderID=conn.execute("select Max(OrderID) From ArticleClass where ParentID=" & ParentID) prevOrderID=rsPrevOrderID(0) 得到同一父栏目但比本栏目级数大的子栏目的最大OrderID,如果比前一个值大,则改用这个值 。 set rsPrevOrderID=conn.execute("select Max(OrderID) From ArticleClass where ParentPath like " & ParentPath & ",%") if (not(rsPrevOrderID.bof and rsPrevOrderID.eof)) then if not IsNull(rsPrevOrderID(0)) then if rsPrevOrderID(0)>prevOrderID then prevOrderID=rsPrevOrderID(0) end if end if end if set rsPrevOrderID=nothing end if nOrderID=prevOrderID+1 else nOrderID=0 sParentPath="0" nDepth=0 end if set rs=nothing nChild=0 sql="insert into ArticleClass (ClassID,ClassName,ParentID,ParentPath,Depth,RootID,Child,OrderID,FilePath) values ("& nClassID &","& sClassName &","& nParentID &","& sParentPath &","& nDepth &","& nRootID &","& nChild &","& nOrderID &","& sFilePath &")" conn.execute(sql) if ParentID>0 then 更新其父类的子栏目数 conn.execute("update ArticleClass set child=child+1 where ClassID="& nParentID) 更新该栏目排序以及大于本需要和同在本分类下的栏目排序序号 if prevOrderID<>"" then conn.execute("update ArticleClass set OrderID=OrderID+1 where rootid=" & nRootid & " and OrderID>"& prevOrderID &" and ClassID<>"& nClassID) end if end if End Sub Public Function FEditCheck() 类别修改检查函数,结果为0表示通过检查,为1表示有错误发生,有错误发生时退出函数,将错误信息写入错误变量ErrorStr dim temprs FEditCheck=0 if nClassID="" then 类别id为空 FEditCheck=1 ErrorStr="类别id不能为空!" exit Function else if sClassName="" then 类名为空 FEditCheck=1 ErrorStr="类名不能为空!" exit Function else if nParentID<>0 then set temprs=conn.execute("select ClassID From ArticleClass where ClassID=" & nParentID) 父类别不存在 if temprs.eof then FAddCheck=1 ErrorStr="所属类别不存在或已经被删除!" exit Function else set rs=conn.execute("select ClassID from ArticleClass where ClassName="& sClassName &" and ClassID<>"& nClassID &"and ParentID="& nParentID) if not rs.eof then 类名重复 FEditCheck=1 ErrorStr="类名重复!" exit Function end if set rs=nothing end if set temprs=nothing end if end if end if End Function Public Sub SEdit() 类别修改 sql="update ArticleClass set ClassName="& sClassName &",FilePath="& sFilePath &" where ClassID="& nClassID conn.execute(sql) End Sub Public Function FDeleteCheck() 类别删除检查函数,结果为0表示通过检查,为1表示有错误发生,有错误发生时退出函数,将错误信息写入错误变量ErrorStr FDeleteCheck=0 这里删除没有写级联删除文章部分的代码,删除时应该级联删除 if nClassID="" then FDeleteCheck=1 ErrorStr="要删除的类别id不能为空!" exit Function else set rs=conn.execute("select Child from ArticleClass where ClassID="& nClassID) if rs.bof and rs.eof then FDeleteCheck=1 ErrorStr="类别不存在或者已经被删除!" exit Function else if trim(rs("Child"))>0 then FDeleteCheck=1 ErrorStr="该类别含有子类别,请删除其子类别后再进行删除本类别的操作!" exit Function end if end if end if End Function Public Sub SDelete() if nDepth>0 then 修改父id孩子数 conn.execute("update ArticleClass set child=child-1 where child>0 and ClassID=" & nParentID) end if sql="delete from ArticleClass where ClassID="& nClassID conn.execute(sql) End Sub Public Function FErrStr() FErrStr=ErrorStr End Function End Class %> index.asp <%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%> <% 作者站点:www.guaishi.org 邮箱:guaishiorg@126.com QQ:514777880 Session.CodePage=65001 Response.Charset = "utf-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style type="text/css"> body{margin:0;padding:0;font-size:12px; background-color:#FFFFFF;} ul{ list-style-type:none; margin:0 0 0 20px; padding:0;} li{ white-space:nowrap; padding:0;} .childdiv{ background:url(images/dot.gif);background-repeat:repeat-y;} span { cursor:pointer;} </style> <script type="text/javascript"> var xmlHttp; //定义一个全局变量 var currentID=1;//设置当前选中ID,如果此ID不存在则会发生js错误 //类别显示主函数 //cid--子类别所在层id //id --类别id //pid--[+]和[-]图标id //fid--类别图标id function DivDisplay(cid,id,pid,fid) { if (GetId(cid).style.display==) //子类别不显示时图标显示控制 { GetId(cid).style.display=none; GetId(pid).src = images/closed.gif; GetId(fid).src = images/folder.gif; } else //展开子类别时的操作 { GetId(cid).style.display=; GetId(pid).src = images/opened.gif; GetId(fid).src = images/folderopen.gif; if (GetId(cid).innerHTML==||GetId(cid).innerHTML==正在提交数据...) { GetId(cid).innerHTML=; ShowChild(cid,id); //调用显示子类别函数 } } } //与上一个函数作用相同,只作用在最后一个类别 function DivDisplay2(cid,id,pid,fid) { if (GetId(cid).style.display==) { GetId(cid).style.display=none; GetId(pid).src = images/lastclosed.gif; GetId(fid).src = images/folder.gif; } else { GetId(cid).style.display=; GetId(pid).src = images/lastopen.gif; GetId(fid).src = images/folderopen.gif; if (GetId(cid).innerHTML==||GetId(cid).innerHTML==正在提交数据...) { GetId(cid).innerHTML=; ShowChild(cid,id); } } } //类别添加函数 //id--类别id function ClassAdd(id){ if (GetId("p"+id).src.indexOf("last")>0){ //最后一个类别时的添加操作 if (!GetId("p"+id).onclick){ GetId("p"+id).onclick=function (){DivDisplay2("c"+id,id,"p"+id,"f"+id);}; //为[+]和[-]添加单击事件 GetId("s"+id).ondblclick=function (){DivDisplay2("c"+id,id,"p"+id,"f"+id);}; //为显示类别文字的span添加双击事件 GetId("p"+id).src = images/lastopen.gif; } } else{ if (!GetId("p"+id).onclick){ //不为最后一个类别的添加操作 GetId("p"+id).onclick=function (){DivDisplay("c"+id,id,"p"+id,"f"+id);}; GetId("s"+id).ondblclick=function (){DivDisplay("c"+id,id,"p"+id,"f"+id);}; GetId("p"+id).src = images/opened.gif; } } GetId("c"+id).style.display=; ShowChild("c"+id,id); } //类别修改函数 function ClassEdit(id,classname){ GetId("s"+id).innerHTML=classname; } //有多个子类别的类别的删除函数 function ClassDel(id){ ShowChild("c"+id,id); CurrentSelect(currentID,id) BrowseRight(id); } //只有一个子类别的类别的删除函数 function ClassDel1(id){ if (GetId("p"+id).src.indexOf("last")>0){ //当类别是当前类别的最后一个类别时 GetId("p"+id).style.cursor="cursor"; //设置图标的鼠标经过样式 GetId("p"+id).onclick=function (){}; //因为只有一个子类别删除后就不再有子类别,故将图标单击事件修改为空函数 GetId("s"+id).ondblclick=function (){}; //同上 GetId("p"+id).src = images/lastnochild.gif; //图标设置 } else{ GetId("p"+id).style.cursor="cursor"; //非最后一个类别的删除操作 GetId("p"+id).onclick=function (){}; GetId("s"+id).ondblclick=function (){}; GetId("p"+id).src = images/nofollow2.gif; //这里的图标设置与前面不一样 } ShowChild("c"+id,id); CurrentSelect(currentID,id); BrowseRight(id); } //向右边框架传递参数 function BrowseRight(id){ CurrentSelect(currentID,id); top.ContentFrame.location="../ArticleMain.asp?ClassID="+ id; } //设置类别选中状态的函数 function CurrentSelect(oldid,newid){ currentID=newid; document.getElementById("s"+oldid).style.backgroundColor="white"; document.getElementById("s"+currentID).style.backgroundColor="#C0C0E9"; } //创建XMLHttpRequest对象 function CreateXMLHttpRequest() { if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else { xmlHttp = new XMLHttpRequest(); } } //Ajax处理函数 //id,层id //rid,数据在表中的id function ShowChild(cid,id) { CreateXMLHttpRequest(); if(xmlHttp) { xmlHttp.open(POST,child.asp,true); xmlHttp.setRequestHeader(Content-Type,application/x-www-form-urlencoded); var SendData = id=+id; xmlHttp.send(SendData); xmlHttp.onreadystatechange=function() { if(xmlHttp.readyState==4) { if(xmlHttp.status==200) { GetId(cid).innerHTML = xmlHttp.responseText; } else { GetId(cid).innerHTML=出错:+xmlHttp.statusText; } } else { GetId(cid).innerHTML="正在提交数据..."; } } } else { GetId(cid).innerHTML=抱歉,您的浏览器不支持XMLHttpRequest,请使用IE6以上版本!; } } //取得页面对象 //id,层id function GetId(id) { return document.getElementById(id); } </script> </head> <body> <!--#include file="../conn.asp"--> <% 显示根目录 sql="select *,(select top 1 ClassID from ArticleClass where Depth=0 order by ClassID desc) as lastid from ArticleClass where Depth=0 order by ClassID" set rs=conn.execute(sql) if not rs.eof then response.Write "<ul>"&vbcr do while not rs.eof if cint(trim(rs("ClassID")))=cint(trim(rs("lastid"))) then if rs("Child")>0 then response.Write "<li><img id=p"&rs("ClassID")&" src=""images/lastclosed.gif"" onclick=""DivDisplay2(c"&rs("ClassID")&","&rs("ClassID")&",p"&rs("ClassID")&",f"& rs("ClassID") &")"" style=""cursor : hand;"" align=""absmiddle"">" response.Write "<img src=""images/folder.gif"" align=""absmiddle"" id=f"& rs("ClassID") &" /> <span id=s"& trim(rs("ClassID")) &" onclick=""BrowseRight("& trim(rs("ClassID")) &")"" ondblclick=""DivDisplay2(c"&rs("ClassID")&","&rs("ClassID")&",p"&rs("ClassID")&",f"& rs("ClassID") &")"">"& rs("ClassName") &"</span>" else response.Write "<li><img id=p"& rs("ClassID") &" src=""images/lastnochild.gif"" align=""absmiddle"" />" response.Write "<img src=""images/folder.gif"" align=""absmiddle"" id=f"& rs("ClassID") &" /> <span id=s"& trim(rs("ClassID")) &" onclick=""BrowseRight("& trim(rs("ClassID")) &")"">"& rs("ClassName") &"</span>" end if else if rs("Child")>0 then response.Write "<li><img id=p"&rs("ClassID")&" src=""images/closed.gif"" onclick=""DivDisplay(c"&rs("ClassID")&","&rs("ClassID")&",p"&rs("ClassID")&",f"& rs("ClassID") &")"" style=""cursor : hand;"" align=""absmiddle"">" response.Write "<img src=""images/folder.gif"" align=""absmiddle"" id=f"& rs("ClassID") &" /> <span id=s"& trim(rs("ClassID")) &" onclick=""BrowseRight("& trim(rs("ClassID")) &")"" ondblclick=""DivDisplay(c"&rs("ClassID")&","&rs("ClassID")&",p"&rs("ClassID")&",f"& rs("ClassID") &")"">"& rs("ClassName") &"</span>" else response.Write "<li><img id=p"& rs("ClassID") &" src=""images/nofollow2.gif"" align=""absmiddle"" />" response.Write "<img src=""images/folder.gif"" align=""absmiddle"" id=f"& rs("ClassID") &" /> <span id=s"& trim(rs("ClassID")) &" onclick=""BrowseRight("& trim(rs("ClassID")) &")"">"& rs("ClassName") &"</span>" end if end if if cint(trim(rs("ClassID")))=cint(trim(rs("lastid"))) then response.Write "<div id=c"&rs("ClassID")&" style=display:none;></div>" else response.Write "<div id=c"&rs("ClassID")&" style=display:none; class=""childdiv""></div>" end if response.Write "</li>"&vbcr rs.movenext loop response.Write "</ul>"&vbcr end if rs.close set rs=nothing conn.close Set conn = Nothing %> </body> </html> 打包下载地址 http://xiazai.jb51.net/200906/yuanma/ajaxtree_51281.rar |