分享个极好的无刷新二级联动下拉列表
可能"极好的"又会带来很多的非议,但是我认为这确实很好,我看了大约20个无刷新的连动下拉列表,他们在firefox下面就一团糟.为了这个我差不多搞了两天,就是如果提交窗体后如何保持第二个列表框的值,因为通过js 给下拉框添加条目那么他的状态是不会被保存的 测试平台:ie6,firefox 功能:二级无刷新连动 特点:跨浏览器;提交窗体取第二下拉框的值;数据来源于数据库;以xmlhttp来发送请求,实现无刷新 请求:如果您能够找到更好的方法请告诉我,非常感谢,您的批评和建议对我是莫大的鼓励 webform1.aspx: <%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="drop.WebForm1" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>WebForm1</title> <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1"> <meta name="CODE_LANGUAGE" Content="C#"> <meta name="vs_defaultClientScript" content="JavaScript"> <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> <script language="javascript"> //jb函数会根据不同的浏览器初始化个xmlhttp对象 function jb() { var A=null; try { A=new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { try { A=new ActiveXObject("Microsoft.XMLHTTP"); } catch(oc) { A=null } } if ( !A && typeof XMLHttpRequest != "undefined" ) { A=new XMLHttpRequest() } return A } //下面Go函数是父列表框改变的时候调用,参数是选择的条目 function Go(obj) { //得到选择框的下拉列表的value var svalue = obj.value; //定义要处理数据的页面 var weburl = "webform1.aspx?parent_id="+svalue; //初始化个xmlhttp对象 var xmlhttp = jb(); //提交数据,第一个参数最好为get,第三个参数最好为true xmlhttp.open("get",weburl,true); // alert(xmlhttp.responseText); //如果已经成功的返回了数据 xmlhttp.onreadystatechange=function() { if(xmlhttp.readyState==4)//4代表成功返回数据 { var result = xmlhttp.responseText;//得到服务器返回的数据 //先清空dListChild的所有下拉项 document.getElementById("dListChild").length = 0; //给dListChild加个全部型号的,注意是Option不是option document.getElementById("dListChild").options.add(new Option("全部型号","0")); if(result!="")//如果返回的数据不是空 { //把收到的字符串按照,分割成数组 var allArray = result.split(","); //循环这个数组,注意是从1开始,因为收到的字符串第一个字符是,号,所以分割后第一个数组为空 for(var i=1;i<allArray.length;i++) { //在把这个字符串按照|分割成数组 var thisArray = allArray[i].split("|"); //为dListChild添加条目 document.getElementById("dListChild").options.add(new Option(thisArray[1].toString(),thisArray[0].toString())); } } } } //发送数据,请注意顺序和参数,参数一定为null或者"" xmlhttp.send(null); } </script> </HEAD> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <asp:DropDownList οnchange="Go(this)" id="dListParent" style="Z-INDEX: 101; LEFT: 248px; POSITION: absolute; TOP: 40px" runat="server"> <asp:ListItem Value="100">摩托罗拉</asp:ListItem> <asp:ListItem Value="101">诺基亚</asp:ListItem> </asp:DropDownList> <asp:DropDownList id="dListChild" style="Z-INDEX: 102; LEFT: 248px; POSITION: absolute; TOP: 104px" runat="server"></asp:DropDownList> <asp:Button id="Button1" style="Z-INDEX: 103; LEFT: 256px; POSITION: absolute; TOP: 176px" runat="server" Text="Button"></asp:Button> </form> </body> </HTML> 后台webform1.aspx.cs: using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.Configuration; using System.Data.SqlClient; namespace drop { /// <summary> /// WebForm1 的摘要说明。 /// </summary> public class WebForm1 : System.Web.UI.Page { [转自:51item.net] protected System.Web.UI.WebControls.DropDownList dListParent; protected System.Web.UI.WebControls.Button Button1; protected System.Web.UI.WebControls.DropDownList dListChild; private void Page_Load(object sender, System.EventArgs e) { // 在此处放置用户代码以初始化页面 //if(!IsPostBack) //{ BindDrop();//如果不是提交回来就绑定列表框 //} } protected void BindDrop() { //首先我想父dropdownlist也绑定数据库,后面想没必要 //if(!IsPostBack) //{ //绑定父dListParent // BindParent(); //} //获得传递过来的parent_id值,如果是第一次请求他为null string str = Request.QueryString["parent_id"]; string str1 = dListParent.SelectedValue;; Response.Write(str1); //如果str加个字符串!=原来的字符串则说明触发过dListParent的onchange事件 if((str+"abc")!="abc") { //绑定 dListChild控件 BindChild(str);//把传来的父DropDownList的value做为参数 } else BindParent(str1); } protected void BindParent(string str) { //如果是第一次请求或者是刷新这个页面则根据dListParent的值来选择 //把参数转化成int int i = Convert.ToInt32(str); dListChild.Items.Clear(); dListChild.Items.Add(new ListItem("全部型号","0")); //得到数据库连接字符串 string connStr = ConfigurationSettings.AppSettings["ConnString"].ToString(); //初始化个conn对象 SqlConnection conn = new SqlConnection(connStr); //数据库语句 string commStr = string.Format("select type_value,type_text from phone_type where parent_id={0}",i); //建立数据库命令对象 SqlCommand comm = new SqlCommand(commStr,conn); //打开数据库 conn.Open(); //执行命令 SqlDataReader dr = comm.ExecuteReader(); //循环dr,给dListParent添加条目 while(dr.Read()) { dListChild.Items.Add(new ListItem(dr[1].ToString(),dr[0].ToString())); //也可以这样 //dListParent.Items.Add(new ListItem(dr["phone_text"].ToString(),dr["phone_value"].ToString())); } dListParent.Items[0].Selected = true; //添加下面这话的意思是当点提交按钮提交窗体的时候第二个dListChild的状态能够得到保存 dListChild.SelectedValue = Request.Form["dListChild"]; dr.Close(); conn.Close(); } protected void BindChild(string str) { //通过js给包括dropdownlist任何控件添加的内容不会被保存状态 //把参数转化成int int i = Convert.ToInt32(str); //定义个字符串用保存从数据库返回的数据 string result = ""; //先清空输出的东西 Response.Clear(); string connStr = ConfigurationSettings.AppSettings["ConnString"].ToString(); SqlConnection conn = new SqlConnection(connStr); SqlCommand comm = conn.CreateCommand(); string commStr = string.Format("select type_value,type_text from phone_type where parent_id = {0}",i); comm.CommandText = commStr; conn.Open(); SqlDataReader dr = comm.ExecuteReader(); while(dr.Read()) { result += ","+dr[0].ToString() +"|" + dr[1].ToString(); //dListChild.Items.Add(new ListItem(dr[1].ToString(),dr[0].ToString())); } //把从数据库得到的信息输出到客户端 Response.Write(result); //输出完成关闭Response,以免造成不必要的输出 Response.Flush(); Response.Close(); dr.Close(); conn.Close(); } #region Web 窗体设计器生成的代码 override protected void OnInit(EventArgs e) { // // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。 // InitializeComponent(); base.OnInit(e); } /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.Button1.Click += new System.EventHandler(this.Button1_Click); this.Load += new System.EventHandler(this.Page_Load); } #endregion private void Button1_Click(object sender, System.EventArgs e) { Response.Write(Request.Form["dListChild"].ToString()); } } } 数据表: 主键id parent_id(int) type_value(int) type_text(varchar) int递增 父下拉框的value值 下拉框的value 下拉框的text
前段时间做一个项目,需要动态的从后台数据里面里面提取相应国家、省份及城市的信息,实现的过程就是通过下拉菜单先选择一个国家,然后在另一个下拉框里面是这个国家的省份,再通过选择的省份填充另外一个城市的下拉框,其实通过级联查询的方式完全可以实现,或者一次性通过数组读取国家省份及城市的信息,然后填充这几个下拉框,觉得这样也不方便,想来想去何不用DOM的方式来实现了,思路如下:
第一,通过后台程序生成一个XML文件,节点分别为:国家——》省——》城市
第二,通过前台的的DOM提取这个XML文件
第三,通过脚本加载这个XML文件到相应的下拉框,首先加载国家,当选择某个国家的时候通过XML的查询语句再填充相应的省,依次类推,填充省下的城市,实现级联查询,省去了不少麻烦:)
生成XML文件的方式在这里就不提了,只把相应读XML文件的脚本贴出来,便于自己记忆:)
<html> <head> <title>city.htm</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; GBK"> <script language="javascript"> var xmlDoc; function init(initProvince, initCity) {//参数1:初始化时的省;参数2:初始化时的城市 var sltOne = document.getElementById("classId"); xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async = false; xmlDoc.load("cityXml.jsp"); if (xmlDoc.parseError.errorCode != 0) { var myErr = xmlDoc.parseError; alert("You have error " + myErr.reason); } else { //alert(xmlDoc.xml); var oNodeList; var sonNode; var oNode; objNodeList = xmlDoc.getElementsByTagName("province"); for (var i=0; i<objNodeList.length; i++) { oNode = objNodeList.item(i) var opt = document.createElement("OPTION"); sltOne.add(opt); opt.innerText = oNode.getAttribute("name"); opt.value = oNode.getAttribute("id"); if(opt.innerValue == initProvince) opt.selected = true; } if(initCity.length > 0 && initProvince.length > 0) getCityByProvince(initProvince, initCity); } } function getCityByProvince(initProvince, initCity) { var sltTwo = document.getElementById("NclassIdt"); sltTwo.length = 0; var curNode;//当前节点 var cNode;//节点 var xpath;//路径 var name;//区域名称 name = initProvince;//event.srcElement.value; xpath = "/catalog/province[@name='" + name + "']/city" //alert(xpath); cNode = xmlDoc.selectNodes(xpath); //alert(cNode.length); if(cNode.length == 0) { var opt = document.createElement("OPTION"); sltTwo.add(opt); opt.value = "null"; opt.innerText = "选择城市"; } for(var i=0;i<cNode.length;i++) { curNode = cNode.item(i); var opt = document.createElement("OPTION"); sltTwo.add(opt); opt.value = curNode.getAttribute("name"); opt.innerText = curNode.getAttribute("name"); if(opt.value == initCity) opt.selected = true; } } </script> </head> <body οnlοad="init('','')"> This is my HTML page. <br> <select id=sltOne οnchange="getVenuesByLocation(this.value)"> <option value="null">选择省 </select> <select id=sltTwo> <option value="null">选择城市 </select> </body> </html>
分享一个无刷新的二级联动下拉列表(是从数据库读取数据) | //从服务器端接受数据 function GetDataFromServer(sXML, sURL) { var oXML = new ActiveXObject("MSXML2.DOMDocument"); oXML.async = false; oXML.loadXML(sXML); //alert(oXML.childNodes(0).text) var xmlResult = PostDataToServer(oXML, sURL); //alert(xmlResult.xml) return xmlResult.xml } //返回对象 function GetDataFromServer_obj(sXML, sURL) { var oXML = new ActiveXObject("MSXML2.DOMDocument"); oXML.async = false; oXML.loadXML(sXML); return PostDataToServer(oXML, sURL); } //向服务器端发送数据 function PostDataToServer(oXML, sURL) { var oXmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); oXmlHttp.Open("POST", sURL , false); oXmlHttp.Send(oXML); //alert(oXML) //alert(oXmlHttp.responseText); //alert(oXmlHttp.responseXML) return oXmlHttp.responseXML; } function ChangeType(thisobj) { var objDom= new ActiveXObject("Microsoft.XMLDOM"); var sURL = "ChangeType.asp"; var tempXml = "<Data>"+thisobj.value+"</Data>"; var InXML = GetDataFromServer(tempXml, sURL); //alert(InXML); //location.href=(sURL) //return; if (objDom.loadXML(InXML)) { if (objDom.childNodes(0).getAttribute("ErrDesc")=="") { form1.SecSelect.innerHTML = "" var ChildNum = objDom.getElementsByTagName("R1") for (i=0;i<ChildNum.length;i=i+1) { var selectobj = form1.SecSelect; selectobj.options.add(new Option(ChildNum[i].text,ChildNum[i].getAttribute("Attr")));
} } else { //alert(objDom.childNodes(0).getAttribute("ErrDesc")) form1.SecSelect.innerHTML = "" } } else { alert("加载服务器端返回的XML文件失败!") } } <tr> <td height="30" align="center">一级类别</td> <td> <% Dim SoRs sSql="select * from FirstTypeTable order by fchrFirstTypeID asc" Set SoRs = conn.execute(sSql) %> <select name="FirSelect" class="FileInput" οnchange="javascript:ChangeType(this)"> <option value="">选择类别</option> <%While Not SoRs.eof%> <option value="<%=SoRs("fchrFirstTypeID")%>"><%=SoRs("fchrFirstName")%></option> <% SoRs.movenext Wend %> </select> </td> </tr> <!--#include file=../database/conn/conn.asp--> <% '-------------------------处理联级下拉列表-------------------------------- dim xmlDoc,xmlResultDoc,strInXml Set xmlDoc = Server.CreateObject("MSXML.DOMDocument") Set xmlResultDoc = Server.CreateObject("MSXML.DOMDocument") Dim blnLoad blnLoad = xmlDoc.load(Request) If blnLoad Then strInXml = xmlDoc.childNodes(0).text 'response.write strInXml 'response.end sSql = "select fchrSecondTypeID,fchrSecondName from SecondTypeTable where fchrFirstTypeID='"&strInXml&"'" Dim oRsXMl,ResoutXML Set oRsXMl = conn.execute(sSql) ResoutXML = "<Resout>" While Not oRsXMl.eof ResoutXML = ResoutXML&"<R1 Attr='"&oRsXMl("fchrSecondTypeID")&"'>"&oRsXMl("fchrSecondName")&"</R1>" oRsXMl.movenext Wend ResoutXML = ResoutXML&"</Resout>" if ResoutXML="<Resout></Resout>" then Call xmlResultDoc.loadXML("<error ErrDesc='没有记录'></error>") else Call xmlResultDoc.loadXML("<error ErrDesc=''>"&ResoutXML&"</error>") End if Else Call xmlResultDoc.loadXML("<error ErrDesc'载入XML串失败'></error>") End If Response.ContentType="text/xml" Call xmlResultDoc.save(Response) Set oRsXMl = Nothing Set conn = Nothing %>
下拉列表联动总结(AJAX下拉列表联动简单示例)( 下拉列表联动有很多方法可以实现: 1.JavaScript实现,JS实现无非在效率上是最优的,而且用户体验性也很好,但是它的缺点就是两个下拉列表的值是固定死的,所以可扩展性和灵活度不够.下面是一个JS实现的省市联动. 首先是shengshi.js文件的代码:
//
定义分隔符,用于分割[select]变量
var
TheSplit1
=
"
*
"
//
一级选项与一级选项之间的分隔符
var
TheSplit2
=
"
|
"
//
一级选项与二级选项之间的分隔符
var
TheSplit3
=
"
^
"
//
二级选项与二级选项之间的分隔符
var
TheSplit4
=
"
@
"
//
选项文本与选项值的分隔符,可以省略[值为选项文本值]
/**/
/* 定义[select]框选项变量,这里以省市二级为例 例:一级选项一|二级选项一^二级选项二^二级选项三*一级选项二|*二级选项三| *香港|*澳门 注:当一级选项没有二级下属时,请在后面加上TheSplit2分隔符,否帽关联将会出错,所以应该注意防止此类错误发生 如果选项文本与选项值不同时,请在选项文本后加上@值格式:[Text@Value] 如:北京@010|东城@0101^西城@0102 */
var
hwallselecttext
=
"
北京|东城^西城^崇文^宣武^朝阳^丰台^石景山^海淀^门头沟^房山^通州^顺义^昌平^大兴^平谷^怀柔^密云^延庆*上海|黄浦^卢湾^徐汇^长宁^静安^普陀^闸北^虹口^杨浦^闵行^宝山^嘉定^浦东^金山^松江^青浦^南汇^奉贤^崇明*天津|和平^东丽^河东^西青^河西^津南^南开^北辰^河北^武清^红挢^塘沽^汉沽^大港^宁河^静海^宝坻^蓟县*重庆|万州^涪陵^渝中^大渡口^江北^沙坪坝^九龙坡^南岸^北碚^万盛^双挢^渝北^巴南^黔江^长寿^綦江^潼南^铜梁^大足^荣昌^壁山^梁平^城口^丰都^垫江^武隆^忠县^开县^云阳^奉节^巫山^巫溪^石柱^秀山^酉阳^彭水^江津^合川^永川^南川*河北|石家庄^邯郸^邢台^保定^张家口^承德^廊坊^唐山^秦皇岛^沧州^衡水*山西|太原^大同^阳泉^长治^晋城^朔州^吕梁^忻州^晋中^临汾^运城*内蒙古|呼和浩特^包头^乌海^赤峰^呼伦贝尔盟^阿拉善盟^哲里木盟^兴安盟^乌兰察布盟^锡林郭勒盟^巴彦淖尔盟^伊克昭盟*辽宁|沈阳^大连^鞍山^抚顺^本溪^丹东^锦州^营口^阜新^辽阳^盘锦^铁岭^朝阳^葫芦岛*吉林|长春^吉林^四平^辽源^通化^白山^松原^白城^延边*黑龙江|哈尔滨^齐齐哈尔^牡丹江^佳木斯^大庆^绥化^鹤岗^鸡西^黑河^双鸭山^伊春^七台河^大兴安岭*江苏|南京^镇江^苏州^南通^扬州^盐城^徐州^连云港^常州^无锡^宿迁^泰州^淮安*浙江|杭州^宁波^温州^嘉兴^湖州^绍兴^金华^衢州^舟山^台州^丽水*安徽|合肥^芜湖^蚌埠^马鞍山^淮北^铜陵^安庆^黄山^滁州^宿州^池州^淮南^巢湖^阜阳^六安^宣城^亳州*福建|福州^厦门^莆田^三明^泉州^漳州^南平^龙岩^宁德*江西|南昌市^景德镇^九江^鹰潭^萍乡^新馀^赣州^吉安^宜春^抚州^上饶*山东|济南^青岛^淄博^枣庄^东营^烟台^潍坊^济宁^泰安^威海^日照^莱芜^临沂^德州^聊城^滨州^菏泽*河南|郑州^开封^洛阳^平顶山^安阳^鹤壁^新乡^焦作^濮阳^许昌^漯河^三门峡^南阳^商丘^信阳^周口^驻马店^济源*湖北|武汉^宜昌^荆州^襄樊^黄石^荆门^黄冈^十堰^恩施^潜江^天门^仙桃^随州^咸宁^孝感^鄂州*湖南|长沙^常德^株洲^湘潭^衡阳^岳阳^邵阳^益阳^娄底^怀化^郴州^永州^湘西^张家界*广东|广州^深圳^珠海^汕头^东莞^中山^佛山^韶关^江门^湛江^茂名^肇庆^惠州^梅州^汕尾^河源^阳江^清远^潮州^揭阳^云浮*广西|南宁^柳州^桂林^梧州^北海^防城港^钦州^贵港^玉林^南宁地区^柳州地区^贺州^百色^河池*海南|海口^三亚*四川|成都^绵阳^德阳^自贡^攀枝花^广元^内江^乐山^南充^宜宾^广安^达川^雅安^眉山^甘孜^凉山^泸州*贵州|贵阳^六盘水^遵义^安顺^铜仁^黔西南^毕节^黔东南^黔南*云南|昆明^大理^曲靖^玉溪^昭通^楚雄^红河^文山^思茅^西双版纳^保山^德宏^丽江^怒江^迪庆^临沧*西藏|拉萨^日喀则^山南^林芝^昌都^阿里^那曲*陕西|西安^宝鸡^咸阳^铜川^渭南^延安^榆林^汉中^安康^商洛*甘肃|兰州^嘉峪关^金昌^白银^天水^酒泉^张掖^武威^定西^陇南^平凉^庆阳^临夏^甘南*宁夏|银川^石嘴山^吴忠^固原*青海|西宁^海东^海南^海北^黄南^玉树^果洛^海西*新疆|乌鲁木齐^石河子^克拉玛依^伊犁^巴音郭勒^昌吉^克孜勒苏柯尔克孜^博尔塔拉^吐鲁番^哈密^喀什^和田^阿克苏*香港|*澳门|*台湾|台北^高雄^台中^台南^屏东^南投^云林^新竹^彰化^苗栗^嘉义^花莲^桃园^宜兰^基隆^台东^金门^马祖^澎湖*其它|北美洲^南美洲^亚洲^非洲^欧洲^大洋洲
"
var
hwallselecttextarr hwallselecttextarr
=
hwallselecttext.split(TheSplit1) hwArraylength
=
hwallselecttextarr.length
var
hwwhere
=
new
Array(hwArraylength); hwwhere[
0
]
=
new
hw_comefrom(
"
请选择@
"
,
"
请选择@
"
);
for
(
var
hwl
=
0
;hwl
<
hwArraylength;hwl
++
)
...
{ eval(hwwhere[hwl+1] = new hw_comefrom(hwallselecttextarr[hwl].split(TheSplit2)[0],hwallselecttextarr[hwl].split(TheSplit2)[1])); }
function
hw_comefrom(hwSelect_s1,hwSelect_s2)
...
{ this.hwSelect_s1 = hwSelect_s1; this.hwSelect_s2 = hwSelect_s2; }
function
hw_select(boss,underling)
...
{ with(document.getElementsByName(boss)[0]) ...{ var hwSelect_s12 = options[selectedIndex].value; } for(hwi = 0;hwi < hwwhere.length;hwi ++) ...{ if (hwwhere[hwi].hwSelect_s1.indexOf(TheSplit4)!=-1) ...{ var hwThisV = hwwhere[hwi].hwSelect_s1.split(TheSplit4)[1] } else ...{ var hwThisV = hwwhere[hwi].hwSelect_s1 } if (hwThisV == hwSelect_s12) ...{ hwSelect_s13 = (hwwhere[hwi].hwSelect_s2).split(TheSplit3); for(hwj = 0;hwj < hwSelect_s13.length;hwj++) ...{ with(document.getElementsByName(underling)[0]) ...{ length = hwSelect_s13.length; if (hwSelect_s13[hwj].indexOf(TheSplit4)!=-1) ...{ options[hwj].text = hwSelect_s13[hwj].split(TheSplit4)[0] options[hwj].value = hwSelect_s13[hwj].split(TheSplit4)[1] } else ...{ options[hwj].text = hwSelect_s13[hwj]; options[hwj].value = hwSelect_s13[hwj]; } var hwSelect_s14=options[selectedIndex].value; } } break; } } }
function
hw_init(boss,underling,hwdefault_value)
...
{ alert("初始化"); with(document.getElementsByName(boss)[0]) ...{ length = hwwhere.length; var hwm = 0 for(hwk=0;hwk<hwwhere.length;hwk++) ...{ if (hwwhere[hwk].hwSelect_s1.indexOf(TheSplit4)!=-1) ...{ options[hwk].text = hwwhere[hwk].hwSelect_s1.split(TheSplit4)[0]; options[hwk].value = hwwhere[hwk].hwSelect_s1.split(TheSplit4)[1]; if (hwdefault_value.indexOf(hwwhere[hwk].hwSelect_s1.split(TheSplit4)[1])!=-1)...{hwm = hwk} } else ...{ options[hwk].text = hwwhere[hwk].hwSelect_s1; options[hwk].value = hwwhere[hwk].hwSelect_s1; if (hwdefault_value.indexOf(hwwhere[hwk].hwSelect_s1)!=-1)...{hwm = hwk} } } selectedIndex = hwm } with(document.getElementsByName(underling)[0]) ...{ var hwn = 0 hwSelect_s13 = (hwwhere[hwm].hwSelect_s2).split(TheSplit3); length = hwSelect_s13.length; for(hwl=0;hwl<length;hwl++) ...{ if (hwSelect_s13[hwl].indexOf(TheSplit4)!=-1) ...{ options[hwl].text = hwSelect_s13[hwl].split(TheSplit4)[0]; options[hwl].value = hwSelect_s13[hwl].split(TheSplit4)[1]; if (hwdefault_value.indexOf(hwSelect_s13[hwl].split(TheSplit4)[1])!=-1)...{hwn = hwl} } else ...{ options[hwl].text = hwSelect_s13[hwl]; options[hwl].value = hwSelect_s13[hwl]; if (hwdefault_value.indexOf(hwSelect_s13[hwl])!=-1)...{hwn = hwl} } } selectedIndex = hwn } }
然后是调用的HTML页面:
<
select
style
="WIDTH: 60px"
name
="province"
onchange
= "hw_select('province','city')"
>
</
select
>
<
select
style
="WIDTH: 85px"
name
="city"
onchange
= "hw_select('province','city')"
>
</
select
>
<
script
src
="shengshi.js"
language
="JavaScript"
></
script
>
<
script
>
...
//初始化 //"陕西西安"指默认显示的省,市。 hw_init("province","city","陕西西安");
</
script
>
2.第二种就是两个下拉列表的值分别存在两张表中,或者是一张表中,他们有父子一对多的关系.具体实现思路是:在页面首先读取出第一个下拉列表的值,然后在它的onChange事件里提交表单到本页面,然后再根据提交的第一个下拉的值去数据库中查询出第二个下拉列表的内容显示. 这种方法的好处是数据是动态的,随时可以更改数据库数据,比较灵活.但是它的缺点也是显而易见的,那就是每次选择第一个下拉都要提交表单,整个页面都要刷新,用户体验很差,性能也比较低.而且如果页面上有很多其他用户填写的数据,要保存这些数据相当麻烦和烦琐. 3.根据网友遥远的意见,在第二种的基础上加进iframe框架也是一个不错的选择,也就是把两个下拉放在一个iframe中,它同样可以实现只刷新局部,也是一种不错的选择.但是仍然存在一点缺陷就是刷新的时候会出现白屏闪过.这是它比第四中弱的地方. 4.第四种就是我今天刚刚用AJAX实现的,在第二种的基础上的改良,不用提交整个表单,按需取的相应的数据,局部刷新,用户体验是和第一种JS实现的一样.性能上比第二个要好很多,因为它只刷新需要改边的地方,所以也没有第二种要保留用户数据的麻烦,有具有第二种的数据动态和灵活性.是一种比较好的选择.下面是一个简单的没有连接数据库的例子: 首先是第一个下拉框页面代码:
<%
...
@ page contentType="text/html; charset=GBK"
%>
<
html
>
<
head
>
<
title
>
下拉列表联动
</
title
>
</
head
>
<
body
bgcolor
="#ffffff"
>
<
table
>
<
tr
>
<
td
>
<
select
name
="s1"
onChange
="haha()"
>
<
option
value
="null"
>
请选择
<
option
value
="1"
>
1
<
option
value
="2"
>
2
<
option
value
="3"
>
3
<
option
value
="4"
>
4
</
select
>
</
td
>
<
td
id
="heihei"
>
<
select
>
<
option
>
请先选择第一个下拉
</
select
>
</
td
>
</
tr
>
</
table
>
<
script
>
...
//定义XMLHttpRequest对象 var http_request=false;
function send_request(url)...{ http_request=false; //开始初始化XMLHttpRequest对象 if(window.XMLHttpRequest)...{//Mozilla等浏览器初始化XMLHttpRequest过程 http_request=new XMLHttpRequest(); //有些版本的Mozilla浏览器处理服务器返回的未包含XML mime-type头部信息的内容时会出错. //因此,要确保返回的内容包含text/xml信息. if(http_request.overrideMimeType)...{ http_request.overrideMimeType("text/xml"); } } else if(window.ActiveXObject)...{//IE浏览器初始化XMLHttpRequest过程 try...{ http_request=new ActiveXObject("Msxml2.XMLHTTP"); } catch(e)...{ try...{ http_request=new ActiveXObject("Microsoft.XMLHTTP"); } catch(e)...{} } } //异常,创建对象失败 if(!http_request)...{ window.alert("不能创建XMLHttpRequest对象实例!"); return false; } //指定响应处理函数 http_request.onreadystatechange=processRequest; //发送HTTP请求信息 http_request.open("GET",url,true); http_request.send(null); }
//处理返回信息函数 function processRequest()...{ //判断对象状态 if(http_request.readyState==4)...{ //判断HTTP状态码 if(http_request.status==200)...{ //信息已经成功返回 //window.document.write(http_request.responseText); //alert(http_request.responseText); document.getElementById("heihei").innerHTML=http_request.responseText; } else ...{ //请求页面有问题 alert("您所请求的页面有异常!错误状态:"+http_request.status); } } }
function haha()...{ var flag=document.all("s1").value; send_request("select.jsp?flag="+flag); }
</
script
>
</
body
>
</
html
>
然后是第二个下拉列表页面代码:
<%
...
@ page contentType="text/html; charset=GBK"
%>
<%
...
String flag=request.getParameter("flag"); if("1".equals(flag)){
%>
<
select
name
="s2"
>
<
option
value
="a"
>
a
<
option
value
="b"
>
b
<
option
value
="c"
>
c
<
option
value
="d"
>
d
</
select
>
<%
...
}else if("2".equals(flag)){
%>
<
select
name
="s2"
>
<
option
value
="e"
>
e
<
option
value
="f"
>
f
<
option
value
="g"
>
g
<
option
value
="h"
>
h
</
select
>
<%
...
}else{
%>
<
select
name
="s2"
>
<
option
value
="null"
>
此项没有内容
</
select
>
<%
...
}
%>
|
|