帶資料庫的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 &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &,& nDepth &, & n & 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
'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>