續上篇 上一篇中我們已經在網頁中實現了動態的菜單。我們使用的是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_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'> " response.write "<a href='"&rs("link")&"' target='main'>"&rs("txt")&"</a> " 'response.write "<a href='"&scr&"?action=add&id="&rs("id")&"'>增</a> " 'response.write "<a href='"&scr&"?action=del&id="&rs("id")&"'>刪</a> " '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'> <a href='" end if '輸出文字部份 response.write rs("link")&"' target='main'>"&rs("txt")&"</a> " 'response.write "<a href='"&scr&"?action=add&id="&rs("id")&"'>增</a> " 'response.write "<a href='"&scr&"?action=del&id="&rs("id")&"'>刪</a> " '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 ""&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) %>
到這里,已經可以顯示菜單了,當然,如果你要改的話,現在只能到數據庫里去改。只要再加上 簡單的功能,就可以進行管理了。下一篇我們給它加上增加、刪除、修改的功能。
|