使用jQuery+HttpHandler+xml模拟一个三级联动的例子

如下是实现过程:
第一步:准备xml文件,并放置在网站根目录下,名为Area.xml


代码如下:

<?xml version="1.0" encoding="utf-8" ?>
<area>
<province id="1" name="北京">
<city id="1" name="北京">
<county id="1" name="东城区" />
<county id="2" name="西城区" />
</city>
</province>
<province id="2" name="河北省">
<city id="1" name="石家庄市">
<county id="1" name="正定县" />
<county id="2" name="灵寿县" />
</city>
<city id="2" name="邯郸市">
<county id="1" name="邯郸县" />
<county id="2" name="永年县" />
</city>
</province>
<province id="3" name="海南省">
<city id="1" name="海口市">
<county id="1" name="龙华区" />
<county id="2" name="秀英区" />
<county id="3" name="美兰区" />
</city>
<city id="2" name="三亚市">
<county id="1" name="天涯镇" />
<county id="2" name="凤凰镇" />
</city>
</province>
</area>

第二步:创建与xml文件中定义的元素对应的实体类。
<province/>对应province类


代码如下:

public class Province
{
private string id;
/// <summary>
/// 编号
/// </summary>
public string Id
{
get { return id; }
set { id = value; }
}
private string name;
/// <summary>
/// 名称
/// </summary>
public string Name
{
get { return name; }
set { name = value; }
}
}

<city/>对应City类:


代码如下:

public class City
{
private string id;
/// <summary>
/// 编号
/// </summary>
public string Id
{
get { return id; }
set { id = value; }
}
private string name;
/// <summary>
/// 名称
/// </summary>
public string Name
{
get { return name; }
set { name = value; }
}
}

<county/>对应county类:


代码如下:

public class County
{
private string id;
/// <summary>
/// 编号
/// </summary>
public string Id
{
get { return id; }
set { id = value; }
}
private string name;
/// <summary>
/// 名称
/// </summary>
public string Name
{
get { return name; }
set { name = value; }
}
}

第三步:编写服务器端处理程序类:Handler.cs


代码如下:

/// <summary>
2 /// 处理程序
3 /// </summary>
4 public class Handler : IHttpHandler
5 {
6
7 private static XDocument doc;
8 private string filePath = HttpContext.Current.Server.MapPath("~/Area.xml");
9 //javascript序列化类
private static JavaScriptSerializer jss = new JavaScriptSerializer();
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string result = "failure";//默认返回结果为失败
HttpRequest req = context.Request;
string province = req["province"];//获取用户选择的省的编号
string city = req["city"];//获取用户选择的市的编号
string county = req["county"];//获取用户选择的县的编号
string type = req["type"];//获取用户需要获取的省市县列表的类型
InitDoc();
if (type.HasValue())
{
switch (type.ToLower())
{
case "province"://如果用户需要获取省级列表
result = jss.Serialize(GetProvinceList());
break;
case "city"://如果用户需要获取的是市级列表
result = jss.Serialize(GetCityListByProvince(province));
break;
case "county"://如果用户需要获取的是县级列表
result = jss.Serialize(GetCountyListByCity(province, city));
break;
default:
break;
}
}
//将结果以文本的格式返回给客户端
context.Response.Write(result);
}
/// <summary>
/// 初始化文档对象
/// </summary>
private void InitDoc()
{
if (doc == null)
{
doc = XDocument.Load(filePath);
}
}
/// <summary>
/// 初始化省级列表
/// </summary>
private List<Province> GetProvinceList()
{
List<Province> list = new List<Province>();
if (doc != null)
{
XElement root = doc.Root;
foreach (var prov in root.XPathSelectElements("province"))
{
list.Add(new Province()
{
Id = prov.Attribute("id").Value,
Name = prov.Attribute("name").Value
});
}
}
return list;
}
/// <summary>
/// 根据省级编号获取市级编号
/// </summary>
/// <param name="provId">省级编号</param>
private List<City> GetCityListByProvince(string provId)
{
List<City> list = new List<City>();
if (doc != null)
{
XElement root = doc.Root;
//xpath表达式:/area/province[@id='1']/city
string queryPath = "/area/province[@id='" + provId + "']/city";
foreach (var city in root.XPathSelectElements(queryPath))
{
list.Add(new City()
{
Id = city.Attribute("id").Value,
Name = city.Attribute("name").Value
});
}
}
return list;
}
/// <summary>
/// 根据省级编号和市级编号获取县级编号
/// </summary>
/// <param name="provId">省级编号</param>
/// <param name="cityId">市级编号</param>
private List<County> GetCountyListByCity(string provId, string cityId)
{
List<County> list = new List<County>();
if (doc != null)
{
XElement root = doc.Root;
string queryPath = "/area/province[@id='" + provId + "']/city[@id='" + cityId + "']/county";
foreach (var county in root.XPathSelectElements(queryPath))
{
list.Add(new County()
{
Id = county.Attribute("id").Value,
Name = county.Attribute("name").Value
});
}
}
return list;
}
public bool IsReusable
{
get
{
return false;
}
}
}

在这里,查询xml我采用的是System.Xml.XPath命名空间下的XPathSelectElements(string xpath)方法和XPathSelectElement(string xpath)方法,在根据省级编号获取市级编号的方法里面,我使用了xpath表达式(假设传入的省级编号为1):/area/province[@id='1']/city,这个表达式以“/”开头,表示使用绝对路径,因为area为根节点所以从area开始,接着它下面有province元素,当我想获取area下所有province元素中id属性值为1的province元素时,我可以使用/area/province[@id='1'],即在province后面加上[@id='1']这个条件,这时我就获取到了area下id属性为1的province元素了。接着我要获取该province元素下所有的city,那么只需在后面加上/city即可,所以最终的xpath表达式为:/area/province[@id='1']/city。
还有,因为此查询的xml是在当前网站的根目录,如果是在其它地方,那么在查询的时候要加上namespace
将从xml文件中读取到的值组装成对应的实体对象只后,我使用了System.Web.Script.Serialization命名空间下的JavaScriptSerializer类中的Serialize方法将得到的实体对象序列化成json数据返回给客户端。
第四步:编写html和js。


代码如下:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>省市县三级联动下拉列表</title>
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$.post("/Handler.ashx", { "type": "province" }, function (data, status) {
if (status == "success") {
if (data != "failure") {
data = $.parseJSON(data); //解析服务器返回的json数据
for (var i = 0; i < data.length; i++) {
var value = data[i].Id + ":" + data[i].Name; //设置option选项的值,格式为:"编号:名称"
$("#province").append("<option value='" + value + "'>" + data[i].Name + "</option>");
}
}
}
}, "text");
$("#province").change(function () {
var selectValue = $(this).val(); //获取选择的省级option的值
var provId = selectValue.split(':')[0]; //取出编号
var provTxt = selectValue.split(':')[1]; //取出名称
$("#txtProvince").html(provTxt); //显示选择的省的名称
$("#city").html("<option>==请选择市==</option>"); //当省级改变时将市级清空
$("#county").html("<option>==请选择县==</option>"); //当省级改变时将县级清空
$.post("/Handler.ashx", { "province": provId, "type": "city" }, function (data, status) {
if (status == "success") {
if (data != "failure") {
data = $.parseJSON(data);
for (var i = 0; i < data.length; i++) {
var value = data[i].Id + ":" + data[i].Name;
$("#city").append("<option value='" + value + "'>" + data[i].Name + "</option>");
}
}
}
}, "text");
});
$("#city").change(function () {
var provId = $("#province").val().split(':')[0];
var selectValue = $(this).val(); //同上
var cityId = selectValue.split(':')[0]; //同上
var cityTxt = selectValue.split(':')[1]; //同上
$("#txtCity").html(cityTxt); //显示选择的市的名称
$("#county").html("<option>==请选择县==</option>"); //同上
$.post("/Handler.ashx", { "province": provId, "city": cityId, "type": "county" }, function (data, status) {
if (status == "success") {
if (data != "failure") {
data = $.parseJSON(data);
for (var i = 0; i < data.length; i++) {
var value = data[i].Id + ":" + data[i].Name;
$("#county").append("<option value='" + value + "'>" + data[i].Name + "</option>");
}
}
}
}, "text");
});
$("#county").change(function () {
$("#txtCounty").html($(this).val().split(':')[1]); //显示选择的县的名称
});
});
</script>
</head>
<body>
<!--省-->
<select id="province" name="province">
</select>
<!--市-->
<select id="city" name="city">
</select>
<!--县-->
<select id="county" name="county">
</select>
<br />
<span id="txtProvince" style="color: #ff0000;"></span>- <span id="txtCity" style="color: #ff0000;"></span>- <span id="txtCounty" style="color: #ff0000;"></span>
</body>
</html>

关于使用jQuery与服务器通信,我使用的是$.post方法,该方法的具体使用可以参考jQuery官方文档,这里我想说的是,遍历后通过对象.属性访问时,这个属性的名字是区分大小写的,这个名字是服务器端定义的名字,因为服务器序列化的是服务器端的实体对象。
在这个例子中,关键点就是如何使用XPath表达式,如何调用System.Xml.XPath命名空间下的XPathSelectElements(string xpath)方法。
最终结果如下图:

代码13,31,50行可以优化。
不建议多次修改DOM结构,可以拼接字符串后一次append
数据源是xml,我会用xslt来解析xml直接输出<option>,这样就不用再前台拼接字符串了。要求所有节点ID不能有相同。


代码如下:

<select id="province" name="province" next="#city">
</select>
<select id="city" name="city" next="#county">
<option>==请选择市==</option>
</select>
</form>
<select id="county" name="county">
<option>==请选择县==</option>
</select>

<script type="text/javascript">
$("#province,#city").change(function () {
var nextSelect = $(this.getAttribute("next"));

//if (nextSelect.size() > 0) {
nextSelect.find("option:gt(0)").remove();

var _id = $(this).find("option:selected").val();
var query = { parentId: _id };
$.get("/Handler.ashx", query, function (data, status) {
//...
nextSelect.append("<option>...</option>....");
});
//}
});
</script>

(0)

相关推荐

  • asp.net省市三级联动的DropDownList+Ajax的三种框架(aspnet/Jquery/ExtJs)示例

    本文主要列举了省市三级联动的DropDownList+Ajax的三种框架(aspnet/Jquery/ExtJs)示例.前段时间需要作一个的Web前端应用,需要用多个框架,一个典型的应用场景是省市三级联动,基于此应用,特将三种主要的ajax框架略作整理,方便有需要的朋友查阅. 在示例之前,我们先设置一个演示数据源,新建一个项目,项目结构如图: 主要文件如下:AreaModel.cs: 复制代码 代码如下: using System; using System.Collections.Generi

  • jquery+json 通用三级联动下拉列表

    Author: shaoyun Email: shaoyun (at) yeah.net Date: 2010-03-10 02:03 Blog: http://shaoyun.cnblogs.com/ 用Jquery实现,原始代码只支持IE,这里我改了一下,我的代码里面有三个版本的实现 第一个是通过读取XML构建,支持IE/firefox,chrome不支持,有兴趣的可以将读取XML的部分改成AJAX的方式,这样chrome支持就不成问题 第二个是采用Json数据格式构建,是我的第二次尝试改进

  • jQuery select表单提交省市区城市三级联动核心代码

    jQuery select表单提交省市区城市三级联动,引用的是"jquery-1.7.min"类库,地区码查询地区名用数组存在AreaData_min,下面摘要部分代码: SelectArea.htm文件 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transition

  • 简单实用jquery版三级联动select示例

    html和js部分 复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta charset=gbk /> <title>selectList</title> <style type="text/css"> *{margin:0;padding:0;} .selectList{width:200px;margin:50px auto;} </style>

  • ajax.net +jquery 无刷新三级联动的实例代码

    复制代码 代码如下: <!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>    <title></titl

  • 基于jQuery+JSON的省市二三级联动效果

    省市区联动下拉效果在WEB中应用非常广泛,尤其在一些会员信息系统.电商网站最为常见.开发者一般使用Ajax实现无刷新下拉联动.本文将讲述,利用jQuery插件,通过读取JSON数据,实现无刷新动态下拉省市二(三)级联动效果. HTML 首先在head中载入jquery库和cityselect插件. <script type="text/javascript" src="js/jquery.js"></script> <script ty

  • Java框架SSH结合Easyui控件实现省市县三级联动示例解析

    Easyui调用数据库实现省市县区三级联动的效果如果下 1.首先要设计数据库,如图所示.一个有4个字段code,note,pycode.code:行政区划代码,note:中文注释,pycode:拼音缩写. 其中code是由6个字段组成.如果是省级最后4位是0000,如果是地级市最后2位是00,其他是县区. 我已经把相关数据库代码上传到我的csdn资源中,需要的同学自行下载. 2.我用的是java.SSH框架结合Easyui控件 3.html代码如下 <tr> <td class=&quo

  • SSH结合jquery实现三级联动效果

    本文实例为大家分享了jquery实现三级联动的具体代码,供大家参考,具体内容如下 jsp页面部分: <li id="floors"> <span class="title" id="floorShow">选择楼栋:</span> <select name="build" id="build" style="width: 282px;height: 40px

  • jquery实现的省市区三级联动

    省市级联动,附使用示例和数据表数据 有部分数据精确到乡镇一级!!! Git 地址:http://git.oschina.net/upliu/province-city-district 演示代码: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>省市区三级联动</title> </head>

  • jQuery JSON实现无刷新三级联动实例探讨

    复制代码 代码如下: <asp:DropDownList ID="ddl1" runat="server" Width="100px" ></asp:DropDownList> <asp:DropDownList ID="ddl2" runat="server" Width="100px" ></asp:DropDownList> <

随机推荐