利用 XMLHttpRequest 对象实现 DropDownList 控件的联

 

这篇来说说如何利用 XMLHttpRequest 对象实现 DropDownList 控件的联动.

先看下效果图

 

 

 

 

Let's get started.

首先来创建相关的数据库和表

这里使用的是Test数据库,当然你可以任意命名数据库名称,只需在相应数据库下执行建表的脚本即可。

建表脚本可以看这里省、市联动数据库SQL脚本

执行脚本之后,数据库的部分就完成了。

然后打开开发环境 vs 2005,选择或新建项目

新建一Web窗体,命名为 LinkageDropDownList.aspx 此Web窗体为View部分,需要为它创建异步请求服务器时的处理对象。
在这里还是选取了Web窗体,当然选取其他的服务器处理对象也是完全可以的。
再新建一Web窗体,命名为 GetCityByProvinceID.aspx 用于处理 LinkageDropDownList.aspx 发送过来的请求。

接着设计 LinkageDropDownList.aspx 的界面,界面效果很简单,就是两个DropDownList 和一个 Button 按钮。

代码如下:

+ expand sourceview plaincopy to clipboardprint?
<asp:DropDownList ID="ddlProvince" onchange="getCityBind(this.value);" runat="server"></asp:DropDownList> 
<asp:DropDownList ID="ddlCity" runat="server"></asp:DropDownList> 
<asp:Button ID="btnSubmit" runat="server" Text="提交" OnClick="btnSubmit_Click" />  
<asp:DropDownList ID="ddlProvince" onchange="getCityBind(this.value);" runat="server"></asp:DropDownList>
<asp:DropDownList ID="ddlCity" runat="server"></asp:DropDownList>
<asp:Button ID="btnSubmit" runat="server" Text="提交" OnClick="btnSubmit_Click" /> 

getCityBind 是一个假定的js函数,让我们来想想函数的功能是怎样的,它应该实现些什么。
在改变省的下拉列表框时,应该根据选择的省的ID获得它对应的市的数据并绑定市的下拉列表框。
主体功能已经出来了,让我们来实现它。首先,在触发事件时我们应该把选择后的省的ID传到方法中,
方法的原型也就出来了,function getCityBind(val) { do something }
代码如下:
+ expand sourceview plaincopy to clipboardprint?
function getCityBind(val)  
 
   if(val=='0')  
      return ;  
   openAjax(val);  

function getCityBind(val)
{
   if(val=='0')
      return ;
   openAjax(val);
}

完整的js代码:

view plaincopy to clipboardprint?
var xmlHttp=null;                
function $(id)  
 
    return document.getElementByIdx_x(id);  
 
function createXMLHttpRequest()   
  
    if(xmlHttp == null){  
        if(window.XMLHttpRequest) {  
            //Mozilla 浏览器  
            xmlHttp = new XMLHttpRequest();  
        }else if(window.ActiveXObject) {  
            // IE浏览器  
            try {  
                xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");  
            } catch (e) {  
                try {  
                    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");  
                } catch (e) {  
                
            
        
    
  
 
function openAjax(val)   
    
      
    if( xmlHttp == null)  
                    
        createXMLHttpRequest();    
        if( xmlHttp == null)  
        
            //alert('出错');  
            return ;  
        
                                                           
    $('<%=ddlCity.ClientID %>').options[0]=new Option("正在加载...","");   
    $('<%=ddlCity.ClientID %>').disabled=true;  
      
    try 
    
        xmlHttp.open("get","GetCityByProvinceID.aspx?PID="+val+"&date="+new Date(),true);   
        //xmlHttp.open("get","GetCityByProvinceID.aspx?PID="+val,true);   
          
        xmlHttp.onreadystatechange=xmlHttpChange;               
     
        xmlHttp.send(null);                  
    
    catch(e)  
                
        $('<%=ddlCity.ClientID %>').options.length=0;   
        $('<%=ddlCity.ClientID %>').disabled=false;  
    
  
 
function xmlHttpChange()   
  
    if(xmlHttp.readyState==4)   
                 
        if(xmlHttp.status==200)   
                                                                        
            $('<%=ddlCity.ClientID %>').options.length=0;   
            $('<%=ddlCity.ClientID %>').disabled=false;                      
            Bind(xmlHttp.responseText);                      
         
     
     
function getCityBind(val)  
 
    if(val=='0')  
        return ;  
    openAjax(val);  
 
function Bind(xmlStr)  
         
    if(xmlStr=='')  
    
        $('<%=ddlCity.ClientID %>').disabled=true;   
        return;  
    
    $('<%=ddlCity.ClientID %>').options.add(new Option("——请选择——", "0"));  
    var xmlDoc;  
    if(window.ActiveXObject)  
    
        xmlDoc    = new ActiveXObject('MSXML2.DOMDocument');  
        xmlDoc.async    = false;      
        xmlDoc.loadXML(xmlStr);                   
        if(xmlDoc.parseError.errorCode!=0)     
                             
            alert("出错!"+xmlDoc.parseError.reason);     
                   
    
    else if (document.implementation&&document.implementation.createDocument)  
    
        xmlDoc  = document.implementation.createDocument('', '', null);  
        xmlDoc.async=false;  
        xmlDoc.loadXML(xmlStr);     
    
    var elementList;  
    elementList = xmlDoc.getElementsByTagName_r('City');  
    // 遍历  
    for (var j = 0;j < elementList.length; j++) {                          
        if(elementList[j].childNodes.length==3)  
        
            $('<%=ddlCity.ClientID %>').options.add(new Option(elementList[j].childNodes[1].text,elementList[j].childNodes[0].text));  
                                
    
    $('<%=ddlCity.ClientID %>').options[1].selected=true;  
 
        var xmlHttp=null;             
        function $(id)
        {
            return document.getElementByIdx_x(id);
        }
        function createXMLHttpRequest()
        {
            if(xmlHttp == null){
                if(window.XMLHttpRequest) {
                    //Mozilla 浏览器
                    xmlHttp = new XMLHttpRequest();
                }else if(window.ActiveXObject) {
                    // IE浏览器
                    try {
                        xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
                    } catch (e) {
                        try {
                            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
                        } catch (e) {
                        }
                    }
                }
            }
        }
       
        function openAjax(val)
        
           
            if( xmlHttp == null)
                         
                createXMLHttpRequest(); 
                if( xmlHttp == null)
                {
                    //alert('出错');
                    return ;
                }
                                                                
            $('<%=ddlCity.ClientID %>').options[0]=new Option("正在加载...","");
            $('<%=ddlCity.ClientID %>').disabled=true;
           
            try
            {
                xmlHttp.open("get","GetCityByProvinceID.aspx?PID="+val+"&date="+new Date(),true);
                //xmlHttp.open("get","GetCityByProvinceID.aspx?PID="+val,true);
               
                xmlHttp.onreadystatechange=xmlHttpChange;            
          
                xmlHttp.send(null);               
            }
            catch(e)
                     
                $('<%=ddlCity.ClientID %>').options.length=0;
                $('<%=ddlCity.ClientID %>').disabled=false;
            }
        }
       
        function xmlHttpChange()
        {
            if(xmlHttp.readyState==4)
                      
                if(xmlHttp.status==200)
                                                                             
                    $('<%=ddlCity.ClientID %>').options.length=0;
                    $('<%=ddlCity.ClientID %>').disabled=false;                   
                    Bind(xmlHttp.responseText);                   
                }
            }
         
        function getCityBind(val)
        {
            if(val=='0')
                return ;
            openAjax(val);
        }
        function Bind(xmlStr)
             
            if(xmlStr=='')
            {
                $('<%=ddlCity.ClientID %>').disabled=true;
                return;
            }
            $('<%=ddlCity.ClientID %>').options.add(new Option("——请选择——", "0"));
            var xmlDoc;
            if(window.ActiveXObject)
            {
                xmlDoc    = new ActiveXObject('MSXML2.DOMDocument');
                xmlDoc.async    = false;   
                xmlDoc.loadXML(xmlStr);                
                if(xmlDoc.parseError.errorCode!=0)  
                                  
                    alert("出错!"+xmlDoc.parseError.reason);  
                        
            }
            else if (document.implementation&&document.implementation.createDocument)
            {
                xmlDoc  = document.implementation.createDocument('', '', null);
                xmlDoc.async=false;
                xmlDoc.loadXML(xmlStr);  
            }
            var elementList;
            elementList = xmlDoc.getElementsByTagName_r('City');
            // 遍历
            for (var j = 0;j < elementList.length; j++) {                       
                if(elementList[j].childNodes.length==3)
                {
                    $('<%=ddlCity.ClientID %>').options.add(new Option(elementList[j].childNodes[1].text,elementList[j].childNodes[0].text));
                                     
            }
            $('<%=ddlCity.ClientID %>').options[1].selected=true;
       

然后编写 LinkageDropDownList.aspx.cs 的代码,功能是读取数据库的数据并绑定省的下拉列表框(DropDownList)。

主要代码如下:

+ expand sourceview plaincopy to clipboardprint?
protected void Page_Load(object sender, EventArgs e)  
 
    if (!IsPostBack)  
    
        using (SqlConnection con = new SqlConnection("server=.;uid=xxx;pwd=xxx;database=Test"))  
        
            SqlDataAdapter sda = new SqlDataAdapter("select * from province", con);  
            DataSet ds = new DataSet();  
            sda.Fill(ds, "province");  
            if (ds.Tables.Contains("province"))  
            
                ddlProvince.DataSource = ds.Tables["province"].DefaultView;  
                ddlProvince.DataTextField = "pName";  
                ddlProvince.DataValueField = "pID";  
                ddlProvince.DataBind();  
                if (ddlProvince.Items.Count > 0)  
                
                    ddlProvince.Items.Insert(0, new ListItem("——请选择——", "0"));  
                    ddlProvince.Items[1].Selected = true;  
                
            
        }//end using block  
    }//end if block  
}//end Page_Load event 
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            using (SqlConnection con = new SqlConnection("server=.;uid=xxx;pwd=xxx;database=Test"))
            {
                SqlDataAdapter sda = new SqlDataAdapter("select * from province", con);
                DataSet ds = new DataSet();
                sda.Fill(ds, "province");
                if (ds.Tables.Contains("province"))
                {
                    ddlProvince.DataSource = ds.Tables["province"].DefaultView;
                    ddlProvince.DataTextField = "pName";
                    ddlProvince.DataValueField = "pID";
                    ddlProvince.DataBind();
                    if (ddlProvince.Items.Count > 0)
                    {
                        ddlProvince.Items.Insert(0, new ListItem("——请选择——", "0"));
                        ddlProvince.Items[1].Selected = true;
                    }
                }
            }//end using block
        }//end if block
    }//end Page_Load event

接下来就是完成 GetCityByProvinceID.aspx 要做的工作,它要做的事就是根据请求中省的ID访问数据库,
获得对应的市的数据并返回指定格式的响应。相应的格式可选的很多,这里返回的是XML文档格式。
GetCityByProvinceID.aspx.cs代码如下:

+ expand sourceview plaincopy to clipboardprint?
protected void Page_Load(object sender, EventArgs e)  
 
    string PID = Request.QueryString["PID"];  
    if (!string.IsNullOrEmpty(PID))  
    
        using (SqlConnection con = new SqlConnection("server=.;uid=xxx;pwd=xxx;database=Test"))  
        
            SqlDataAdapter sda = new SqlDataAdapter("select * from city where pId=@pId order by cId", con);  
            sda.SelectCommand.Parameters.Add(new SqlParameter("@pId", PID));  
            DataSet ds = new DataSet();  
            sda.Fill(ds, "city");                  
            if (ds.Tables.Contains("city") && ds.Tables["city"].Rows.Count > 0)  
            
                XmlTextWriter writer = new XmlTextWriter(Response.OutputStream, Response.ContentEncoding);  
                writer.Formatting = Formatting.Indented;  
                writer.Indentation = 4;  
                writer.IndentChar = ' ';  
                ds.Tables["city"].TableName = "City";  
                ds.Tables["city"].WriteXml(writer);  
                writer.Flush();  
                writer.Close();  
            
        }//end using block              
             
        Response.End();  
    

 protected void Page_Load(object sender, EventArgs e)
 {
     string PID = Request.QueryString["PID"];
     if (!string.IsNullOrEmpty(PID))
     {
         using (SqlConnection con = new SqlConnection("server=.;uid=xxx;pwd=xxx;database=Test"))
         {
             SqlDataAdapter sda = new SqlDataAdapter("select * from city where pId=@pId order by cId", con);
             sda.SelectCommand.Parameters.Add(new SqlParameter("@pId", PID));
             DataSet ds = new DataSet();
             sda.Fill(ds, "city");               
             if (ds.Tables.Contains("city") && ds.Tables["city"].Rows.Count > 0)
             {
                 XmlTextWriter writer = new XmlTextWriter(Response.OutputStream, Response.ContentEncoding);
                 writer.Formatting = Formatting.Indented;
                 writer.Indentation = 4;
                 writer.IndentChar = ' ';
                 ds.Tables["city"].TableName = "City";
                 ds.Tables["city"].WriteXml(writer);
                 writer.Flush();
                 writer.Close();
             }
         }//end using block           
           
         Response.End();
     }
 }

到这里已经可以运行查看效果了,是不是和截图一样,联动的效果已经出来了。

不过,先别急着高兴,点击提交你会发现出错了。
 

为什么出错了呢?这个错误又是什么意思呢?

具体可以看这篇文章 回发或回调参数无效 的解决办法

你可能感兴趣的:(XMLhttpREquest)