实现级联查询
共有两个下拉框,第一级为学院,第二级为学院开设的科目。
实现的功能为:当改变学院的选择,第二级下拉框需变为对应学院开设的科目内容。
结果预览:
jsp页面
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head><title>JSP - Hello World</title><script type="text/javascript" src="js/jquery-3.6.0.min.js"></script><script type="text/javascript" src="js/index.js"></script>
</head>
<body>
学院:
<select name="academy" id="select-academy"></select>
科目:
<select name="subject" id="select-subject"></select>
</body>
</html>
其中导入了jQuery的脚本,下面将会使用jQuery语法编写脚本
JS脚本
实现级联查询的核心代码:
var $select_academy = $("#select-academy");
var $select_subject = $("#select-subject");$select_academy.change(function () {var selected_academy_id = $("#select-academy>option:selected").val();$.get("subjectField", {"academyId":selected_academy_id}, function (resp) {$select_subject.empty();$.each(resp, function (i, e) {$select_subject.append("<option value='"+e.id+"'>"+e.name+"</option>");});}, "json");
});
- 监听学院下拉框选择发生改变
change
- 获取被选中(
selected
)的学院的value
值即学院的id - 以get方式发送ajax请求,参数为学院id号
academyId
- 首先将科目下拉框原有内容清空
empty
- 再向其中添加
append
被选中的学院对应开设的科目集,resp
为服务器端返回的数据,格式为json数组
Servlet
package com.exposerain.controller;import com.exposerain.dao.SubjectDao;
import com.exposerain.entity.Subject;
import com.fasterxml.jackson.databind.ObjectMapper;import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;public class SubjectFieldServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {SubjectDao dao = new SubjectDao();Integer academyId = Integer.valueOf(request.getParameter("academyId"));List<Subject> list = dao.field(academyId);//jackson.jarObjectMapper om = new ObjectMapper();String json = om.writeValueAsString(list);response.setContentType("application/json;charset=utf-8");PrintWriter out = response.getWriter();out.println(json);out.flush();out.close();}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
- 从请求对象中获取参数
academyId
的值作为学院id号 - 根据学院id号获取对应开设的科目列表
list
(DAO中方法具体见下文) - 将科目列表转化为json格式的字符串(这里采用的是jackson.jar包里的方法)
- 设置响应对象文本格式并发送json字符串
DAO
SubjectDao
package com.exposerain.dao;import com.exposerain.entity.Subject;
import com.exposerain.util.JdbcUtil;import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;public class SubjectDao {private JdbcUtil util = new JdbcUtil();public List<Subject> field(Integer academyId){List<Subject> list = new ArrayList<>();String sql = "select * from Subject where acId = ?";PreparedStatement ps = util.createStatement(sql);ResultSet rs = null;try {ps.setInt(1,academyId);rs = ps.executeQuery();while(rs.next()){Integer id = rs.getInt("subId");String name = rs.getString("subName");Integer acId = rs.getInt("acId");Subject subject = new Subject(id, name, acId);list.add(subject);}} catch (SQLException throwables) {throwables.printStackTrace();} finally {util.close(rs);}return list;}
}
其中的JdbcUtil为JDBC工具类用于连接数据库、发送SQL命令至数据库等功能,不再赘述。
初始化
目前直接进入网页两级的下拉框都还是空的,因此要对其进行初始化。
var $select_academy = $("#select-academy");
var $select_subject = $("#select-subject");
var selected_academy_id = null;
//初始化学院下拉框
$.ajax({url:"academyField",async:false, //同步success:function (resp) {$.each(resp, function (i, e) {$select_academy.append("<option value='"+e.id+"'>"+e.name+"</option>");});$select_academy.children().eq(0).attr("selected", "true");},dataType:"json"
});
selected_academy_id = $("#select-academy>option:selected").val();
$.get("subjectField", {"academyId":selected_academy_id}, function (resp) {$.each(resp, function (i, e) {$select_subject.append("<option value='"+e.id+"'>"+e.name+"</option>");});
}, "json");
//初始化完毕
- 首先发送ajax请求加载出第一级学院下拉框,再将其中的首个学院选中,由于要根据选中的元素提取value值作为学院id号,因此选中操作必须在提取操作之前执行,因此采用同步(
async:false
)的方式发送请求,同步的方式缺点是速度慢,第二级下拉框肉眼可见地比第一级加载慢一瞬间(这里可以将提取操作改为直接赋被选中的学院的id确值即selected_academy_id = 1;
然后便可用异步的方式请求,不过可维护性差一点) - 接着是将级联查询静态执行一遍用于初始化加载科目下拉框
初始页面: