`

Ajax 三级联动菜单(有bug)

    博客分类:
  • AJAX
 
阅读更多

数据库设计

 

drop database if exists mydb;  
create database mydb character set gbk;  
  
--多级联动菜单  
use mydb;  
drop table if exists select_menu;  
create table select_menu(  
    id varchar(255) not null default '',  
    text varchar(255) not null,  
    pid varchar(255) not null,  
    seq int(11) not null default 0,  
    primary key (id)  
)ENGINE=InnoDB DEFAULT CHARSET=gbk;  
  
insert into select_menu values('A1','列表A选项1','INIT',1);  
insert into select_menu values('A2','列表A选项2','INIT',2);  
insert into select_menu values('B11','列表B选项11','A1',1);  
insert into select_menu values('B12','列表B选项12','A1',2);  
insert into select_menu values('B13','列表B选项13','A1',3);  
insert into select_menu values('B21','列表B选项21','A2',1);  
insert into select_menu values('B22','列表B选项22','A2',2);  
insert into select_menu values('C111','列表C选项111','B11',1);  
insert into select_menu values('C112','列表C选项112','B11',2);  
insert into select_menu values('C121','列表C选项121','B12',1);  
insert into select_menu values('C122','列表C选项122','B12',2);  
insert into select_menu values('C131','列表C选项131','B13',1);  
insert into select_menu values('C132','列表C选项132','B13',2);  
insert into select_menu values('C211','列表C选项211','B21',1);  
insert into select_menu values('C212','列表C选项212','B21',2);  
insert into select_menu values('C221','列表C选项221','B22',1);  
insert into select_menu values('C222','列表C选项222','B22',2)

 连接数据库的工具类package com.lanp.ajax.db;

  
import java.sql.Connection;  
import java.sql.DriverManager;  
import java.sql.PreparedStatement;  
import java.sql.ResultSet;  
import java.sql.SQLException;  
  
/** 
 * 连接数据库的工具类,被定义成不可继承且是私有访问 
 * @author lanp 
 * @since 2012-2-29 22:27 
 */  
public final class DBUtils {  
    private static String url = "jdbc:mysql://localhost:3306/mydb?characterEncoding=gbk";  
    private static String user = "root";  
    private static String psw = "root";  
      
    private static  Connection conn;  
      
    static {  
        try {  
            Class.forName("com.mysql.jdbc.Driver");  
        } catch (ClassNotFoundException e) {  
            e.printStackTrace();  
            throw new RuntimeException(e);  
        }  
    }  
      
    private DBUtils() {  
          
    }  
      
    /** 
     * 获取数据库的连接 
     * @return conn 
     */  
    public static Connection getConnection() {  
        try {  
            conn = DriverManager.getConnection(url, user, psw);  
        } catch (SQLException e) {  
            e.printStackTrace();  
            throw new RuntimeException(e);  
        }  
        return conn;  
    }  
      
    /** 
     * 释放资源 
     * @param conn 
     * @param pstmt 
     * @param rs 
     */  
    public static void closeResources(Connection conn,PreparedStatement pstmt,ResultSet rs) {  
        if(null != rs) {  
            try {  
                rs.close();  
            } catch (SQLException e) {  
                e.printStackTrace();  
                throw new RuntimeException(e);  
            } finally {  
                if(null != pstmt) {  
                    try {  
                        pstmt.close();  
                    } catch (SQLException e) {  
                        e.printStackTrace();  
                        throw new RuntimeException(e);  
                    } finally {  
                        if(null != conn) {  
                            try {  
                                conn.close();  
                            } catch (SQLException e) {  
                                e.printStackTrace();  
                                throw new RuntimeException(e);  
                            }  
                        }  
                    }  
                }  
            }  
        }  
    }  
}  

 select_menu.html页面

 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
<title>多级联动菜单</title>  
  
    <script type="text/javascript">  
        var xmlHttp;                    //用于保存XMLHttpRequest对象的全局变量  
        var targetSelId;                //用于保存要更新选项的列表ID      
        var selArray = new Array();     //用于保存级联菜单ID的数组,《Ajax经典案例开发大全》中没有= new Array()代码  
          
        //用于创建XMLHttpRequest对象  
        function createXmlHttp() {  
            if(window.XMLHttpRequest) {  
                xmlHttp = new XMLHttpRequest();  
            } else {  
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");  
            }  
        }  
          
        //获取列表选项的调用函数  
        function buildSelect(selectedId,targetId) {  
            if("" == selectedId) {          //selectedId为空串表示选中了默认项  
                clearSubSel(targetId);      //清楚目标列表及下级列表中的值  
                return;                     //直接结束调用,不必向服务器请求信息  
            }  
              
            targetSelId = targetId;         //将传入的目标列表ID赋值给targetSelId变量  
            createXmlHttp();                //创建XMLHttpRequest对象  
            xmlHttp.onreadystatechange = buildSelectCallBack;       //设置回调函数  
            xmlHttp.open("GET", "select_menu.jsp?selectedId="+selectedId, true);  
            xmlHttp.send(null);  
        }  
          
        //获取列表选项的回调函数  
        function buildSelectCallBack() {  
            if(4 == xmlHttp.readyState) {  
                //将从服务器获得的文本转为对象直接量  
                var optionsInfo = eval("(" + xmlHttp.responseText + ")");  
                var targetSelNode = document.getElementById(targetSelId);  
                clearSubSel(targetSelId);  
                //遍历对象直接量中的成员  
                for(var o in optionsInfo) {  
                    //在目标列表追加新的选项  
                    targetSelNode.appendChild(createOption(o,optionsInfo[o]));  
                }  
            }  
        }  
          
        //根据传入的value和text创建选项  
        function createOption(value,text) {  
            var opt = document.createElement("option");         //创建一个option节点  
            opt.setAttribute("value", value);                   //设置value  
            opt.appendChild(document.createTextNode(text));     //给节点加入文本信息  
            return opt;  
        }  
          
        //清除传入的列表节点内所有选项  
        function clearOptions(selNode) {  
            selNode.options.length = 1;  
            selNode.options[0].selected = true;  
        }  
          
        //初始化列表数组,《Ajax经典案例开发大全》中该方法的代码是有误没有实现真正的初始化  
        function initSelArray(selA,selB,selC) {  
            selArray[0] = selA;  
            selArray[1] = selB;  
            selArray[2] = selC;  
        }  
          
        //清除下级子列表选项  
        function clearSubSel(targetId) {  
            var len = selArray.length;  
            for(var i=0;i<len;i++) {  
                var j = 0;  
                if(selArray[i] == targetId) {  
                    j = i;  
                    break;  
                }  
            }  
            for(; j<len; j++) {  
                clearOptions(document.getElementById(selArray[j]));  
            }  
            //《Ajax经典案例开发大全》中该方法的代码是有误,不能实现下级列表全部清除功能,且代码冗余,如下示:  
            //var canClear = false;  
            //for(var i=0; i<selArray.length; i++) {  
            //  if(selArray[i] == targetId) {  
            //      canClear = true;  
            //  }  
            //  if(canClear) {  
            //      clearOptions(document.getElementById(selArray[i]));  
            //  }  
            //}  
        }  
    </script>  
</head>  
<!-- 页面加载完毕做2件事:1.初始化列表数组,2.为第一个列表赋值 -->  
<body onload="initSelArray('selA','selB','selC');buildSelect('INIT','selA')">  
    <h1>多级联动菜单</h1>  
    <table>  
        <tr>  
            <td>列表A</td>  
            <td>  
                <select name="selA" id="selA" onchange="buildSelect(this.value,'selB')">  
                    <option value="" selected>-------请选择-------</option>  
                </select>  
            </td>  
        </tr>  
          
        <tr>  
            <td>列表B</td>  
            <td>  
                <select name="selB" id="selB" onchange="buildSelect(this.value,'selC')">  
                    <option value="" selected>-------请选择-------</option>  
                </select>  
            </td>  
        </tr>  
          
        <tr>  
            <td>列表C</td>  
            <td>  
                <select name="selC" id="selC">  
                    <option value="" selected>-------请选择-------</option>  
                </select>  
            </td>  
        </tr>  
    </table>  
</body>  
</html>  

 select_menu.jsp后台服务

 

<%@ page language="java" contentType="text/html; charset=UTF-8"  
    pageEncoding="UTF-8"%>  
<%@ page import="java.sql.*,com.lanp.ajax.db.DBUtils" %>      
<%!  
    //访问数据库取得下级选项信息  
    String getOptions(String selectedId) {  
        int counter = 0;  
        StringBuffer opts = new StringBuffer("{");  
        String sql = "select * from select_menu where pid=? order by seq asc";  
        Connection conn = null;  
        PreparedStatement pstmt = null;  
        ResultSet rs = null;  
        try {  
            conn = DBUtils.getConnection();  
            pstmt = conn.prepareStatement(sql);  
            pstmt.setString(1,selectedId);  
            rs = pstmt.executeQuery();  
              
            while(rs.next()) {  
                //如果不是第一项,追加一个","用于分隔选项  
                if(counter > 0) {  
                    opts.append(",");  
                }  
                opts.append("'");  
                opts.append(rs.getString("id"));  
                opts.append("':'");  
                opts.append(rs.getString("text"));  
                opts.append("'");  
                counter++;  
            }  
        } catch(SQLException e) {  
            System.out.println(e.toString());  
        } finally {  
            DBUtils.closeResources(conn,pstmt,rs);  
        }  
        opts.append("}");  
        System.out.println(opts.toString());  
        return opts.toString();  
    }  
%>  
  
<%  
    out.clear();  
    String selectedId = request.getParameter("selectedId");  
    String optionsInfo = getOptions(selectedId);  
    out.print(optionsInfo);  
%>  

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics