【JSP】ajax实现省市县三级级联

需求:

在这里插入图片描述
我们要实现的界面如上图,具体需求如下:

  • 省、市、县/区数据从数据库读取;
  • 选择省份后,该省对应的市添加在“请选择市”的下拉列表中供用户选择;
  • 选择市后,该市对应的县/区添加在“请选择县/区”的下拉列表中供用户选择;
  • 没有选择省份时,无法选择市、县/区;
  • 没有选择市时,无法选择县/区;
  • 切换省份时,后面的市、县/区恢复无选择状态;
  • 切换市时,后面的县/区恢复无选择状态。
数据准备:

建表:打开Navicat --> 新建数据库“mytest” --> 选择“Queries” --> 选择“New Query”,然后将下面的代码拷贝进去,点击“Run”

CREATE TABLE `area` (
  `id` varchar(36) NOT NULL COMMENT '地域ID',
  `code` varchar(30) NOT NULL COMMENT '地域编码',
  `name` varchar(30) NOT NULL COMMENT '地域名称',
  `parent_code` varchar(30) DEFAULT NULL COMMENT '父节点编码',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='地域';

插入数据前往下载省市县数据

步骤:

1、创建Web项目:打开eclipse(自选,这里用eclipse) --> 新建Web项目“area”
2、拷贝相关文件

  • 将之前“com.jdbc.dbutil”包和数据库的配置文件“app.properties ”一同拷贝到“area”项目中“Java Resources”目录下的“src”文件夹中,修改“app.properties ”文件中的数据库名、用户名和密码等信息;
  • 将“gson-2.8.4.jar”、“mysql-connector-java-5.1.9.jar”和“servlet-api.jar”文件拷贝到“WebContent”目录下的“WEB-INF”文件夹下的“lib”文件夹中;
  • 在“WebContent”目录下新建文件夹“js”,将“jquery-3.3.1.min.js”和“json2.js”拷贝进去;

3、新建servlet文件:在“src”文件夹中新建“com.jpc.servlet”包,在该包中新建DataServlet类,继承HttpServlet类并重写其方法“doGet()”
4、修改“PropertiesUtil.java”文件:将“PropertiesUtil.java”文件中的“inuptStream”做如下修改:

InputStream inputStream = DataServlet.class.getClassLoader().getResourceAsStream("app.properties");

5、新建Area类:在“src”文件夹中新建“com.jpc.vo”包,在该包中新建Area类,如下,用于将每条省市县信息作为一个对象存储起来:

package com.jpc.vo;

public class Area {
	private String id;
	private String name;
	private String code;
	private String parentCode;
	public Area(String id, String name, String code, String parentCode) {
		this.id = id;
		this.name = name;
		this.code = code;
		this.parentCode = parentCode;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public String getParentCode() {
		return parentCode;
	}
	public void setParentCode(String parentCode) {
		this.parentCode = parentCode;
	}
	@Override
	public String toString() {
		return "Area [id=" + id + ", name=" + name + ", code=" + code + ", parentCode=" + parentCode + "]";
	}
}

6、“doGet()”方法的思路及代码实现
1. 设置响应的字符集为“UTF-8”;
2. 声明字符串变量code,用于接收浏览器客户端传来的code的值
3. 定义实现IRowMapper接口的内部类RowMapper,在内部类中声明一个泛型为Area类的ArrayList集合,用于将存储每条省市县信息的Area对象添加进其中
4. 声明一条sql语句,创建一个RowMapper对象rowMapper
5. 调用DBUtil的select方法(这里用的是防sql注入的方法)将创建的sql语句、对象rowMapper和从浏览器客户端获取的code作为该方法的三个参数传进去
6. 由于DBUtil的select方法会回调当前doGet()方法中内部类RowMapper的rowMapper()方法,而该方法将Area对象逐个添加进了内部类RowMapper的list中,所以在内部类外面声明的接收rowMapper.list的list中存储的也都是Area对象
7. 新建Gson匿名对象,调用其tojson()方法,将list作为参数传入,返回一个字符串,将该字符串直接传递(赋值)给调用jquery的ajax()方法并且参数对象的url指向本servlet文件的外部文件中该ajax()方法的参数对象的success函数的形参

package com.jpc.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import com.jdbc.dbutil.DBUtil;
import com.jdbc.dbutil.IRowMapper;
import com.jpc.vo.Area;

public class DataServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setCharacterEncoding("UTF-8");
		String code = request.getParameter("code");
		class RowMapper implements IRowMapper {
			List<Area> list = new ArrayList<Area>();
			public void rowMapper(ResultSet resultSet) {
				try {
					while(resultSet.next()) {
						list.add(new Area(resultSet.getString("id"), resultSet.getString("name"), resultSet.getString("code"), resultSet.getString("parent_code")));
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		String sql = "select * from area where parent_code = ?";
		RowMapper rowMapper = new RowMapper();
		DBUtil.select(sql, rowMapper, code);
		List<Area> list = rowMapper.list;
		PrintWriter writer = response.getWriter();
		writer.write(new Gson().toJson(list));
		writer.flush();
		writer.close();
	}
}

7、创建jsp文件
1. 在“WebContent”文件夹中创建“index.jsp”文件
2. 导入“jquery-3.3.1.min.js”文件与“json2.js”文件
3. 创建三个select下拉列表标签,分别用于选择省市县
4. 声明JavaScript区域,在其中直接定义一个ajax,并且定义两个方法,分别给市、县两个select标签绑定为onchange事件

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Insert title here</title>
		<script type="text/javascript" src="./js/jquery-3.3.1.min.js"></script>
		<script type="text/javascript" src="./js/json2.js"></script>
	</head>
	<body>
		<select id="one" onchange="select_first()">
			<option>--请选择省份--</option>
		</select>
		<select id="two" onchange="select_second()">
			<option>--请选择市--</option>
		</select>
		<select id="three">
			<option>--请选择县/区--</option>
		</select>
		<script type="text/javascript">
			//定义第一个异步
			var one = {
				//code传入空值,意为检索所有的省份
				url:"./DataServlet?code="+"",
				type:"get",
				success:function(data){
					//JSON.parse(data),用于将DataServlet传来的字符串转换为对象数组
					var area_objs = JSON.parse(data);
					for (var i = 0; i < area_objs.length; i++) {
						//为省份的下拉列表添加option标签,顺便为该标签添加value属性
						$("#one").append("<option value=\""+area_objs[i].code+"\">"+area_objs[i].name+"</option>");
					}
				}
			};
			//触发异步
			$.ajax(one);		
			var select_first = function(){
				//声明一个数组,接收省份下拉列表的所有option
				var one_area = $("#one option");
				//遍历省份下拉列表的所有option,找到被选中的option
				for(i = 0; i < one_area.length; i++){
					if(one_area[i].selected){
						var two = {
							//将被选中的省份的value赋值给code,最终匹配数据库中parent_code等于该值的所有区域信息
							url:"./DataServlet?code=" + one_area[i].value,
							type:"get",
							success:function(data){
								//将由数据库中parent_code等于该值的所有区域信息组成的字符串转换为对象数组
								var area_objs = JSON.parse(data);
								//每次触发事件就将市、县下拉列表恢复无选择状态
								$("#two").html("<option>--请选择市--</option>");
								$("#three").html("<option>--请选择县/区--</option>");
								
								for (var i = 0; i < area_objs.length; i++) {
									//为市的下拉列表添加option标签,顺便为该标签添加value属性
									$("#two").append("<option value=\""+area_objs[i].code+"\">"+area_objs[i].name+"</option>");
								}
							}
						};
						//触发异步
						$.ajax(two);
						//由于已经找到了被选择项,所以不再遍历
						break;
					}
				}
			};
			//该方法的处理思路与流程与select_first方法一致,不再注释
			var select_second = function(){
				var two_area = $("#two option");
				for(i = 0; i < two_area.length; i++){
					if(two_area[i].selected){
						var select_two = two_area[i].value;
						var three = {
							url:"./DataServlet?code="+select_two,
							type:"get",
							success:function(data){
								var area_objs = JSON.parse(data);
								$("#three").html("<option>--请选择县/区--</option>");
								for (var i = 0; i < area_objs.length; i++) {
									$("#three").append("<option value=\""+area_objs[i].code+"\">"+area_objs[i].name+"</option>");
								}
							}
						};
						$.ajax(three);
						break;
					}
				}
			};
		</script>
	</body>
</html>
附:项目目录结构图,谨防文件放错位置

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一些基于 AJAX级联下拉菜单的实现方法。级联下拉菜单是一种常用的交互方式,它可以让用户在选择一个下拉菜单选项的同时,动态地加载下一个下拉菜单的选项。这种交互方式可以帮助用户快速地找到自己需要的选项,提高用户体验。 下面是一个简单的基于 AJAX级联下拉菜单的实现方法: 1. HTML 页面中添加两个下拉菜单,分别用于选择省份和城市: ```html <select id="province"> <option value="">请选择省份</option> <option value="北京">北京</option> <option value="上海">上海</option> <option value="广东">广东</option> </select> <select id="city"> <option value="">请选择城市</option> </select> ``` 2. 使用 jQuery 监听省份下拉菜单的 change 事件,在该事件中发送 AJAX 请求获取城市数据: ```javascript $('#province').on('change', function() { var province = $(this).val(); if (province) { $.ajax({ type: 'GET', url: '/api/cities?province=' + province, success: function(data) { // 更新城市下拉菜单的选项 updateCityOptions(data); } }); } else { // 如果省份选择为空,则清空城市下拉菜单的选项 $('#city').html('<option value="">请选择城市</option>'); } }); ``` 3. 在后端服务器端编写一个接口,用于根据省份查询城市数据,返回 JSON 格式的数据: ```python @app.route('/api/cities') def get_cities(): province = request.args.get('province') cities = get_cities_by_province(province) # 根据省份查询城市数据 return jsonify(cities) ``` 4. 在前端页面中编写一个函数,用于更新城市下拉菜单的选项: ```javascript function updateCityOptions(data) { var options = '<option value="">请选择城市</option>'; for (var i = 0; i < data.length; i++) { options += '<option value="' + data[i] + '">' + data[i] + '</option>'; } $('#city').html(options); } ``` 这样,当用户选择省份选项时,就会发送 AJAX 请求获取城市数据,然后更新城市下拉菜单的选项。用户可以在城市下拉菜单中选择自己需要的选项。 以上是一个简单的基于 AJAX级联下拉菜单的实现方法,您可以根据自己的实际需求进行修改和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值