JSP、Java实现选择框多级连动
版权声明:原创作品,如需转载,请与作者联系。否则将追究法律责任。 |
JSP、Java实现选择框多级连动
环境:
DB2 9.1 J2SDK 1.5 Servlet 2.4 一、问题
在web开发中,经常会遇到两级三级甚至更多级的选项框连动的情况,一般情况下都考虑用js来实现,但是在有大量等级选项的情况下,js实现也很麻烦,并且页面反应很慢,抛弃了js,我们还能用什么来做呢? 这是我在实际项目中遇到的一个问题,为了在有大量数据请况下不至于慢的无法接受,我打算用JSP/java来实现这个需求。下面我给出我做测试用的例子,以探求其可行性,是两级连动的,有数据回填功能。
作为测试,业务很简单,第一个选择况是省,第二个显示省里的市,省市分别存储在数据库中的两个表province、city(实际项目中一般都用一个表)。另外还有个静态选择框和文本况,目的是演示数据回填功能。 所谓的数据回填就是自动为客户回复填过的选项,比如你填写一个注册单,填写有错误,又返回了,在返回的时候,要把所有正确的填写项恢复回来,不必用户再从头填写。(这个回填功能用struts很容易实现,但是我面对现实是不用struts、hibernate,呵呵,因为没有复杂业务处理,主要是报表页面)。 下面是省市两个建表SQL的(DB2脚本)
drop table province; create table province( code varchar(10), name varchar(10)); insert into province (code,name) values('1','河南'),
('2','陕西'), ('3','河北'); drop table city;
create table city( code varchar(10), name varchar(10)); insert into city (code,name) values('1','郑州'),
('1','洛阳'), ('1','许昌'), ('1','焦作'), ('1','开封'), ('2','西安'), ('2','咸阳'), ('2','宝鸡'), ('3','石家庄'), ('3','唐山'); 二、实现方法
1、两级连动
在省选择框中读取所有省,当选项改变的时候触发一个js事件(onchange),将选择的省份代码和发送给自身页面,进一步显示该省下的城市选择框。 2、回填
对于文本框回填,则将请求参数记录下来。 对于静态选择框,将选择项记录下来,在再次进入页面时候利用查询,设置checked属性。 对于动态文本框,有专门的后台方法来实现。 三、实现代码
实现很简单,就两个文件,一个后台工具类,一个页面就搞定了。
1、后台工具类
package test;
import javax.naming.InitialContext;
import javax.naming.Context; import javax.sql.DataSource; import java.sql.*; /**
* File Name: TestDBUitl.java * Created by: IntelliJ IDEA. * Copyright: Copyright (c) 2003-2006 * Date Time: 2007-3-6 14:05:42 * Readme: JSP实现多级选择框连动测试,后台工具类 */ /**
* 数据库工具类 */ public final class TestDBUitl { /** * 通过数据源获取一个JDBC链接(如果没有配置数据源,可以将此完全方法注释掉,下面直接用JDBC的方式获取数据库连接) * * @return 一个JDBC链接 */ public static Connection getConnectionByJNDI() { try { //建立数据库连接 Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/zfvds"); //tomcat数据源 //DataSource ds = (DataSource) ctx.lookup("zfvds"); //Weblogic或者WebSphere数据源 return ds.getConnection(); } catch (Exception e) { e.printStackTrace(); return null; } } /**
* 直接获取JDBC链接 * * @return 一个JDBC链接(测试用,方便) */ public static Connection getConnectionByJDBC() { Connection conn = null; try {
//装载驱动类 Class.forName("com.ibm.db2.jcc.DB2Driver"); } catch (ClassNotFoundException e) { System.out.println("装载驱动异常!"); e.printStackTrace(); } try { //建立JDBC连接 conn = DriverManager.getConnection("jdbc:db2://192.168.3.8:50000/zfvims", "zfvims", "zfvimsdb2"); } catch (SQLException e) { System.out.println("链接数据库异常!"); e.printStackTrace(); } return conn; } /**
* 获取省份选项的html代码串 * @param sect 要选择的省份 * @param topage 要转向的页面 * @return 省份选项的html代码串 */ public static String getProvinceOptions(String sect, String topage) { String optionHTML = ""; Connection conn = getConnectionByJDBC(); Statement stmt; ResultSet rs; String sqlx = "select t.code,t.name from province t order by t.code asc"; try { //创建一个JDBC声明 stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); //执行查询 rs = stmt.executeQuery(sqlx); while (rs.next()) { String code = rs.getString("code"); String name = rs.getString("name"); String linked = "\"" + topage + "?province=" + code + "\""; if (sect.equals(code)) { optionHTML = optionHTML + "<option value=\"" + code + "\"" + "\" tourl=" + linked + " selected>" + code + "-" + name + "</option>\n\t\t"; } else { optionHTML = optionHTML + "<option value=\"" + code + "\" tourl=" + linked + ">" + code + "-" + name + "</option>\n\t\t"; } } } catch (SQLException e) { System.out.println(e.getMessage()); e.printStackTrace(); } return optionHTML; } /**
* 获取一个省份下城市选项的html代码串 * @param pcode 省份 * @param sect 默认选中的城市代码 * @return 城市选项的html代码串 */ public static String getCityOptions(String pcode, String sect) { String optionHTML = ""; Connection conn = getConnectionByJDBC(); ResultSet rs; String sqlx = "select t.code,t.name from city t where t.code = ? order by t.code asc"; try { //开始一个事务(注意关闭事务) conn.setAutoCommit(false); //创建一个JDBC声明 PreparedStatement pstmt = conn.prepareStatement(sqlx, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT); //设置预定义参数 pstmt.setString(1, pcode); rs = pstmt.executeQuery(); while (rs.next()) { String code = rs.getString("code"); String name = rs.getString("name"); if (sect.equals(code)) { optionHTML = optionHTML + "<option value=\"" + code + "\"" + " selected>" + code + "-" + name + "</option>\n\t\t"; } else { optionHTML = optionHTML + "<option value=\"" + code + "\">" + code + "-" + name + "</option>\n\t\t"; } } //提交事务 conn.commit(); //关闭连接等资源(注意先后顺序) rs.close(); pstmt.close(); conn.close(); } catch (SQLException e) { System.out.println(e.getMessage()); e.printStackTrace(); } finally { //预防性关闭连接(避免异常发生时在try语句块关闭连接没有执行) try { if (conn != null) conn.close(); } catch (SQLException e) { System.out.println(e.getMessage()); e.printStackTrace(); } } return optionHTML; } } 2、测试用的页面
<%--
File Name: TestCheckBoxLinks.jsp Created by: IntelliJ IDEA. Copyright: Copyright (c) 2003-2006 Date: 2007-3-6 15:14:33 Readme: JSP、Java实现选择框连动,实现页面输入信息回填功能。 --%> <%@ page contentType="text/html; charset=GBK" %> <%@ page import="test.TestDBUitl" %> <% String rootPath = request.getContextPath(); String topage = rootPath + "/pages/test/TestCheckBoxLinks.jsp"; String province = request.getParameter("province");
String city = request.getParameter("city"); String stype = request.getParameter("stype"); String author = request.getParameter("author"); if (province == null || "null".equals(province)) province = "";
if (city == null || "null".equals(city)) city = ""; if (stype == null || "null".equals(stype)) stype = ""; if (author == null || "null".equals(author)) author = "熔 岩"; %>
<html> <head> <title>JSP、Java实现选择框连动,实现页面输入信息回填功能。</title> </head> <body>
<form method="post"> <table> <tr> <td>省 份:</td> <td> <select name="province" onchange="getallpames(this)"> <option value="" tourl="/zfvims/pages/test/TestCheckBoxLinks.jsp">不限制</option> <%=TestDBUitl.getProvinceOptions(province, topage)%> </select> </td> <td>城 市:</td> <td> <select name="city"> <option value="">不限制</option> <%=TestDBUitl.getCityOptions(province, city)%> </select> </td> </tr> <tr> <td>类 型:</td> <td> <select name="stype"> <option value="04">A</option> <option value="07">B</option> <option value="11">C</option> <option value="13">D</option> </select> </td> <script language="javascript"> var a = document.all.stype.options; var n = a.length; for (var i = 0; i < n; i++) { var b = document.all.stype.options[i].value; if (b == "<%=stype%>") { document.all.stype.options[i].selected = true; } } </script> <td>作 者:</td> <td> <input type="text" name="author" value="<%=author%>" maxlength="20"> </td> </tr> </table> <table> <tr> <td colspan="2"></td> <td><input type="button" name="CX" value="查询"></td> <td><input type="reset" value="重置"></td> <td colspan="2"></td> </tr> </table> </form> </body> </html> <script type="text/javascript"> function getallpames(obj) { var pames = "&province=" + document.all.province.value; pames += "&city=" + document.all.city.value; pames += "&stype=" + document.all.stype.value; pames += "&author=" + document.all.author.value; var tourl = obj.options[obj.selectedIndex].tourl + pames; //alert(tourl); //打印转向地址的开关 window.location = tourl; } </script> 三、效果图预览
![]() ![]() ![]() ![]() ![]() ![]() 四、评价
这中做法适合有大量数据的情况下,即使数据很多,也不会很慢,但也在少量数据的情况下,速度和用户体验度上都不及JS的实现。现在的AJAX技术是个更好的选择,只是我还不会,呵呵。 这个例子在实际项目中应该慎用,因为需要考虑回填,校验等相关问题。 数据库脚本稍作修改就可以用到其他数据库中,后台方法也一样,主要差别在于注册驱动和驱动url上面。 本文出自 “熔 岩” 博客,转载请与作者联系! 本文出自 51CTO.COM技术博客 |
附件下载:
源代码
源代码








leizhimin
博客统计信息
热门文章
最新评论
友情链接