最近在做项目使用了关于jsTree的插件,趁有时间就写一篇总结。
这是jsTree插件的使用文档地址:https://www.jstree.com/。
文档里写得清楚了,这是就不多说。现是对自己写的代码做简单的记录,如有什么不足之处之处欢迎指出。
实现的效果:
html:
<div id="jsTree"></div>
js:
$(function(){
$('#jsTree').jstree({
'core':{
'check_callback': true,
'themes' : {'dots' : false},//去掉连接线
'data': function(obj, cb){
var jsonStr = '[]';
var jsonArray = eval('('+jsonStr+')');
$.ajax({
url: url,
type: 'post',
dataType: 'json',
async: false,
success: function(data){
for(var i=0; i<data.length; i++){
var arr = {
"id": data[i].id,
"parent": data[i].parent,
"text": data[i].name,
//是否展开,可选 默认为false
"state": {"opened": true}
}
jsonArray.push(arr);
}
}
});
cb.call(this, jsonArray);
}
},
'plugins': ['types', 'dnd', 'contextmenu'],
//右击时弹出选择菜单
'contextmenu':{
select_node: false,
show_at_node: true,
items:{
'add':{
//一级菜单
'label': '新建',
'icon' : 'fa fa-plus-square-o',
//二级菜单
'submenu':{
'addLevel':{
'lable': '本级',
'icon' : 'fa fa-plus-square-o',
'action': function(){
//获取节点信息(json)
var node = jQuery.jstree.reference(data.reference);
var clickedNode = node.get_node(data.reference);
}
},
'addDown':{
'lable': '下级',
'icon' : 'fa fa-plus-square-o',
'action': function(){
//获取节点信息(json)
var node = jQuery.jstree.reference(data.reference);
var clickedNode = node.get_node(data.reference);
}
}
}
},
'update':{
'label': '修改',
'icon' : 'fa fa-edit',
'action': function(data){
var node = jQuery.jstree.reference(data.reference);
var clickedNode = node.get_node(data.reference);
}
},
'del':{
'label': '删除',
'icon' : 'fa fa-trash-o',
'action': function(data){
var node = jQuery.jstree.reference(data.reference);
var clickedNode = node.get_node(data.reference);
}
}
}
},
'types': {
'default':{'icon': 'fa fa-folder'},
'icon-floor': {'icon': 'fa fa-file'}
}
})
//点击时触发
.on('changed.jstree', function(e, obj){
//获取节点信息(json)
var nodes = obj.node;
})
//加载完成后触发
.on('load_node.jstree', function(e, obj){
var nodes = obj.node;
})
})
这是我的源码:
$(function(){
var basePath = 'http://localhost:8080/gym';
var addMatchOrganByIdUrl = basePath + '/admin/addmatchorganbyid';//添加
var updateMatchOrganByIdUrl = basePath + '/admin/updatematchorganbyid';//修改
var deleteMatchOrganByIdUrl = basePath + '/admin/deletematchorganbyid';//删除(一条)
var deleteMatchOrganByIdsUrl = basePath + '/admin/deletematchorganbyids';//删除(list)
var getMatchOrganListUrl = basePath + '/admin/getmatchorganlist';
var getMatchOrganByIdUrl = basePath + '/admin/getmatchorganbyid';
var getMatchOrganByNodeUrl = basePath + '/admin/getmatchorganbynode';
$('input[type="file"]' ).prettyFile();//加载上传图片按钮样式
$('#organJstree').jstree({
'core':{
'check_callback': true,
'themes' : {'dots' : false},//去掉连接线
'data': function(obj, cb){
var jsonStr = '[]';
var jsonArray = eval('('+jsonStr+')');
$.ajax({
url: getMatchOrganListUrl,
type: 'post',
dataType: 'json',
async: false,
success: function(data){
for(var i=0; i<data.length; i++){
var arr = {
"id": data[i].organId,
"parent": data[i].parentId,
"text": data[i].organName
//是否展开,可选 默认为false
//"state": {"opened": true}
}
jsonArray.push(arr);
}
}
});
cb.call(this, jsonArray);
}
},
'plugins': ['types', 'dnd', 'contextmenu','themes'],
//右击时弹出选择菜单
'contextmenu':{
select_node: false,
show_at_node: true,
items:{
'add':{
//一级菜单
'label': '新建',
'icon' : 'fa fa-plus-square-o',
//二级菜单
'submenu':{
'addLevel':{
'label': '本级',
'icon' : 'fa fa-plus-square-o',
'action':function(data){
//获取节点信息(json)
var nodes = jQuery.jstree.reference(data.reference);
var node = nodes.get_node(data.reference);
var id = node.parent;
var parentId = node.parent == '#'? '#': node.parents[1];
//var parentId = node.parent == '#'? '#': node.parents[1];
getOrganByParentId(id, parentId);
}
},
'addDown':{
'label': '下级',
'icon' : 'fa fa-plus-square-o',
'action':function(data){
//获取节点信息(json)
var nodes = jQuery.jstree.reference(data.reference);
var node = nodes.get_node(data.reference);
var id = node.id;
var parentId = node.parent;
//var parentId = node.parent;
getOrganByParentId(id, parentId);
}
}
}
},
'update':{
'label': '修改',
'icon' : 'fa fa-edit',
'action': function(data){
var node = jQuery.jstree.reference(data.reference);
var clickedNode = node.get_node(data.reference);
//隐藏添加按钮 显示修改按钮
$('#submitOrgan').css('display', 'none');
$('#updateOrgan').css('display', 'inline');
//获取节点信息 obj.node
getOrganById(clickedNode);
}
},
'del':{
'label': '删除',
'icon' : 'fa fa-trash-o',
'action': function(data){
var nodes = jQuery.jstree.reference(data.reference);
var node = nodes.get_node(data.reference);
//判断是否是最底层
var isChildren = node.children_d == ''? true: false;
var id;
alert(isChildren);
if(isChildren)
id = node.id;
else
id = node.id +','+ node.children_d;
swal({
title: "确定删除吗?",
text: "将无法恢复数据!",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
cancelButtonText: "取消",
confirmButtonText: "确定",
closeOnConfirm: false
},function(){
$.post(deleteMatchOrganUrl, {id: id, isChildren: isChildren}, function(data){
if(data.success)
swal("删除!", "数据已成功删除!", "success");
else
swal("哎呦...", "出错了!", "error");
refreshTree();
})
})
}
}
}
},
'types': {
'default':{'icon': 'fa fa-folder'},
'icon-floor': {'icon': 'fa fa-file-code-o'}
}
})
//点击时触发
.on('changed.jstree', function(e, obj){
//获取节点信息 obj.node
getOrganById(obj.node);
})
//加载完成后触发
.on('load_node.jstree', function(e, obj){
var nodes = obj.node;
var children = obj.node.children_d;
var parArr = new Array(children.length);
for(var i in children){
parArr[i] = obj.instance.get_node(children[i]).parent;
}
var newArr = reArr(parArr, children);
for(var i in newArr){
obj.instance.set_type(obj.instance.get_node(newArr[i]), 'icon-floor');
}
})
//刷新Tree
$('#refreshOrganTree').click(function(){
refreshTree();
})
//提交表单
$('#submitOrgan').click(function(){
var organImg = $('#organImage')[0].files[0];
if(organImg == null){
throw swal("警告", "请选择上传图片", "error");
}
var formData = getMatchOrganFrom();
$.ajax({
url: addMatchOrganByIdUrl,
type: 'post',
data: formData,
async: false,
cache: false,
contentType: false,
processData: false,
success: function(data){
if(data.success)
swal("添加成功!", "", "success");
else{
alert(data.errMsg);
swal("哎呦...", data.errMsg, "error");
}
refreshTree();
}
})
})
//更新表单
$('#updateOrgan').click(function(){
var formData = getMatchOrganFrom();
$.ajax({
url: updateMatchOrganByIdUrl,
type: 'post',
data: formData,
async: false,
cache: false,
contentType: false,
processData: false,
success: function(data){
if(data.success)
swal("修改成功!", "", "success");
else
swal("哎呦...", "出错了!", "error");
refreshTree();
}
})
})
//根据parentId获取数据
function getOrganByParentId(id, parentId){
$('#updateOrgan').css('display','none');
$('#submitOrgan').css('display','inline');
$.post(getMatchOrganByNodeUrl, {parentId: parentId}, function(data){
var html = '';
$.each(data.organ, function(list, key){
if(id == key.organId)
html += '<option selected="selected" value="'+key.organId+'">'+key.organName+'</option>';
else
html += '<option value="'+key.organId+'">'+key.organName+'</option>';
})
$('#parentId').html(html);
})
emptyFrom();
}
//点击或编辑时根据id获取数据
function getOrganById(json){
//隐藏添加按钮 显示修改按钮
$('#submitOrgan').css('display', 'none');
$('#updateOrgan').css('display', 'inline');
if(typeof(json) != 'undefined'){
//获取id
var id = json.id;
//判断是否是根节点
var isRoot = json.parent == '#' ? true : false;
var parentId;
if(!isRoot)
parentId = json.parents[1];
$.post(getMatchOrganByIdUrl, {id: id, parentId: parentId}, function(data){
if(isRoot){
$('#parentId').html('<option selected="selected" value="-1"></option>');
}else{
$('#parentId').removeAttr('disabled');
if(data.organType != ''){
var html = '';
$.each(data.organType, function(list, key){
if(json.parent == key.organId)
html += '<option selected="selected" value="'+key.organId+'">'+key.organName+'</option>';
else
html += '<option value="'+key.organId+'">'+key.organName+'</option>';
})
$('#parentId').html(html);
}
}
setMatchOrganFrom(data.organ);
})
}else{
emptyFrom();
}
}
//获取表单数据
function getMatchOrganFrom(){
var organ = {};
var formData = new FormData();
var parentId = $('#parentId option:selected').val();
var organImg = $('#organImage')[0].files[0];
organ.organId = $('#organId').val();
organ.organName = $('#organName').val();
organ.organMgr = $('#organMgr').val();
organ.organPhone = $('#organPhone').val();
organ.organAddr = $('#organAddr').val();
organ.remarks = $('#remarks').val();
organ.parentId = parentId == -1 ? '#': parentId;
if(organImg != null)
formData.append('organImg', organImg);
formData.append('organStr', JSON.stringify(organ));
return formData;
}
//数组去重并返回节点最底层的数组
function reArr(arr, nodeArr){
var newArr = [];
for(var i=0; i<arr.length; i++){
if(newArr.indexOf(arr[i]) == -1)
newArr.push(arr[i]);
}
//concat() 方法用于连接两个或多个数组
return newArr.concat(nodeArr).filter(function(v, i, arr){
return arr.indexOf(v) === arr.lastIndexOf(v);
})
}
//设置表单数据
function setMatchOrganFrom(json){
$('#organId').val(json.organId);
$('#organName').val(json.organName);
$('#organMgr').val(json.organMgr);
$('#organPhone').val(json.organPhone);
$('#organAddr').val(json.organAddr);
$('#remarks').val(json.remarks);
}
//清空
function emptyFrom(){
$('#organId').val('');
$('#organName').val('');
$('#organMgr').val('');
$('#organPhone').val('');
$('#organAddr').val('');
$('#remarks').val('');
}
//刷新
function refreshTree(){
$('#organJstree').jstree(true).refresh();
}
})
上个方法是通过后台传回的JSON数据,使用JS重新生成的JSON,下面这方法是在后台生成jsTree要的JSON数据类型(id,parent,text),只传回这些字段的数据,其他的不要(需要引入Gson.jar)。
Controller:
@RequestMapping(value="/getmatchitemjstree", method=RequestMethod.POST)
@ResponseBody
public Map<String, Object> getMatchItemJstree(){
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setFieldNamingStrategy(new FieldNamingStrategy){
@Override
public String translateName(Field f){
if(f.getName().equals("itemId"))
return "id";
if(f.getName().equals("parentId"))
return "parent";
if(f.getName().equals("itemName"))
return "text";
return f.getName();
}
}
Gson gson = gsonBuilder.serializeNulls().create();
String itemStr = gson.toJson(matchItemService.getMatchItemJstree());
Map<String, Object> modelMap = new hashMap<>();
if("".equals(itemStr)){
modelMap.put("success", true);
modelMap.put("item", itemStr);
}else{
modelMap.put("success", false);
modelMap.put("errMsg", "获取数据为空");
}
}