跟我学做树型菜单(三)

发表于:2007-06-30来源:作者:点击数: 标签:
续上篇 上一篇中我们已经在网页中实现了动态的菜单。我们使用的是JS脚本来实现的。 但是菜单的内容是手工写的,现在我们要用ASP程序来从数据库中读出这些数据,并 在程序中生成这些菜单。 一、用递归的方式生成菜单 在讲到从数据库中读取数据并生成菜单的时候
续上篇
上一篇中我们已经在网页中实现了动态的菜单。我们使用的是JS脚本来实现的。
但是菜单的内容是手工写的,现在我们要用ASP程序来从数据库中读出这些数据,并
在程序中生成这些菜单。

一、用递归的方式生成菜单
在讲到从数据库中读取数据并生成菜单的时候,我们先来回忆一下第一篇中提到
的数据库结构。数据表(treemenu)中,我们记录了每个菜单的父菜单的ID,如果这
ID是0,那么它就是根菜单;并且记录了每个菜单的子菜单的个数:chi_id 也就是说
对于任意一个菜单,我们都可以用
select * from treemenu where par_id=当前ID
这样的SQL语句来找到它的子菜单。而要找到任意一个菜单的父菜单,可以用:
select * from treemenu where id=当前par_id
理解了这两个SQL语句,我们来说说递归的思路,递归的表现是一个函数或者子程序
又调用了自己本身。现在我们定义一个子程序,叫distree(id),它的作用是显示ID为id的
菜单及所有的子菜单。然后我们调用distree(0)就可以显示所有的根菜单。看看这个子程序
的简单算法思路:
<%
sub distree(id)
‘’找到ID字段为id的所有记录
‘’ 显示这个记录,并记下它的id(记为id2)
‘’ 显示它的子菜单及子菜单的子菜单:disptree(id2) 这里用到了递归
‘’直到结束
end sub
%>


二、完成递归函数
现在我们来完成这个递归的函数。下面是已经完成的函数,注释写在里面。
<%
sub distree(id) ‘’定义子程序
‘’定义变量,注意,这些变量一定要定义,才是局部的变量,否则将会是全局变量
dim sql,rs,chid,i
‘’下面这句定义SQL查询语句,取得父菜单为id的子菜单
sql="select * from treemenu where par_id="&id
searchtable my,sql,rs ‘’查询表
if rs.eof then exit sub ‘’如果没有一个记录,就退出子程序
if id=0 then ‘’如果是根菜单,要另外处理,因为它没有前面的连接图
response.write "<table width=‘’100%‘’ border=0 cellspacing=0 cellpadding=0>"&br
else
‘’如果不是根菜单,就显示全部。其中cellid是菜单所在表的名字,命名方法按上一篇
response.write "<table id=‘’"&cellidc&"‘’ style=‘’display=none‘’"&_
" width=‘’100%‘’ border=‘’0‘’ cellspacing=‘’0‘’ cellpadding=‘’0‘’>"&br
end if
totalrec=rs.recordcount ‘’得到全部的记录数,这里是按实际的数量,也可以用rs("chi_id")
for i=1 to totalrec ‘’用一个循环来显示所有的记录
if id=0 then ‘’如果是根菜单,就用另一个图标
ico="images/home.gif"
else ‘’否则,就用文件夹的图标
ico="images/fc.gif"
end if
chid=rs("chi_id") ‘’得到它的子菜单的数量
if chid=0 then ‘’如果它没有子菜单,连接图就用没有"+"号的。
if i=totalrec then ‘’如果是最后一个子菜单,就用90度的连接图
ph="images/line_clearcase/" target="_blank" >cco.gif"
else
ph="images/line_co.gif" ‘’否则就用T字型的连接图
end if
response.write " <tr height=‘’16‘’>"&br ‘’输出一行,来显示一个记录(菜单)
if id<>0 then ‘’如果是不根菜单,就显示连接图,ph是上面生成的连接图的文件名
response.write " <td width=‘’16‘’ height=‘’16‘’>"&br
response.write " <img src=‘’"&ph&"‘’ width=‘’16‘’ height=‘’16‘’>"&br
response.write " </td>"&br
end if
‘’下面输出这个记录(菜单)
response.write " <td height=‘’16‘’>"&br
response.write " <img src=‘’"&ico&"‘’ width=‘’16‘’ height=‘’16‘’ align=‘’absmiddle‘’>&nbsp;"
response.write "<a href=‘’"&rs("link")&"‘’ target=‘’main‘’>"&rs("txt")&"</a>&nbsp;&nbsp;"
‘’response.write "<a href=‘’"&scr&"?action=add&id="&rs("id")&"‘’>增</a>&nbsp;"
‘’response.write "<a href=‘’"&scr&"?action=del&id="&rs("id")&"‘’>删</a>&nbsp;"
‘’response.write "<a href=‘’"&scr&"?action=mod&id="&rs("id")&"‘’>改</a>"&br
response.write " </td>"&br
response.write " </tr>"&br
else ‘’如果它还有子菜单,就用"+"号的连接图
if i=totalrec then ‘’如果是最后一个子菜单,就用没用后续菜单的连接图
ph="images/ctc.gif"
else
ph="images/cc.gif" ‘’否则就用有后续菜单的连接图
end if
l=l+1 ‘’l表示行,
r=r+1 ‘’r表示列
cellid="L"&l&"R"&r ‘’生成名字
cellida="L"&l&"R"&r ‘’生成连接图的名字
cellidb="L"&l&"R"&r+1 ‘’生成图标的名字
cellidc="L"&l+1&"R"&r+1 ‘’生成子菜单的名字
if id=0 then ‘’如果是根菜单,就直接输出这个子菜单
response.write " <tr height=‘’16‘’ width=‘’100%‘’>"&br
else ‘’否则,要先输出连接图
response.write " <tr height=‘’16‘’>"&br
end if
if id<>0 then ‘’不是根菜单,输出连接图
response.write " <td width=‘’16‘’ height=‘’16‘’>"&br
response.write " <img id=‘’"&cellid&"‘’ onclick=‘’showhide("&cellida&","&cellidb&_
","&cellidc&")‘’ src=‘’"&ph&"‘’ width=‘’16‘’ height=‘’16‘’ class=‘’cur‘’>"&br
response.write " </td>"&br
end if
response.write " <td height=‘’16‘’>"&br
r=r+1
l=l+1
if id=0 then ‘’如果是根菜单,就显示小房子图标
response.write " <img id=‘’home‘’ onclick=showhide(‘’‘’,‘’‘’,"&cellidc&") src=‘’"&ico&_
"‘’ class=‘’cur‘’ width=‘’16‘’ height=‘’16‘’ align=‘’absmiddle‘’>"&br
response.write "<a href=‘’"
else ‘’否则,就输出前面定义的图标,ico是图标的文件名
response.write " <img id=‘’"&cellidb&_
"‘’ onclick=‘’showhide("&cellida&","&cellidb&","&cellidc&")‘’ src=‘’"&ico&_
"‘’ class=‘’cur‘’ width=‘’16‘’ height=‘’16‘’ align=‘’absmiddle‘’>&nbsp;<a href=‘’"
end if
‘’输出文字部份
response.write rs("link")&"‘’ target=‘’main‘’>"&rs("txt")&"</a>&nbsp;&nbsp;"
‘’response.write "<a href=‘’"&scr&"?action=add&id="&rs("id")&"‘’>增</a>&nbsp;"
‘’response.write "<a href=‘’"&scr&"?action=del&id="&rs("id")&"‘’>删</a>&nbsp;"
‘’response.write "<a href=‘’"&scr&"?action=mod&id="&rs("id")&"‘’>改</a>"&br
response.write " </td>"&br
response.write " </tr>"&br
response.write " <tr>"&br
response.write " <td height=‘’0‘’ "
‘’为了让子菜单隐藏时表格高度为0,要输入一个图像
if id<>0 then response.write "width=‘’16‘’ "
if i<>totalrec and id<>0 then
response.write "background=‘’images/line.gif‘’"
end if
response.write ">"&br
if id<>0 then ‘’如果不是根菜单,输入一行,用于显示下一级菜单
response.write " </td>"&br
response.write " <td height=0>"&br
end if
‘’最关键的地方啦,调用自己,显示它的子菜单及子菜单的子菜单
distree(rs("id"))
‘’最后,结束这一单元格
response.write " </td>"&br
‘’结束行
response.write " </tr>"&br
end if
rs.movenext ‘’循环,显示完所有的子菜单
next
response.write "</table>"&br ‘’显示完后结束表格
closetable rs
end sub
%>


现在把上次的HTML文件改写成ASP程序,把文件名改一下,再把原来的菜单部份删除,加入上面的子程序
再加入下面这些语句就行了。记住不要把JS脚本删除了!
<!--#include file="operation$db.asp" -->
<%
opendb my
dim i,l,r,cellid,ph
dim cellida,cellidb,cellidc
l=0
r=0
br=vbcrlf
distree(0)
%>

到这里,已经可以显示菜单了,当然,如果你要改的话,现在只能到数据库里去改。只要再加上
简单的功能,就可以进行管理了。下一篇我们给它加上增加、删除、修改的功能。

原文转自:http://www.ltesting.net