使用JS创建一个 ‘tree’,自定义 contextmenu


前言

开发项目难免碰到像权限管理,组织架构之类的层级显示结构(也就是常说的’Tree’ )。使用树形结构显示出来的页面即美观还比普通的页面表格展示好分辨出来父级和子级,说白了也就是一目了然。先看效果:
在这里插入图片描述

一、jsTree是什么?

jsTree 是一个jquery 插件, 提供交互式树.它是完全免费的,开源的,并根据MIT许可进行分发。jsTree易于扩展,可定义和配置,它支持HTML和JSON数据源以及AJAX加载。

下载JsTree

二、使用步骤

1.包括一个jsTree主题

<link rel="stylesheet" href="dist/themes/default/style.min.css" />

2.设置一个容器

这是您希望树出现的元素,一个<div>就足够了。<ul>由于没有配置其他数据源(例如JSON),因此此示例具有嵌套。
 <div id="jstree_demo_div"></div>

3.包含jQuery

jsTree 在您的网页中需要1.9.0或更高版本。您可以使用CDN版本或包含本地副本。
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>

3.包含jsTree

DOM准备就绪后,您可以开始创建jstree实例。
<script src="dist/jstree.min.js"></script>

4.监听事件

当用户(或您)与树交互时发生某些更改时,jsTree使用事件通知您。因此,绑定到jstree事件就像绑定到单击一样容易。有一个事件的名单,他们的API文档中提供的信息和。

$('#jstree_demo_div').on("changed.jstree", function (e, data) {
  console.log(data.selected);
});

传送门:更多API点击此处查看文档

三、使用示例

以上是官方给出的使用步骤,也是操作jsTree的必须步骤,下面是个人示例


<head>
    <meta charset="utf-8">
    <title>jsTree test</title>
    <!-- 2 包含主题模板CSS文件 -->
    <link rel="stylesheet" href="/assets/js/jstree/dist/themes/default/style.min.css"/>
</head>
<body>

<button id="open_all">展开全部</button>
<button id="close_all">关闭全部</button>
<!-- 3 设置容器元素 -->
<div id="jstreelist">
<!--    后端返回数据格式示例
    id=>1,
    name=>'aa'
    childlist=>[
            [
                    id=>1,
                    name=>'aa'
                    childlist=>[]
            ]
     ]
-->
    <!-- 在本例中,树是从内联HTML填充的 -->
    <ul>
        <li id="{$treeArr.id}">{$treeArr.name}
            <ul>
                {volist name="treeArr['childlist']" id="vo"}
                <li id="{$vo.id}">{$vo.name}
                    {notempty name="$vo.childlist"}
                    <ul>
                        {foreach $vo['childlist'] as $va}
                        <li id="{$va.id}">{$va.name}
                            {notempty name="$vo.childlist"}
                            <ul>
                                {foreach $va['childlist'] as $vb}
                                <li id="{$vb.id}">{$vb.name}</li>
                                {/foreach}
                            </ul>
                            {/notempty}
                        </li>
                        {/foreach}
                    </ul>
                    {/notempty}
                </li>
                {/volist}
            </ul>
    </ul>

</div>



<!-- 4 包含jQuery库 -->
<script src="/assets/js/jquery-3.0.0.min.js"></script>
<!-- 5 包括缩小的jstree源文件 -->
<script src="/assets/js/jstree/dist/jstree.min.js"></script>
<script>

    $(function () {
        var $jstree = $.jstree;
        var a = $('#jstreelist');
        a.jstree({
            "core": {
                "check_callback": true,
            },
            "types": {
                "default": {
                    "icon": "fa fa-user"  //设置ICON
                },
            },
            "plugins": ["contextmenu", "dnd", "types"],
            "contextmenu": {   //自定义
                items: function (o, cb) {
                    //因为这里我们之后需要定义多个项,所以通过对象的方式返回
                    var actions = {};
                    //添加一个"新增"右键菜单
                    actions.create = {
                        "label": "新增",  //Create这一项的名称 可自定义
                        "action": function (data) {  //点击Create这一项触发该方法,这理还是蛮有用的
                            var inst = $jstree.reference(data.reference),
                                obj = inst.get_node(data.reference);//获得当前节点,可以拿到当前节点所有属性
                            //新加节点,以下三行代码注释掉就不会添加节点
                            inst.create_node(obj, {}, "last", function (new_node) {
                                inst.edit(new_node, '', function (node) {
                                    //判断输入节点是否有值,防止添加空数据
                                    console.log(node)
                                    layer.open({
                                        type: 2,
                                        title: '新增[' + new_node.text + ']的子组',
                                        shadeClose: true,
                                        area: ['200px', '150px'],
                                        content: 'create_node?name=' + node.text + '&parent_id=' + node.parent + '&id=' + node.id//iframe的url
                                    });
                                });
                            });
                        }
                    },
                        actions.del = {
                            "label": "删除",
                            "action": function (data) {
                                var inst = $jstree.reference(data.reference),
                                    obj = inst.get_node(data.reference);//获得当前节点,可以拿到当前节点所有属性
                                //判断下面是否还有层级
                                if (obj.children.length > 0) {
                                    alert('下面还有子节点不可删除');
                                    return;
                                }
                                console.log(obj)
                                if (confirm("确认删除此节点吗?删除后将不可恢复")) {
                                    $.ajax({
                                        type: "post",
                                        url: "delete_node",
                                        data: {
                                            name: obj.text
                                        },
                                        async: false,
                                        success: function (data) {
                                            if (data.status == 1) {
                                                alert(data.msg);
                                                inst.delete_node(obj);
                                            } else {
                                                alert(data.msg);
                                            }
                                        }
                                    });
                                }

                            }
                        },
                        actions.rename = {
                            "label": "重命名",  //Create这一项的名称 可自定义
                            "action": function (data) {  //点击Create这一项触发该方法,这理还是蛮有用的
                                var inst = $jstree.reference(data.reference),
                                    obj = inst.get_node(data.reference);//获得当前节点,可以拿到当前节点所有属性
                                //新加节点,以下三行代码注释掉就不会添加节点
                                inst.edit(obj, '', function (node) {
                                    console.log(node)
                                    $.ajax({
                                        type: "post",
                                        url: "rename_node",
                                        data: {
                                            id: node.id,
                                            name: node.text
                                        },
                                        async: false,
                                        success: function (data) {
                                            if (data.status == 1) {
                                                alert(data.msg);
                                            } else {
                                                alert(data.msg);
                                            }
                                        }
                                    });
                                });
                            }
                        }
                    return actions;//返回右键菜单项
                }
            }
        })


        $('#jstreelist').on("changed.jstree", function (e, data) {
            console.log(data.selected);
        });

        //节点移动时触发
        $('#jstreelist').on('move_node.jstree', function (e, data) {
            console.info(data);
            $.post("save_parent",
                {
                    id: data.node.id,
                    parent: data.parent,
                },
                function (data, status) {
                    alert(data);
                }, 'json');
        })

        //默认展开全部节点
        a.jstree().open_all();

        //展开
        $("#open_all").click(function () {
            a.jstree("open_all");
        })

        //关闭
        $("#close_all").click(function () {
            a.jstree("close_all");
        })


    });

效果预览:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃橘子的汤圆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值