联动下拉菜单程序(省份/城市示例说明)
发布时间:2007-3-28 9:25:50
网上有很多联动下拉菜单的程序,自己最近学AJAX的时候看了一些JS的教程(含asp页面),也附庸写了一个,只是还没有完全做好,先把代码共享出来,出错的地方已经标示(在IE中正常,但在OP/FF中传递中文参数就会出错,英文或数字参数也正常),顺便也请大家帮忙解决一下.
原理:利用asp与数据库连接,先取出第一个下拉菜单全部内容(示例中为省份),当第一下拉菜单值发生改变时,触发onchange事件,该事件将先调用一个生成XMLHttpRequest的对象函数,再利用XMLHttpRequest把第一下拉菜单值传递给后台的ASP页面进行处理,处理结果再返回给add_option函数,该函数利用W3C DOM把返回的值添加到第二下拉菜单中.而后台的ASP页面最主要是根据XMLHttpRequest传递的参数重新查询数据库,并从数据库内取出相应的值.
优点:利用ajax技术,实现无闪刷新,用户不能等待页面的全新刷新,按需刷新,并很好的处理了数据库记录过大时带给用户的等待郁闷.
缺点:使用js之后,不利于搜索引擎搜索,也会由于js引起浏览器不兼容问题(不过该程序在目前常用的浏览器中--IE6/OP7/OP8/FF1中均测试通过,NS7未测试,不过在FF1中测试通过的在NS7中应当不成问题).
运行环境:服务器端ASP运行环境,客户端支持JS运行的浏览器
数据库的数据结构:
数据库系统:Access xp
表名:pro_city
字段 数据类型 字符长度 字段说明
pro 文本型 20 省份
city 文本型 20 城市
记录示例:
pro city
湖南 长沙
湖南 衡阳
湖北 武汉
广东 深圳
湖北 黄冈
北京 北京
广东 广州
文件说明(所有文件均位于同一目录下):
文件名 文件说明
ajax4.asp 用户界面页,该页先取出第一下拉菜单值,并利用XMLHttpRequest接收该下拉菜单值,并给后台ASP页面传递该值
ajax4.mdb 数据库文件
ajax4_2.asp 后台处理ASP页面,接收XMLHttpRequest传递的参数进行处理,然后输出处理结果
源文件:
ajax4.asp:
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'
'http://www.w3.org/TR/2002/REC-xhtml1-20020801/DTD/xhtml1-strict.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<meta http-equiv='Content-Language' content='zh-cn' />
<meta http-equiv='Content-Type' content='text/html; charset=gb2312' />
<title>不想说乔丹</title>
<script type="text/javascript">
/*两级联动菜单,示例数据库为省份/城市数据库
不想说乔丹于2007-3-26编写
wggipkhgef@yahoo.com.cn
http://www.wgg.com.cn http://www.wucq.cn
*/
function createXHR() {
//建立XMLHttpRrquest对象
if (window.ActiveXObject) xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
else if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
if (xmlhttp.overrideMimeType) xmlhttp.overrideMimeType("text/xml");
}
}
function pro_city(pro){
if (pro!=""){ //判断第一个下拉菜单是否被改变值
createXHR(); //调用XMLHttpRequest对象建立函数
xmlhttp.onreadystatechange=add_option; //回调函数是add_option
//调用URL为带参数的ASP页面,该页面接收第一个下拉菜单改变后的值,从数据库内取出相对应的第二个下拉菜单的值
url="ajax4_2.asp?pro="+pro; //当pro值为英文或数字时,IE/OP/FF中都能正常运行,当pro值为中文时,只有IE中能正常运行
xmlhttp.open("GET",url,true);
xmlhttp.send(null);
}
}
function add_option(){
if (xmlhttp.readyState==4){
if (xmlhttp.status==200){
city_id=document.getElementById("city")
if (city_id.hasChildNodes){
//清空第二个下拉菜单原有内容
for (i=0;i<city_id.childNodes.length;i++){
city_id.removeChild(city_id.childNodes[0]);//每次删除第一个节点
i-=1;
}
}
citys=xmlhttp.responseText; //取得ASP页面返回的值
//alert(citys);
city_a=citys.split(",");
for (i=0;i<city_a.length;i++){
//把从ASP页面得到的值和相对应的属性添加到第二个下拉菜单中去
city=city_a[i];
opt=document.createElement("option");
opt.appendChild(document.createTextNode(city));//建立一文本节点
city_id.appendChild(opt);//添加该文本节点于第二下拉菜单中
city_id.childNodes[i].setAttribute("value",city);给该文本节点添加一名为value的属性,并赋值
}
}
}
}
</script>
</head>
<body>
<form action="#">
<select id="pro" onChange="pro_city(this.value);">
<option value="" selected="selected">选择...</option>
<%
'数据库内连接语句,数据库驱动
connstr="DBQ="+server.mappath("ajax4.mdb")+";DefaultDir=;DRIVER={Microsoft Access Driver (*.mdb)};"
set conn=server.createobject("ADODB.CONNECTION")
conn.open connstr
'从数据库取出值初始化第一个下拉菜单内容
set rs=server.createobject("adodb.recordset")
rs.open ("select distinct [pro] from [pro_city] order by [pro] desc"),conn,1,1
if not (rs.eof and rs.bof) then
for i=1 to rs.recordcount
response.write"<option value='"&trim(rs("pro"))&"'>"&trim(rs("pro"))&"</option>"
rs.movenext
next
end if
rs.close
set rs=nothing
conn.close
set conn=nothing
%>
</select>
<select id="city"></select>
</form>
</body>
</html>
---------------------------------------
ajax4_2.asp:
<%
'数据库内连接语句,数据库驱动
connstr="DBQ="+server.mappath("ajax4.mdb")+";DefaultDir=;DRIVER={Microsoft Access Driver (*.mdb)};"
set conn=server.createobject("ADODB.CONNECTION")
conn.open connstr
'获得参数,从数据库内取出相对应的值
pro=request("pro")
pro=trim(pro)
set rs=server.createobject("adodb.recordset")
sql="select distinct [city] from [pro_city] where [pro]='"&pro&"' order by [city] desc"
rs.open sql,conn,1,1
if not (rs.eof and rs.bof ) then
for i=1 to rs.recordcount
if i=1 then
city=city&trim(rs("city"))
else
city=city&","&trim(rs("city"))
end if
rs.movenext
next
end if
rs.close
set rs=nothing
conn.close
set conn=nothing
response.write city '输出处理结果
%>