欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ajax+asp无限级分类树型结构(带数据库)

程序员文章站 2022-11-19 16:37:28
ie测试通过,ff有点小bug cls_leibie.asp 复制代码 代码如下:<% '数据库字段为类属性,添加、删除、修改、操作检查等函数为类的方法 class...
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>

打包下载地址