自定义树Tree

来源:互联网 发布:打火机推荐 知乎 编辑:程序博客网 时间:2024/06/08 17:04

本例是jQueryEasyUi中datagrid的树形展示,包含上下移动,编辑等。

可以主要看树形的部分。

 

Bean:

package com.zte.soa.demo.model;import java.util.List;public class Tree {private Long id;private Long pid;private List<Tree> children;private String attribute1;private String attribute2;private String attribute3;private String attribute4;private String attribute5;private String attribute6;private String attribute7;private String attribute8;private String attribute9;  //serviceIdprivate Long treeIndex;  //treeIndex//临时Id、Pid,操作时取该字段private String idStr;private String pidStr;...}

 

package com.zte.soa.demo.model;import java.io.Serializable;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.SequenceGenerator;import javax.persistence.Table;import javax.persistence.Temporal;import javax.persistence.TemporalType;import org.codehaus.jackson.map.annotate.JsonSerialize;import com.zte.soa.util.JsonDateSerializer;/** * 类 编 号: * 类 名 称: EipServiceParameter * 内容摘要:  * 完成日期:  * 编码作者:*/@Entity@Table(name = "eip_service_parameter")public class EipServiceParameter  implements Serializable{/** *  */private static final long serialVersionUID = -3159405932590138034L;@Id@SequenceGenerator(name = "EIP_SERVICE_PARAMETER_S", sequenceName = "EIP_SERVICE_PARAMETER_S", initialValue = 1, allocationSize = 1)@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="EIP_SERVICE_PARAMETER_S")@Column(name = "ID", nullable = false)protected java.lang.Long  id;@Column(name = "SERVICE_VERSION_ID")protected Long serviceId;@Column(name = "PARAMETER_NAME_CH", nullable = false)protected java.lang.String  parameterNameCh;@Column(name = "PARAMETER_NAME_EN", nullable = false)protected java.lang.String  parameterNameEn;@Column(name = "REMARK", nullable = true)protected java.lang.String  remark;@Column(name = "PARAMETER_TYPE", nullable = true)protected java.lang.String  parameterType;@Column(name = "DATA_TYPE", nullable = false)protected java.lang.String  dataType;@Column(name = "DATA_TYPE_LENGTH")protected java.lang.Long  dataTypeLength;@Column(name = "BELONG_FLAG", nullable = false)protected java.lang.String  belongFlag;@Column(name = "PARAM_CONSTRAINT", nullable = true)protected java.lang.String  constraint;@Column(name = "PARENT_PARAMETER_ID")protected java.lang.Long  parentParameterId;   @Column(name = "CREATED_BY")protected java.lang.Long  createdBy;@Column(name = "CREATION_DATE")@Temporal(TemporalType.DATE)@JsonSerialize(using=JsonDateSerializer.class)protected java.util.Date  creationDate;    @Column(name = "LAST_UPDATED_BY", nullable = false)    protected java.lang.Long lastUpdateBy;    @Column(name = "LAST_UPDATE_LOGIN", nullable = false)    protected java.lang.Long lastUpdateLogin;    @Column(name = "LAST_UPDATE_DATE", nullable = false)    @Temporal(TemporalType.TIMESTAMP)    @JsonSerialize(using = JsonDateSerializer.class, include = JsonSerialize.Inclusion.NON_NULL)    protected java.util.Date lastUpdateDate;    @Column(name = "ENABLED_FLAG", length = 1)    protected java.lang.String enabledFlag;        @Column(name = "TREE_INDEX")protected java.lang.Long  treeIndex;    ...}

 

Java:

package com.zte.soa.demo.controller.json;import java.io.StringWriter;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;import org.apache.commons.lang3.StringUtils;import org.codehaus.jackson.JsonGenerator;import org.codehaus.jackson.map.ObjectMapper;import org.hibernate.Criteria;import org.hibernate.criterion.Restrictions;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import com.zte.soa.demo.model.EipServiceParameter;import com.zte.soa.demo.model.EipUser;import com.zte.soa.demo.model.Tree;import com.zte.soa.demo.model.User;import com.zte.soa.demo.service.EipServiceParmService;import com.zte.soa.demo.service.EipServiceService;import com.zte.soa.demo.service.EipUserService;import com.zte.soa.demo.service.UserService;@Controllerpublic class UserController {@Autowiredprotected EipServiceParmService eipServiceParmService;public static <T> T fromJson(String json, Class<T> valueType){ObjectMapper mapper = new ObjectMapper();try {return mapper.readValue(json, valueType);} catch (Exception e) {e.printStackTrace();return null;}}public static String toJson(Object obj){String json = "";ObjectMapper mapper = new ObjectMapper();try {StringWriter writer = new StringWriter();JsonGenerator generator = mapper.getJsonFactory().createJsonGenerator(writer);mapper.writeValue(generator, obj);json = writer.toString();generator.close();writer.close();} catch (Exception e) {e.printStackTrace();}return json;}public EipServiceParameter getOriginalData(Tree t1){EipServiceParameter p = new EipServiceParameter();p.setParentParameterId(Long.parseLong(t1.getPidStr()));p.setParameterNameCh(t1.getAttribute1());p.setParameterNameEn(t1.getAttribute2());p.setDataType(t1.getAttribute3());Long dataTypeLen = StringUtils.isBlank(t1.getAttribute4()) || t1.getAttribute4().equals("null") ? 0 : Long.parseLong(t1.getAttribute4());p.setDataTypeLength(dataTypeLen);p.setBelongFlag(t1.getAttribute5());p.setConstraint(t1.getAttribute6());p.setParameterType(t1.getAttribute7());p.setRemark(t1.getAttribute8());p.setServiceId(Long.parseLong(t1.getAttribute9()));p.setTreeIndex(t1.getTreeIndex());p.setCreatedBy(1l);p.setCreationDate(new Date());p.setLastUpdateBy(1l);p.setLastUpdateDate(new Date());p.setLastUpdateLogin(1L);p.setEnabledFlag("Y");p = eipServiceParmService.save(p);return p;}public Boolean checkIsBlankAppend(Map map ){if(StringUtils.isBlank(String.valueOf(map.get("attribute1"))) &&StringUtils.isBlank(String.valueOf(map.get("attribute2"))) &&StringUtils.isBlank(String.valueOf(map.get("attribute3"))) &&StringUtils.isBlank(String.valueOf(map.get("attribute4"))) &&StringUtils.isBlank(String.valueOf(map.get("attribute5"))))return true;return false;}public List<Tree> changeDataType(List<HashMap> list){List<Tree> treeList = new ArrayList<Tree>();for(Map map : list){if(checkIsBlankAppend(map)) continue; //忽略空白添加Tree t = new Tree();String idStr = String.valueOf(map.get("id"));String pidStr = String.valueOf(map.get("pid"));//t.setId(idStr.startsWith("copy") ? 0l : Long.parseLong(idStr));//t.setPid(pidStr.startsWith("copy") ? 0l : Long.parseLong(pidStr));t.setAttribute1(String.valueOf(map.get("attribute1")));t.setAttribute2(String.valueOf(map.get("attribute2")));t.setAttribute3(String.valueOf(map.get("attribute3")));t.setAttribute4(String.valueOf(map.get("attribute4")));t.setAttribute5(String.valueOf(map.get("attribute5")));t.setAttribute6(String.valueOf(map.get("attribute6")));t.setAttribute7(String.valueOf(map.get("attribute7")));t.setAttribute8(String.valueOf(map.get("attribute8")));t.setAttribute9(String.valueOf(map.get("attribute9")));t.setIdStr(idStr);t.setPidStr(pidStr);t.setTreeIndex(Long.parseLong(String.valueOf(map.get("treeIndex"))));treeList.add(t);}return treeList;}/* * 需要添加的都为新增节点,id都是如copy1000这种临时Id * 添加需要一个一个保存到数据库,因为可能新增的节点他的父节点也是新增的,需要得到真实的父节点Id */public void insertData(List<Tree> insertedList , Map<String,Long> copyIdsMap){System.out.println();//先保存父节点是真实节点的数据,保存后从List中删除for(int i = insertedList.size() - 1 ; i >= 0 ;i--){Tree t1 = insertedList.get(i);String copyId = t1.getIdStr();String pid = t1.getPidStr();//父节点也是新增的if(pid.startsWith("copy")) continue; EipServiceParameter p = getOriginalData(t1);insertedList.remove(t1);copyIdsMap.put(copyId, p.getId());  //收集新增节点的真实Id,以备其他父节点是临时Id的节点使用}//再递归保存父节点是临时节点的数据for(int i = insertedList.size() - 1 ; i >= 0 ;i--){Tree t = insertedList.get(i);String copyId = t.getIdStr();String pid = t.getPidStr();if(copyIdsMap.containsKey(pid)){Long id = copyIdsMap.get(pid); //获取真实Idt.setPidStr(String.valueOf(id));EipServiceParameter p = getOriginalData(t);insertedList.remove(t);copyIdsMap.put(copyId, p.getId()); }else{insertData(insertedList,copyIdsMap); //递归获取id}}}@SuppressWarnings("unchecked")@RequestMapping(value = "/json/saveTreeGridData.json")@ResponseBodypublic Map<String, Object> saveTreeGridData(@RequestParam String treeGridData) {Map map = fromJson(treeGridData,Map.class);List<HashMap> insertedList = (List<HashMap>) map.get("inserted"); List<HashMap> updatedList = (List<HashMap>) map.get("updated"); List<HashMap> deletedList = (List<HashMap>) map.get("deleted"); List<EipServiceParameter> updList = new ArrayList<EipServiceParameter>();List<EipServiceParameter> delList = new ArrayList<EipServiceParameter>();//添加Map<String,Long> copyIdsMap = new HashMap<String,Long>();insertData(changeDataType(insertedList),copyIdsMap);System.out.println();//更新for(Tree t : changeDataType(updatedList)){Long id = Long.parseLong(t.getIdStr());EipServiceParameter p = eipServiceParmService.getById(id);p.setParentParameterId(Long.parseLong(t.getPidStr()));p.setParameterNameCh(t.getAttribute1());p.setParameterNameEn(t.getAttribute2());p.setDataType(t.getAttribute3());Long dataTypeLen = StringUtils.isBlank(t.getAttribute4()) || t.getAttribute4().equals("null") ? 0 : Long.parseLong(t.getAttribute4());p.setDataTypeLength(dataTypeLen);p.setBelongFlag(t.getAttribute5());p.setConstraint(t.getAttribute6());p.setParameterType(t.getAttribute7());p.setRemark(t.getAttribute8());p.setServiceId(Long.parseLong(t.getAttribute9()));p.setTreeIndex(t.getTreeIndex());updList.add(p);}eipServiceParmService.batchUpdate(updList);//删除for(Tree t : changeDataType(deletedList)){Long id = Long.parseLong(t.getIdStr());EipServiceParameter p = eipServiceParmService.getById(id);delList.add(p);}eipServiceParmService.batchDelete(delList);return null;}//入口方法@RequestMapping(value = "/json/getTreeGridData.json")@ResponseBodypublic Map<String, Object> getTreeGridData() {List<Tree> lt = new ArrayList<Tree>();String paramHql = " from EipServiceParameter pt where 1 = 1 and pt.serviceId = 492 order by pt.treeIndex desc";List<EipServiceParameter> paramList = eipServiceParmService.findByHql(paramHql);buildTreeData(paramList,lt);//展示树List<Tree> topTree = buildTree(lt);Map<String,Object> map = new HashMap<String,Object>();map.put("total", topTree.size());map.put("rows", topTree);return map;}//转换树数据private void buildTreeData(List<EipServiceParameter> paramList, List<Tree> lt) {long i = 0;if(paramList.get(0).getTreeIndex() == null){ //首次进入初始化更新全部TreeIndexfor(EipServiceParameter p : paramList){p.setTreeIndex(i);i++;}eipServiceParmService.batchUpdate(paramList); }for(EipServiceParameter p : paramList){Tree t = new Tree();t.setId(p.getId());t.setPid(p.getParentParameterId());t.setAttribute1(p.getParameterNameCh());t.setAttribute2(p.getParameterNameEn());t.setAttribute3(p.getDataType());t.setAttribute4(String.valueOf(p.getDataTypeLength()));t.setAttribute5(p.getBelongFlag());t.setAttribute6(p.getConstraint());t.setAttribute7(p.getParameterType());t.setAttribute8(p.getRemark());t.setAttribute9(String.valueOf(p.getServiceId()));t.setTreeIndex(p.getTreeIndex());lt.add(t);}}//构建树根public List<Tree> buildTree(List<Tree> data){List<Tree> topTree = new ArrayList<Tree>();for(int i = data.size() - 1 ; i >= 0 ;i--){Tree t = data.get(i);Long pid = t.getPid();if(pid == -1){topTree.add(t);data.remove(t);}}for(Tree top : topTree){buildBranchTree(top, data);}return topTree;}//构建树的子节点public void buildBranchTree(Tree parent , List<Tree> data){for(int i = data.size() - 1 ; i >= 0 ;i--){  //倒叙,否则remove后List会有问题Tree t = data.get(i);if(parent.getId() - 544  == 0 && t.getId() - 545 == 0){System.out.println();}if(parent.getId() - t.getPid() == 0){if(null == parent.getChildren())parent.setChildren(new ArrayList<Tree>());parent.getChildren().add(t);data.remove(t);}}if(data.size() == 0) return;if(null != parent.getChildren()){for(Tree branch : parent.getChildren()){buildBranchTree(branch, data);}}}}

 JSP:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!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><%@include file="/taglibs.jsp"%><script type="text/javascript" src="treegrid_data.json"></script><style>.tree-collapsed {    margin-left: 12px;}.tree-collapsed-hover {    background: url("js/jquery-easyui/themes/default/images/tree_arrows.gif") no-repeat scroll 0 0 transparent;}.tree-expanded {    margin-left: 12px;}.tree-expanded-hover {    background: url("js/jquery-easyui/themes/default/images/tree_arrows.gif") no-repeat scroll -18px 0 transparent;}.tree-folder-open {    background: none;}.tree-folder {    background: none;    width: 4px;}</style><script type="text/javascript">var lastIndex;  //结束编辑的上一行用到var codeIndex = 1000;  //临时Id起始值var insertRows = [];var updateRows = [];var deleteRows = [];//编辑时选项下拉框数据var belongFlag = [      {type:'Y',typeName:'是'},      {type:'N',typeName:'否'}  ];  var dataType = [{type:'VARCHAR2'},{type:'TIMESTAMP'},{type:'NVARCHAR2'},{type:'NUMBER'},{type:'LONG'},{type:'BLOB'},{type:'CLOB'},{type:'DATE'}]; (function($) {          $.extend($, {              //获取下标,删除时使用            getArrayIndex :  function (array,value) {var index = -1;var length = array.length;for (var i = 0; i < length; i++) {if (array[i].id == value.id) {index = i;break;}}return index;} ,removeValue : function (array,value){var index = $.getArrayIndex(array,value);if(index < 0) return array;array.splice(index,1);return array;}        });      })(jQuery); $(function() {$('#test').treegrid({       url:"json/getTreeGridData.json",     idField:'id',            treeField:'id',            animate: true,              checkbox:true,            singleSelect:true,            checkOnSelect:true,              selectOnCheck:true,              toolbar: '#toolbar',           /* frozenColumns: [[{            title: '参数中文名',            field: 'attribute1',            width: 200,            align:'left',            editor:'text'        }]],*/    columns:[[            {field:'id',title:'id',width:300},           {field:'pid',title:'pid',width:100,align:'right'},          {field:'treeIndex',title:'行位置标记',hidden:false},          {field:'attribute1',title:'参数中文名',width:200,align:'left',editor:'text'},           {field:'attribute2',title:'参数英文名',width:200,align:'right',editor:'text'},           {field:'attribute3',title:'数据类型',width:200,align:'right',        formatter:function(value){                      for(var i=0; i<dataType.length; i++){                          if (dataType[i].type == value) return dataType[i].type;                      }                      return value;                  },                  editor:{                      type:'combobox',                      options:{                          valueField:'type',                          textField:'type',                          data:dataType,                          required:true                    }                  }         },           {field:'attribute4',title:'数据长度',width:200,align:'right',editor:'text'},           {field:'attribute5',title:'是否必填',width:200,align:'right',        formatter:function(value){                      for(var i=0; i<belongFlag.length; i++){                          if (belongFlag[i].type == value) return belongFlag[i].typeName;                      }                      return value;                  },                  editor:{                      type:'combobox',                      options:{                          valueField:'type',                          textField:'typeName',                          data:belongFlag,                          required:true                     }                  }                  },           {field:'attribute6',title:'约束',width:200,align:'right',editor:'text'},          {field:'attribute7',title:'参数类型',width:200,align:'right',editor:'text',hidden:true},          {field:'attribute8',title:'备注',width:200,align:'right',editor:'text'},          {field:'attribute9',title:'服务Id',width:200,align:'right',editor:'text',hidden:true}    ]],    onLoadSuccess:function(data){            //alert(data);            //drag();        },    onLoadError:function(data){            alert("1:"+data);        },        onClickRow: function(row) { //运用单击事件实现一行的编辑结束,在该事件触发前会先执行onAfterEdit事件            var rowIndex = row.id;            if (lastIndex != rowIndex) {                $('#test').treegrid('endEdit', lastIndex);            }        },        onDblClickRow: function(row) { //运用双击事件实现对一行的编辑            var rowIndex = row.id;            if (lastIndex != rowIndex) {                $('#test').treegrid('endEdit', lastIndex);                $('#test').treegrid('beginEdit', rowIndex);                lastIndex = rowIndex;            }else{            $('#test').treegrid('beginEdit', lastIndex);            }        },        onBeforeEdit: function(row) {           // beforEditRow(row); //这里是功能实现的主要步骤和代码        },        onAfterEdit: function(row, changes) {        if(!checkExist(updateRows,row)){        updateRows[updateRows.length] = row;        }            var rowId = row.id;            $.ajax({                url: "",                data: row,                success: function(text) {                    //$.messager.alert('提示信息', text, 'info');                }            });        }});  setTimeout(collapseAll,1000);setTimeout(toolbar,1000);});//将工具条从默认位置移到下方function toolbar(){var bar = $("#toolbar").html();var toolbarTitle = "<div id='toolbar' class='datagrid-toolbar'>";var toolbar = toolbarTitle + bar + "</div>";$(".datagrid-view").prev().remove();$(".datagrid-view").parent().append(toolbar);}//拖动drag和drop都是datagrid的头的datagrid-cell    function drag() {        $('.datagrid-row').draggable({            revert: true,            proxy: 'clone'        }).droppable({            accept: '.datagrid-row',            onDrop: function (e, source) {                //取得拖动源的html值                var src = $(e.currentTarget.innerHTML).html();                //取得拖动目标的html值                var sou = $(source.innerHTML).html();                var tempcolsrc;//拖动后源和目标列交换                var tempcolsou;                var tempcols=[];                for (var i = 0; i < cols.length; i++) {                    if (cols[i].title == sou) {                        tempcolsrc = cols[i];//循环读一遍列把源和目标列都记下来                    }                    else if (cols[i].title == src) {                        tempcolsou = cols[i];                    }                }                for (var i = 0; i < cols.length; i++) {                    //再循环一遍,把源和目标的列对换                    var col = {                        field: cols[i].field,                        title: cols[i].title,                        align: cols[i].align,                        width: cols[i].width                    };                    if (cols[i].title == sou) {                        col = tempcolsou;                    }                    else if (cols[i].title == src) {                        col = tempcolsrc;                    }                     tempcols.push(col);                  }                 cols = tempcols;                 //1秒后执行重绑定datagrid操作。可能是revert需要时间,这边如果没有做延时就直接重绑 就会出错。                 //我目前的水平就想到这个笨办法,各位如果有好的想法建议可以提出来讨论下。                timeid = setTimeout("init()", 1000);            }        });    }function beforEditRow(row){         }function checkExist(array,node){var id = node.id;var flag = false;for(var i = 0;i<array.length; i++){var row = array[i];if(row.id == id){flag = true;break; //中断循环}}return flag;}/*function checkInsertExist(array,node){return checkExist(insertRows,node);}function checkUpdateExist(node){return checkExist(updateRows,node);}*/function saveChanges(){if (lastIndex != undefined) {$('#test').treegrid('endEdit', lastIndex);}var s = $('#test').treegrid('getChanges');       /*var insertRows = $('#test').datagrid('getChanges','inserted');var updateRows = $('#test').datagrid('getChanges','updated');var deleteRows = $('#test').datagrid('getChanges','deleted');*///updateRows = $('#test').treegrid('getChanges','updated');for(var i = updateRows.length - 1 ;i>=0 ;i--){var nod = updateRows[i];if(checkExist(insertRows,nod)){ //该项是新增的,删除更新组数据和新增组中老数据,将新数据添加到新增组中//$.removeValue(insertRows,nod); //删除添加组中老数据,替换新数据$.removeValue(updateRows,nod);  //新增组中会自动获取到最新数据,因此不用删除老数据即可。//insertRows[insertRows.length] = nod;}}var changesRows = {  inserted : [],  updated : [],  deleted : [],   };if (insertRows.length>0) {for (var i=0;i<insertRows.length;i++) {changesRows.inserted.push(insertRows[i]);}}if (updateRows.length>0) {for (var k=0;k<updateRows.length;k++) {changesRows.updated.push(updateRows[k]);}}if (deleteRows.length>0) {for (var j=0;j<deleteRows.length;j++) {changesRows.deleted.push(deleteRows[j]);}}//alert(JSON.stringify(changesRows));// 保存成功后,可以刷新页面,也可以://$('#test').treegrid('acceptChanges');var json = JSON.stringify(changesRows);$.post('json/saveTreeGridData.json', {"treeGridData": json}, function(data){/*if(data == 'success'){alert(1);}else{alert(2);}*/reload();});}function reload(){//var node = $('#test').treegrid('getSelected');//if (node){//$('#test').treegrid('reload', node.id);//} else {$('#test').treegrid('reload');//}insertRows = [];updateRows = [];deleteRows = [];setTimeout(collapseAll,1000);}function getChildren(){var node = $('#test').treegrid('getSelected');if (node){var nodes = $('#test').treegrid('getChildren', node.id);} else {var nodes = $('#test').treegrid('getChildren');}var s = '';for(var i=0; i<nodes.length; i++){s += nodes[i].id + ',';}alert(s);}function getSelected(){var node = $('#test').treegrid('getSelected');if (node){alert(node.id);}return false;}function collapse(){var node = $('#test').treegrid('getSelected');if (node){$('#test').treegrid('collapse', node.id);}}function expand(){var node = $('#test').treegrid('getSelected');if (node){$('#test').treegrid('expand', node.id);}}function collapseAll(){$('#test').treegrid('collapseAll');}function expandAll(){$('#test').treegrid('expandAll');}function commonDataCopy(pid){codeIndex++;   var copyId = 'copy'+codeIndex;var node = $('#test').treegrid('getSelected');var data = [{id: copyId,pid: pid,treeIndex:new Date().getTime(),attribute1: node.attribute1,attribute2: node.attribute2,attribute3: node.attribute3,attribute4: node.attribute4,attribute5: node.attribute5,attribute6: node.attribute6,attribute7: node.attribute7,attribute8: node.attribute8,attribute9: node.attribute9}];$('#test').treegrid('append', {parent: (node?pid:null),data: data});var node = $('#test').treegrid('find', copyId);insertRows[insertRows.length] = node;}function commonBlankCopy(pid){codeIndex++;   var node = $('#test').treegrid('getSelected');var copyId = 'copy'+codeIndex;var data = [{id: copyId,pid: pid,treeIndex:new Date().getTime(),attribute1: '',attribute2: '',attribute3: '',attribute4: '',attribute5: '',attribute6: '',attribute7: '',attribute8: '',attribute9: ''}];$('#test').treegrid('append', {parent: pid,data: data});var node = $('#test').treegrid('find', copyId);insertRows[insertRows.length] = node;}//添加平行节点        function copy(){   var node = $('#test').treegrid('getSelected');if(!node) alert("Please one row !");commonDataCopy(node.pid);return false;}//添加子节点function appendCopy(){var node = $('#test').treegrid('getSelected');if(!node) alert("Please one row !");commonDataCopy(node.id);return false;}function appendBlank(){var node = $('#test').treegrid('getSelected');commonBlankCopy(node ? node.id : -1);return false;}function blank(){var node = $('#test').treegrid('getSelected');commonBlankCopy(node ? node.pid : -1);return false;}function remove(){$.messager.confirm('确认','是否真的删除?',function(r){               if (r){                   var node = $('#test').treegrid('getSelected');if (node){deleteNode(node);$('#test').treegrid('remove', node.id);}               }           });}function removeMulSelected(){$.messager.confirm('确认','是否真的删除?',function(r){               if (r){                   var nodes = $('#test').treegrid('getSelections');                   for(var i = 0;i<nodes.length;i++){                     var node = nodes[i];                     if (node){  deleteNode(node);  $('#test').treegrid('remove', node.id);  }                   }               }           });}function commonDelete(node){if(checkExist(insertRows,node)){$.removeValue(insertRows,node);}else{//添加组中没有,说明不是新增的,需要加入删除组deleteRows[deleteRows.length] = node;}if(checkExist(updateRows,node)){$.removeValue(updateRows,node);}}function deleteNode(node){var children = $('#test').treegrid('getChildren', node.id);//删除添加组和更新组中的子数据if(children != null && children.length > 0){for(var i = 0 ; i < children.length ; i++){var child = children[i];commonDelete(child);}}//删除添加组和更新组中的当前节点数据commonDelete(node);}function toggle(){var node = $('#test').treegrid('getSelected');if (node){$('#test').treegrid('toggle', node.id);}}function moveUp(){var node = $('#test').treegrid('getSelected');var selectRow = $('#datagrid-row-r2-2-'+node.id);var pre = selectRow.prev();var next = selectRow.next();//处理新增行的移动//var i = node.id.indexOf("copy");var preLen = selectRow.parent().parent().prev().length; var flag = typeof node.id == 'string'; //只有新增的未移动的行才需要重新设置pre//pre.length == 0 判断是否是新增的未移动的行(新增的移动过的行和数字行一样)//preLen > 0 判断是否已移动到同级第一行if(flag && pre.length == 0 && preLen > 0){var tmpTable = selectRow.parent().parent().prev();var ran = new Date().getTime();tmpTable.attr("id","id"+ran);var _tr = $("#id"+ran+">tbody>tr");var tmpLast = _tr[_tr.length-1];var last = $(tmpLast);if(last.hasClass('treegrid-tr-tree')){pre = last.prev();}else{pre = last;}selectRow.parent().parent().remove();//删除新增行所在的table//pre = tmp.find("tr[class!='treegrid-tr-tree'] :last");//selectRow.parent().parent().remove(); //删掉新增行的Table}var preId;var preTreeIndex;if(pre.hasClass('treegrid-tr-tree')){  //前面节点含有子节点var child = pre;var treeprev = child.prev();preHtml = treeprev;}else{preHtml = pre;}//获取pre的IdpreId = preHtml.find("td:eq(0)").text();selectRow.insertBefore(preHtml);if(next.hasClass('treegrid-tr-tree')){ //自己含有子节点var child = next;selectRow.after(child);}//交换treeIndexvar selectTreeIndex = node.treeIndex;var prenode = $('#test').treegrid('find',preId);node.treeIndex = prenode.treeIndex;prenode.treeIndex = selectTreeIndex;$('#test').treegrid('refresh',node.id);$('#test').treegrid('refresh',preId);updateTreeIndex(node);updateTreeIndex(prenode);var i ;}function updateTreeIndex(node){if(checkExist(insertRows,node)){ $.removeValue(insertRows,node); $.removeValue(updateRows,node);  insertRows[insertRows.length] = node;}else{//将换了treeIndex的行加入更新组updateRows[updateRows.length] = node;}}</script></head><body><table id="test" class="easyui-treegrid" style="width: 1200px; height: 400px" data-options="rownumbers:true,pagination:false,fitColumns:true,autoRowHeight:false"></table><div id="toolbar">         <a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-tree-save" plain="true" onclick="saveChanges()">保存</a>         <a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-tree-reload" plain="true" onclick="reload()">重置</a>         <a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-tree-expand" plain="true" onclick="expandAll()">全部展开</a>         <a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-tree-collapse" plain="true" onclick="collapseAll()">全部收缩</a>         <a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-tree-appendBlank" plain="true" onclick="appendBlank()">添加子节点</a>         <a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-tree-appendCopy" plain="true" onclick="appendCopy()">复制子节点</a>         <a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-tree-blank" plain="true" onclick="blank()">添加节点</a>         <a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-tree-copy" plain="true" onclick="copy()">复制节点</a>         <a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-tree-remove" plain="true" onclick="remove()">删除节点</a>         <a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-tree-moveUp" plain="true" onclick="moveUp()">同级上移</a>         <a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-tree-moveDown" plain="true" onclick="javascript:alert('Save')">同级下移</a>     </div>  </body></html>

 

。。

 

 java 递归读取数据库生成tree的结构

 http://bbs.csdn.net/topics/320094100

 根据递归高效的生成树:

http://jsf.iteye.com/blog/124799

原创粉丝点击