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";