无刷新的四级联动下拉框实例(AjaxPro)

来源:互联网 发布:网络兼职广告 编辑:程序博客网 时间:2024/05/17 09:03

之前的“省市县镇”四级控件是使用 MagicAjax 开发的。每一级都是到数据库中读取。经过 DBA 分析,
和该控件有关的表查询量很大, SQL 语句解析次数也非常多,虽然是 Oracle 数据库还是要尽量避免的。
为此新的控件将“省市”两级的数据存放在 JS 里,而“县镇”两级从数据库中读取,同时再结合项目需
要的特殊功能。

主要功能:
用户访问网站,首先根据二级域名加载用户所在的地区(如 http://xm.XXXX.com 福建-厦门)。如果没
有二级域名,那么根据 Cookie (如果之前访问过)加载用户所在的地区。如果没有,最后根据 IP 来
加载用户所在的地区。
如果是通过 Cookie 或是 IP 来判断,最后还要进行重定向(就是将 http://www.XXXX.com 转成
http://bj.XXXX.com)。如果是根据 IP 判断的,还要把用户所在的地区存入 Cookie。方便下次使用。
为了能从数据库读取数据,直接加载相应地区,还有能从下拉框中读取用户选择的地区就自定义一些属性。

特殊功能
是否重定向、是否只显示“省市”两级、是否垂直排列下拉框(默认是横向)、是否在在省份下拉框前
显示“省份”,城市下拉框前显示“城市”......、是否禁用控件(有些情况下,你可能要禁止用户选
择,等满足条件后才能选)

其他说明
前台脚本采用 JavaScript 和 DOM 互操作,全部使用 W3C 标准使其在各种浏览器下都正常。操作
<select> 采用更通用的 createElement() 而没有使用 options.add()。
后台采用 ASP.NET 进行少量操作(保存 Cookie||读数据库)
前后台采用 AjaxPro 使 JavaScript 和 C# 交互(传递枚举||调用方法||传递结果集)这部分应该是
重点....脚本和高级语言的交互是很让人向往的...暂时只会第三方 Ajax
最后采用一些看似多余的调用,实际上是为了防止 AjaxPro 生成的代码泄露了程序集和命名空间,老
大要求的...

顺便说下,如果数据库设计合理,前两位省份,中间两位城市,最后两位县/区,那么程序中很多地方
的代码都能省了...可见良好的数据库设计是非常重要的。

项目请一定要采用 AjaxPro 6.10.4.1 版本,其他版本有 BUG ,我也是开发中被搞乱了
下面就是源码了,没什么好说了...注释都很详细了

首先是 AreaInfo.cs 地区信息实体类,方便在其他程序读取用的

namespace AreaDropDownList
{
    
/// <summary>
    
/// 地区信息类
    
/// </summary>

    public sealed class AreaInfo
    
{
        
private int _SFID;
        
private int _CSID;
        
private int _XianID;
        
private int _ZhenID;

        
private string _SF;
        
private string _CS;
        
private string _Xian;
        
private string _Zhen;

        
private string _Domain;

        
/// <summary>
        
/// 省份ID
        
/// </summary>

        public int SFID
        
{
            
get return this._SFID; }
            
set this._SFID = value; }
        }

        
/// <summary>
        
/// 城市ID
        
/// </summary>

        public int CSID
        
{
            
get return this._CSID; }
            
set this._CSID = value; }
        }

        
/// <summary>
        
/// 县/区ID
        
/// </summary>

        public int XianID
        
{
            
get return this._XianID; }
            
set this._XianID = value; }
        }

        
/// <summary>
        
/// 镇
        
/// </summary>

        public int ZhenID
        
{
            
get return this._ZhenID; }
            
set this._ZhenID = value; }
        }


        
/// <summary>
        
/// 省份名称
        
/// </summary>

        public string SF
        
{
            
get return this._SF; }
            
set this._SF = value; }
        }

        
/// <summary>
        
/// 城市名称
        
/// </summary>

        public string CS
        
{
            
get return this._CS; }
            
set this._CS = value; }
        }

        
/// <summary>
        
/// 县/区名称
        
/// </summary>

        public string Xian
        
{
            
get return this._Xian; }
            
set this._Xian = value; }
        }

        
/// <summary>
        
/// 镇名称
        
/// </summary>

        public string Zhen
        
{
            
get return this._Zhen; }
            
set this._Zhen = value; }
        }


        
/// <summary>
        
/// 域名
        
/// </summary>

        public string Domain
        
{
            
get return this._Domain; }
            
set this._Domain = value; }
        }

    }

}

 接下来是数据访问层,项目使用的是 Oracle
using System;
using System.Data;
using System.Data.OracleClient;
using System.Web;

namespace AreaDropDownList
{
    
/// <summary>
    
/// 地区控件数据访问操作层
    
/// </summary>

    public static class AreaDAL
    
{
        
private static readonly string Link = "server=gou200;user=gou;pwd=gou;";
            private static readonly string[] SecondDomain = new string[] "www""gou""un""help""hotel""news""trip""brand""soft""train" };
            private static readonly int CookieDay = 3;   //Cookie 保存的天数
        private static readonly string CookieDomain = "xxx.cn";   //Cookie 的域

        
/// <summary>
        
/// 返回符合 SQL语句 的 DataTable
        
/// </summary>
        
/// <param name="sql">SQL 语句</param>
        
/// <returns></returns>

        public static DataTable GetDataTable(string sql)
        
{
            OracleConnection conn 
= new OracleConnection(Link);
            OracleDataAdapter adapter 
= new OracleDataAdapter(sql, conn);
            DataTable table 
= new DataTable();
            adapter.Fill(table);
            
return table;
        }


        
/// <summary>
        
/// 将当前所有下拉框的值存入 Cookie
        
/// </summary>
        
/// <param name="sfid">省份ID</param>
        
/// <param name="csid">城市ID</param>
        
/// <param name="xianid">县/区ID</param>
        
/// <param name="zhenid">镇ID</param>
        
/// <param name="sf">省份名</param>
        
/// <param name="cs">城市名</param>
        
/// <param name="xian">县/区名</param>
        
/// <param name="zhen">镇名</param>
        
/// <param name="domain">地区域名</param>

        public static void SaveCookie(int sfid, int csid, int xianid, int zhenid, string sf, string cs, string xian, string zhen, string domain)
        
{
            HttpCookie cookie 
= new HttpCookie("Area");
            cookie[
"SFID"= sfid.ToString();
            cookie[
"CSID"= csid.ToString();
            cookie[
"XianID"= xianid.ToString();
            cookie[
"ZhenID"= zhenid.ToString();
            cookie[
"SF"= HttpContext.Current.Server.UrlEncode(String.IsNullOrEmpty(sf) ? "" : sf.Replace("—请选择—"""));
            cookie[
"CS"= HttpContext.Current.Server.UrlEncode(String.IsNullOrEmpty(cs) ? "" : cs.Replace("—请选择—"""));
            cookie[
"Xian"= HttpContext.Current.Server.UrlEncode(String.IsNullOrEmpty(xian) ? "" : xian.Replace("—请选择—"""));
            cookie[
"Zhen"= HttpContext.Current.Server.UrlEncode(String.IsNullOrEmpty(zhen) ? "" : zhen.Replace("—请选择—"""));
            cookie[
"Domain"= domain;
            cookie.Domain 
= CookieDomain;
            cookie.Expires 
= DateTime.Now.AddDays(CookieDay);
            HttpContext.Current.Response.Cookies.Add(cookie);
        }


        
/// <summary>
        
/// 将地区信息存入 Cookie
        
/// </summary>
        
/// <param name="ai">地区信息</param>

        private static void SaveCookie(AreaInfo ai)
        
{
            SaveCookie(ai.SFID, ai.CSID, ai.XianID, ai.ZhenID, ai.SF, ai.CS, ai.Xian, ai.Zhen, ai.Domain);
        }


        
/*=====================================================================*/

        
/// <summary>
        
/// 通过 域名 加载相应的地区
        
/// </summary>
        
/// <returns></returns>

        public static AreaInfo GetAreaInfoByDomain()
        
{
            
string domain = HttpContext.Current.Request.Url.Host.Split('.')[0].ToLower();
            
if (IsSecondDomain(domain))
                
return null;

            AreaInfo ai;
            HttpCookie cookie 
= HttpContext.Current.Request.Cookies["Area"];
            
if (cookie != null && cookie["Domain"== domain)
            
{
                
//Cookie 里的域名和当前的域名相同,说明 Cookie 里有更详细的地区信息(如:从 Cookie 重定向而来)
                ai = new AreaInfo();
                ai.SFID 
= Convert.ToInt32(cookie["SFID"]);
                ai.CSID 
= Convert.ToInt32(cookie["CSID"]);
                ai.XianID 
= Convert.ToInt32(cookie["XianID"]);
                ai.ZhenID 
= Convert.ToInt32(cookie["ZhenID"]);
                ai.SF 
= HttpContext.Current.Server.UrlDecode(cookie["SF"]);
                ai.CS 
= HttpContext.Current.Server.UrlDecode(cookie["CS"]);
                ai.Xian 
= HttpContext.Current.Server.UrlDecode(cookie["Xian"]);
                ai.Zhen 
= HttpContext.Current.Server.UrlDecode(cookie["Zhen"]);
                ai.Domain 
= cookie["Domain"];
            }

            
else
            
{
                ai 
= GetAreaInfoByDomain(domain);
                
if (ai == null)
                    
return null;
                SaveCookie(ai);
            }


            
return ai;
        }


        
/// <summary>
        
/// 返回域名对应的地区信息
        
/// </summary>
        
/// <param name="domain">三级域名</param>
        
/// <returns></returns>

        private static AreaInfo GetAreaInfoByDomain(string domain)
        
{
            OracleConnection conn 
= new OracleConnection(Link);
            
//使用一条SQL 代替 多次SQL查询
            string sql = String.Format("SELECT cs.csid,(cs.sfid || sf.sfid) AS sfid,cs.CityName,(cs.sfname || sf.sfname) AS sfname FROM (SELECT c.pkid AS csid,c.OneID AS sfid,c.CityName AS CityName,s.sfname AS sfname FROM (SELECT PKID,OneID,CityName FROM CityInfo WHERE CityDomain='{0}') c RIGHT JOIN(SELECT pkid,CityName AS sfname FROM CityInfo WHERE pkid=(SELECT OneID FROM CityInfo WHERE CityDomain='{0}')) s ON c.oneid=s.pkid) cs FULL OUTER JOIN (SELECT pkid AS sfid,CityName AS sfname FROM cityinfo WHERE citydomain='{0}' AND OneID=0) sf ON cs.sfid=sf.sfid", domain);
            OracleCommand cmd 
= new OracleCommand(sql, conn);
            conn.Open();
            OracleDataReader dr 
= cmd.ExecuteReader();
            
if (dr.Read())
            
{
                AreaInfo ai 
= new AreaInfo();
                Object[] os 
= new object[dr.FieldCount];
                dr.GetValues(os);
                dr.Close();
                conn.Close();
                ai.CSID 
= (os[0is DBNull) ? 0 : Convert.ToInt32(os[0]);
                ai.SFID 
= (os[1is DBNull) ? 0 : Convert.ToInt32(os[1]);
                ai.CS 
= (os[2is DBNull) ? String.Empty : os[2].ToString();
                ai.SF 
= (os[3is DBNull) ? String.Empty : os[3].ToString();
                ai.Domain 
= domain;
                
return ai;
            }

            dr.Close();
            conn.Close();
            
return null;
        }


        
/// <summary>
        
/// 是否是二级域名
        
/// </summary>
        
/// <param name="domain">可能是二级域名的字符串</param>
        
/// <returns>是,返回 ture</returns>

        private static bool IsSecondDomain(string domain)
        
{
            
foreach (string sd in SecondDomain)
            
{
                
if (domain == sd)
                    
return true;
            }

            
return false;
        }


        
/*=====================================================================*/

        
/// <summary>
        
/// 返回 Cookie 对应的地区信息
        
/// </summary>
        
/// <returns></returns>

        public static AreaInfo GetAreaInfoByCookie()
        
{
            AreaInfo ai 
= new AreaInfo();
            HttpCookie cookie 
= HttpContext.Current.Request.Cookies["Area"];
            
if (cookie == null)
                
return null;

            ai.SFID 
= Convert.ToInt32(cookie["SFID"]);
            ai.CSID 
= Convert.ToInt32(cookie["CSID"]);
            ai.XianID 
= Convert.ToInt32(cookie["XianID"]);
            ai.ZhenID 
= Convert.ToInt32(cookie["ZhenID"]);
            ai.SF 
= HttpContext.Current.Server.UrlDecode(cookie["SF"]);
            ai.CS 
= HttpContext.Current.Server.UrlDecode(cookie["CS"]);
            ai.Xian 
= HttpContext.Current.Server.UrlDecode(cookie["Xian"]);
            ai.Zhen 
= HttpContext.Current.Server.UrlDecode(cookie["Zhen"]);
            ai.Domain 
= cookie["Domain"];

            
if (ai.SFID == 0)
                
return null;

            
return ai;
        }


        
/*=====================================================================*/

        
/// <summary>
        
/// 通过 IP 加载相应的地区
        
/// </summary>
        
/// <returns></returns>

        public static AreaInfo GetAreaInfoByIP()
        
{
            AreaInfo ai 
= GetAreaInfoByIP(HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]);
            
if (ai == null)
                
return null;
            SaveCookie(ai);
            
return ai;
        }


        
/// <summary>
        
/// 返回 IP 对应的地区信息
        
/// </summary>
        
/// <param name="ip">IP字符串</param>
        
/// <returns></returns>

        private static AreaInfo GetAreaInfoByIP(string ip)
        
{
            AreaInfo ai 
= new AreaInfo();
            
uint IpNum;
            
string[] IPList = ip.Split('.');
            IpNum 
= Convert.ToUInt32(Convert.ToUInt32(IPList[0]) * 255 * 255 * 255 + Convert.ToUInt32(IPList[1]) * 255 * 255 + Convert.ToUInt32(IPList[2]) * 255 + Convert.ToUInt32(IPList[3]));
            
string sql = String.Format("SELECT i.sfid00,i.CityCode,i.sfname,i.CityName,c.CityDomain FROM (SELECT CityDomain,pkid FROM CityInfo) c RIGHT JOIN (SELECT SFID00,CityCode,SFName,CityName FROM T_BM_Ip WHERE IpOne<={0} AND IpTwo>={0}) i ON c.pkid=i.CityCode", IpNum);
            OracleConnection conn 
= new OracleConnection(Link);
            OracleCommand cmd 
= new OracleCommand(sql, conn);
            conn.Open();
            OracleDataReader dr 
= cmd.ExecuteReader();
            
if (dr.Read())
            
{
                Object[] os 
= new object[dr.FieldCount];
                dr.GetValues(os);
                dr.Close();
                conn.Close();
                ai.SFID 
= (os[0is DBNull) ? 0 : Convert.ToInt32(os[0]);
                ai.CSID 
= (os[1is DBNull) ? 0 : Convert.ToInt32(os[1]);
                ai.SF 
= (os[2is DBNull) ? String.Empty : os[2].ToString();
                ai.CS 
= (os[3is DBNull) ? String.Empty : os[3].ToString();
                ai.Domain 
= (os[4is DBNull) ? String.Empty : os[4].ToString();
                
return ai;
            }

            dr.Close();
            conn.Close();
            ai.SFID 
= 11//设置默认值
            ai.SF = "北京";
            ai.Domain 
= "bj";
            
return ai;
        }

    }

}




然后就是重点了...用户控件 前台代码,中间有段很长的 省份城市JS 数组,我去掉了,想看可以去另一篇同名 blog 看
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="AreaControl.ascx.cs" Inherits="AreaControl" %>
<div>
<table id="AreaTable" runat="server">
    
<tr>
        
<td>
            
<select id="sSF" runat="server">
                
<option selected="selected" value="0">—请选择—</option>
            
</select>
        
</td>
        
<td>
            
<select id="sCS" runat="server">
                
<option selected="selected" value="0">—请选择—</option>
            
</select>
        
</td>
        
<td>
            
<select id="sXian" runat="server">
                
<option selected="selected" value="0">—请选择—</option>
            
</select>
        
</td>
        
<td>
            
<select id="sZhen" runat="server">
                
<option selected="selected" value="0">—请选择—</option>
            
</select>
        
</td>
    
</tr>
</table>
<input type="hidden" id="hSF" runat="server" />
<input type="hidden" id="hCS" runat="server" />
<input type="hidden" id="hXian" runat="server" />
<input type="hidden" id="hZhen" runat="server" />
<input type="hidden" id="hDomain" runat="server" />
</div>

<script type="text/javascript">
//<%-- ID 城市 上级ID 二级域名--%>
var aDQ=new Array();
//<%-- 省份的上级ID改为 -1 和 "—请选择—" 区分开 --%>
aDQ[0]=["11","北京","-1","bj"];
//该数组请去另一篇 Blog 看

//<%-- 通过 DOM 创建下拉框 --%>
//
<%-- obj:下拉框的 options 数据集 --%>
//
<%-- id:下拉框的 id --%>
function CreateDropDownList(obj,id)
{
    
var sel=document.getElementById(id);
    
if(sel==null)   //<%-- 可能只显示省市 --%>
        return;
    sel.options.length
=1;   //<%-- 保存"—请选择—" --%>
    //<%-- 对于省份、城市常用 Array 存储,对于县、镇则从数据库读取 --%>
    if(obj==null)
        
return;
    
if(obj instanceof Array)
    
{
        
for(var i=0;i<obj.length;i++)
        
{
            
var op=document.createElement("option");
            op.setAttribute(
"value",obj[i][0]);   //<%-- 可考虑改成 value="xm,厦门">厦门 --%>
            var txt=document.createTextNode(obj[i][1]);
            op.appendChild(txt);
            sel.appendChild(op);
        }

    }

    
else
    
{
        
for(var i=0;i<obj.Rows.length;i++)  //<%-- 注意这里是 length 不是 Count --%>
        {
            
var op=document.createElement("option");
            op.setAttribute(
"value",obj.Rows[i].ID);    //<%-- 注意区分大小写 --%>
            var txt=document.createTextNode(obj.Rows[i].NAME);  //<%-- 根 DataTable 的列名称要一致 --%>
            op.appendChild(txt);
            sel.appendChild(op);
        }

    }

    
//<%-- 绑定下一个下拉框 --%>
    switch(id)
    
{
        
//<%-- 选择一次,保存到 Cookie 一次,可以往 onchange 事件里加入 Save(); --%>
        case "<%=this.sSF.ClientID%>":sel.onchange=function(){ClearXianZhen();CreateDropDownList(GetArray(this.value),"<%=this.sCS.ClientID%>");Save();};break;
        
case "<%=this.sCS.ClientID%>":sel.onchange=function(){ClearZhen();CreateDropDownList(AreaControl.GetDataTable(this.value,AreaEnum.Xian).value,"<%=this.sXian.ClientID%>");Save();};break;  //<%-- JS 向 C# 传递参数,并取得 C# 的返回值 --%>
        case "<%=this.sXian.ClientID%>":sel.onchange=function(){CreateDropDownList(AreaControl.GetDataTable(this.value,AreaEnum.Zhen).value,"<%=this.sZhen.ClientID%>");Save();};break;   //<%-- 返回值.value --%>
        default:sel.onchange=function(){Save();};break//alert(this.value);
    }

}

//<%-- 获取要求的数组 --%>
//
<%-- val:所属的省份ID --%>
function GetArray(val)
{
    
if(val==0)  //<%-- 用户选"—请选择—"不查询 --%>
        return null;
    
var temp=new Array();
    
var j=0;
    
for(var i=0;i<aDQ.length;i++)
    
{
        
if(val==aDQ[i][2].toString())
        
{
            temp[j]
=aDQ[i];
            j
++;
        }

    }

    
return temp;
}

//<%-- 清空"镇"下拉框 --%>
function ClearZhen()
{
    CreateDropDownList(
null,"<%=this.sZhen.ClientID%>");
}

//<%-- 清空"县"和"镇"下拉框 --%>
function ClearXianZhen()
{
    CreateDropDownList(
null,"<%=this.sXian.ClientID%>");
    CreateDropDownList(
null,"<%=this.sZhen.ClientID%>");
}


//<%-- 将当前所有下拉框的值存入 Cookie --%>
function Save()
{
    
var sf=Single("<%=this.sSF.ClientID%>","<%=this.hSF.ClientID%>");
    
var cs=Single("<%=this.sCS.ClientID%>","<%=this.hCS.ClientID%>");
    
var xian=Single("<%=this.sXian.ClientID%>","<%=this.hXian.ClientID%>");
    
var zhen=Single("<%=this.sZhen.ClientID%>","<%=this.hZhen.ClientID%>");
    
    
var domain=GetDomain((cs.ID==0)?sf.ID:cs.ID);
    document.getElementById(
"<%=this.hDomain.ClientID%>").value=domain;
    
//<%-- 暂时不存 Cookie ,只存到隐藏控件里 --%>
    //<%-- AreaControl.SaveCookie(sf.ID,cs.ID,xian.ID,zhen.ID,sf.Name,cs.Name,xian.Name,zhen.Name,domain); --%>
}

//<%-- 返回单个下拉框的值和文本 --%>
//
<%-- sid:下拉框ID --%>
//
<%-- hid:隐藏控件ID --%>
function Single(sid,hid)
{
    
var sel=document.getElementById(sid);
    
var a=new Area();
    
if(sel==null)   //<%-- 可能只显示省市 --%>
        return a;
    a.ID
=sel.value; //<%-- 取得下拉框的 value --%>
    a.Name=sel.options[sel.selectedIndex].text; //<%-- 取得下拉框的 text --%>
    document.getElementById(hid).value=a.Name;  //<%-- text 另存到隐藏控件里 --%>
    return a;
}

//<%-- 构造函数 --%>
function Area()
{
    
this.ID;    //<%-- 下拉框的值 --%>
    this.Name;  //<%-- 下拉框的文本 --%>
}

//<%-- 返回 ID 对应的域名 --%>
//
<%-- id:地区ID --%>
function GetDomain(id)
{
    
for(var i=0;i<aDQ.length;i++)
    
{
        
if(aDQ[i][0]==id)
            
return aDQ[i][3];
    }

    
return "";
}

/*<%------------------------------------------------------------------%>*/
//<%-- 通过 域名 加载相应的地区 --%>
function LoadAreaByDomain()
{
    
var ai=AreaControl.GetAreaInfoByDomain().value;
    
if(ai==null)
        
return false;

    Bind(ai);
    
return true;
}

//<%-- 根据地区信息绑定相应的下拉框 --%>
//
<%-- ai:地区信息类 --%>
function Bind(ai)
{
    bind(ai.SFID,ai.CSID,ai.XianID,ai.ZhenID);
}

//<%-- 根据地区信息绑定相应的下拉框 --%>
//
<%-- 因为JS不支持重载写成2个方法 --%>
function bind(sfid,csid,xianid,zhenid)
{
    
var index;
    
if(sfid!=0)
    
{
        index
=Val2Index(sfid,"<%=this.sSF.ClientID%>");
        document.getElementById(
"<%=this.sSF.ClientID%>").selectedIndex=index;
        document.getElementById(
"<%=this.hSF.ClientID%>").value=Index2Text(index,"<%=this.sSF.ClientID%>"); //<%-- text 另存到隐藏控件里 --%>
        CreateDropDownList(GetArray(sfid.toString()),"<%=this.sCS.ClientID%>");
    }

    
if(csid!=0)
    
{
        index
=Val2Index(csid,"<%=this.sCS.ClientID%>");
        document.getElementById(
"<%=this.sCS.ClientID%>").selectedIndex=index;
        document.getElementById(
"<%=this.hCS.ClientID%>").value=Index2Text(index,"<%=this.sCS.ClientID%>");
        CreateDropDownList(AreaControl.GetDataTable(csid.toString(),AreaEnum.Xian).value,
"<%=this.sXian.ClientID%>")    //<%-- 要把 int 型的转换成字符串--%>
    }

    
if(xianid!=0 && document.getElementById("<%=this.sXian.ClientID%>")!=null)  //<%-- 可能只显示省市 --%>
    {
        index
=Val2Index(xianid,"<%=this.sXian.ClientID%>");
        document.getElementById(
"<%=this.sXian.ClientID%>").selectedIndex=index;
        document.getElementById(
"<%=this.hXian.ClientID%>").value=Index2Text(index,"<%=this.sXian.ClientID%>");
        CreateDropDownList(AreaControl.GetDataTable(xianid.toString(),AreaEnum.Zhen).value,
"<%=this.sZhen.ClientID%>");
    }

    
if(zhenid!=0 && document.getElementById("<%=this.sZhen.ClientID%>")!=null)
    
{
        index
=Val2Index(zhenid,"<%=this.sZhen.ClientID%>");
        document.getElementById(
"<%=this.sZhen.ClientID%>").selectedIndex=index;
        document.getElementById(
"<%=this.hZhen.ClientID%>").value=Index2Text(index,"<%=this.sZhen.ClientID%>");
    }

    
    document.getElementById(
"<%=this.hDomain.ClientID%>").value=GetDomain((csid==0)?sfid:csid);
}

//<%-- 将 <select> 的 value 换算成 selectedIndex --%>
//
<%-- val:下拉框的值 --%>
//
<%-- id:下拉框 ID --%>
function Val2Index(val,id)
{
    
var sel=document.getElementById(id);
    
for(var i=0;i<sel.options.length;i++)
    
{
        
if(val==sel.options[i].value)
            
return i;
    }

    
return 0;
}

//<%-- 将 <select> 的 value 换算成 text --%>
//
<%-- index:下拉框的值 --%>
//
<%-- id:下拉框 ID --%>
function Index2Text(index,id)
{
    
return document.getElementById(id).options[index].text;
}

/*<%------------------------------------------------------------------%>*/
//<%-- 通过 cookie 加载相应的地区 --%>
function LoadAreaByCookie()
{
    
var ai=AreaControl.GetAreaInfoByCookie().value;
    
if(ai==null)
        
return false;

    
//<%-- 根据地区域名重定向 --%>
    if(<%=this.IsRedirect.ToString().ToLower()%> && ai.Domain!=null && ai.Domain!="" && ai.Domain!=window.location.hostname.split(".")[0])
    
{
        window.location.href
=window.location.href.substring(0,7)+ai.Domain+"."+window.location.href.slice(7);
        
return true;    //<%-- 返回真,不执行后面的判断,直接页面重定向 --%>
    }

       
    Bind(ai);
    
return true;
}

/*<%------------------------------------------------------------------%>*/
//<%-- 通过 IP 加载相应的地区 --%>
function LoadAreaByIP()
{
    
var ai=AreaControl.GetAreaInfoByIP().value;
    
if(ai==null)
        
return false;
        
    
if(<%=this.IsRedirect.ToString().ToLower()%> && ai.Domain!=null && ai.Domain!="" && ai.Domain!=window.location.hostname.split(".")[0])
    
{
        window.location.href
=window.location.href.substring(0,7)+ai.Domain+"."+window.location.href.slice(7);
        
return true;
    }

        
    Bind(ai);
    
return true;
}

/*<%------------------------------------------------------------------%>*/
//<%-- 执行入口 --%>
var arr=GetArray("-1");
CreateDropDownList(arr,
"<%=this.sSF.ClientID%>");

//<%-- 是否只显示省份和城市 --%>
if(<%=this.OnlySFCS.ToString().ToLower()%>//<%-- JS 的布尔值是小写 --%>
{
    
var table=document.getElementById("<%=this.AreaTable.ClientID%>");
    table.rows[
0].deleteCell(3);    //<%-- 删除后行索引变小,因此要从后面开始删除 --%>
    table.rows[0].deleteCell(2);
}


if(<%=this.SFID%>==0)   //<%-- 没赋值才根据 域名->Cookie->IP 绑定下拉框 --%>
    (LoadAreaByDomain()) ? "" : ((LoadAreaByCookie()) ? "" : LoadAreaByIP());
else    //<%-- 只要省份有值就绑定 --%>
    bind(<%=this.SFID%>,<%=this.CSID%>,<%=this.XianID%>,<%=this.ZhenID%>);  //<%-- 赋值绑定 --%>

//<%-- 是否垂直显示 --%>
if(<%=this.IsVertical.ToString().ToLower()%>)
{
    
var h=document.getElementById("<%=this.AreaTable.ClientID%>");
    
var v=document.createElement("table");
    v.setAttribute(
"id","<%=this.AreaTable.ClientID%>");
    
    InsertRow(h.rows[
0].cells.length);

    h.parentNode.replaceChild(v,h);  
//<%-- 注意这里要通过添加 <div> 来解决 ascx 不能操作 aspx 的问题 --%>
}

//<%-- 循环创建(将列变成行) --%>
//
<%-- length:循环次数 --%>
function InsertRow(length)
{
    
for(var i=0;i<length;i++)
    
{
        v.insertRow(i);
        v.rows[i].insertCell(
0);
        v.rows[i].cells[
0].appendChild(h.rows[0].cells[i].childNodes[0]);   //<%-- 将 cell 的的元素剪贴走 --%>
    }
 
}


//<%-- 是否显示在下拉框前显示名称(省份、城市、县、镇) --%>
if(<%=this.IsDisplayName.ToString().ToLower()%>)
{
    
var sel=document.getElementById("<%=this.sSF.ClientID%>");
    sel.parentNode.insertBefore(document.createTextNode(
"省份:"),sel);
    
    sel
=document.getElementById("<%=this.sCS.ClientID%>");
    sel.parentNode.insertBefore(document.createTextNode(
"城市:"),sel);
    
    sel
=document.getElementById("<%=this.sXian.ClientID%>");
    
if(sel!=null)
        sel.parentNode.insertBefore(document.createTextNode(
"县区:"),sel);
    
    sel
=document.getElementById("<%=this.sZhen.ClientID%>");
    
if(sel!=null)
        sel.parentNode.insertBefore(document.createTextNode(
"乡镇:"),sel);
}


//<%-- 是否禁用控件 --%>
if(<%=this.IsDisabled.ToString().ToLower()%>)
{
    
var sels=document.getElementById("<%=this.AreaTable.ClientID%>").getElementsByTagName("select");
    
for(var i=0;i<sels.length;i++)
        sels[i].setAttribute(
"disabled","disabled");
}

</script>

最后就是用户控件的后台页了.
using System;
using System.Data;
using System.Data.OracleClient;
using System.Web.UI.MobileControls;
using AreaDropDownList;

public partial class AreaControl : System.Web.UI.UserControl
{
    
属性

    
//在 aspx 取值用(赋值用 JS)
    protected void Page_Init()
    
{
        
//为了在 aspx 页面的 按钮事件里取值
        if (this.IsPostBack)
        
{
            
this.SFID = Convert.ToInt32(this.Request.Form[this.sSF.UniqueID]);
            
this.CSID = Convert.ToInt32(this.Request.Form[this.sCS.UniqueID]);
            
this.XianID = Convert.ToInt32(this.Request.Form[this.sXian.UniqueID]);
            
this.ZhenID = Convert.ToInt32(this.Request.Form[this.sZhen.UniqueID]);
            
this.SF = this.Request.Form[this.hSF.UniqueID].Replace("—请选择—""");
            
this.CS = this.Request.Form[this.hCS.UniqueID].Replace("—请选择—""");
            
this.Xian = this.Request.Form[this.hXian.UniqueID].Replace("—请选择—""");
            
this.Zhen = this.Request.Form[this.hZhen.UniqueID].Replace("—请选择—""");
            
this.Domain = this.Request.Form[this.hDomain.UniqueID];
        }

    }


    
protected void Page_Load(object sender, EventArgs e)
    
{
        
//将C#的类和枚举分别注册到JS里
        AjaxPro.Utility.RegisterTypeForAjax(typeof(AreaControl));
        AjaxPro.Utility.RegisterEnumForAjax(
typeof(AreaEnum));
    }


    
/// <summary>
    
/// 将当前下拉框对应的地区信息存入 Cookie(供"保存"按钮使用)
    
/// </summary>

    public void SaveCookie()
    
{
        AreaDAL.SaveCookie(
this.SFID, this.CSID, this.XianID, this.ZhenID, this.SF, this.CS, this.Xian, this.Zhen, this.Domain);
    }


    
/*====================== 以下是为防止命名空间暴露在 JS 里 ==========================*/

    
/// <summary>
    
/// 取得下拉框所需数据
    
/// </summary>
    
/// <param name="UpID">上一级ID</param>
    
/// <param name="ae">县/镇</param>
    
/// <returns>返回 DataTable</returns>

    [AjaxPro.AjaxMethod]
    
public static DataTable GetDataTable(string UpID, AreaEnum ae)
    
{
        
if (UpID == "0" || String.IsNullOrEmpty(UpID))    //用户选"—请选择—"不查询
            return null;

        
//处于安全性考虑采用 列别名
        
//Oracle 返回的 DataTable 里的列名全是大写,在页面取值时记得大写
        string sql;
        
if (Enum.Equals(ae, AreaEnum.Xian))
            sql 
= "SELECT PKID AS id,CityName AS name,OneID,CityDomain FROM CityInfo WHERE THREEID=0 AND TWOID=" + UpID;
        
else
            sql 
= "SELECT PKID AS id,CityName AS name,OneID,CityDomain FROM CityInfo WHERE THREEID=" + UpID;

        
return AreaDAL.GetDataTable(sql);
    }


    
/// <summary>
    
/// 将当前所有下拉框的值存入 Cookie
    
/// </summary>
    
/// <param name="sfid">省份ID</param>
    
/// <param name="csid">城市ID</param>
    
/// <param name="xianid">县/区ID</param>
    
/// <param name="zhenid">镇ID</param>
    
/// <param name="sf">省份名</param>
    
/// <param name="cs">城市名</param>
    
/// <param name="xian">县/区名</param>
    
/// <param name="zhen">镇名</param>
    
/// <param name="domain">地区域名</param>

    [AjaxPro.AjaxMethod]
    
public static void SaveCookie(int sfid, int csid, int xianid, int zhenid, string sf, string cs, string xian, string zhen, string domain)
    
{
        AreaDAL.SaveCookie(sfid, csid, xianid, zhenid, sf, cs, xian, zhen, domain);
    }


    
/*=====================================================================*/

    
/// <summary>
    
/// 通过 域名 加载相应的地区
    
/// </summary>
    
/// <returns></returns>

    [AjaxPro.AjaxMethod]
    
public static AreaInfo GetAreaInfoByDomain()
    
{
        
return AreaDAL.GetAreaInfoByDomain();
    }


    
/*=====================================================================*/

    
/// <summary>
    
/// 返回 Cookie 对应的地区信息
    
/// </summary>
    
/// <returns></returns>

    [AjaxPro.AjaxMethod]
    
public static AreaInfo GetAreaInfoByCookie()
    
{
        
return AreaDAL.GetAreaInfoByCookie();
    }


    
/*=====================================================================*/

    
/// <summary>
    
/// 通过 IP 加载相应的地区
    
/// </summary>
    
/// <returns></returns>

    [AjaxPro.AjaxMethod]
    
public static AreaInfo GetAreaInfoByIP()
    
{
        
return AreaDAL.GetAreaInfoByIP();
    }


}


/// <summary>
/// 地区枚举(如果数据库设计合理,前两位省份,中间两位城市,最后两位县/区,那么就不需要这个枚举,代码量也少很多)
/// </summary>

public enum AreaEnum
{
    
/// <summary>
    
/// 省
    
/// </summary>

    SF,
    
/// <summary>
    
/// 市
    
/// </summary>

    CS,
    
/// <summary>
    
/// 县
    
/// </summary>

    Xian,
    
/// <summary>
    
/// 镇
    
/// </summary>

    Zhen
}



完成
最后是测试页

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{
    
protected void Page_Init()
    
{
        
//this.AreaControl1.OnlySFCS = true;
    }


    
protected void Page_Load(object sender, EventArgs e)
    
{
        
//要通过给控件赋值,绑定相应地区,只需给 ID 即可,Name就不用了
        
//this.AreaControl1.SFID = 42;
        
//this.AreaControl1.CSID = 4205;
        
//this.AreaControl1.XianID = 420521;
        
//this.AreaControl1.ZhenID=35020303;
        
//this.AreaControl1.OnlySFCS = true;
        this.AreaControl1.IsVertical=true;
        
this.AreaControl1.IsDisplayName = true;
        
//this.AreaControl1.IsDisabled=true;
    }


    
protected void Button1_Click(object sender, EventArgs e)
    
{
        
//添加一个按钮 用来读取 用户选择的地区信息
        Response.Write(String.Format("{0}{4},{1}{5},{2}{6},{3}{7}", AreaControl1.SF, AreaControl1.CS, AreaControl1.Xian, AreaControl1.Zhen, AreaControl1.SFID, AreaControl1.CSID, AreaControl1.XianID, AreaControl1.ZhenID));
    }


    
protected void Button2_Click(object sender, EventArgs e)
    
{
        
//直接调用 AreaControl 里的 SaveCookie 把 用户选择的地区存入 Cookie (这是为了方便,集成的)
        this.AreaControl1.SaveCookie();
    }

}


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<%@ Register Src="AreaControl.ascx" TagName="AreaControl" TagPrefix="uc1" %>



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title>无标题页</title>
</head>
<body>
    
<form id="form1" runat="server">
    
<div>
        
<uc1:AreaControl id="AreaControl1" runat="server"></uc1:AreaControl>
        
<asp:Button ID="Button1" runat="server" Text="跳转" OnClick="Button1_Click" />
        
<asp:Button ID="Button2" runat="server" Text="存 Cookie" OnClick="Button2_Click" />
        
    
</div>
    
</form>
</body>
</html>

记得 是 AjaxPro 6.10.4.1 的版本

Web.Config  在<system.web>来上这句
<httpHandlers>
    
<add verb="POST,GET" path="ajaxpro/*.ashx" type="AjaxPro.AjaxHandlerFactory, AjaxPro.2"/>
</httpHandlers>
原创粉丝点击