关于如何实现无限分类,请看教程:http://bbs.chinahtml.com/t2991.html 关于本无限级联下拉选择,演示请看:http://www.purewhite.cn/demo/sorts/select.html 先给出各部分代码,稍后解释。 select.html 功能:显示下拉选择 代码: 代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>无限分类 之 无限级联下拉选择(ASP版)</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="xmlhttprequest.js"></script> <script type="text/javascript"> <!-- // Unlimited sorts var objSorts; var objValue; function init() { objSorts = document.getElementById("sorts"); objValue = document.getElementById("selectedValue"); } function getSorts(strURL) { var req = new XMLHttpRequest(); var xml; req.open("GET", strURL, true); if (req) { req.onreadystatechange = function() { if (req.readyState == 4 && req.status == 200) { xml = req.responseXML; var arrIDs = xml.getElementsByTagName("ID"); var arrTitles = xml.getElementsByTagName("TITLE"); var k = objSorts.childNodes.length; if (arrIDs.length > 0) { var objSelect = document.createElement("select"); objSelect.setAttribute("name", "sel_" + k); objSelect.setAttribute("id", "sel_" + k); objSelect.setAttribute("onchange", "getChildSorts('sel_" + k + "', this);"); var objOption = document.createElement("option"); objOption.setAttribute("value", "") var objText = document.createTextNode(""); objOption.appendChild(objText); objSelect.appendChild(objOption); for (var l = 0; l < arrIDs.length; l++) { objOption = document.createElement("option"); objOption.setAttribute("value", arrIDs[l].childNodes[0].nodeValue); objText = document.createTextNode(arrTitles[l].childNodes[0].nodeValue); objOption.appendChild(objText); objSelect.appendChild(objOption); } objSorts.appendChild(objSelect); } } } } req.send(null); } function getChildSorts(so, o) { var myValue = o.options[o.selectedIndex].value; var obj = document.getElementById(so); if (myValue != "" && myValue > 0) { doKillSorts(obj); //remove the old child sorts objValue.value = myValue; var strURL = "getXML.asp?action=list&SortID=" + myValue; getSorts(strURL); } else { doKillSorts(obj); if (obj.previousSibling) { //abort objValue.value = obj.previousSibling.options[obj.previousSibling.selectedIndex].value; } else { objValue.value = 0; } return false; } } function doKillSorts(obj) { //remove the old child sorts while (obj.nextSibling) { obj.parentNode.removeChild(obj.nextSibling); } } //--> </script> </head> <body onload="init(); getSorts('getXML.asp?action=list&SortID=0');"> <div id="sorts"></div> <br /> <p><input name="selectedValue" type="text" id="selectedValue" size="4" value="0" /></p> </body> </html>
getXML.asp 功能:根据传递过来的 SortID ,列出子类别列表,以 XML 文档的形式返回数据。 代码: 代码: <%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%> <% Option Explicit %> <% Dim conn Set conn = Server.CreateObject("ADODB.Connection") conn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & Server.MapPath("sorts.mdb") Call listData() Sub listData() Dim intSortID : intSortID = CID(Request.QueryString("SortID")) Dim strXML : strXML = "<?xml version=""1.0"" encoding=""utf-8""?><SORTS>" Dim rs, sql Set rs = Server.CreateObject("ADODB.Recordset") sql = "SELECT ID, Title FROM Sorts WHERE ParentID = " & intSortID & ";" rs.Open sql, conn, 1, 1, 1 Do While Not rs.EOF strXML = strXML & "<SORT><ID>" & rs("ID") & "</ID><TITLE>" & rs("Title") & "</TITLE></SORT>" rs.MoveNext Loop rs.Close Set rs = Nothing strXML = strXML & "</SORTS>" Response.ContentType = "text/xml" Response.Write(strXML) End Sub '-------------------------------------------------------------------------------- Function CID(strS) '-------------------------------------------------------------------------------- ' 转换为有效的 ID ' 返回值类型:Integer (>=0) '-------------------------------------------------------------------------------- Dim intI intI = 0 If IsNull(strS) Or strS = "" Then intI = 0 Else If Not IsNumeric(strS) Then intI = 0 Else Dim intk On Error Resume Next intk = Abs(Clng(strS)) If Err.Number = 6 Then intk = 0 ''数据溢出 Err.Clear intI = intk End If End If CID = intI End Function %> 这里依然用到了无限分类中的 CID() 自定义函数。
xmlhttprequest.js 功能:定义跨平台的 XMLHttpRequest 对象(这个是网上的资源) 代码: 代码: /* Cross-Browser XMLHttpRequest v1.1 ================================= Emulate Gecko 'XMLHttpRequest()' functionality in IE and Opera. Opera requires the Sun Java Runtime Environment <http://www.java.com/>. by Andrew Gregory http://www.scss.com.au/family/andrew/webdesign/xmlhttprequest/ This work is licensed under the Creative Commons Attribution License. To view a copy of this license, visit http://creativecommons.org/licenses/by/1.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. Not Supported in Opera ---------------------- * user/password authentication * responseXML data member Not Fully Supported in Opera ---------------------------- * async requests * abort() * getAllResponseHeaders(), getAllResponseHeader(header) */ // IE support if (window.ActiveXObject && !window.XMLHttpRequest) { window.XMLHttpRequest = function() { return new ActiveXObject((navigator.userAgent.toLowerCase().indexOf('msie 5') != -1) ? 'Microsoft.XMLHTTP' : 'Msxml2.XMLHTTP'); }; } // Gecko support /* ;-) */ // Opera support if (window.opera && !window.XMLHttpRequest) { window.XMLHttpRequest = function() { this.readyState = 0; // 0=uninitialized,1=loading,2=loaded,3=interactive,4=complete this.status = 0; // HTTP status codes this.statusText = ''; this._headers = []; this._aborted = false; this._async = true; this.abort = function() { this._aborted = true; }; this.getAllResponseHeaders = function() { return this.getAllResponseHeader('*'); }; this.getAllResponseHeader = function(header) { var ret = ''; for (var i = 0; i < this._headers.length; i++) { if (header == '*' || this._headers.h == header) { ret += this._headers.h + ': ' + this._headers.v + '\n'; } } return ret; }; this.setRequestHeader = function(header, value) { this._headers[this._headers.length] = {h:header, v:value}; }; this.open = function(method, url, async, user, password) { this.method = method; this.url = url; this._async = true; this._aborted = false; if (arguments.length >= 3) { this._async = async; } if (arguments.length > 3) { // user/password support requires a custom Authenticator class opera.postError('XMLHttpRequest.open() - user/password not supported'); } this._headers = []; this.readyState = 1; if (this.onreadystatechange) { this.onreadystatechange(); } }; this.send = function(data) { if (!navigator.javaEnabled()) { alert("XMLHttpRequest.send() - Java must be installed and enabled."); return; } if (this._async) { setTimeout(this._sendasync, 0, this, data); // this is not really asynchronous and won't execute until the current // execution context ends } else { this._sendsync(data); } } this._sendasync = function(req, data) { if (!req._aborted) { req._sendsync(data); } }; this._sendsync = function(data) { this.readyState = 2; if (this.onreadystatechange) { this.onreadystatechange(); } // open connection var url = new java.net.URL(new java.net.URL(window.location.href), this.url); var conn = url.openConnection(); for (var i = 0; i < this._headers.length; i++) { conn.setRequestProperty(this._headers.h, this._headers.v); } this._headers = []; if (this.method == 'POST') { // POST data conn.setDoOutput(true); var wr = new java.io.OutputStreamWriter(conn.getOutputStream()); wr.write(data); wr.flush(); wr.close(); } // read response headers // NOTE: the getHeaderField() methods always return nulls for me :( var gotContentEncoding = false; var gotContentLength = false; var gotContentType = false; var gotDate = false; var gotExpiration = false; var gotLastModified = false; for (var i = 0; ; i++) { var hdrName = conn.getHeaderFieldKey(i); var hdrValue = conn.getHeaderField(i); if (hdrName == null && hdrValue == null) { break; } if (hdrName != null) { this._headers[this._headers.length] = {h:hdrName, v:hdrValue}; switch (hdrName.toLowerCase()) { case 'content-encoding': gotContentEncoding = true; break; case 'content-length' : gotContentLength = true; break; case 'content-type' : gotContentType = true; break; case 'date' : gotDate = true; break; case 'expires' : gotExpiration = true; break; case 'last-modified' : gotLastModified = true; break; } } } // try to fill in any missing header information var val; val = conn.getContentEncoding(); if (val != null && !gotContentEncoding) this._headers[this._headers.length] = {h:'Content-encoding', v:val}; val = conn.getContentLength(); if (val != -1 && !gotContentLength) this._headers[this._headers.length] = {h:'Content-length', v:val}; val = conn.getContentType(); if (val != null && !gotContentType) this._headers[this._headers.length] = {h:'Content-type', v:val}; val = conn.getDate(); if (val != 0 && !gotDate) this._headers[this._headers.length] = {h:'Date', v:(new Date(val)).toUTCString()}; val = conn.getExpiration(); if (val != 0 && !gotExpiration) this._headers[this._headers.length] = {h:'Expires', v:(new Date(val)).toUTCString()}; val = conn.getLastModified(); if (val != 0 && !gotLastModified) this._headers[this._headers.length] = {h:'Last-modified', v:(new Date(val)).toUTCString()}; // read response data var reqdata = ''; var stream = conn.getInputStream(); if (stream) { var reader = new java.io.BufferedReader(new java.io.InputStreamReader(stream)); var line; while ((line = reader.readLine()) != null) { if (this.readyState == 2) { this.readyState = 3; if (this.onreadystatechange) { this.onreadystatechange(); } } reqdata += line + '\n'; } reader.close(); this.status = 200; this.statusText = 'OK'; this.responseText = reqdata; this.readyState = 4; if (this.onreadystatechange) { this.onreadystatechange(); } if (this.onload) { this.onload(); } } else { // error this.status = 404; this.statusText = 'Not Found'; this.responseText = ''; this.readyState = 4; if (this.onreadystatechange) { this.onreadystatechange(); } if (this.onerror) { this.onerror(); } } }; }; } // ActiveXObject emulation if (!window.ActiveXObject && window.XMLHttpRequest) { window.ActiveXObject = function(type) { switch (type.toLowerCase()) { case 'microsoft.xmlhttp': case 'msxml2.xmlhttp': return new XMLHttpRequest(); } return null; }; }
不学无术,很高兴看到你的贴,程序写得太好了. 我想问一下,目前我使用你的程序完成我的项目时,遇到个问题,你目前只能取最未一级的ID号,我需要取得每一级的ID号,应该如何实现? 希望能得到你的回答,QQ:371143491,E-MAIL:[email protected]
挖哈哈哈,谢谢你在蓝色发的帖子,偶晓得了~ 在 objSelect.setAttribute("onchange", "getChildSorts('sel_" + k + "', this);");下面加上这句 objSelect.onchange = function() { getChildSorts("sel_" + k ,this); }