树组件——jstree使用

本文记录的只是我自己当时的代码,每行的注释很清楚了,你自己可以做相应变通

一、使用前提:

1、下载jstree依赖包

2、相关页面引入样式["jstree/themes/default/style.css"]、js["jstree/jstree.js"]

3、页面声明一个空div 

 

二、对应的代码

1、树的初始化及相关的操作

$(function () {/*** 该树分为三层为  --项目*                  --项目文档分类*                    --分类下具体文档* 即项目在1级、文档分类在2级、文档在3级*///项目的上下文,在上面提到的页面中var contextPath = $('#contextPath').val();//树的当前操作节点级别(实际上就是树的1级或2级或其他)var beforeLevel = null;//树的目标操作节点级别var targetLevel = null;//节点拖动的目标地址位置下标var targetPosition = null;//页面中树div的domvar tree = $('#sortTree');//树的初始化tree.on('move_node.jstree', function (event, data) { //以下是节点的移动事件要触发的操作var targetId = data.parent;var sourceId = data.node.id;targetPosition = data.position;//分类移动if(beforeLevel == 2) {$.ajax({type: "POST",url: contextPath + "/docclassify/move",data: {"docClassifyId": sourceId, "helpDocSystemId": targetId, "targetPosition": targetPosition},dataType: "json",success: function (res) {layer.msg(res.message);}})} else if(beforeLevel == 3) { //文档移动
            $.ajax({type: "POST",url: contextPath + "/helpDoc/move",data: {"helpDocId": sourceId, "docClassifyId": targetId, "targetPosition": targetPosition},dataType: "json",success: function (res) {layer.msg(res.message);}})}}).jstree({"core":{ //树的事件方法回调"check_callback": function (op, node, parent) {beforeLevel = $('#'+node.id).attr("aria-level");targetLevel = $('#'+parent.id).attr("aria-level");if(beforeLevel == 3 && targetLevel == 1) { //文档不能直接移到项目下layer.msg("文档需要移动到分类");return false;} else if(beforeLevel == 3 && targetLevel == 3) { // 文档不能移到文档return false;} else if(beforeLevel == 2 && targetLevel == 2) { // 分类不能移到分类return false;} else if(beforeLevel == 2 && targetLevel == 3) { // 分类不能移到文档return false;} else if(beforeLevel == 1 ) { //我这边遇到的问题就是第1级节点,也就是所有项目节点不能拖动,所以我在下面把项目的排序变为右键点击出现上移下移菜单来处理return false;}},data: function (obj, callback) { //初始化树的第1级数据,即所有有序排列的项目var jsonStr = "[]";var jsonArray = eval(jsonStr);$.ajax({type: "GET",url: contextPath + "/helpdocsystem/initTree",dataType: "json",success: function (res) {var arrays = res.result;for (var i = 0; i < arrays.length; i++) {var arr = {"id": arrays[i].id,"parent": "#","text": arrays[i].name,"icon": "icon iconfont icon-report-type","index": arrays[i].index //数据库中的数据排序字段
                            }jsonArray.push(arr);}callback.call(this, jsonArray);}});}},"contexmenu": { //右键菜单"item": function (node) {var temp = {"上移": {"lable": "上移","action": function () {$.ajax({type: "POST",url: contextPath + "/helpdocsystem/order",data: {"docSystemId": node.id, "moveFlag": 1},dataType: "json",success: function (res) {layer.msg(res.message);//刷新树tree.jstree(true).refresh();}})}},"下移": {"lable": "下移","action": function () {$.ajax({type: "POST",url: contextPath + "/helpdocsystem/order",data: {"docSystemId": node.id, "moveFlag": 0},dataType: "json",success: function (res) {layer.msg(res.message);//刷新树tree.jstree(true).refresh();}})}}};var menu = {};var level = $('#'+node.id).attr("aria-level");//此处限制节点为1级时才允许出现右键菜单(level == 1) && (menu = temp);return menu;}},"plugins": ["sort", "contextmenu", "dnd", "state"], //依次为排序、右键菜单、拖拽移动、状态组件"sort": function (a, b) {return a['index'] - b['index'];}}).bind("select_node.jstree", function (event, data) {var instant = data.instance;var selectedNode = instant.get_node(data.selected);var level = $('#'+selectNode.id).attr("aria-level");if(parseInt(level) == 2) { //点击2级节点,加载分类下的文档
            loadHelpDoc(instant, selectedNode);}if(parseInt(level) == 1) { //点击1级节点,加载项目下的文档分类
            loadDocClassify(instant, selectedNode);}});/*** 加载分类下文档* @param instant* @param selectNode*/function loadHelpDoc(instant, selectedNode) {$.ajax({type: "GET",url: contextPath + "/helpdoc/initTree",data: {"docClassifyId": selectedNode.id},dataType: "json",success: function (res) {var data = res.result;if(null != data && data.length > 0) {selectedNode.children = [];$.each(data, function (i, item) {var obj = {"id": item.id,"parent": item.parentId,"text": item.name,"icon": "icon iconfont icon-over-task"};instant.create_node(selectedNode, obj, "last"); //创建子节点if($("#"+selectedNode.id).hasClass("jstree-open")){ //打开关闭节点
                            instant.close_node(selectedNode);} else if($("#"+selectedNode.id).hasClass("jstree-closed")) {instant.open_node(selectedNode);}});}}})}/*** 加载项目下文档分类* @param instant* @param selectNode*/function loadDocClassify(instant, selectedNode) {$.ajax({type: "GET",url: contextPath + "/docclassify/initTree",data: {"helpDocSystemId": selectedNode.id},dataType: "json",success: function (res) {var data = res.result;if(null != data && data.length > 0) {selectedNode.children = [];$.each(data, function (i, item) {var obj = {"id": item.id,"parent": item.parentId,"text": item.name,"icon": "icon iconfont icon-report-type"};instant.create_node(selectedNode, obj, "last"); //创建子节点if($("#"+selectedNode.id).hasClass("jstree-open")){ //打开关闭节点
                            instant.close_node(selectedNode);} else if($("#"+selectedNode.id).hasClass("jstree-closed")) {instant.open_node(selectedNode);}});}}});}
});

还是贴一下一个接口排序的例子,当时写的确实有点烦,以免以后会忘;initTree相关接口就是关联查询出的有序集合,拼接成需要格式数据即可。

在这把排序可以理解成往一个有序的list中的某个位置插入元素,假如插入元素a,i作为目标位置,那么a元素的实际orderNo为list(i-1).getOrderNo() + 1,那么i位置以下的节点orderNo依次为i+1

需要注意的地方:1、目标位置为0时做了处理,a元素实际位置从1开始;2、目标元素的所有下级元素orderNo增加时需要排除目标元素

1、/docclassify/move

@PostMapping("/docclassify/move")public String move(DocClassifyVo docClassifyVo, int targetPosition, Model model) {try {if (StringUtils.isNotEmpty(docClassifyVo.getHelpDocSystemId)) {this.docClassifyManager.move(docClassifyVo, targetPosition);model.addAttribute("message", "移动成功");}} catch (Exception e) {e.printStackTrace();model.addAttribute("message", "移动失败");}return "json";}
public void move(DocClassifyVo docClassifyVo, int targetPosition) {DocClassify docClassify = this.docClassifyService.findById(docClassifyVo.getDocClassifyId());HelpDocSystem helpDocSystem = new HelpDocSystem();helpDocSystem.setHelpDocSystemId(docClassifyVo.getHelpDocSystemId());docClassify.setHelpDocSystem(helpDocSystem);
docClassify.setOrderNo(this.docClassifyService.getMaxOrderByHelpDocSystemId(docClassifyVo.getHelpDocSystemId) + 1);
this.docClassifyService.update(docClassify);//按orderNo升序查询该项目下的所有分类DocClassifyQo docClassifyQo = new DocClassifyQo();docClassifyQo.setHelpDocSystemId(docClassifyVo.getHelpDocSystemId());List docClassifies = this.docClassifyService.queryPageList(docClassifyQo);if(CollectionUtils.isNotEmpty(docClassifies)) {for (int i = 0; i < docClassifies.size(); i++) {if(docClassifies.get(i).getDocClassifyId().equals(docClassifyVo.getDocClassifyId())) {List batchUpdateList = new ArrayList<>();//目标节点上级DocClassify upDocClassify = null;//目标节点DocClassify targetDocClassify = docClassifies.get(i);int realTargetPosition = 0;int tempTargetPosition = 0;if(targetPosition != 0) {upDocClassify = docClassifies.get(targetPosition - 1);tempTargetPosition = upDocClassify.getOrderNo() + 1;realTargetPosition = upDocClassify.getOrderNo() + 1;targetDocClassify.setOrderNo(realTargetPosition);} else {upDocClassify = docClassifies.get(targetPosition);//移动到第一个时从1开始计算tempTargetPosition = 1;realTargetPosition = 1;targetDocClassify.setOrderNo(realTargetPosition);}this.docClassifyService.update(targetDocClassify);//目标节点所有下级List afterDocClassifies = this.docClassifyService.queryPageList(docClassifyQo);for (int j = targetPosition; j < afterDocClassifies.size(); j++) {if(!afterDocClassifies.get(i).getDocClassifyId().equals(docClassifyVo.getDocClassifyId())) {DocClassify downDocClassify = afterDocClassifies.get(j);downDocClassify.setOrderNo(++tempTargetPosition);batchUpdateList.add(downDocClassify);}}batchUpdateList.add(targetDocClassify);this.docClassifyService.batchUpdate(batchUpdateList);break;}}}//重新设置orderNo,避免排序次数多了后orderNo不连续List beforeDocClassifies = this.docClassifyService.queryPageList(docClassifyQo);List batchUpdateList = new ArrayList<>();if(CollectionUtils.isNotEmpty(beforeDocClassifies)) {for (int i = targetPosition; i < beforeDocClassifies.size(); i++) {DocClassify sortDocClassify = beforeDocClassifies.get(i);downDocClassify.setOrderNo(i+1);batchUpdateList.add(sortDocClassify);}this.docClassifyService.batchUpdate(batchUpdateList);}}

2、/helpdocsystem/order

关于项目排序由于我们采用的是右键上移下移的操作,所以排序的算法也就没那么复杂,上移时moveFlag为1,下移时moveFlag为0。上移时取移动节点的前一个节点(i-1)的orderNo,下移时orderNo则为(i+1)
,互相交换orderNo更新即可
public void order(String docSystemId, int moveFlag) {//按orderNo升序查询该所有项目HelpDocSystemQo helpDocSystemQo = new HelpDocSystemQo();PageList helpDocSystems = this.helpDocSystemService.queryPageList(helpDocSystemQo);if(CollectionUtils.isNotEmpty(helpDocSystems)) {List batchUpdateList = new ArrayList<>();for (int i = 0; i < helpDocSystems.size(); i++) {if(helpDocSystems.get(i).getHelpDocSystemId().equals(docSystemId)) {if(i == 0 && moveFlag == 1) {throw new RuntimeException("到顶了,不能再移动了");}if(i == helpDocSystems.size() - 1 && moveFlag == 0) {throw new RuntimeException("到底了,不能再移动了");}HelpDocSystem sourceHelpDocSystem = helpDocSystems.get(i);HelpDocSystem targetHelpDocSystem = null;if(moveFlag == 1) {targetHelpDocSystem = helpDocSystems.get(i - 1);} else {targetHelpDocSystem = helpDocSystems.get(i + 1);}int sourceOrderNo = sourceHelpDocSystem.getOrderNo();int targetOrderNo = targetHelpDocSystem.getOrderNo();sourceHelpDocSystem.setOrderNo(targetOrderNo);targetHelpDocSystem.setOrderNo(sourceOrderNo);batchUpdateList.add(sourceHelpDocSystem);batchUpdateList.add(targetHelpDocSystem);this.helpDocSystemService.batchUpdate(batchUpdateList);}}}}

 

转载于:https://www.cnblogs.com/guxiong/p/10837570.html


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部