联动下拉选择菜单的实现

联动选择下拉菜单是我们在开发中经常遇到的问题,一般来讲,三级联动是最为常见的。具体实现方式有很多种:比如每一次下拉选择change的时候发一次ajax请求调数据库加载,或者全部加载信息使用dom方式控制菜单。从性能上来说,第二种实现方式优于第一种,减少了数据库调用次数,并且也能很好地控制菜单显示速度。本文将使用第二种实现方式:

1表设计和准备数据:建立以下数据表并插入示例数据,用于反映学院、专业、班级的三个层级关系,使用lvl和parcode来表示层次关系。

create table grade_tab(
       code varchar2(20) primary key,
       codenm varchar2(40),
       parcode varchar2(20),
       lvl varchar2(1)
       );
--lvl1 data
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ETC', 'Electric', '', '1');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ECO', 'Economics', '', '1');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('STW', 'softwa', '', '1');
--lvl2 data
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ETC01', 'Electric automatic', 'ETC', '2');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ETC02', 'Electric machintic', 'ETC', '2');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ETC03', 'Electric emmbed', 'ETC', '2');
  
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ECO01', 'E-commerce', 'ECO', '2');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ECO02', 'National trade', 'ECO', '2');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('SE', 'Software erginerring', 'STW', '2');
--lvl3 data
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ETCC1', '011007', 'ETC01', '3');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ETCC2', '011008', 'ETC01', '3');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ETCC3', '011009', 'ETC02', '3');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ETCC4', '011010', 'ETC02', '3');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ETCC5', '011011', 'ETC03', '3');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ETCC6', '011012', 'ETC03', '3');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('ETCC7', '011014', 'ETC03', '3');
  
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('STWC1', '011201', 'SE', '3');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('STWC2', '011202', 'SE', '3');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('STWC3', '011203', 'SE', '3');
insert into grade_tab
  (code, codenm, parcode, lvl)
values
  ('STWC4', '011204', 'SE', '3');

 2前端页面:

 页面将使用ajax作为请求处理技术,同时使用json作为数据传输格式,使用JQuery作为dom操作的主要工具,具体代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>choose</title>
<c:set var="root" value="${pageContext.request.contextPath}"></c:set>
<script src="js/jquery-1.9.0.min.js"></script>
<script>
var lvl1;
var lvl2;
var lvl3;
$(function(){
	$.ajax({
		type : "POST",
		url : "${root}/GradeServ",
		dataType : "json",
		//data : "method=init",
		success : function(data){
			lvl1 = data.lvl1;
			lvl2 = data.lvl2;
			lvl3 = data.lvl3;
			var cell1 = $("#lvl1");
			for(var i = 0;i<lvl1.length;i++){
				var school = lvl1[i];
				cell1.append("<option value="+school.code+">"+school.codenm+"</option>");
			}
			cell1.change(function(){
				nextVal("2");
				nextVal("3");
			})
			var cell2 = $("#lvl2");
			cell2.change(function(){
				nextVal("3");
			})
		}
	})
});
function nextVal(level){
	var now_node = $("#lvl"+level);
	now_node.empty();
	var parcode = $("#lvl"+(level-1)).val();
	console.log(parcode);
	var list = null;
	if(level==2){
		list = lvl2;
	} else {
		list = lvl3;
	}
	for(var i =0;i<list.length;i++){
		var node = list[i];
		if(node.parcode==parcode && level==node.lvl){
			now_node.append("<option value="+node.code+">"+node.codenm+"</option>");
		}
	}
	if(now_node.find("option").length==0){
		now_node.append("<option value='0'>--Choose--</option>");
	}
}
</script>
</head>
<body>
	<select name='lvl1' id='lvl1'>
		<option value='0'>--Choose--</option>
	</select>
	<select name='lvl2' id='lvl2'>
		<option value='0'>--Choose--</option>
	</select>
	<select name='lvl3' id='lvl3'>
		<option value='0'>--Choose--</option>
	</select>
</body>
</html>

 页面在加载时即发送请求到服务程序,加载所有的层级信息,并将这些信息使用Array形式进行存放。

3.服务端代码

    Bean类:

package com.any.grade;

/** 
 * @ClassName: GradeBean 
 * @author Helen
 */

public class GradeBean {
	private String code;
	private String codenm;
	private String parcode;
	private String lvl;
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public String getCodenm() {
		return codenm;
	}
	public void setCodenm(String codenm) {
		this.codenm = codenm;
	}
	public String getParcode() {
		return parcode;
	}
	public void setParcode(String parcode) {
		this.parcode = parcode;
	}
	public String getLvl() {
		return lvl;
	}
	public void setLvl(String lvl) {
		this.lvl = lvl;
	}
	public GradeBean(String code, String codenm, String parcode, String lvl) {
		super();
		this.code = code;
		this.codenm = codenm;
		this.parcode = parcode;
		this.lvl = lvl;
	}
	public GradeBean(){}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((code == null) ? 0 : code.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		GradeBean other = (GradeBean) obj;
		if (code == null) {
			if (other.code != null)
				return false;
		} else if (!code.equals(other.code))
			return false;
		return true;
	}
}

   使用Servlet作为数据准备程序,用于处理请求并将数据发送给前端页面:

package com.any.grade;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;

/**
 * Servlet implementation class GradeServ
 */
@WebServlet("/GradeServ")
public class GradeServ extends HttpServlet {
	private static final long serialVersionUID = 1L;
    private GradeDao gd = new GradeDao();   
    public GradeServ() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request,response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Map<String, List<GradeBean>> data = gd.loadData();
		List<GradeBean> lvl1 = data.get("lvl1");
		List<GradeBean> lvl2 = data.get("lvl2");
		List<GradeBean> lvl3 = data.get("lvl3");
		JSONArray j_lvl1 = JSONArray.fromObject(lvl1);
		JSONArray j_lvl2 = JSONArray.fromObject(lvl2);
		JSONArray j_lvl3 = JSONArray.fromObject(lvl3);
		String json = "{\"lvl1\":"+j_lvl1.toString()+",\"lvl2\":"+j_lvl2.toString()+",\"lvl3\":"+j_lvl3.toString()+"}";
		response.setContentType("text/json");
		response.setCharacterEncoding("UTF-8");
		response.getWriter().println(json);
	}

}

 Dao类,查询数据库并将数据通过bean传递:

package com.any.grade;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.any.servlet.DbUtil;

/** 
 * @ClassName: GradeDao 
 * @author Helen
 */

public class GradeDao {
	private List<GradeBean> getPriGrade(String lvl){
		String sql = "select code,codenm,parcode,lvl from grade_tab	"
					+ "where lvl=?									"
					+ "and codenm is not null						";
		ResultSet rs = DbUtil.executeQuery(sql, lvl);
		List<GradeBean> list = new ArrayList<GradeBean>();
		try {
			while(rs.next()){
				list.add(new GradeBean(rs.getString("code"), 
							rs.getString("codenm"), 
							rs.getString("parcode"), 
							rs.getString("lvl")));
			}
			return list;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	public Map<String, List<GradeBean>> loadData(){
		Map<String, List<GradeBean>> data = new HashMap<String, List<GradeBean>>();
		List<GradeBean> lvl1 = getPriGrade("1");
		List<GradeBean> lvl2 = getPriGrade("2");
		List<GradeBean> lvl3 = getPriGrade("3");
		data.put("lvl1", lvl1);
		data.put("lvl2", lvl2);
		data.put("lvl3", lvl3);
		return data;
	}
	
}

 数据库工具类,用于连接数据库并执行SQL,返回对应的结果:

package com.any.servlet;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DbUtil {
	private static String url="jdbc:oracle:thin:@localhost:1521:orcl";
	private static String user="scott";
	private static String password="tiger";
	private static Connection conn;
	private static Connection getConnection(){
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			conn=DriverManager.getConnection(url, user, password);
			return conn;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	public static int executeUpdate(String sql,Object... params){
		PreparedStatement pmst = null;
		try {
			pmst = getConnection().prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				pmst.setObject(i+1, params[i]);
			}
			return pmst.executeUpdate();
		} catch (SQLException e) {
			try {conn.rollback();} catch (SQLException e1) {e1.printStackTrace();}
			e.printStackTrace();
		} 
		return -1;
	}
	public static ResultSet executeQuery(String sql,Object... params){
		PreparedStatement pmst = null;
		try {
			pmst = getConnection().prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				pmst.setObject(i+1, params[i]);
			}
			return pmst.executeQuery();
		} catch (SQLException e) {
			try {conn.rollback();} catch (SQLException e1) {e1.printStackTrace();}
			e.printStackTrace();
		} 
		return null;
	}
	public static void closeConnection(){
		if(conn!=null){
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

 经过以上步骤,就初步完成了三级联动选择菜单的制作。在页面加载时,必须首先选择第一层级下拉选项,从而进行后续选项的选择。

猜你喜欢

转载自bjtale.iteye.com/blog/2233511