EXTJS动态树的实现举例

一、描述:通过dwr实现JS与后台的交互,从而实现动态树中叶子节点和目录节点的增加和编辑、以及节点的拖曳,节点的增删和拖曳都会改变自身以及它所在的目录节点下的相关节点的序号,能使得后台与前台同步。这个序号借助了tree中node的index。
1、相关基础:
servlet、mysql、dwr、json
2、涉及的ExtJs中部分知识点:
menu、tree、window以及事件机制
3、实现的效果图:
a)ExtJs动态树-右键叶子节点菜单

b)ExtJs动态树-选择右键叶子节点菜单的“编辑”选项

c)ExtJs动态树-右键目录节点菜单

d)ExtJs动态树-选择右键目录节点菜单的“编辑”选项

e)ExtJs动态树-拖曳节点

4、导航数据表结构:

5、源码结构图:

6、页面结构图:


二、实现流程
JAVA源码部分:
1、数据库连接
Java代码   收藏代码
  1. package com.demo.core.dao;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.DriverManager;  
  5.   
  6. public class DBConn {  
  7.   
  8.     private static  String url = "jdbc:mysql://localhost:3306/langsin";  
  9.     private static  String username = "root";  
  10.     private static  String password = "";  
  11.     private static  String driver = "com.mysql.jdbc.Driver";  
  12.       
  13.     public static Connection getConnection(){  
  14.         Connection conn = null;  
  15.         try{  
  16.             Class.forName(driver);  
  17.             conn = DriverManager.getConnection(url,username,password);  
  18.         }catch(Exception e){  
  19.             e.printStackTrace();  
  20.         }  
  21.         return conn;  
  22.     }  
  23. }  

2、dao层:
Java代码   收藏代码
  1. package com.demo.navigate.dao;  
  2.   
  3. import java.io.Serializable;  
  4. import java.sql.Connection;  
  5. import java.sql.ResultSet;  
  6. import java.sql.SQLException;  
  7. import java.sql.Statement;  
  8. import java.util.ArrayList;  
  9. import java.util.List;  
  10.   
  11. import com.demo.core.dao.DBConn;  
  12. import com.demo.navigate.model.Navigate;  
  13.   
  14. public class NavigateDao {  
  15.     private static NavigateDao dao;  
  16.     private NavigateDao(){        
  17.     }     
  18.     public static NavigateDao getInstanece(){  
  19.         if(null == dao){  
  20.             dao = new NavigateDao();  
  21.         }  
  22.         return dao;  
  23.     }  
  24.     /** 
  25.      * 获得指定ID的数据 
  26.      * @param id 
  27.      * @return 
  28.      */  
  29.     public Navigate get(Serializable id){  
  30.         Connection conection = null;  
  31.         Statement stmt = null;  
  32.         ResultSet rs = null;  
  33.         Navigate obj = null;  
  34.         try{  
  35.             conection = DBConn.getConnection();   
  36.             stmt = conection.createStatement();  
  37.             StringBuffer sql = new StringBuffer("select * from navigate where id = ");  
  38.             sql.append(id);  
  39.             rs = stmt.executeQuery(sql.toString());  
  40.             if(rs.next())  
  41.             {  
  42.                 obj = new Navigate();  
  43.                 obj.setId(rs.getInt("id"));  
  44.                 obj.setLeaf(rs.getInt("leaf"));  
  45.                 obj.setNumber(rs.getInt("number"));  
  46.                 obj.setParentId(rs.getInt("parentId"));  
  47.                 obj.setTitle(rs.getString("title"));  
  48.                 obj.setUrl(rs.getString("url"));  
  49.             }  
  50.         }catch(Exception e){  
  51.             e.printStackTrace();              
  52.         }finally{  
  53.             try{  
  54.                 if(rs != null) {  
  55.                     try {  
  56.                         rs.close();  
  57.                     } catch (SQLException e) {  
  58.                     }  
  59.                     rs = null;  
  60.                 }                 
  61.                 if (stmt != null) {  
  62.                     try {  
  63.                         stmt.close();  
  64.                     } catch (SQLException sqlex) {  
  65.                     }  
  66.                     stmt = null;  
  67.                 }  
  68.                 if (conection != null) {  
  69.                     try {  
  70.                         conection.close();  
  71.                     } catch (SQLException sqlex) {  
  72.                     }  
  73.                     conection = null;  
  74.                 }  
  75.             }catch(Exception e){  
  76.                 e.printStackTrace();  
  77.             }  
  78.         }  
  79.         return obj;  
  80.     }  
  81.       
  82.     /** 
  83.      * 获得指定节点的所有儿子节点 
  84.      * @param id 
  85.      */  
  86.     @SuppressWarnings("unchecked")  
  87.     public List<Navigate> getChildrenById(Integer id){  
  88.         List<Navigate> list = new ArrayList<Navigate>();  
  89.         Connection conection = null;  
  90.         Statement stmt = null;  
  91.         ResultSet rs = null;  
  92.         try{  
  93.             conection = DBConn.getConnection();   
  94.             stmt = conection.createStatement();  
  95.             StringBuffer sql = new StringBuffer("select * from navigate where parentId = ");  
  96.             sql.append(id);  
  97.             sql.append(" order by number,id");  
  98.             rs = stmt.executeQuery(sql.toString());  
  99.             while(rs.next())  
  100.             {  
  101.                 Navigate obj = new Navigate();  
  102.                 obj.setId(rs.getInt("id"));  
  103.                 obj.setLeaf(rs.getInt("leaf"));  
  104.                 obj.setNumber(rs.getInt("number"));  
  105.                 obj.setParentId(rs.getInt("parentId"));  
  106.                 obj.setTitle(rs.getString("title"));  
  107.                 obj.setUrl(rs.getString("url"));  
  108.                 list.add(obj);  
  109.             }  
  110.         }catch(Exception e){  
  111.             e.printStackTrace();              
  112.         }finally{  
  113.             try{  
  114.                 if(rs != null) {  
  115.                     try {  
  116.                         rs.close();  
  117.                     } catch (SQLException e) {  
  118.                     }  
  119.                     rs = null;  
  120.                 }                 
  121.                 if (stmt != null) {  
  122.                     try {  
  123.                         stmt.close();  
  124.                     } catch (SQLException sqlex) {  
  125.                     }  
  126.                     stmt = null;  
  127.                 }  
  128.                 if (conection != null) {  
  129.                     try {  
  130.                         conection.close();  
  131.                     } catch (SQLException sqlex) {  
  132.                     }  
  133.                     conection = null;  
  134.                 }  
  135.             }catch(Exception e){  
  136.                 e.printStackTrace();  
  137.             }  
  138.         }  
  139.         return list;  
  140.     }  
  141.       
  142.     /** 
  143.      * 保存数据 
  144.      * @param obj  
  145.      */  
  146.     public void save(Navigate obj){  
  147.         StringBuffer sql = new StringBuffer("insert into navigate(parentId,title,leaf,number,url) values(");  
  148.         sql.append(obj.getParentId());  
  149.         sql.append(",'");  
  150.         sql.append(obj.getTitle());  
  151.         sql.append("',");  
  152.         sql.append(obj.getLeaf());  
  153.         sql.append(",");  
  154.         sql.append(obj.getNumber());  
  155.         sql.append(",'");  
  156.         sql.append(obj.getUrl());  
  157.         sql.append("')");  
  158.         this.bulkUpdate(sql.toString());  
  159.     }  
  160.       
  161.     /** 
  162.      * 更新数据 
  163.      * @param obj  
  164.      */  
  165.     public void update(Navigate obj){  
  166.         StringBuffer sql = new StringBuffer("update navigate set");  
  167.         sql.append(" parentId = ");  
  168.         sql.append(obj.getParentId());  
  169.         sql.append(",");  
  170.         sql.append(" title = '");  
  171.         sql.append(obj.getTitle());  
  172.         sql.append("',");  
  173.         sql.append(" leaf = ");  
  174.         sql.append(obj.getLeaf());  
  175.         sql.append(",");  
  176.         sql.append(" number = ");  
  177.         sql.append(obj.getNumber());  
  178.         sql.append(", url = '");  
  179.         sql.append(obj.getUrl());  
  180.         sql.append("' where id = ");  
  181.         sql.append(obj.getId());  
  182.         this.bulkUpdate(sql.toString());  
  183.     }  
  184.       
  185.     /** 
  186.      * 异步更新标题 
  187.      * @param id 
  188.      * @param title 
  189.      * @return true-修改成功 false-修改失败 
  190.      */  
  191.     public Boolean ajaxUpdateTitle(Integer id,String title){  
  192.         Boolean flag = false;  
  193.         Navigate obj = this.get(id);  
  194.         if(null != obj){  
  195.             StringBuffer sql = new StringBuffer("update navigate set");  
  196.             sql.append(" title = '");  
  197.             sql.append(title);  
  198.             sql.append("'");  
  199.             sql.append(" where id = ");  
  200.             sql.append(id);  
  201.             this.bulkUpdate(sql.toString());  
  202.             flag = true;  
  203.         }  
  204.         return flag;  
  205.     }  
  206.       
  207.     /** 
  208.      * 删除指定的一条数据 
  209.      * @param id 
  210.      */  
  211.     public void removeById(Integer id){  
  212.         StringBuffer sql = new StringBuffer("delete from navigate where id = ");  
  213.         sql.append(id);  
  214.         this.bulkUpdate(sql.toString());  
  215.     }  
  216.       
  217.     /** 
  218.      * 异步删除数据,包括其子孙节点 
  219.      * @param id 
  220.      * @param title 
  221.      */  
  222.     @SuppressWarnings("unchecked")  
  223.     public void ajaxRemoveNode(Integer id){  
  224.         List list = this.getChildrenById(id);  
  225.         for (Object object : list) {  
  226.             Navigate obj = (Navigate)object;  
  227.             ajaxRemoveNode(obj.getId());  
  228.         }  
  229.         this.removeById(id);  
  230.     }  
  231.       
  232.     /** 
  233.      * 移动指定节点 
  234.      * @param id    指定的节点的id 
  235.      * @param oldParentId   节点移动前所在的父节点 
  236.      * @param newParentId   节点移动后的目标父节点 
  237.      * @param nodeIndex     节点移动后的目标位置 
  238.      */  
  239.     public void ajaxMoveNode(int id, int oldParentId, int newParentId, int nodeIndex){  
  240.         Navigate obj = this.get(id);  
  241.         int minIndex = obj.getNumber().intValue();  
  242.         int maxIndex = nodeIndex;  
  243.         if(oldParentId == newParentId && minIndex != maxIndex){  
  244.             // 在同一个父节点下发生移动  
  245.             if(minIndex < maxIndex){  
  246.                 // 当要移动的节点的序号小于要移动到的目标序号,则下移  
  247.                 this.downNode(oldParentId, minIndex, maxIndex);  
  248.             }else if(minIndex > maxIndex){  
  249.                 // 当要移动的节点的序号大于要移动到的目标序号,则上移  
  250.                 maxIndex = minIndex;  
  251.                 minIndex = nodeIndex;  
  252.                 this.upNode(oldParentId, minIndex, maxIndex);  
  253.             }  
  254.             // 节点本身的序号设置成要移动到的目标序号  
  255.             obj.setNumber(nodeIndex);  
  256.             this.update(obj);  
  257.         }  
  258.         if(oldParentId != newParentId){  
  259.             // 在不同父节点下发生移动  
  260.             //1、相当于要移动的节点在原父节点下下移到最后再删除掉,因此要指定移动发生时节点所在的位置  
  261.             this.downNode(oldParentId, minIndex, -1);  
  262.             //2、相当于要移动的节点在新父节点下上移到指定的位置,因此需要指定要移动到的位置  
  263.             this.upNode(newParentId, maxIndex, -1);  
  264.             // 节点本身的序号设置成要移动到的目标序号  
  265.             obj.setNumber(nodeIndex);  
  266.             obj.setParentId(newParentId);  
  267.             this.update(obj);  
  268.         }  
  269.     }  
  270.     /** 
  271.      * 指定的节点下移 
  272.      * @param parentId  指定范围内要移动的节点的父节点 
  273.      * @param minIndex  指定节点移动发生时所在的位置 
  274.      * @param maxIndex  指定节点要移动到的目标位置 
  275.      */  
  276.     @SuppressWarnings("unchecked")  
  277.     public void downNode(int parentId, int minIndex, int maxIndex){  
  278.         // 指定的节点下移,意味着其范围内的节点各自减1  
  279.         StringBuffer sql = new StringBuffer("update navigate set number=number-1 where parentId = ");  
  280.         sql.append(parentId);  
  281.         if(maxIndex != -1){  
  282.             sql.append(" and number <= ");  
  283.             sql.append(maxIndex);  
  284.         }  
  285.         if(minIndex != -1){  
  286.             sql.append(" and number > ");  
  287.             sql.append(minIndex);  
  288.         }         
  289.         this.bulkUpdate(sql.toString());  
  290.     }  
  291.     /** 
  292.      * 指定的节点上移 
  293.      * @param parentId  指定范围内要移动的节点的父节点 
  294.      * @param minIndex  指定节点要移动到的目标位置 
  295.      * @param maxIndex  指定节点移动发生时所在的位置 
  296.      */  
  297.     @SuppressWarnings("unchecked")  
  298.     public void upNode(int parentId, int minIndex, int maxIndex){  
  299.         // 指定的节点上移,意味着其范围内的节点各自加1  
  300.         StringBuffer sql = new StringBuffer("update navigate set number=number+1 where parentId = ");  
  301.         sql.append(parentId);  
  302.         if(maxIndex != -1){  
  303.             sql.append(" and number < ");  
  304.             sql.append(maxIndex);  
  305.         }  
  306.         if(minIndex != -1){  
  307.             sql.append(" and number >= ");  
  308.             sql.append(minIndex);  
  309.         }  
  310.         this.bulkUpdate(sql.toString());  
  311.     }  
  312.     /** 
  313.      * 批量更新或删除操作 
  314.      * @param sql 
  315.      */  
  316.     public void bulkUpdate(String sql){  
  317.         Connection conection = null;  
  318.         Statement stmt = null;  
  319.         try{  
  320.             conection = DBConn.getConnection();   
  321.             stmt = conection.createStatement();  
  322.             stmt.executeUpdate(sql);  
  323.         }catch(Exception e){  
  324.             e.printStackTrace();              
  325.         }finally{  
  326.             try{          
  327.                 if (stmt != null) {  
  328.                     try {  
  329.                         stmt.close();  
  330.                     } catch (SQLException sqlex) {  
  331.                     }  
  332.                     stmt = null;  
  333.                 }  
  334.                 if (conection != null) {  
  335.                     try {  
  336.                         conection.close();  
  337.                     } catch (SQLException sqlex) {  
  338.                     }  
  339.                     conection = null;  
  340.                 }  
  341.             }catch(Exception e){  
  342.                 e.printStackTrace();  
  343.             }  
  344.         }  
  345.     }  
  346. }  

3、Service层
Java代码   收藏代码
  1. package com.demo.navigate.service;  
  2.   
  3. import java.io.Serializable;  
  4. import java.util.List;  
  5.   
  6. import com.demo.navigate.dao.NavigateDao;  
  7. import com.demo.navigate.model.Navigate;  
  8.   
  9. public class NavigateManager {  
  10.     private NavigateDao dao = NavigateDao.getInstanece();  
  11.     public Navigate get(Serializable id){  
  12.         return dao.get(id);  
  13.     }  
  14.     /** 
  15.      * 获得指定节点的所有儿子节点 
  16.      * @param id 
  17.      */  
  18.     @SuppressWarnings("unchecked")  
  19.     public List<Navigate> getChildrenById(Integer id){  
  20.         return dao.getChildrenById(id);  
  21.     }  
  22.     /** 
  23.      * 保存数据 
  24.      * @param obj  
  25.      */  
  26.     public void save(Navigate obj){  
  27.         dao.save(obj);  
  28.     }  
  29.     /** 
  30.      * 更新数据 
  31.      * @param obj  
  32.      */  
  33.     public void update(Navigate obj){  
  34.         dao.update(obj);  
  35.     }  
  36.     /** 
  37.      * 删除指定的一条数据 
  38.      * @param id 
  39.      */  
  40.     public void removeById(Integer id){  
  41.         dao.removeById(id);  
  42.     }  
  43.     /** 
  44.      * 异步更新标题 
  45.      * @param id 
  46.      * @param title 
  47.      * @return true-修改成功 false-修改失败 
  48.      */  
  49.     public Boolean ajaxUpdateTitle(Integer id,String title){  
  50.         return dao.ajaxUpdateTitle(id, title);  
  51.     }  
  52.     /** 
  53.      * 异步删除数据,包括其子孙节点 
  54.      * @param id 
  55.      * @param title 
  56.      */  
  57.     public void ajaxRemoveNode(Integer id){  
  58.         Navigate obj = dao.get(id);  
  59.         dao.downNode(obj.getParentId(), obj.getNumber(), -1);  
  60.         dao.ajaxRemoveNode(id);  
  61.     }  
  62.     /** 
  63.      * 异步移动指定节点 
  64.      * @param id    指定的节点的id 
  65.      * @param oldParentId   节点移动前所在的父节点 
  66.      * @param newParentId   节点移动后的目标父节点 
  67.      * @param nodeIndex     节点移动后的目标位置 
  68.      */  
  69.     public void ajaxMoveNode(int id, int oldParentId, int newParentId, int nodeIndex){  
  70.         dao.ajaxMoveNode(id, oldParentId, newParentId, nodeIndex);  
  71.     }  
  72. }  

4、Servlet层
a)edit
Java代码   收藏代码
  1. package com.demo.navigate.web;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.RequestDispatcher;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. import com.demo.navigate.model.Navigate;  
  12. import com.demo.navigate.service.NavigateManager;  
  13.   
  14. @SuppressWarnings("serial")  
  15. public class NavigateEditServlet extends HttpServlet {  
  16.       
  17.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  18.             throws ServletException, IOException {  
  19.         this.doPost(request, response);  
  20.     }  
  21.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  22.             throws ServletException, IOException {  
  23.         String idstr = request.getParameter("id");  
  24.         String parentId = request.getParameter("parentId");  
  25.         String leaf = request.getParameter("leaf");  
  26.         String number = request.getParameter("number");  
  27.         Navigate obj = null;  
  28.         if(null != idstr){  
  29.             NavigateManager navigateManager = new NavigateManager();  
  30.             obj = navigateManager.get(idstr);  
  31.         }else{  
  32.             obj = new Navigate();  
  33.             obj.setParentId(new Integer(parentId));  
  34.             obj.setLeaf(new Integer(leaf));  
  35.             obj.setNumber(new Integer(number));  
  36.         }  
  37.         request.setAttribute("obj", obj);  
  38.         RequestDispatcher dispatcher = request.getRequestDispatcher("/navigate/console-edit.jsp");  
  39.         dispatcher.forward(request, response);  
  40.     }  
  41. }  

b)save
Java代码   收藏代码
  1. package com.demo.navigate.web;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.RequestDispatcher;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. import com.demo.navigate.model.Navigate;  
  12. import com.demo.navigate.service.NavigateManager;  
  13.   
  14. @SuppressWarnings("serial")  
  15. public class NavigateSaveServlet extends HttpServlet {  
  16.       
  17.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  18.             throws ServletException, IOException {  
  19.         this.doPost(request, response);  
  20.     }  
  21.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  22.             throws ServletException, IOException {  
  23.         NavigateManager navigateManager = new NavigateManager();  
  24.         Navigate obj = null;  
  25.         request.setCharacterEncoding("UTF-8");  
  26.         String id = request.getParameter("id");  
  27.         String number = request.getParameter("number");  
  28.         String parentId = request.getParameter("parentId");  
  29.         String leaf = request.getParameter("leaf");  
  30.         String title = request.getParameter("title");  
  31.         String url = request.getParameter("url");  
  32.           
  33.         if(null != id && !"".equals(id)){  
  34.             obj = navigateManager.get(id);  
  35.             if(obj == null){  
  36.                 RequestDispatcher dispatcher = request.getRequestDispatcher("/navigate/error.jsp");  
  37.                 dispatcher.forward(request, response);  
  38.                 return;  
  39.             }  
  40.         }else{  
  41.             obj = new Navigate();  
  42.             obj.setLeaf(new Integer(leaf));  
  43.             obj.setParentId(new Integer(parentId));  
  44.         }  
  45.         obj.setNumber(new Integer(number));  
  46.         obj.setTitle(title);  
  47.         obj.setUrl(url);  
  48.         if(null != id && !"".equals(id)){  
  49.             navigateManager.update(obj);  
  50.         }else{  
  51.             navigateManager.save(obj);  
  52.         }  
  53.         RequestDispatcher dispatcher = request.getRequestDispatcher("/navigate/success.jsp");  
  54.         dispatcher.forward(request, response);        
  55.     }  
  56.   
  57. }  

c)json
Java代码   收藏代码
  1. package com.demo.navigate.web;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.RequestDispatcher;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. import com.demo.navigate.service.NavigateManager;  
  12.   
  13. @SuppressWarnings("serial")  
  14. public class NavigateJsonServlet extends HttpServlet {  
  15.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  16.             throws ServletException, IOException {  
  17.         this.doPost(request, response);  
  18.     }  
  19.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  20.             throws ServletException, IOException {  
  21.   
  22.         NavigateManager navigateManager = new NavigateManager();  
  23.         request.setAttribute("list", navigateManager.getChildrenById(new Integer(request.getParameter("id"))));  
  24.         RequestDispatcher dispatcher = request.getRequestDispatcher("/navigate/console-json.jsp");  
  25.         dispatcher.forward(request, response);  
  26.     }  
  27.   
  28. }  


页面:
1、edit
Html代码   收藏代码
  1. <%@ page contentType="text/html;charset=UTF-8" %>  
  2. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
  3. <%@ include file="/common/in.jsp"%>  
  4. <html>  
  5. <head>  
  6.     <base href="<%=basePath%>">  
  7.     <title>菜单编辑</title>  
  8.     <link rel="stylesheet" type="text/css" href="scripts/ext/resources/css/ext-all.css">  
  9.     <script type="text/javascript" src="scripts/ext/adapter/ext/ext-base.js"></script>  
  10.   
  11.   
  12.   
  13.     <script type="text/javascript" src="scripts/ext/ext-all.js"></script>  
  14.     <script type="text/javascript">  
  15.         function checkForm(form){  
  16.             if(form.parentId.value == "" || form.leaf.value == ""){  
  17.                 Ext.Msg.alert("错误提示","表单信息不健全!");  
  18.                 return false;  
  19.             }  
  20.             if(form.title.value == ""){  
  21.                 Ext.Msg.alert("错误提示","标题不能为空!");  
  22.                 return false;  
  23.             }  
  24.         }  
  25.     </script>  
  26. </head>  
  27. <body style="background-color: white">  
  28.     <br/><br/>  
  29.     <form action="navigatesave" method="post" onsubmit="return checkForm(this)">  
  30.         <input type="hidden" name="id" value="${obj.id}"/>  
  31.         <input type="hidden" name="parentId" value="${obj.parentId}"/>  
  32.         <input type="hidden" name="leaf" value="${obj.leaf}"/>  
  33.         <input type="hidden" name="number" value="${obj.number}"/>  
  34.         <table align="center">  
  35.             <tr><td width="60">标题:</td>  
  36.                 <td><input type="text" name="title" value="${obj.title}"/></td></tr>  
  37.             <c:if test="${obj.leaf==1}">  
  38.             <tr><td>URL:</td>  
  39.                 <td><input type="text" name="url" value="${obj.url}"/></td></tr>  
  40.             </c:if>  
  41.             <tr><td colspan="2" align="center">  
  42.                     <br/>  
  43.                     <input type="submit" name="submit" value="保存"/>  
  44.                     &nbsp;&nbsp;  
  45.                     <input type="reset" name="reset" value="重置"/>  
  46.                     &nbsp;&nbsp;  
  47.                     <input type="button" name="button" value="取消" onclick="window.parent.FormEditWin.close();">  
  48.                 </td></tr>  
  49.         </table>  
  50.     </form>  
  51. </body>  
  52. </html>  


2、success
Html代码   收藏代码
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  4. <html>  
  5. <head>  
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  7. <title>信息更新成功</title>  
  8. <script type="text/javascript">  
  9.     // 信息保存成功后,刷新父节点  
  10.     this.parent.FormEditWin.reloadNavNode();  
  11. </script>  
  12. </head>  
  13. <body>  
  14.     <center>  
  15.         恭喜,信息更新成功!  
  16.     </center>  
  17. </body>  
  18. </html>  


3、json
Html代码   收藏代码
  1. <%@ page contentType="text/html;charset=UTF-8" %>  
  2. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
  3. <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>  
  4.   
  5. <c:set var="len" value="${fn:length(list)-1}" ></c:set>  
  6. [  
  7. <c:forEach items="${list}" var="obj" varStatus="i">  
  8. {  
  9.     id:'${obj.id}',  
  10.     text:'${obj.title}',  
  11.     <c:if test="${obj.leaf == 1}">  
  12.         leaf:true,  
  13.     </c:if>  
  14.     singleClickExpand:true  
  15. }  
  16.     <c:if test="${i.index<len}">,</c:if>  
  17. </c:forEach>  
  18. ]  


4、in.jsp
Html代码   收藏代码
  1. <%@ page language="java" pageEncoding="UTF-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  


js核心:
console-index.js
Js代码   收藏代码
  1. // 全局路径  
  2. var basePath = "http://localhost:8080/langsinext";  
  3. if(typeof(glbRootPath) != "undefined"){  
  4.     basePath = glbRootPath;  
  5. }  
  6. // 扩展窗体  
  7. FormEditWin = function(){  
  8.     var curFormWin;  
  9.     return {  
  10.         width : 600,  
  11.         height : 400,  
  12.         showAddDirWin : function(parentNode) {  
  13.             // 显示添加子目录窗口  
  14.             var number = parentNode.indexOf(parentNode.lastChild) + 1;  
  15.             var editpage = basePath  
  16.                     + "/navigateedit?parentId="  
  17.                     + parentNode.id + "&leaf=0&number=" + number;  
  18.             var window = this.createWin("windirnew""新建目录节点", editpage, function() {  
  19.                 parentNode.reload();  
  20.             });  
  21.             window.show();  
  22.         },  
  23.         showAddLeafWin : function(parentNode) {  
  24.             // 显示添加子叶子节点窗口  
  25.             var number = parentNode.indexOf(parentNode.lastChild) + 1;  
  26.             var editpage = basePath  
  27.                     + "/navigateedit?parentId="  
  28.                     + parentNode.id + "&leaf=1&number=" + number;  
  29.             var window = this.createWin("winleafnew""新建叶子节点", editpage, function() {  
  30.                 parentNode.reload();  
  31.             });  
  32.             window.show();  
  33.         },  
  34.         showEditDirWin : function(node) {  
  35.             // 显示目录编辑窗口  
  36.             var editpage = basePath  
  37.                     + "/navigateedit?id=" + node.id;  
  38.             var window = this.createWin("win" + node.id, node.text, editpage, function() {  
  39.                 var nodeparent = node.parentNode;  
  40.                 var tree = node.getOwnerTree();  
  41.                 nodeparent.on("expand"function(pnode) {  
  42.                     tree.getNodeById(node.id).select();  
  43.                 }, this, {  
  44.                     single : true  
  45.                 });  
  46.                 node.parentNode.reload();  
  47.             });  
  48.             window.show();  
  49.         },  
  50.         showEditLeafWin : function(node) {  
  51.             // 显示叶子节点编辑窗口  
  52.             var editpage = basePath  
  53.                     + "/navigateedit?id=" + node.id;  
  54.             var window = this.createWin("win" + node.id, node.text, editpage, function() {  
  55.                 var nodeparent = node.parentNode;  
  56.                 var tree = node.getOwnerTree();  
  57.                 nodeparent.on("expand"function(pnode) {  
  58.                     tree.getNodeById(node.id).select();  
  59.                 }, this, {  
  60.                     single : true  
  61.                 });  
  62.                 node.parentNode.reload();  
  63.             });  
  64.             window.show();  
  65.         },  
  66.         createWin : function(winId, winTitle, iframePage, closeFun) {  
  67.             // 供各类型窗口创建时调用  
  68.             var win = Ext.getCmp(winId);  
  69.             if (!win) {  
  70.                 win = new Ext.Window({  
  71.                     id : winId,  
  72.                     title : "菜单编辑窗口-" + winTitle,  
  73.                     width : this.width,  
  74.                     height : this.height,  
  75.                     maximizable : true,  
  76.                     modal : true,  
  77.                     html : "<iframe width='100%' height='100%' frameborder='0' src='"  
  78.                             + iframePage + "'></iframe>"  
  79.                 });  
  80.                 this.reloadNavNode = closeFun;  
  81.             }  
  82.             curFormWin = win;  
  83.             return win;  
  84.         },  
  85.         reloadNavNode : function() {  
  86.         },  
  87.         close : function() {  
  88.             if(curFormWin){  
  89.                 curFormWin.close();  
  90.             }  
  91.         }  
  92.     }  
  93. }();  
  94.   
  95. // 导航树  
  96. NavTree = function(){  
  97.     var nav;  
  98.     var navEditor;  
  99.     var leafMenu;  
  100.     var dirMenu;  
  101.     var loader;  
  102.     var root;  
  103.     var removeFlag = false;  
  104.     var titleChangeFlag = false;  
  105.     var nodeSelected;  
  106.     var mgr;  
  107.     return {  
  108.         init : function(){  
  109.             if(!mgr){  
  110.                 Ext.Msg.alert("警告提示","请先通过NavTree.setMgr()设置mgr");  
  111.                 return;  
  112.             }  
  113.             if(!loader){  
  114.                 loader = new Ext.tree.TreeLoader({  
  115.                     url : basePath + '/navigatejson'  
  116.                 });  
  117.                 loader.on('beforeload'function(treeloader, node) {  
  118.                     treeloader.baseParams = {  
  119.                         id : node.id,  
  120.                         method : 'tree'  
  121.                     };  
  122.                 }, this);  
  123.             }  
  124.             if(!root){  
  125.                 root = new Ext.tree.AsyncTreeNode({  
  126.                     id : '0',  
  127.                     text : "系统菜单"  
  128.                 });  
  129.             }  
  130.             if(!nav){  
  131.                 nav = new Ext.tree.TreePanel({  
  132.                     title : "左部导航",  
  133.                     width : 232,  
  134.                     autoScroll : true,  
  135.                     animate : true,  
  136.                     loader : loader,  
  137.                     root : root,  
  138.                     enableDD : true,  
  139.                     listeners : {  
  140.                         'click' : function(node, event) {  
  141.                             if (node.isLeaf()) {  
  142.                                 // 为叶子节点时,点击不进入链接  
  143.                                 event.stopEvent();  
  144.                             }  
  145.                         }  
  146.                     }  
  147.                 });  
  148.                 // 添加右键菜单  
  149.                 nav.on("contextmenu"this.showTreeMenu);  
  150.                 // 当节点文本改变时触发事件  
  151.                 nav.on("textchange"function(node, newText, oldText) {  
  152.                     if (!titleChangeFlag && newText != oldText) {  
  153.                         mgr.ajaxUpdateTitle(node.id, newText, function(success) {  
  154.                             if (!success) {  
  155.                                 Ext.Msg.show({  
  156.                                     title : "操作失败!",  
  157.                                     msg : "菜单修改失败!",  
  158.                                     buttons : Ext.Msg.OK,  
  159.                                     icon : Ext.MessageBox.ERROR  
  160.                                 });  
  161.                                 titleChangeFlag = true;  
  162.                                 node.setText(oldText);  
  163.                                 titleChangeFlag = false;  
  164.                             }  
  165.                         });  
  166.                     }  
  167.                 });  
  168.                 // 当节点移动时触发事件  
  169.                 nav.on("movenode"function(tree, node, oldParent, newParent, index) {  
  170.                     mgr.ajaxMoveNode(node.id, oldParent.id, newParent.id, index);  
  171.                 });  
  172.                 // 当节点删除时触发事件  
  173.                 nav.on("remove"function(tree, parentNode, node) {  
  174.                     if (removeFlag) {  
  175.                         mgr.ajaxRemoveNode(node.id);  
  176.                     }  
  177.                 });  
  178.             }  
  179.             if(!navEditor){  
  180.                 navEditor = new Ext.tree.TreeEditor(nav, {  
  181.                     allowBlank : false,  
  182.                     ignoreNoChange : true,  
  183.                     blankText : '标题不能为空',  
  184.                     selectOnFocus : true  
  185.                 });  
  186.             }  
  187.             this.setLeafMenu();  
  188.             this.setDirMenu();  
  189.         },  
  190.         setMgr : function(manager){  
  191.             mgr = manager;  
  192.         },  
  193.         getMgr : function(){  
  194.             return mgr;  
  195.         },  
  196.         setLeafMenu: function(){  
  197.             // 设置叶子菜单  
  198.             if(!leafMenu){  
  199.                 leafMenu = new Ext.menu.Menu({  
  200.                     items : [{  
  201.                         text : "修改标题",  
  202.                         handler : function() {  
  203.                             navEditor.triggerEdit(nodeSelected);  
  204.                         }  
  205.                     }, "-", {  
  206.                         text : "编辑",  
  207.                         handler : function() {  
  208.                             FormEditWin.showEditLeafWin(nodeSelected);  
  209.                         }  
  210.                     }, "-", {  
  211.                         text : "删除",  
  212.                         handler : this.delTreeItemComfirm  
  213.                     }]  
  214.                 });  
  215.             }  
  216.         },  
  217.         setDirMenu: function(){  
  218.             // 设置目录菜单  
  219.             if(!dirMenu){  
  220.                 dirMenu = new Ext.menu.Menu({  
  221.                     items : [{  
  222.                         text : "修改标题",  
  223.                         handler : function() {  
  224.                             navEditor.triggerEdit(nodeSelected);  
  225.                         }  
  226.                     }, "-", {  
  227.                         text : "编辑",  
  228.                         handler : function() {  
  229.                             FormEditWin.showEditDirWin(nodeSelected);  
  230.                         }  
  231.                     }, "-", {  
  232.                         text : "添加叶子节点",  
  233.                         handler : function() {  
  234.                             FormEditWin.showAddLeafWin(nodeSelected);  
  235.                         }  
  236.                     }, "-", {  
  237.                         text : "添加目录节点",  
  238.                         handler : function() {  
  239.                             FormEditWin.showAddDirWin(nodeSelected);  
  240.                         }  
  241.                     }, "-", {  
  242.                         text : "删除",  
  243.                         handler : this.delTreeItemComfirm  
  244.                     }]  
  245.                 });  
  246.             }  
  247.         },  
  248.         showTreeMenu : function(node, e){  
  249.             nodeSelected = node;  
  250.             nodeSelected.select();  
  251.             if (node.isLeaf()) {  
  252.                 // 显示叶子节点菜单  
  253.                 leafMenu.showAt(e.getPoint());  
  254.             } else {  
  255.                 // 显示目录节点菜单  
  256.                 dirMenu.showAt(e.getPoint());  
  257.             }  
  258.         },  
  259.         delTreeItemComfirm : function(){  
  260.             Ext.Msg.confirm("确认删除""确定要删除所选节点吗?"function(btn) {  
  261.                 if (btn == "yes") {  
  262.                     NavTree.delTreeItem();  
  263.                 }  
  264.             });  
  265.         },  
  266.         delTreeItem : function(){  
  267.             if (nodeSelected != nav.getRootNode()) {  
  268.                 removeFlag = true;  
  269.                 nodeSelected.remove();  
  270.                 removeFlag = false;  
  271.             } else {  
  272.                 Ext.Msg.alert("警告""不能删除树的根节点!");  
  273.             }  
  274.         },  
  275.         show : function(){  
  276.             nav.render(Ext.getBody());  
  277.             nav.getRootNode().toggle();  
  278.         }  
  279.     }  
  280. }();  
  281.   
  282. // 文档加载完毕执行  
  283. Ext.onReady(function(){  
  284.     Ext.BLANK_IMAGE_URL = "../scripts/ext/resources/images/default/s.gif";  
  285.     if(typeof(NavigateManager)=="undefined"){  
  286.         Ext.Msg.alert("警告提示","请先设置DWR,并实例化NavigateManager");  
  287.     }else{  
  288.         NavTree.setMgr(NavigateManager);  
  289.         NavTree.init();  
  290.         NavTree.show();  
  291.     }  
  292. });  


dwr配置:
dwr.xml
Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://www.getahead.ltd.uk/dwr//dwr20.dtd">  
  3.   
  4. <dwr>  
  5.     <allow>  
  6.         <create javascript="NavigateManager" creator="new">  
  7.             <param name="class"  
  8.                 value="com.demo.navigate.service.NavigateManager">  
  9.             </param>  
  10.             <include method="ajaxUpdateTitle" />  
  11.             <include method="ajaxRemoveNode" />  
  12.             <include method="ajaxMoveNode" />  
  13.         </create>  
  14.     </allow>  
  15. </dwr>  


servlet配置:
web.xml
Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.4"   
  3.     xmlns="http://java.sun.com/xml/ns/j2ee"   
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   
  6.     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
  7.   <servlet>  
  8.         <servlet-name>navigatejson</servlet-name>  
  9.         <servlet-class>  
  10.             com.demo.navigate.web.NavigateJsonServlet  
  11.         </servlet-class>  
  12.     </servlet>  
  13.     <servlet>  
  14.         <servlet-name>navigateedit</servlet-name>  
  15.         <servlet-class>  
  16.             com.demo.navigate.web.NavigateEditServlet  
  17.         </servlet-class>  
  18.     </servlet>  
  19.     <servlet>  
  20.         <servlet-name>navigatesave</servlet-name>  
  21.         <servlet-class>  
  22.             com.demo.navigate.web.NavigateSaveServlet  
  23.         </servlet-class>  
  24.     </servlet>  
  25.     <servlet-mapping>  
  26.         <servlet-name>navigatejson</servlet-name>  
  27.         <url-pattern>/navigatejson</url-pattern>  
  28.     </servlet-mapping>  
  29.     <servlet-mapping>  
  30.         <servlet-name>navigateedit</servlet-name>  
  31.         <url-pattern>/navigateedit</url-pattern>  
  32.     </servlet-mapping>  
  33.     <servlet-mapping>  
  34.         <servlet-name>navigatesave</servlet-name>  
  35.         <url-pattern>/navigatesave</url-pattern>  
  36.     </servlet-mapping>  
  37.     <servlet>  
  38.         <servlet-name>dwr-invoker</servlet-name>  
  39.         <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>  
  40.         <init-param>  
  41.             <param-name>debug</param-name>  
  42.             <param-value>true</param-value>  
  43.         </init-param>  
  44.         <init-param>  
  45.             <param-name>  
  46.                 allowGetForSafariButMakeForgeryEasier  
  47.             </param-name>  
  48.             <param-value>true</param-value>  
  49.         </init-param>  
  50.         <load-on-startup>1</load-on-startup>  
  51.     </servlet>  
  52.     <servlet-mapping>  
  53.         <servlet-name>dwr-invoker</servlet-name>  
  54.         <url-pattern>/dwr/*</url-pattern>  
  55.     </servlet-mapping>  
  56.     <welcome-file-list>  
  57.         <welcome-file>index.jsp</welcome-file>  
  58.     </welcome-file-list>  
  59. </web-app> 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值