1、首先导入Bootstrap js、样式
<script src="/static/common/ztree/js/jquery.ztree.all.js" type="text/javascript" charset="utf-8"></script>
<script src="/static/exp/treeselect/selectree.js"></script>
2、引入的 selectree.js (这是固定代码,哪里有变动我会详细说明)
(function ($) {
"use strict";
//default selecttree
var defaultOptions = {
width: 'auto',
height: '300px',
isSimpleNode: true, //是否启用简单的节点属性(id,ame),次配置是form表单传递到后台的参数值,数据通过json传递
pIcon: '',
cIcon: '',
debug: false,
data: [{
id: '111111',
name: "父节点1",
children: [
{id: '22222', name: "子节点1"},
{id: '33333', name: "子节点2"}
]
}]
}
//define some global dom
var SelectTree = function (element, options) {
this.options = options;
this.$element = $(element);
this.$containner = $('<div></div>');
this.$ztree = $('<ul id="ztree" class="ztree"></ul>');
this.$pInput = $('<input id="nodes" type="hidden"/>'); // 这里为隐藏域数据 id='nodes',选中的数都存储在这。
}
//prototype method
SelectTree.prototype = {
constructor: SelectTree,
init: function () {
var that = this,
st = this.$element;
// style
that.$containner.css({'display': 'inline-block', 'position': 'relative'});
that.$ztree.css({
'position': 'absolute',
'z-index': 10000,
'border-radius': '3px',
'border': '1px #ccc solid',
'overflow': 'auto',
'background': '#fff',
'margin-top': '30px'
});
that.$ztree.css({'width': this.options.width || that.defaultOptions.width});
that.$ztree.css({'height': this.options.height || taht.defaultOptions.height});
// dom
if (that.$element.data('pname')) {
that.$pInput.attr('name', that.$element.data('pname'));
}
if (that.$element.attr('name')) {
that.$element.removeAttr('name');
}
that.$ztree.attr('id', 'selectTree-ztree');
that.$ztree.css('display', 'none');
that.$element.attr('readonly', 'readonly');
st.wrap(that.$containner);
st.after(that.$pInput);
st.after(that.$ztree);
//listener
that.$element.bind('click', function (e) {
that.$ztree.toggle();
});
//ztree
//listener
this.options.ztree.setting.callback = {
onCheck: function (event, treeId, treeNode) {
return that._onSelectTreeCheck(event, treeId, treeNode);
}
}
$.fn.zTree.init(that.$ztree, this.options.ztree.setting, this.options.ztree.data);
// this 这个东西啊你理解成 它是当前选中的数据 赋给 selectttt ,aaaa 这是一个function 往下看
aaaa.selectttt(this);
},
_onSelectTreeCheck: function (event, treeId, treeNode) {
var that = this;
//获得所有选中节点
var pValue = '',
text = '';
var treeObj = $.fn.zTree.getZTreeObj(that.$ztree.attr('id'));
console.log(treeObj)
if (treeObj) {
var nodes = treeObj.getCheckedNodes(true);
if (this.options.debug) {
console.log("选中的节点:");
console.log(nodes);
}
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].isParent) {
text = text + nodes[i].name + ':';
} else {
text = text + nodes[i].name + ',';
}
}
if (this.options.isSimpleNode) {
nodes = common._transformToSimpleNodes(nodes);
}
if (this.options.debug) {
console.log("提交到表单的数据结构:");
console.log(JSON.stringify(nodes));
}
// nodes数据 从这赋给隐藏域input(id='nodes')
that.$pInput.val(JSON.stringify(nodes));
text = text ? text.substr(0, text.length - 1) : '';
that.$element.val(text);
that.$element.attr('title', text);
}
}
}
var common = {
//这里组织默认参数,用户传过来的参数,ztree的一些固定参数
_getSelectTreeOptions: function (options) {
options = options ? options : {};
return {
width: options.width || defaultOptions.width,
height: options.height || defaultOptions.height,
isSimpleNode: options.isSimpleNode || defaultOptions.isSimpleNode,
pIcon: options.pIcon || defaultOptions.pIcon,
cIcon: options.cIcon || defaultOptions.cIcon,
debug: options.debug || defaultOptions.debug,
ztree: {
data: options.data || defaultOptions.data,
setting: {
check: {
enable: true,
chkStyle: "checkbox",
chkboxType: {"Y": "ps", "N": "ps"}
}
}
}
}
},
//转换ztree为简单的节点,只包含id,name
_transformToSimpleNodes: function (nodes) {
var newNodes = [];
if (nodes instanceof Array) {
for (var i = 0; i < nodes.length; i++) {
var pNode = nodes[i].getParentNode();
var node = {};
node.pId = pNode ? pNode.id : null;
node.id = nodes[i].id;
node.name = nodes[i].name;
newNodes.push(node);
}
}
return newNodes;
}
}
$.fn.selectTree = function (options) {
var data = new SelectTree(this, common._getSelectTreeOptions(options));
return data.init();
}
$.fn.selectTree.Constructor = SelectTree;
// 为什么这有一个aaaa?他的作用是用来回显你当前选中的数据,回显展示在input输入框内 ,这个是需求问题,如果不需要回显,可以忽略这段代码
var aaaa ={
selectttt:function (e) {
debugger
var that = e;
//获得所有选中节点
var pValue = '',
text = '';
var treeObj = $.fn.zTree.getZTreeObj(that.$ztree.attr('id'));
console.log(treeObj)
if (treeObj) {
var nodes = treeObj.getCheckedNodes(true);
if (that.options.debug) {
console.log("选中的节点:");
console.log(nodes);
}
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].isParent) {
text = text + nodes[i].name + ':';
} else {
text = text + nodes[i].name + ',';
}
}
if (that.options.isSimpleNode) {
nodes = common._transformToSimpleNodes(nodes);
}
if (that.options.debug) {
console.log("提交到表单的数据结构:");
console.log(JSON.stringify(nodes));
}
that.$pInput.val(JSON.stringify(nodes));
text = text ? text.substr(0, text.length - 1) : '';
that.$element.val(text);
that.$element.attr('title', text);
}
}
}
})(jQuery)
3、HTML 页面中接收数据
// 通过id = selectree, 赋值数据到div中
<script type="text/javascript">
$(function() {
var nodes = [{
id: '111111',
name: "父节点1",
children: [
{ id: '22222', name: "子节点1" },
{ id: '33333', name: "子节点2" }
]
}];
$("#selectree").selectTree({
isSimpleNode: true,
debug: true,
data: JSON.parse('${data}') // 后台查询的数据 返回为data
});
});
</script>
// input框在页面上展示数据
<div class="col-md-3">
<div class="input-group">
<span class="input-group-addon" id="zh_box">部门</span>
<input type="text" autocomplete="off"
class="input-sm form-control" id="selectree"/>
</div>
</div>
// 从Selectree.js nodes 中获取选中的数据,传到后台作为查询条件使用
var nos = $('#nodes').val(); // 通过nodes 拿到
if(nos!="") {
var nodesJson = eval('(' + $('#nodes').val() + ')');// 转换成字符串
var deptIds = '';
if (nodesJson != null && nodesJson.length > 0) { // 进行遍历存储到deptIdS中 返回到后台
for (var i = 0; i < nodesJson.length; i++) {
deptIds += nodesJson[i].id + ',';
}
}
if (nodesJson != null && nodesJson.length > 0) {
url += "&dement=" + deptIds // 传到后台 dement 作为查询条件
}
}
4、前台说完了,咱们主要来看后台代码的实现,如何返回json数据,是通过什么方式 继续往下看
后台代码
1、Controller
// 我这个是通过权限控制的:dept当前登录人有哪些部门,dement默认所有部门
List<SysDepartment> dment = iSysDepartmentService.findDepartmentTreeList(dept, dement);
// dment 查询出所部门数据
modelAndView.addObject("data", JSON.toJSONString(dment));//部门下拉框,返回页面data
2、service
List<SysDepartment> findDepartmentTreeList(DepartmentAllPo<SysDepartmentVo> dept, String dement);
3、serviceImpl
// 当前部门全查询 ,递归查询
@Override
public List<SysDepartment> findDepartmentTreeList(DepartmentAllPo<SysDepartmentVo> dept, String dement) {
List<SysDepartment> firstDepart = null;
if(dept != null){
// 遍历一级菜单
List<SysDepartment> deptList = sysDepartmentMapper.selectList(new QueryWrapper<SysDepartment>().lambda().in(SysDepartment::getId,dept.getDepts()).eq(SysDepartment::getIsDelete,0));
for (SysDepartment d:deptList) {// 遍历判断当前默认全部选中,或者选中进行查询
if(StringUtils.isBlank(dement) || StringUtils.indexOf(dement,d.getId())>-1){
d.setChecked(true); // 选中状态
}
}
// 查询一级数据
firstDepart = deptList.stream().filter(o -> StringUtils.equals(o.getParentId(),"0")).sorted(Comparator.comparing(SysDepartment::getDepartmentLevel)).collect(Collectors.toList());
for (SysDepartment o : firstDepart) {
fullChild(o,deptList);// 子级数据存储到fullChild
}
}
return firstDepart;
}
// 递归查询树形结构
private void fullChild(SysDepartment o, List<SysDepartment> deptList) {
// 查询上级部门与它父级部门的ID是否相同
List<SysDepartment> clist = deptList.stream().filter(d->StringUtils.equals(d.getParentId(),o.getId())).collect(Collectors.toList());
if(clist.isEmpty()){// 如果为空不执行任何操作
}else{// 遍历多级树形结构
o.setChirldList(clist);
for (SysDepartment c:clist) {
fullChild(c,deptList);
}
}
}
5、树形结构 以及 结构数据格式
6、json数据格式
[{"pId":null,"id":"b18163ce656911e99d9200163e2e7cd0","name":"润兴科技"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"163869757257f5050285a3330f53e514","name":"市场运营部"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"2d9f849249bd859b6e0281a54504e7cb","name":"人力行政部"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"9fa5921e170654f932865e1adfa497f7","name":"总经理办公室"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"bdf8691f38e5e1a84b50c2ad002b828c","name":"研发部"},{"pId":"bdf8691f38e5e1a84b50c2ad002b828c","id":"5eab5513531e6c25a2f1a83a14bd6dfb","name":"市局研发"},{"pId":"bdf8691f38e5e1a84b50c2ad002b828c","id":"793122a044131109b71decb2ab95321c","name":"研发中心"},{"pId":"bdf8691f38e5e1a84b50c2ad002b828c","id":"fbf41954c2fbc5b2dbf0e6021b35b6ac","name":"测试部"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"d395473b953d37a88b43fb79840e80d4","name":"物联网事业部"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"f1ec10683d539eaae6a626d8eeb634c2","name":"政府事业部"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"f9a6b6bccb77db27e9c4af26c520704c","name":"经营财务部"}]