JsTree3 基本用法 – checkbox和动态加载

jsTree是jQuery的插件,具有交互性的树。

它是免费的、开源的、容易扩展、主题化和可配置的,它支持HTML、JSON数据源和数据加载。

HTML:

 1<div class="row">
 2    <div class="col-xs-3"></div>
 3        <div class="box box-primary">
 4            <div class="box-header with-border">
 5                <i class="fa fa-gears"></i><h3 class="box-title">权限选择实验</h3>
 6            </div>
 7            <div class="box-body table-responsive">
 8                <div id="mytree">
 9                </div>
10                <button class="btn btn-primary" type="button" onclick="submitForm()">提交</button>
11            </div>
12
13            <div class="box-header with-border">
14                <i class="fa fa-gears"></i><h3 class="box-title">动态加载实验</h3>
15            </div>
16            <div class="box-body table-responsive">
17                <div id="mytree2">
18                </div>
19                <button type="button" class="btn btn-success btn-sm" onclick="demo_create();">添加子节点</button>
20            </div>
21
22        </div>
23    </div>
24</div>

使用场景一:checkbox (如:权限设置)

需求1:加载所有权限树形清单
需求2:加载完后动态勾选已有权限
需求3:提交勾选的权限列表

 1// 选择实验
 2$('#mytree').jstree({
 3    "plugins": ["sort", "checkbox", "state"], //"wholerow",
 4    "check_callback" : true,
 5    "checkbox": {
 6        //"keep_selected_style": false//是否默认选中
 7        //"three_state": false//父子级别级联选择
 8    },
 9    "core" : {
10        "themes" : {
11            "responsive": false,
12            "stripes" : true
13            // "icons" : true,
14            // "dots" : false
15        },
16        'check_callback': true,
17        'data': [
18            { "id" : "1", "parent" : "#", "text" : "test1 1"},
19            { "id" : "2", "parent" : "#", "text" : "test2 1" },
20            { "id" : "3", "parent" : "#", "text" : "test3 1" },
21            { "id" : "21", "parent" : "2", "text" : "test21 21" },
22            { "id" : "22", "parent" : "2", "text" : "test22 22" },
23            { "id" : "11", "parent" : "1", "text" : "test11 11" },
24            { "id" : "12", "parent" : "1", "text" : "test12 11" },
25            { "id" : "31", "parent" : "3", "text" : "test31 11" },
26            { "id" : "311", "parent" : "31", "text" : "test311 11" },
27            { "id" : "312", "parent" : "31", "text" : "test312 11" }
28        ]
29
30    },
31    "types": {
32        "default": {
33            "icon": "fa fa-folder icon-state-warning icon-lg"
34        },
35        "file": {
36            "icon": "fa fa-file icon-state-warning icon-lg"
37        }
38    },
39    'state': "closed"
40});
41
42$('#mytree').on("loaded.jstree", function (event, jstree) {   
43    let _inst = jstree.instance;
44    let $jstree = $('#mytree').jstree(true);
45    let data = _inst._model.data;
46
47    let ids = ["1", "3", "31", "312"];
48
49    // 根据json参数勾选默认
50    for(let key in data) {
51        if('#' === key) {
52            continue;
53        }
54        if ($.inArray(key, ids) != -1) {
55            $jstree.check_node(key);
56        }
57    }
58
59    $jstree.jstree('close_all');
60});
 1/**
 2 * 获取所有选择的数据
 3 * @param treeId
 4 */
 5function getCheckTreeIds(treeId) {
 6    // 方法一
 7    // 打开所有的节点,不然获取不到子节点数据
 8    var that = $("#" + treeId);
 9    that.jstree('open_all');
10
11    var ids = [];
12    var treeNode = that.jstree(true).get_selected(true);
13
14    for (var i = 0; i < treeNode.length; i++) {
15
16        var node = treeNode[i];
17        var nodeId = node.original.id;
18
19        // 判断是否重复
20        if ($.inArray(nodeId, ids) == -1) {
21            ids.push(nodeId);
22        }
23
24        for (var j = 0; j < node.parents.length; j++) {
25            // 判断是否重复
26            var parentId = node.parents[j];
27            if (parentId != "#" && $.inArray(parentId, ids) == -1) {
28                ids.push(parentId);
29            }
30        }
31    }
32    that.jstree('close_all');
33    return ids;
34
35    // 方法二
36    // var ids = [];
37    // var $jstree = $('#mytree').jstree(true);
38    // var data = $jstree._model.data;
39    // for(key in data) {
40    //     if($jstree.is_checked(key)) {
41    //         //alert(data[key].li_attr._id);
42    //         ids.push(data[key].id);
43    //     }
44    // }
45}
46
47// 提交表单
48function submitForm(){
49    var userTreeIds = getCheckTreeIds("mytree");
50    bootbox.alert(userTreeIds);
51    $.ajax({
52        type :"post",
53        url : "<?= Url::to(['edit', 'id' => $model->id])?>",
54        dataType : "json",
55        data : {
56            id : '<?= $model['id']?>',
57            pid : $("#authrole-pid").val(),
58            sort : $("#authrole-sort").val(),
59            title : $("#authrole-title").val(),
60            userTreeIds : userTreeIds
61        },
62        success : function(data){
63            if (parseInt(data.code) === 200) {
64                window.location = "<?= Url::to(['index'])?>";
65            } else {
66                error(data.message);
67            }
68        }
69    });
70}

使用场景二:动态加载****(如:文件展示、部门展示等)

需求1:展开时动态加载节点
需求2:有子节点的节点上显示 + 号
需求3:异步加载
需求4:节点支持超链接

 1//动态加载实验
 2$('#mytree2').jstree({
 3    "plugins" : ["sort", "state"],
 4    "core" : {
 5        //"animation" : 0,
 6        "check_callback" : true,
 7        "themes" : {
 8            "responsive": false,
 9            "stripes" : true
10        },
11        //"force_text" : true,
12        "data": {
13            "url" : "<?=Url::toRoute('/article-cat/tree00');?>",
14            // 'data' : function (node) {
15            //     return { 'id' : node.id };
16            // },
17            // 'success': function(data) {
18            //     //console.info(data);
19            //     if(data) {
20            //         callback.call(this, data);
21            //     }else{
22            //         $("#jstree").html("暂无数据!");
23            //     }
24            // }
25            'dataType' : 'json'
26        },
27        "state": "closed"
28    },
29});
 1$('#mytree2').on("open_node.jstree", function (e, data) {
 2//$('#mytree2').on("select_node.jstree", function (e, data) {
 3    /*//添加节点
 4    var node = [{id:"111",parent:"2",text:"1111"},{id:"222",parent:"2",text:"2222"}];
 5    var selNodeId = data.node.id;
 6    var parentId = data.node.parent;
 7    for(var i=0;i<node.length;i++){
 8        $("#mytree2").jstree("create_node", selNodeId,  node[i], "last", false, true);
 9    }*/
10
11    //适配 open_node.jstree 和 select_node.jstree
12    var selNode = (typeof(data.selected) == "undefined") ? data.node : data.selected;
13
14    var inst = data.instance;
15    var selectedNode = inst.get_node(selNode);
16    var level = $("#"+selectedNode.id).attr("aria-level");
17
18    if(parseInt(level) <= 4){
19        loadNodes(inst, selectedNode);
20    }
21});
22
23//添加节点
24function demo_create() {
25    var ref = $('#mytree2').jstree(true),
26        sel = ref.get_selected();
27    if(!sel.length) { return false; }
28    sel = sel[0];
29    sel = ref.create_node(sel, {"type":"file"});
30    if(sel) {
31        ref.edit(sel);
32    }
33};
34
35//动态异步加载节点
36function loadNodes(inst, selectedNode) {
37    //inst.open_node(selectedNode);
38    //alert(selectedNode.text);
39    $.ajax({
40        url: "<?=Url::toRoute('/article-cat/tree01');?>",
41        data : {'pid': selectedNode.id},
42        dataType: "json",
43        type: "POST",
44        success: function (data) {
45            if (data) {
46                //<strong>json 中添加此语句可以支持超链接:   "a_attr":{"href":"xxxx"}</strong>
47                //data = [{"id":"6","text":"aaaaa","icon":"fa fa-file", "a_attr":{"href":"<!--?=Url::toRoute(' /article/index')?-->"}},
48                    //    {"id":"5","text":"bbbbb","icon":"fa fa-file", "children":[{"text":"-","icon":"fa fa-folder"}]}];
49                selectedNode.children = [];
50                $.each(data, function (i, item) {
51                    var obj = {text: item};
52                    //$('#mytree2').jstree('create_node', selectedNode, obj, 'last');
53                    inst.create_node(selectedNode, item, "last");
54                });
55                inst.open_node(selectedNode);
56
57            } else {
58                $("#mytree2").html("暂无数据!");
59            }
60        },
61        error : function(){
62            alert("操作失败");
63        }
64    });
65}
66
67//点击跳转
68$("#mytree2").on('activate_node.jstree', function(e, data){
69        alert(data.node.a_attr.href);
70        document.location.href = data.node.a_attr.href;
71});
 1//查询所有 id 的 child 数量
 2//遍历此数据,如果 child > 0则添加空节点以显示加号,展开时再添加全部数据: "children":[{"text":"","icon":false}]
 3$sql = "SELECT f2.id, COUNT(b.id) amount FROM
 4            (
 5              SELECT id,pid FROM ".static::tableName()."
 6            ) b
 7            right join 
 8            (
 9              SELECT id,pid FROM ".static::tableName()."
10            ) f2
11            on f2.id=b.pid  GROUP BY f2.id";