树(tree)在网页中以树形结构显示分层数据。它向用户提供展开、折叠、拖拽、编辑和异步加载功能。
树(tree)定义在 元素中。该标记可定义叶节点和子节点。节点将是 ul 列表内的
每个节点可以包括下列属性:
1、树的基本用法
--index.js--
$(function(){
$("#tt").tree({
data: [
{id:0,text:"全部",children:[
{id:"1",text:"node1"},
{id: 2, text:"node2"},
{id:"3", checked:true,text:"node3"}, //复选框有效可用checked属性
{id:"5",text:"node4",children:[
{id:"5",text:"node4-1",iconCls:"icon-save"},
{id:"6",text:"node4-1"}
]}
]}
],
dnd: true, //可拖放
lines: true, //显示树线条
checkbox: true, //显示复选框
animate: true //展开动画效果
});
});
2、格式化树节点和过滤树节点
formatter | function(node) | 定义如何呈现节点文本。 代码实例:
|
|
loadFilter | function(data,parent) | 返回要显示的过滤数据。返回数据时以标准树格式返回的。该函数有下列参数: data:要加载的原始数据。 parent:DOM 对象,表示父节点。 |
在1中添加如下js
animate: true, //展开动画效果
formatter: function(node){ //格式化节点,参数node:为tree所有节点
var ftext = node.text;
if (node.children){
ftext += ' (' + node.children.length + ')';
}
return ftext;
},
loadFilter: function(data){ //对显示节点过滤,data:要加载的原始数据。
for(var i=0; i
3、节点加右键菜单可编辑 : 事件与方法见文档
名称 |
参数 |
描述 |
onClick |
node |
当用户点击一个节点时触发。 |
onAfterEdit |
node |
编辑节点后触发。 |
onContextMenu | e, node | 当右键点击节点时触发。 |
名称 |
参数 |
描述 |
beginEdit |
target |
开始编辑节点。 |
getSelected |
none |
获取选中的节点并返回它,如果没有选中节点,则返回 null。 |
select | target | 选中一个节点,target 参数表示节点的 DOM 对象。 |
append | param | 追加一些子节点到一个父节点,param 参数有两个属性: parent:DOM 对象,要追加到的父节点,如果没有分配,则追加为根节点。 data:数组,节点的数据。 |
insert | param | 在指定节点的前边或后边插入一个节点,param 参数包括下列属性: before:DOM 对象,前边插入的节点。 after:DOM 对象,后边插入的节点。 data:对象,节点数据。 |
remove | target | 移除一个节点和它的子节点,target 参数表示节点的 DOM 对象。 |
--index.js--
$(function(){
$("#tt").tree({
data: [
{id:0,text:"全部",children:[
{id:"1",text:"node1"},
{id: 2, text:"node2"},
{id:"3", checked:true,text:"node3"}, //复选框有效可用checked属性
{id:"4",text:"node4",children:[
{id:"5",text:"node4-1",iconCls:"icon-save"},
{id:"6",text:"node4-1"}
]}
]}
],
dnd: true, //可拖放
lines: true, //显示树线条
checkbox: true, //显示复选框
animate: true, //展开动画效果
onContextMenu: function(e,node){
e.preventDefault();
$(this).tree("select",node.target); //让右键点击的节点对象被选中
$("#mm").menu("show",{
left: e.pageX,
top:e.pageY
});
}
});
var id = 7;
$("#addSonNode").on("click",function(){
//获取选中的节点对象
var selectedNode = $("#tt").tree("getSelected");
//创建新添加的子节点
var node = {
parent: selectedNode.target,
data: [
{
id: ++id, //模拟数据id,项目中取数据库中最新的id+1
text: ""
}
]
}
//把子节点追加添加到树上
$("#tt").tree("append",node);
//通过新节点的id获取它的对象
var actNode = $("#tt").tree("find",id); //模拟数据id
//alert(actNode + id);
$("#tt").tree("beginEdit",actNode.target);
});
$("#addBrotherNode").on("click",function(){
var selectedNode = $("#tt").tree("getSelected");
//创建新添加的兄弟节点
var node = {
after: selectedNode.target,
data: {
id: ++id, //模拟数据id,项目中取数据库中最新的id+1
text: ""
}
}
$("#tt").tree("insert",node);
var actNode = $("#tt").tree("find",id); //模拟数据id
//alert(actNode + id);
$("#tt").tree("beginEdit",actNode.target);
});
$("#delNode").on("click",function(){
//获取选中的节点对象
var selectedNode = $("#tt").tree("getSelected");
//删除选中的节点对象
$("#tt").tree("remove",selectedNode.target);
});
});
4、获取带复选框的树
cascadeCheck |
boolean |
定义是否级联检查。 |
true |
onlyLeafCheck |
boolean |
定义是否只在叶节点前显示复选框。 |
false |
名称 |
参数 |
描述 |
getChecked |
state |
获取选中的节点。状态可用值有:'checked'、'unchecked'、'indeterminate'。如果状态未分配,则返回 'checked' 节点。 |
arrayObject.join(separator) 方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。
jQuery 遍历 - each() 方法
$(selector).each(function(index,element))
参数必需。为每个匹配元素规定运行的函数。
--index.js--
$(function(){
$("#tt").tree({
data: [
{id:0,text:"全部",children:[
{id:"1",text:"node1"},
{id: 2, text:"node2"},
{id:"3", checked:true,text:"node3"}, //复选框有效可用checked属性
{id:"4",text:"node4",children:[
{id:"5",text:"node4-1",iconCls:"icon-save"},
{id:"6",text:"node4-1"}
]}
]}
],
dnd: true, //可拖放
lines: true, //显示树线条
checkbox: true, //显示复选框
animate: true, //展开动画效果
});
$("#allchk").on("click",function(){
getCheckedArr("checked");
});
$("#unchk").on("click",function(){
getCheckedArr("unchecked");
});
$("#nochk").on("click",function(){
getCheckedArr("indeterminate");
});
});
function getCheckedArr(state){
var nodes = $("#tt").tree("getChecked",state);
var textarr = new Array();
$(nodes).each(function(i,node){
textarr[i] = node["text"];
});
alert(textarr.join(", "));
}
名称 | 类型 | 描述 | 默认值 |
---|---|---|---|
url | string | 获取远程数据的 URL 。 | null |
onAfterEdit | node | 编辑节点后触发。 |
1)前端
欢迎进入首页
--index.js--
$(function(){
var id = 0;
$("#tt").tree({
url: "getAllNodes",
dnd: true, //可拖放
lines: true, //显示树线条
checkbox: true, //显示复选框
animate: true, //展开动画效果
onAfterEdit:function(node){
//获取修改后的节点数据,通过ajax修改后台数据
console.log(node);
var nodeText = node.text;
var parentNode = $("#tt").tree("getParent",node.target);
if(parentNode != null){
$.post("addNode",{
text: nodeText,
parentId: parentNode.id
},function(data){
alert(data);
});
}else{
$.post("addNode",{
text: nodeText
},function(data){
alert(data);
});
}
},
onContextMenu: function(e,node){
//右键点击时, ajax 获取数据库中最新的id值,赋值给全局变量id;
$.post("getNewestId",{},function(data){
id = data;
});
e.preventDefault();
$(this).tree("select",node.target); //让右键点击的节点对象被选中
$("#mm").menu("show",{
left: e.pageX,
top:e.pageY
});
}
});
$("#addSonNode").on("click",function(){
var selectedNode = $("#tt").tree("getSelected");
//创建新添加的子节点
var node = {
parent: selectedNode.target,
data: [
{
id: ++id,
text: ""
}
]
}
//把子节点追加添加到树上
$("#tt").tree("append",node);
//通过新节点的id获取它的对象
var actNode = $("#tt").tree("find",id);
$("#tt").tree("beginEdit",actNode.target);
});
$("#addBrotherNode").on("click",function(){
var selectedNode = $("#tt").tree("getSelected");
//创建新添加的兄弟节点
var node = {
after: selectedNode.target,
data: {
id: ++id,
text: ""
}
}
$("#tt").tree("insert",node);
var actNode = $("#tt").tree("find",id);
$("#tt").tree("beginEdit",actNode.target);
});
$("#delNode").on("click",function(){
var selectedNode = $("#tt").tree("getSelected");
$("#tt").tree("remove",selectedNode.target);
//删除数据库中的节点对象
$.ajax({
type : "post",
url : "deleteNode",
data : {id:selectedNode.id},
datatype : "json",
success : function(data){
alert(data);
}
});
});
});
2)后端
model:
public class TreeNode {
private int id;
private String text;
private List children = new ArrayList<>();
private String parentId;
service:
@Service("treeNodeService")
public class TreeNodeServiceImpl extends BaseServiceImpl implements TreeNodeService{
@Autowired
private TreeNodeDao treeNodeDao;
/**
* 实现节点的层次结构,返回一个有层次结构的list
*/
@Override
public List getAllNodes() {
//获取所有节点:父子节点没有被区分,children属性为空
List allnodes = treeNodeDao.getAllNodes();
//重构父子结构
List listDTO = parentAndChildrenList(allnodes);
//添加全部根节点,
List list = new ArrayList<>();
TreeNode firstNode = new TreeNode();
firstNode.setId(0);
firstNode.setText("全部");
firstNode.setChildren(listDTO);
list.add(firstNode);
return list;
}
@Override
public int getNewestId() {
return treeNodeDao.getNewestId();
}
//重构父子结构, 返回一个父子分层结构的List
public List parentAndChildrenList(List allNodeList){
List listDTO = new ArrayList<>();
Map allNodeMap = new HashMap<>();
for(TreeNode node : allNodeList) {
allNodeMap.put(node.getId(), node); //放allnodes
if(node.getParentId() == null) { //.equals("0")
listDTO.add(node); //放没有父节点的根节点
}
}
for(TreeNode node : allNodeList) {
int parent_id= 0;
if(node.getParentId() != null) {
parent_id = Integer.parseInt(node.getParentId());
TreeNode parent = allNodeMap.get(parent_id); //null,null,null,3
parent.getChildren().add(node); //组装父子关系
}
}
return listDTO;
}
}
controller:
@Controller
public class TreeNodeController {
@Autowired
private TreeNodeService treeNodeService;
@ResponseBody //返回jsonString
@RequestMapping(value="/getAllNodes", method=RequestMethod.POST)
public List getAllNodes(){
List nodes = treeNodeService.getAllNodes();
return nodes;
}
@ResponseBody
@RequestMapping(value="/getNewestId", method=RequestMethod.POST)
public int getNewestId(){
return treeNodeService.getNewestId();
}
@ResponseBody
@RequestMapping(value="/addNode", method=RequestMethod.POST)
public String addNode(TreeNode node){
System.out.println(node);
treeNodeService.add(node);
return "添加success";
}
@ResponseBody
@RequestMapping(value="/deleteNode", method=RequestMethod.POST)
public String deleteNode(@RequestParam("id") int id){
System.out.println(id);
treeNodeService.delete(id);
return "删除success";
}
}
小问题:ajax回调data 有点乱码,后续解决
在springmvc.xml 中配置:
EasyUI Tree 树 到此 可实现基本操作