zTree -- jQuery 树插件

https://www.treejs.cn/v3/main.php#_zTreeInfo    官方文档,demo和api

https://www.cnblogs.com/fonour/p/zTree.html  

https://www.cnblogs.com/longlyseul/p/12111143.html    通俗容易理解

 

http://127.0.0.1:8000/appsmarts/home/

 

 <script type="text/javascript" src="{% static 'ztree/js/jquery.ztree.core.js' %}"></script>  只能做显示

<script type="text/javascript" src="{% static 'ztree/js/jquery.ztree.all.js' %}"></script>   可以复选、编辑等

API:

@router.get('/treedict')
def list_person(request):
    dictdata=Jg.objects.values('p_code','parent_code','short_name')
    return list(dictdata)

 

相关tree.html

<!DOCTYPE html>
{% load static %}
<HTML>
<HEAD>
    <TITLE> ZTREE DEMO </TITLE>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link href="{% static 'ztree/css/zTreeStyle/zTreeStyle.css' %}"  rel="stylesheet" />
    <link href="{% static 'ztree/css/demo.css' %}"  rel="stylesheet" />
    <script type="text/javascript" src="{% static 'ztree/js/jquery-1.4.4.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'ztree/js/jquery.ztree.core.js' %}"></script>


    <SCRIPT LANGUAGE="JavaScript">
        var zTreeObj;
        // zTree 的参数配置,深入使用请参考 API 文档(setting 配置详解)
        var setting = {
            view: {
                selectedMulti: true, //设置是否能够同时选中多个节点
            },
            data: {
                simpleData: {
                    enable: true,
                    idKey: "p_code",
                    pIdKey: "parent_code",
                    //rootPId: 0
                },
                key: {
                    name: "short_name",//name是共通化属性,不是simpleData仅有的,所以与idKey不同,单独用key设置
                }
            },
            check:{
                enable: true         //设置是否显示checkbox复选框
            },
            callback: {
                beforeClick: beforeClick,
                onClick: onClick
            }
        };
        // zTree 的数据属性,深入使用请参考 API 文档(zTreeNode 节点数据详解)
        var zNodes =[
            { id:1, pId:0, name:"普通的父节点", t:"我很普通,随便点我吧", open:true},
            { id:11, pId:1, name:"叶子节点 - 1", t:"我很普通,随便点我吧"},
            { id:2, pId:0, name:"NB的父节点", t:"点我可以,但是不能点我的子节点,有本事点一个你试试看?", open:true},
            { id:21, pId:2, name:"叶子节点2 - 1", t:"你哪个单位的?敢随便点我?小心点儿..", click:false},
            { id:23, pId:2, name:"叶子节点2 - 3", t:"好歹我也是个领导,别普通群众就来点击我..", click:false},
            { id:3, pId:0, name:"郁闷的父节点", t:"别点我,我好害怕...我的子节点随便点吧...", open:true, click:false },
            { id:31, pId:3, name:"叶子节点3 - 1", t:"唉,随便点我吧"},
        ];
        var log,className = "dark";
        function beforeClick(treeId, treeNode, clickFlag) {
            return (treeNode.click != false);
        }
        function onClick(event, treeId, treeNode, clickFlag) {
            if (treeNode.isParent)  //如果不是叶子结点,结束
                return;
            showLog( treeNode.short_name+'&nbsp;&nbsp;'+ treeNode.p_code);
        };
        function showLog(str) {
            if (!log) log = $("#log");
            log.append("<li class='"+className+"'>"+str+"</li>");
            if(log.children("li").length > 8) {
                log.get(0).removeChild(log.children("li")[0]);
            }
        }
        $(document).ready(function () {
            //这是用var zNodes的假设数据启动tree
            //zTreeObj = $.fn.zTree.init($("#treeDemo"), setting, zNodes);
            //这是用ajax ipi调用数据启用tree
            $.ajax({
                type: "Get",
                url: "http://127.0.0.1:8000/api/api3/treedict",                  //ajax请求地址
                success: function (data) {
                    $.fn.zTree.init($("#treeDemo"), setting, data);  //加载数据
                },
            });

            $(".btn1").click(function(){
                $("p").slideToggle();
            });

        });
        //below three is same
        //$(document).ready(function)
        //$().ready(function)
        //$(function)
    </SCRIPT>
</HEAD>
<BODY>
<div>
    <ul class="list">
        <li><p><span class="highlight_red">请尝试按下 <b>Ctrl</b><b>Cmd</b> 键进行 多节点选择 和 取消选择</span><br/>
            click log:<br/>
            <ul id="log" class="log"></ul></p>
        </li>
    </ul>
    <div id="rMenu" style="z-index:100;">

    </div>
    <ul id="treeDemo" class="ztree"></ul>
</div>
</BODY>
</HTML>

关键说明:

1、默认提供的数据是 id, pId,name,如

            { id:23, pId:2, name:"叶子节点2 - 3", t:"好歹我也是个领导,别普通群众就来点击我..", click:false},
            { id:3, pId:0, name:"郁闷的父节点", t:"别点我,我好害怕...我的子节点随便点吧...", open:true, click:false },
            { id:31, pId:3, name:"叶子节点3 - 1", t:"唉,随便点我吧"},
如果api提供的是key name不同,则可以通过setting{data{} }的设定,把id,pId,name变成api 的相关key,参考上述 p_code, parent_code,short_name的例子

2、data中,click:false 的用途: 在function beforeClick函数中,限制onclick的相应
3、

可以对节点crud的tree的例子
<!DOCTYPE html>
{% load static %}
<HTML>
<HEAD>
    <TITLE> ZTREE DEMO </TITLE>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link href="{% static 'ztree/css/zTreeStyle/zTreeStyle.css' %}" rel="stylesheet"/>
    <link href="{% static 'ztree/css/demo.css' %}" rel="stylesheet"/>
    //
    <script type="text/javascript" src="{% static 'ztree/js/jquery-1.4.4.min.js' %}"></script>
    <script src="{% static 'js/jquery-3.3.1.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'ztree/js/jquery.ztree.all.js' %}"></script>


    <SCRIPT LANGUAGE="JavaScript">
        var zTreeObj;
        // zTree 的参数配置,深入使用请参考 API 文档(setting 配置详解)
        var setting = {
            view: {
                selectedMulti: true, //设置是否能够同时选中多个节点
            },
            data: {
                simpleData: {
                    enable: true
                }
            },
            check: {
                enable: false//true         //设置是否显示checkbox复选框
            },
            callback: {
                //onRightClick: OnRightClick,
                beforeClick: beforeClick,
                onClick: onClick,
                beforeRename: beforeRename,
            }
        };
        // zTree 的数据属性,深入使用请参考 API 文档(zTreeNode 节点数据详解)
        var zNodes = [
            {id: 1, pId: 0, name: "普通的父节点", t: "我很普通,随便点我吧", open: true},
            {id: 11, pId: 1, name: "叶子节点 - 1", t: "我很普通,随便点我吧"},
            {id: 2, pId: 0, name: "NB的父节点", t: "点我可以,但是不能点我的子节点,有本事点一个你试试看?", open: true},
            {id: 21, pId: 2, name: "叶子节点2 - 1", t: "你哪个单位的?敢随便点我?小心点儿..", click: false},
            {id: 23, pId: 2, name: "叶子节点2 - 3", t: "好歹我也是个领导,别普通群众就来点击我..", click: false},
            {id: 3, pId: 0, name: "郁闷的父节点", t: "别点我,我好害怕...我的子节点随便点吧...", open: true, click: false},
            {id: 31, pId: 3, name: "叶子节点3 - 1", t: "唉,随便点我吧"},
        ];
        var log, className = "dark";

        function beforeClick(treeId, treeNode, clickFlag) {
            return (treeNode.click != false);
        }

        function onClick(event, treeId, treeNode, clickFlag) {
            if (treeNode.isParent)  //如果不是叶子结点,结束
                return;
            showLog(treeNode.name + '&nbsp;&nbsp;' + treeNode.id);


        };

        function showLog(str) {
            if (!log) log = $("#log");
            log.append("<li class='" + className + "'>" + str + "</li>");
            if (log.children("li").length > 8) {
                log.get(0).removeChild(log.children("li")[0]);
            }
        }

        //增加节点
        function addTreeNode() {
            var zTree = $.fn.zTree.getZTreeObj("treeDemo");
            var newNode = {
                name: name
            };
            if (zTree.getSelectedNodes()[0]) {
                newNode.checked = zTree.getSelectedNodes()[0].checked;
                newNode.pid = zTree.getSelectedNodes()[0].id;
                zTree.addNodes(zTree.getSelectedNodes()[0], newNode);
            } else {
                zTree.addNodes(null, newNode);
            }
            var node = zTree.getNodeByParam("name", name, null);  //得到新增加的节点
            zTree.selectNode(node);   //选中新增加的节点
            zTree.editName(node);     //让新增加的节点处于编辑状态
        }

        //编辑节点
        function editTreeNode() {
            var zTree = $.fn.zTree.getZTreeObj("treeDemo");
            var nodes = zTree.getSelectedNodes();  //得到选中节点集合
            if (nodes && nodes.length > 0) {
                var parent = nodes[0].getParentNode();  //得到选中节点的父节点
                if (parent) {
                    nodes[0].pid = parent.id;  //如果选中节点父节点存在,将当前结点的pid属性值设置为父节点的id
                }
                zTree.editName(nodes[0]);  //让选中节点处于编辑状态
            }

        };

        //刷新
        function refreshTreeNode() {
            var zTree = $.fn.zTree.getZTreeObj("treeDemo");
            zTree.refresh();
        };

        function removeTreeNode() {
            var zTree = $.fn.zTree.getZTreeObj("treeDemo");
            var nodes = zTree.getSelectedNodes();
            if (nodes && nodes.length > 0) {
                if (nodes[0].children && nodes[0].children.length > 0) {
                    alert("包含下级,无法删除。");
                } else {
                    if (confirm("该操作会将关联数据同步删除,是否确认删除?") == true) {
                        mydata = {"id": Number(nodes[0].id)};
                        console.log(mydata);
                        $.ajax({
                            url: "/api/apitree/post_del",//数据入库
                            method: "POST",
                            data: JSON.stringify(mydata),
                            success: function (data) {
                                if (data.result == "Success") {
                                    zTree.removeNode(nodes[0]);
                                } else {
                                    alert("删除失败。");
                                }
                            }
                        });
                    }
                    ;
                }
            }
        };

        //新增和编辑后,节点编辑状态离开时触发事件
        function beforeRename(treeId, treeNode, newName, isCancel) {
            if (newName.length == 0) {   //节点名称判断
                alert("不能为空。");
                return false;
            }
            var mydata = {name: newName};
            if (treeNode.id !== undefined) {
                mydata.id = treeNode.id
            }
            if (treeNode.pid !== undefined) {
                mydata.pid = treeNode.pid
            }
            console.log(mydata);
            $.ajax({
                url: "/api/apitree/ins_or_upd",//数据入库
                method: "POST",
                data: JSON.stringify(mydata),
                success: function (data) {
                    if (data.result == "Faild") {
                        layerAlert("保存失败。");
                        return false;
                    } else {
                        treeNode.id = data.result;  //将返回的id赋值给当前结点
                        return true;
                    }

                }
            });

        };

        $(document).ready(function () {
            //这是用var zNodes的假设数据启动tree
            zTreeObj = $.fn.zTree.init($("#treeDemo"), setting, zNodes);

            //这是用ajax ipi调用数据启用tree
            $.ajax({
                type: "Get",
                url: "http://127.0.0.1:8000/api/api3/treedict_good",                  //ajax请求地址
                success: function (data) {
                    $.fn.zTree.init($("#treeDemo"), setting, data);  //加载数据
                },
            });

            $(".btn1").click(function () {
                $("p").slideToggle();
            });


        });
        //below three is same
        //$(document).ready(function)
        //$().ready(function)
        //$(function)
    </SCRIPT>
</HEAD>
<BODY>
<div>
    <ul class="list">
        <li>利用 click 事件回调函数 可以进行各种其他的附加操作,这里简单演示如何监控此事件</li>
        <li><p><span class="highlight_red">请尝试按下 <b>Ctrl</b><b>Cmd</b> 键进行 多节点选择 和 取消选择</span><br/>
            click log:<br/>
            <ul id="log" class="log"></ul>
            </p>
        </li>
    </ul>
    <div id="rMenu" style="z-index:100;">
        <ul>
            <li id="m_add" onclick="addTreeNode();">新增节点</li>
            <li id="m_del" onclick="removeTreeNode();">删除节点</li>
            <li id="m_edit" onclick="editTreeNode();">编辑节点</li>
            <!--<li id="m_reset" onclick="refreshTreeNode();">重置节点</li>-->

        </ul>
    </div>
    <ul id="treeDemo" class="ztree"></ul>
</div>
</BODY>
</HTML>

以下是相关api,注意,本次的treeNode的节点属性用了默认的,数据必须是id,pId,name,可以增加(onclick=true or false)

@router.post("/ins_or_upd")
def create_employee(request, payload: Jginout):
    print(payload)
    if payload.id:
        testjg = get_object_or_404(Testig, id=payload.id)
        for attr, value in payload.dict().items():
            setattr(testjg, attr, value)
        testjg.save()
    else:
         payload.id=None
         testjg = Testig.objects.create(**payload.dict())

    return {'result': testjg.id }

@router.post("/post_del")
def post_del_Testig(request, plyload: Jginout):
    print(request)
    print('ssss')
    print(plyload)
    print('aaaaa')
    person = get_object_or_404(Testig, id=plyload.id)
    person.delete()
    return {"result": 'Success'}
#参数必须是pId ,注意大小写,pid不可以形成tree
@router.get('/treedict_good')
def treedict_good(request):
    dictdata=Testig.objects.annotate(pId=F('pid')).values('id','pId','name')
    return list(dictdata)

 

 
 

 

posted @ 2023-07-06 14:41  花生与酒  阅读(183)  评论(0编辑  收藏  举报