带数据库的ajax+asp无限级分类树型结构,好东西别错过!

作者:网络 来源:佚名 更新时间:2008-10-26 23:04:57 点击:
跟大家分享一下自己写的一个树型结构,参考了动力文章的无限极分类树形结构数据库,看演示吧http://asptree.guaishi.org/aspajax/

下面是核心类代码,注释是后来加的,可能有些写的不太正确
复制内容到剪贴板
代码:
<%
'数据库字段为类属性,添加、删除、修改、操作检查等函数为类的方法
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)    '类别文件根目录(生成静态文件路径,小站奇人异事网(www.guaishi.org)用的是生成静态,故设置此字段)
        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
%>
下面是核心js代码
复制内容到剪贴板
代码:
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);
}


收集最实用的网页特效代码!