学院首页>网络编程>ASP>ASP + XML + JavaScript 实现动态无限级联动菜单

ASP + XML + JavaScript 实现动态无限级联动菜单

作者: 来源: 添加时间:2006-5-21 18:34:37
我们可结合ASP来完成对数据库值的读取,然后写入XML文件,再用JavaScript读出来并且控制它的联动。
这儿的关键是把数据库内的N层数据类读出来:
我的数据库表结构是这样的:
'tbl_Class
 列名 数据类型 长度  说明
ClassID   int 4  类ID
ModuleID  int 4  模块ID
GroupID   int 2  标识一个组
ClassName nvarchar  50   类别名称
ParentID  int 2  连接到组(0表示是父类)

'####################################我的ASP代码如下##########################################
'我把连接数据库的代码忽略。

'函数名字:OpenXml(FileName)
'入口参数: filename 需要连接或打开的xml文件名
'返回值 :XmlDoc就是一个成功装载XML文档的对象了。
' 有错误则打印错误信息strError
'------------------------------------------------

function OpenXml(filename)
dim strSourceFile ,XmlDoc,strError
strSourceFile = filename
Set XmlDoc = Server.CreateObject("Microsoft.XMLDOM")  '创建XMLDOM实例
XmlDoc.async = false 
XmlDoc.load(strSourceFile)
OpenXml=XmlDoc.parseerror.errorcode
if XmlDoc.parseerror.errorcode<>0 then
strError="<h2>error"&XmlDoc.parseerror.errorcode&"</h2>"
strError=strError&XmlDoc.parseerror.reason&"<br>"
strError=strError&XmlDoc.parseerror.url&"<br>"
strError=strError&XmlDoc.parseerror.line&"<br>"
strError=strError&XmlDoc.parseerror.filepos&"<br>"
strError=strError&XmlDoc.parseerror.srcText&"<br>"
response.write strError '输出错误
else
  set OpenXml=XmlDoc '返回实例
end if
end function

'------------------------------------------------
'函数名字:CloseXml()
'参数: XmlDoc XML组件实例
'------------------------------------------------
function CloseXml(XmlDoc)
if IsObject(XmlDoc) then
set XmlDoc=nothing
end if
end function

'------------------------------------------------
'函数名字:SelectXmlNode
'参数:XmlDoc XML组件实例
'   e 元素的名字
'返回元素实例
'------------------------------------------------
function SelectXmlNode(XmlDoc,e) 
dim n

set n=XmlDoc.selectSingleNode("//" & e )
set selectXmlNode= n

end function 

Dim n,np,MaxGroup,root,xmlDoc,nt,filename,s,ss,TorF
filename=server.mappath("demo.xml")
set xmlDoc=openXML(filename)'打开XML
RemoveAllNodes xmlDoc,"Root"'把Root和它下面的子项清除,这样可以多次方便读写
set root= xmlDoc.createElement("Root")
xmlDoc.appendChild root'创建一个顶层元素
sql="select  Max(GroupID) from tbl_Class  " '读出最大的层次
set rs=cn.execute(sql)
if isnull(rs(0)) then MaxGroup=0 else MaxGroup=rs(0) '如果为null 表示没有数据
s="":ss=""
set nt=xmldoc.createElement("item")
nt.setAttribute "text", "请选择"
 root.appendChild nt '创建一个元素
for i=1 to MaxGroup '开始循环
sql="select * from tbl_Class where GroupID=" & i  '由底层向顶层读取
 set rs=cn.execute(sql)
 TorF=False '为了每一个层上都创建一个“请选择”的空取。
 do while rs.eof =false '开始读取下层的数据
Set n = xmlDoc.createElement("item" & rs("ClassID")) '创建一个命名为item + ID号的标记元素
n.setAttribute "text",rs("ClassName")'把它的属性“text”设置为数据库表内的

ClassName
n.setAttribute "value",rs("ClassID")'把它的属性“value”设置为数据库表内的

ClassID
if rs("ParentID")>0 then '是有上层数据的
set np=selectXmlNode(xmlDoc,"item" & rs("ParentID"))   '把它的上层数据元素先读出保存在np
  if TorF=false  then '如果TorF为False值时
  set nt=xmldoc.createElement("item") '创建一个元素保存在nt
nt.setAttribute "text", "请选择"'把它的text属性设置为“请选择”
  np.appendChild nt 'np把它加为子元素
end if
TorF=true '设置true
np.appendChild n 'np 把n加为子元素
else
  root.appendChild n  '如果是第一层数据就把它加入为root下的一个子元素
end if
rs.movenext '下一条指针
 loop
 
ss=ss & "<SELECT id=Select" & i & " width=1 ></SELECT></span>" '每有一层就创建一个

<select>
s=s & ",'Select" & i  & "'" '把每个<select>的id 保存在变量s,它的格式为:id1,id2,id3,id4
 
next
xmlDoc.save filename '正式保存Xml文件
CloseXml xmlDoc '关闭Xml文件
  
  
   response.write ss '直接把<select>输出到文档
   s=mid(s,2)

//在HTM文件内调用xmlselect.js
<SCRIPT language=JavaScript src="xmlselect.js"></SCRIPT>
<SCRIPT language=JavaScript>
<!--//** power by fason
function init() {
  var Sel = [<%=s%>];
attachSelect("demo.xml", Sel,["论坛导航"]);
};//-->
</SCRIPT>
init();

//#########我把它的JS代码贴出来,作者叫:蒲佛信,http://fason.nease.net/samples/xmlselect/这儿有示例和代码。

//-----------------------------xmlselect.js文件开始-------------------------------

//-----------------------------------------------------/
// NichName :fason
// Autho  :Forbes Pu(蒲佛信)
// Email  :fason_pfx@hotmail.com
// HomePage :http://fason.nease.net
// Blog  :http://blog.mvpcn.net/fason/
//  http://blog.csdn.net/fason/
//
//  function :attachSelect(sXMLSrc, aSel[, sStore])
// param1  :sXMLSrc(URL of XML data source)
// param2  :aSel(array of SELECT controls's ID)
// param3  :array of default value when display
//-----------------------------------------------------/

function attachSelect(sXMLSrc, aSel, sStore) {
 var oXML = CreateXmlDocument();
 var oDocument = null;
 var store = sStore ? sStore : [];
 var Sel = new Array();

for (var i=0; i<aSel.length; i++)
  Sel[i] = document.getElementById(aSel[i]);
 
 if (!oXML){ throw new Error('Not support!\nplease install a XML parser');return; }
 oXML.onreadystatechange = function () {
  if (oXML.readyState == 4) {
attachXML();
  }
 };
 oXML.load(sXMLSrc);

function CreateXmlDocument() {
  if (document.implementation && document.implementation.createDocument) {
var doc = document.implementation.createDocument("", "", null);
if (doc.readyState == null) {
 doc.readyState = 1;
 doc.addEventListener("load", function () {
  doc.readyState = 4;
  if (typeof doc.onreadystatechange == "function")
doc.onreadystatechange();
 }, false);
}
return doc;
  }
  else if (window.ActiveXObject) {
var prefix = ["MSXML3","MSXML2","MSXML","Microsoft"];
for (var i=0;i<prefix.length;i++) {
 try {
  var doc = new ActiveXObject(prefix[i] +

".DomDocument");
  doc.setProperty("SelectionLanguage","XPath");
  return doc;  
 } catch (e) {}
}
  }
  return null;
 };

function attachXML() {
  oDocument = oXML.documentElement;
  if (!oDocument) { throw new Error('No XML data!'); return; }
  for (var i=0;i<aSel.length-1;i++){
addEvent(Sel[i], "onchange", function(x) {
 return function () { doChange(x); }
}(i+1));
  }
  doChange(0);
 };

function selectXMLNode(x) {
  var sPath = "/*";
  var oDoc = oDocument;
  for (var i=0;i<x;i++)
sPath += "/*[" + (Sel[i].selectedIndex+1) + "]";
  if (typeof(oDoc.selectSingleNode)!='undefined') return

oDoc.selectSingleNode(sPath);
  else {
var doc=oDoc.nodeType==9?oDoc:oDoc.ownerDocument;
var res = doc.createNSResolver(oDoc.nodeType==9?

oDoc.documentElement:oDoc);
return doc.evaluate(sPath,oDoc, res, 9, null).singleNodeValue;
  }
 };

function addEvent(el, sHandler, fnc) {
  if (el.attachEvent) {
el.attachEvent(sHandler, fnc);
  } else if (el.addEventListener) {
el.addEventListener(sHandler.replace(/on/i, ''), fnc, false);
  } else {
el[sHandler] = fnc;
  }
 };

function doChange(n) {
  var el = selectXMLNode(n);
  var nodes = el ? el.childNodes :[];
  var s = Sel[n];
  var f = 0;
  if (nodes.length>0) {
with (s){
 length = 0;
 for (var i = 0,j = 0;i<nodes.length;i++) {
  if (nodes[i].nodeType!=1)continue;
  var t = nodes[i].getAttribute("text");
  var v = nodes[i].getAttribute("value") ? nodes

[i].getAttribute("value") : t;
  if (v == store[n]) f = j;
  options[j++] = new Option(t, v);
 } 
 options[f].selected = true;
}
if (++n<Sel.length) doChange(n);
  } else {
for (var i=n; i<Sel.length; i++) {
 with (Sel[i]) {
  length = 0;
  options[0] = new Option('--');
  options[0].selected = true;
 }
}
  }
 }; 
};

//-----------------------------xmlselect.js文件结束-------------------------------

站内搜索