Extjs4.1 TreePanel 的增删改查与拖拽排序

用了一天的时间完成了对Extjs TreePanel的 增删改查与拖拽排序

一来对自己写的代码做一个总结,二来给有需要的人一些帮组,

如果代码有什么BUG或者更好的建议,欢迎大家留言


先看效果图

[img]http://dl.iteye.com/upload/attachment/0083/7703/1459de1c-1c14-336b-83c7-6042648e7858.jpg[/img]



/**
* 定义树节点
*/
public class TreeNode {

//ID
private int id;

//展示数时显示的文本
private String text;

//是否是叶子节点
private boolean leaf;

//子节点的集合
//(@JsonInclude(Include.NON_NULL)序列化时的标记 如果为空则不参与序列化)
@JsonInclude(Include.NON_NULL)
private List<TreeNode> children;

public TreeNode() {}

public TreeNode(int id, String text, boolean leaf) {
super();
this.id = id;
this.text = text;
this.leaf = leaf;
}

public TreeNode(int id, String text, boolean leaf, List<TreeNode> children) {
super();
this.id = id;
this.text = text;
this.leaf = leaf;
this.children = children;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}

public boolean isLeaf() {
return leaf;
}

public void setLeaf(boolean leaf) {
this.leaf = leaf;
}

public List<TreeNode> getChildren() {
return children;
}

public void setChildren(List<TreeNode> children) {
this.children = children;
}
}




package com.sshe.operation.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.sshe.base.controller.BaseController;
import com.sshe.operation.entity.TreeNode;

/**
* 控制层,我用的Spring3 MVC
* 4个方法分别与Extjs的API对应
* api: {
* create: 'TreeApiController.do?method=createTreeNode',
* read: 'TreeApiController.do?method=queryTreeList',
* update: 'TreeApiController.do?method=updateTreeNode',
* destroy: 'TreeApiController.do?method=destroyTreeNode'
* }
*/
@Controller
@RequestMapping("/TreeApiController.do")
public class TreeApiController extends BaseController {

/**
* 查询的方法
* 对应 read: 'TreeApiController.do?method=queryTreeList'
*/
@ResponseBody
@RequestMapping(params="method=queryTreeList")
public Object queryTreeList(ModelMap map) {
System.out.println(map);
JsonResult result = new JsonResult();
result.setSuccess(true);
result.setData(getTreeList());
return getTreeList();
}

/**
* 新增方法
* 对应create: 'TreeApiController.do?method=createTreeNode'
*/
@ResponseBody
@RequestMapping(params="method=createTreeNode")
public Object createTreeNode(ModelMap map) {
System.out.println(map);
JsonResult result = new JsonResult();
result.setSuccess(true);
return result;
}

/**
* 更新的方法
* 对应 update: 'TreeApiController.do?method=updateTreeNode'
*/
@ResponseBody
@RequestMapping(params="method=updateTreeNode")
public Object updateTreeNode(ModelMap map) {
System.out.println(map);
JsonResult result = new JsonResult();
result.setSuccess(true);
return result;
}

/**
* 删除的方法
* 对应 destroy: 'TreeApiController.do?method=destroyTreeNode'
*/
@ResponseBody
@RequestMapping(params="method=destroyTreeNode")
public Object destroyTreeNode(ModelMap map) {
System.out.println(map);
JsonResult result = new JsonResult();
result.setSuccess(true);
return result;
}

/**
* 测试数据
*/
public List<TreeNode> getTreeList() {
List<TreeNode> list = new ArrayList<TreeNode>();

TreeNode java = new TreeNode(1, "java-1", false, new ArrayList<TreeNode>());
TreeNode hibernate = new TreeNode(2, "hibernate-2", true);
TreeNode spring = new TreeNode(3, "spring-3", true);
TreeNode struts = new TreeNode(4, "struts-4", true);
java.getChildren().add(hibernate);
java.getChildren().add(spring);
java.getChildren().add(struts);

TreeNode javascript = new TreeNode(5, "javascript-5", false, new ArrayList<TreeNode>());
TreeNode extjs = new TreeNode(6, "extjs-6", false, new ArrayList<TreeNode>());
javascript.getChildren().add(extjs);
TreeNode extPlugin = new TreeNode(7, "extPlugin-7", true);
extjs.getChildren().add(extPlugin);

list.add(java);
list.add(javascript);

return list;
}
}




Ext.onReady(function() {

//GUID
function newGuid() {
var guid = "";
for (var i = 1; i <= 32; i++){
var n = Math.floor(Math.random()*16.0).toString(16);
guid += n;
if((i==8)||(i==12)||(i==16)||(i==20))
guid += "-";
}
return guid;
}

//Toopitp
Ext.tip.QuickTipManager.init();

//定义菜单
Ext.define('SimpleTasks.view.lists.ContextMenu', {
extend: 'Ext.menu.Menu',
xtype: 'listsContextMenu',
items: [
{
text: 'New List',
iconCls: 'tasks-new-list',
id: 'new-list-item'
},
{
text: 'New Folder',
iconCls: 'tasks-new-folder',
id: 'new-folder-item'
},
{
text: 'Delete',
iconCls: 'tasks-delete-folder',
id: 'delete-folder-item'
}
]

});

//Model
Ext.define('MyTreeModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'string'},
{name: 'text', type: 'string'},
{name: 'index', type: 'int', persist: true}
]
});

//Store
Ext.define("MyTreeStore", {
extend: "Ext.data.TreeStore",
model: 'MyTreeModel',
proxy: {
type: 'ajax',
api: {
create: 'TreeApiController.do?method=createTreeNode',
read: 'TreeApiController.do?method=queryTreeList',
update: 'TreeApiController.do?method=updateTreeNode',
destroy: 'TreeApiController.do?method=destroyTreeNode'
},
writer: {
type: 'json',
allowSingle: false,
encode: true,
root: 'records'
}
},
root: {
id: -1,
expanded: true,
text: "My Root"
},
autoLoad: true
});



var store = Ext.create("MyTreeStore");

Ext.define("MyTreePanel", {
extend: 'Ext.tree.Panel',
title: 'Simple Tree',
width: 250,
height: 400,
store: store,
hideHeaders: true,
rootVisible: true,
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop'
},
listeners: {
drop: function(node, data, dropRec, dropPosition) {
store.sync();
}
}
},

initComponent: function() {
var me = this;
//可编辑
me.plugins = [me.cellEditingPlugin = Ext.create('Ext.grid.plugin.CellEditing')];

//定义列
me.columns = [{
xtype: 'treecolumn',
dataIndex: 'text',
flex: 1,
editor: {
xtype: 'textfield',
selectOnFocus: true,
validator: function(value){
value = Ext.String.trim(value);
return value.length < 1 ? this.blankText : true;
}
}
},{
xtype: 'actioncolumn',
width: 24,
icon: 'resources/images/delete.png',
iconCls: 'x-hidden',
tooltip: 'Delete',
handler: Ext.bind(me.handleDeleteClick, me)
}];

//定义底部tbar
me.dockedItems = [{
xtype: 'toolbar',
dock: 'bottom',
items: [{
iconCls: 'tasks-new-list',
tooltip: 'New List',
handler: me.handleNewListClick,
scope: me
},{
iconCls: 'tasks-new-folder',
tooltip: 'New Folder',
handler: me.handleNewFolderClick,
scope: me
},{
iconCls: 'tasks-delete-folder',
id: 'delete-folder-btn',
tooltip: 'Delete Folder'
}]
}];

me.contextMenu = Ext.create("SimpleTasks.view.lists.ContextMenu");

me.callParent();

me.on("itemmouseenter", me.showActions);
me.on("itemmouseleave", me.hideActions);
me.on("edit", me.updateNode);
me.on("afterrender", me.handleAfterListTreeRender);
me.on("beforeedit", me.handleBeforeEdit, me);
//me.on("canceledit", me.handleCancelEdit);
me.on("itemcontextmenu", me.showContextMenu, me);
},

//刷新树
refreshView: function() {
//refresh the data in the view.
//This will trigger the column renderers to run,
this.getView().refresh();
},

//显示actioncolumn
showActions: function(view, list, node, rowIndex, e) {
var icons = Ext.DomQuery.select('.x-action-col-icon', node);
if(view.getRecord(node).get('id') != "-1") {
Ext.each(icons, function(icon){
Ext.get(icon).removeCls('x-hidden');
});
}
},

//隐藏actioncolumn
hideActions: function(view, list, node, rowIndex, e) {
var icons = Ext.DomQuery.select('.x-action-col-icon', node);
Ext.each(icons, function(icon){
Ext.get(icon).addCls('x-hidden');
});
},

//Handles a click on a delete icon
handleDeleteClick: function(gridView, rowIndex, colIndex, column, e, record) {
//这个model区别于普通的model
//在定义store的时候并没有定义fields或model属性,该model由treeStore自动创建
//该model包含树展示所需要的数据结构,具备parentNode,isLeaf,loaded等属性
var model = gridView.getRecord(gridView.findTargetByEvent(e));
this.deleteNode(model);
},

//删除节点
deleteNode: function(nodel) {
nodel.parentNode.removeChild(nodel);
//与服务器端同步
store.sync();
},

//更新节点
updateNode: function(editor, e) {
var me = this;
//与服务器端同步
store.sync();
},

//树加载完毕后设置默认选中第一个
handleAfterListTreeRender: function(tree) {
tree.getSelectionModel().select(0);
},

//编辑前判断跟节点不允许编辑
handleBeforeEdit: function(editingPlugin, e) {
return e.record.get('id') !== -1;
},

//取消编辑事件
handleCancelEdit: function(editor, e) {
var list = e.record,
parent = list.parentNode;
parent.removeChild(list);
this.getListTree().getSelectionModel().select([parent]);
},

//添加叶子节点
handleNewListClick: function(component, e) {
this.addNode(true);
},

//添加跟节点
handleNewFolderClick: function(component, e) {
this.addNode();
},

//添加节点
addNode: function(leaf) {
var me = this;
var listTree = me;
cellEditingPlugin = listTree.cellEditingPlugin,
selectionModel = listTree.getSelectionModel(),
selectedList = selectionModel.getSelection()[0],
parentList = selectedList.isLeaf() ? selectedList.parentNode : selectedList,
newList = Ext.create('MyTreeModel', {
id: newGuid(),
text: 'New ' + (leaf ? 'List' : 'Folder'),
leaf: leaf,
loaded: true // set loaded to true,
//so the tree won't try to dynamically load children
//for this node when expanded
}),
expandAndEdit = function() {
if(parentList.isExpanded()) {
selectionModel.select(newList);
cellEditingPlugin.startEdit(newList, 0);
} else {
listTree.on('afteritemexpand', function startEdit(list) {
if(list === parentList) {
selectionModel.select(newList);
cellEditingPlugin.startEdit(newList, 0);
// remove the afterexpand event listener
listTree.un('afteritemexpand', startEdit);
}
});
parentList.expand();
}
};
parentList.appendChild(newList);
if(listTree.getView().isVisible(true)) {
expandAndEdit();
} else {
listTree.on('expand', function onExpand() {
expandAndEdit();
listTree.un('expand', onExpand);
});
listTree.expand();
}
},

//添加右键菜单
showContextMenu: function(view, list, node, rowIndex, e) {
this.contextMenu.showAt(e.getX(), e.getY());
e.preventDefault();
}
});

Ext.create("MyTreePanel", {
renderTo: Ext.getBody()
});
});


[size=x-large][color=red]
源码压缩后太大无法上传,需要的留邮箱我发给大家
[/color][/size]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值