JS、AJAX 实现级联下拉列表

需求

实现在下拉框的级联查询,可以使得用户不进行页面跳转便可以根据下拉框中所选的高级选项更改低级选项的内容。增进用户体验

以省市县/区为例,在用户选择不同的省时,更新后面的市和对应的县/区;在用户选择不同的市时,更新后面县/区的内容。

前端

前端页面上,放一个div,用CSS简单装饰一下。在中间放上我们的主角:三个下拉框,分别代表省、市、县/区。最后加上一个提交按钮。

捏个页面

这里我们仅演示如何实现下拉框的级联查询,所以省略了action属性的内容,并使用onsubmit属性显示所选项。

<!--页面加载时自动更新省份-->
<body onload="getProvince()">
<div id="show" >
	<!--提交表单时显示所选省市县-->
	<form action="" onsubmit="return show()" >
		<!--更改省份时更新城市--><select id="province" onchange="getCity()">
		</select>
		<!--更改城市时更区县--><select id="city" onchange="getArea()">
		</select>
		
		县/区<select id="area">
		</select>
		
		<input type="submit" id="submit">
	</form>
</div>

</body>

效果图:
在这里插入图片描述
很吃藕,简单修饰一番:

#show{
width:500px;
	height:100px;
	background-color:#f3f3f3;
	margin:0 auto;
	padding:20px;
}
#province,#city,#area{
	width:100px;
	height:20px;
	margin:0px 10px;
}
#submit{
	width:200px;
	height:50px;	
	background-color:#ff30;
	margin-top:30px;
	margin-left:120px;
}

在这里插入图片描述
好的,现在可以看了

写脚本

把页面捏完,现在完成级联查询的脚本,三个函数,分别是省市县/区的更新。还要有一个显示最终选项的函数。

传递数据采用“-”做分隔符,如:北京市-上海市-天津市
显示
function show(){
	var province = document.getElementById("province").value;
	var city = document.getElementById("city").value;
	var area = document.getElementById("area").value;
	
	var result = "province = " + province + "\ncity = " + city + "\narea = " + area;
	alert(result);
	return false;
}
更新省份
function getProvince(){
	var xml = new XMLHttpRequest;
	
	xml.open("get","Province");
	
	xml.setRequestHeader("Content-type","application/x-www-form-urlencoded");
	
	xml.send(null);
	
	xml.onreadystatechange = function(){
		if(xml.readyState == 4){
			//解析后台传来的省份
			var province = xml.responseText.split("-");	
			var select = document.getElementById("province");
			//删除原有节点
			while(select.hasChildNodes()){
				select.removeChild(select.lastChild);
			}
			//追加新的节点
			for(var i = 0;i < province.length;i++){
				var option = document.createElement("option");
				option.value = province[i];
				option.innerText = province[i];
				
				select.appendChild(option);
			}
			//更新城市下拉框
			getCity();
		}
	}
}
更新城市
function getCity(){
	var xml = new XMLHttpRequest;
	var province = document.getElementById("province").value;
	
	xml.open("post","City");
	
	xml.setRequestHeader("Content-type","application/x-www-form-urlencoded");
	
	xml.send("province=" + province);
	
	xml.onreadystatechange = function(){
		if(xml.readyState == 4){
			//解析后台传来的城市
			var city = xml.responseText.split("-");	
			var select = document.getElementById("city");
			//删除原有城市
			while(select.hasChildNodes()){
				select.removeChild(select.lastChild);
			}
			//添加新的城市
			for(var i = 0;i < city.length;i++){
				var option = document.createElement("option");
				option.value = city[i];
				option.innerText = city[i];
				
				select.appendChild(option);
			}
			//更新县/区下拉框
			getArea();
		}
	}
}
更新县区
function getArea(){
	var xml = new XMLHttpRequest;
	var city = document.getElementById("city").value;
	
	xml.open("post","Area");
	
	xml.setRequestHeader("Content-type","application/x-www-form-urlencoded");
	
	xml.send("city=" + city);
	
	xml.onreadystatechange = function(){
		if(xml.readyState == 4){
			var area = xml.responseText.split("-");	
			var select = document.getElementById("area");
			
			while(select.hasChildNodes()){
				select.removeChild(select.lastChild);
			}
			
			for(var i = 0;i < area.length;i++){
				var option = document.createElement("option");
				option.value = area[i];
				option.innerText = area[i];
				
				select.appendChild(option);
			}
		}
	}
}

后端

数据库

存放省市县/区的数据库表单:

在这里插入图片描述

在这里插入图片描述

县/区

在这里插入图片描述
配合前端的三个查询,后端设置三个servlet:Province,City,Area分别查询省份,城市,地区.
另外,这个后端设涉及jdbc的使用,本文仅使用而没有给出对应的实现。

tips:

  • 由于所有的省市县都使用的是名称,因此在查询城市和地区的数据库时,可以使用嵌套查询,先从省市表中查出对应的code再查询所有的市县名称。
    例如:SELECT name FROM city WHERE provincecode = (select code from province where name = ‘北京市’);
  • 为了防止后端获取和前后端传递数据中文乱码,请将requestresponse编码方式设置为“UTF-8”
  • 如果后端拿不到前端传递的参数,且后端代码逻辑没有问题,请检查前端拼写。
获取省份
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/*设置编码方式*/
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		
		/*访问数据库*/
		JDBC jdbc = JDBC.getJDBC();
		
		StringBuffer sql = new StringBuffer();
		
		sql.append("SELECT name FROM province;");
		
		ArrayList<HashMap<String,Object>> list = jdbc.query(sql.toString());
		
		/*构建答案*/
		StringBuffer result = new StringBuffer();
		for(int i = 0;i < list.size() - 1;i++)
		{
			result.append(list.get(i).get("name").toString()).append("-");
		}
		result.append(list.get(list.size() - 1).get("name").toString());
		/*返回答案*/
		PrintWriter out = response.getWriter();
		out.print(result.toString());
		out.close();
	}
获取城市
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/*设置编码格式*/
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		/*访问数据库*/
		JDBC jdbc = JDBC.getJDBC();
		
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT name FROM city WHERE provincecode = (SELECT code FROM province WHERE name = '").append(request.getParameter("province")).append("');");
		
		ArrayList<HashMap<String,Object>> list = jdbc.query(sql.toString());
		/*构建结果*/
		StringBuffer result = new StringBuffer();
		
		for(int i = 0;i < list.size() - 1;i++)
		{
			result.append(list.get(i).get("name").toString()).append("-");
		}
		result.append(list.get(list.size() - 1).get("name").toString());
		/*返回结果*/
		PrintWriter out = response.getWriter();
		out.print(result.toString());
		out.close();
	}
获取区县
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/*设置编码格式*/
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		/*访问数据库*/
		JDBC jdbc = JDBC.getJDBC();
		
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT name FROM area WHERE citycode = (SELECT code FROM city WHERE name = '").append(request.getParameter("city")).append("');");
		
		ArrayList<HashMap<String,Object>> list = jdbc.query(sql.toString());
		/*构造结果*/
		StringBuffer result = new StringBuffer();
		
		for(int i = 0;i < list.size() - 1;i++)
		{
			result.append(list.get(i).get("name").toString()).append("-");
		}
		result.append(list.get(list.size() - 1).get("name").toString());
		/*返回结果*/
		PrintWriter out = response.getWriter();
		out.print(result.toString());
		out.close();
	}

最终效果

选个博主所在学校的地址:

点开网页:

在这里插入图片描述

选择吉林省

在这里插入图片描述
在这里插入图片描述
可以看到城市和区县已经修改

选择朝阳区

在这里插入图片描述
在这里插入图片描述

点击提交

在这里插入图片描述

nice~~~~~~


创作不易,点个关注再走好不好,要不,赞也行QAQ

  • 12
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值