LayUI—tree樹形結構的使用

一枕江風發表於2019-09-01

樹形結構在實際開發中很長用到,比如部門管理,許可權選單等。因為用樹形結構來展示會顯的很清晰明瞭。最近寫了一個個人部落格小專案中用到了LayUI的樹形結構,之後寫了一個小案例整理一下。

官網地址:https://www.layui.com/v1/doc/modules/tree.html

先看一下顯示的效果圖。

點選節點右面會顯示對應部門的詳情資訊,可以修改。可以自定義按鈕新增部門,也可以直接用自帶的方法對部門進行新增,修改和刪除。可以獲取選中的節點,根據專案需求(有的需要選中儲存)。

先需要引入LayUI的樣式檔案JS和CSS。

案例對應的實體類Dept。

@Entity
public class Dept {
    private Integer id;
    private String name;    //部門名稱
    private String deptName;    //部門負責人
    private String phone;   //電話號
    private String number;  //編號
    private double idx;     //排序
    @JsonIgnore
    private Dept parent;
    @JsonIgnore
    private List<Dept> children = new ArrayList<>();

    @Id
    @GeneratedValue
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDeptName() {
        return deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public double getIdx() {
        return idx;
    }

    public void setIdx(double idx) {
        this.idx = idx;
    }

    @ManyToOne
    @CreatedBy
    public Dept getParent() {
        return parent;
    }

    public void setParent(Dept parent) {
        this.parent = parent;
    }

    @OneToMany(cascade=CascadeType.ALL,mappedBy="parent")
    @OrderBy(value="idx")
    public List<Dept> getChildren() {
        return children;
    }

    public void setChildren(List<Dept> children) {
        this.children = children;
    }

    public Dept(Integer id, String name, String deptName, String phone, String number, double idx, Dept parent, List<Dept> children) {
        this.id = id;
        this.name = name;
        this.deptName = deptName;
        this.phone = phone;
        this.number = number;
        this.idx = idx;
        this.parent = parent;
        this.children = children;
    }

    public Dept(Integer id) {
        this.id = id;
    }

    public Dept() {
    }
}

顯示LayUI樹形選單,只需要一個標籤容器即可。

<div id="dept_tree">
</div>

在案例中還有一些其他樣式,比如右邊的詳情資訊,新增按鈕等。完整程式碼如下。

<style type="text/css">
    #dept_main, #dept_particulars{
        width: 48.5%;
        display: inline-block;
        vertical-align: top;
        padding: 20px;
        background: white;
        box-sizing: border-box;
    }
    #dept_tree{
        margin-top: 20px;
    }
</style>

<div id="dept_main" style="margin-right: 2%;">
    <fieldset class="layui-elem-field layui-field-title">
        <legend>所有部門</legend>
    </fieldset>
    <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept"><i class="layui-icon">&#xe654;</i>新增部門</button>
    <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">獲取選中節點</button>
    <div id="dept_tree">

    </div>
</div>
<div id="dept_particulars">
    <fieldset class="layui-elem-field layui-field-title">
        <legend>部門詳情</legend>
    </fieldset>
    <div id="dept_home">
        <div class="layui-tree-emptyText">無資料</div>
    </div>
</div>

JS請求資料渲染頁面程式碼,data為請求資料來源,當時直接放入的請求連結,好像不行,所以之後才寫了一個方法去請求資料來源。

layui.use(['tree', 'util'], function() {
    var tree = layui.tree;
    var util = layui.util;
    tree.render({
        elem: '#dept_tree',
        data: getData(),
        id: 'treeId',
        showCheckbox: true,     //是否顯示覆選框
        onlyIconControl: true
    });
});

function getData(){
    var data = [];
    $.ajax({
        url: "dept/treeload",    //後臺資料請求地址
        type: "post",
        async:false,
        success: function(resut){
            data = resut;
        }
    });
    return data;
}

 tree 元件提供的有以下基礎引數,可根據需要進行相應的設定。

引數選項 說明 型別 示例值
elem 指向容器選擇器 String/Object -
data 資料來源 Array -
id 設定例項唯一索引,用於基礎方法傳參使用。 String -
showCheckbox 是否顯示覆選框 Boolean false
edit 是否開啟節點的操作圖示。預設 false。
  • 若為 true,則預設顯示“改刪”圖示
  • 若為 陣列,則可自由配置操作圖示的顯示狀態和順序,目前支援的操作圖示有:addupdatedel,如: 
    edit: ['add', 'update', 'del']
Boolean/Array ['update', 'del']
accordion 是否開啟手風琴模式,預設 false Boolean false
onlyIconControl 是否僅允許節點左側圖示控制展開收縮。預設 false(即點選節點本身也可控制)。若為 true,則只能通過節點左側圖示來展開收縮 Boolean false
isJump 是否允許點選節點時彈出新視窗跳轉。預設 false,若開啟,需在節點資料中設定 link 引數(值為 url 格式) Boolean false
showLine 是否開啟連線線。預設 true,若設為 false,則節點左側出現三角圖示。 Boolean true
text 自定義各類預設文字,目前支援以下設定:

text: {

     defaultNodeName: '未命名' //節點預設名稱

     ,none: '無資料' //資料為空時的提示文字

}

Object -

因為tree指定了json資料的鍵名稱,所以後臺傳遞過來的資料對應的鍵名不一樣時需要做一下處理,或者實體類中的屬性名就和tree的JSON資料的鍵名稱一樣。

鍵名:

屬性選項 說明 型別 示例值
title 節點標題 String 未命名
id 節點唯一索引,用於對指定節點進行各類操作 String/Number 任意唯一的字元或數字
children 子節點。支援設定選項同父節點 Array [{title: '子節點1', id: '111'}]
href 點選節點彈出新視窗對應的 url。需開啟 isJump 引數 String 任意 URL
spread 節點是否初始展開,預設 false Boolean true
checked 節點是否初始為選中狀態(如果開啟核取方塊的話),預設 false Boolean true
disabled 節點是否為禁用狀態。預設 false Boolean false

後臺請求資料的方法。

@RequestMapping(value = "/treeload")
@ResponseBody
public Object treeload(){
    Sort sort = Sort.by("idx");
    List<Dept> dpet = deptService.findByParentIsNull(sort);    //查詢所有選單
    List<HashMap<String, Object>> result = new ArrayList<>();    //定義一個map處理json鍵名問題
    return fun(dpet, result);
}

private Object fun(List<Dept> dpet, List<HashMap<String, Object>> result) {
    for(Dept d : dpet){
        HashMap<String, Object> map = new HashMap<>();
        map.put("id", d.getId());
        map.put("title", d.getName());
        map.put("spread", true);      //設定是否展開
        List<HashMap<String, Object>> result1 = new ArrayList<>();
        List<Dept> children = d.getChildren();    //下級選單
        //這裡可以根據自己需求判斷節點預設選中
        /*if(m.getParent() != null || m.getChildren().size() == 0){
            map.put("checked", true);    //設定為選中狀態
        }*/
        map.put("children", fun(children, result1));
        result.add(map);
    }
    return result;
}

因為這裡新建的實體類欄位名和tree指定了json資料的鍵名稱不一樣,所以這裡用了一個fun遞迴方法處理的。中間可以根據專案需求,根據條件判斷是否需要選中該節點。

返回的JSON資料格式

[
	{
		"children": [		//子節點
			{
				"children": [
					{
						"children": [],
						"id": 30,
						"title": "測試",
						"spread": true
					}, {
						"children": [],
						"id": 31,
						"title": "開發",
						"spread": true
					}, {
						"children": [
							{
								"children": [],
								"id": 36,
								"title": "測試節點",
								"spread": true
							}
						],
						"id": 32,
						"title": "測試",
						"spread": true
					}
				],
				"id": 2,
				"title": "技術部",
				"spread": true
			}, {
				"children": [],
				"id": 19,
				"title": "財務部",
				"spread": true
			}
		],
		"id": 1,	//節點id
		"title": "某某公司",	//節點名稱
		"spread": true
	}, {
		"children": [],
		"id": 33,
		"title": "測試",
		"spread": true
	}
]

設定節點點選回撥方法(在載入資料方法tree.render中新增以下程式碼)。

click: function (obj) {
    var id = obj.data.id;
    $("#dept_home").load("dept/show?id="+id);
}

把請求過來的詳情頁面load到右邊的div中顯示。後臺請求方法

@RequestMapping(value = "/show")
public void show(DeptForm form, ModelMap map) throws InstantiationException, IllegalAccessException {
    Dept model = new Dept();
    Integer id = form.getId();
    Integer parentId = 0;
    if(id!=null) {
        model = deptService.findById(id);
        parentId = model.getParent()==null?0:model.getParent().getId();
    }
    map.put("parentId", parentId);
    map.put("model", model);
}

DeptForm類為一個接收類,其中欄位和實體類中一樣。根據請求傳遞過來的id,查詢這條資料的詳細資訊,之後把查詢的當前部門詳情資料及父級節點id(用於下拉樹TreeSelect)傳遞給詳情頁面。

show.html詳情頁面程式碼。

<meta charset="UTF-8" />
<style type="text/css">
    .myData .layui-form-item{
        margin: 20px 100px 10px 45px;
    }
    .myData .layui-form-label{
        width: 85px;
    }
    .layui-input-block {
        margin-left: 120px;
    }
</style>
<form class="layui-form myData" action="save" method="post" lay-filter="stuform">
    <input type="hidden" name="id" data-th-value="${model.id}" />

    <div class="layui-form-item">
        <label class="layui-form-label">上級部門:</label>
        <div class="layui-input-block">
            <input type="text" name="parentId" id="tree" lay-filter="tree" class="layui-input" />
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label">部門名稱:</label>
        <div class="layui-input-block">
            <input type="text" name="name" lay-verify="required" th:value="${model.name}" class="layui-input" />
        </div>
    </div>
    <div class="layui-form-item" >
        <label class="layui-form-label">部門負責人:</label>
        <div class="layui-input-block">
            <input type="text" name="deptName" th:value="${model.deptName}" class="layui-input" />
        </div>
    </div>
    <div class="layui-form-item" >
        <label class="layui-form-label">電話:</label>
        <div class="layui-input-block">
            <input type="text" name="phone" th:value="${model.phone}" class="layui-input" />
        </div>
    </div>
    <div class="layui-form-item" >
        <label class="layui-form-label">編號:</label>
        <div class="layui-input-block">
            <input type="text" name="number" th:value="${model.number}" class="layui-input" />
        </div>
    </div>
    <div class="layui-form-item" >
        <label class="layui-form-label">排序:</label>
        <div class="layui-input-block">
            <input type="text" name="idx" value="0" th:value="${model.idx}" class="layui-input" />
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label"></label>
        <div class="layui-input-block">
            <button lay-submit class="layui-btn layui-btn-radius layui-btn-normal" lay-filter="btnSub">
                <i class="layui-icon">&#xe642;</i>修改並儲存
            </button>
        </div>
    </div>
</form>

<script th:inline="javascript">
    layui.use(["treeSelect", "form", "tree"], function () {
        var form = layui.form;
        var tree = layui.tree;
        form.render('select');
        var treeSelect = layui.treeSelect;
        treeSelect.render({
            // 選擇器
            elem: '#tree',
            // 資料
            data: 'dept/treeSelect?id='+[[${model.id==null ? 0 : model.id}]],
            // 非同步載入方式:get/post,預設get
            type: 'post',
            // 佔位符
            placeholder: '上級選單',
            // 是否開啟搜尋功能:true/false,預設false
            search: true,
            // 一些可定製的樣式
            style: {
                folder: {
                    enable: true
                },
                line: {
                    enable: true
                }
            },
            // 載入完成後的回撥函式
            success: function (d) {
                // 選中節點,根據id篩選
                treeSelect.checkNode('tree', [[${model.parent == null? parentId: model.parent.id}]]);
                treeSelect.refresh('tree');
            }
        });

        form.on('submit(btnSub)', function (data) {
            $.post('dept/save', data.field, function (result) {
                if (result.success) {
                    tree.reload('treeId', {data: getData()});
                }
                layer.msg(result.msg, {offset: 'rb'});
            });
            return false;
        });
    });
</script>

上級部門使用的是LayUI下拉樹顯示的,下拉樹資料請求方法。關於下拉樹的使用,可以訪問LayUI下拉樹TreeSelect的使用

@RequestMapping(value="/treeSelect")
@ResponseBody
public Object treeSelect(Integer id) {
    Sort sort = Sort.by("idx");
    Specification<Dept> spec = buildSpec1();
    List<Dept> list = deptService.findAll(spec,sort);
    return buildTree(list, id);
}

private Object buildTree(List<Dept> list, Integer id) {
    List<HashMap<String, Object>> result=new ArrayList<>();
    for (Dept dept : list) {
        if(dept.getId() != id) {
            HashMap<String, Object> node=new HashMap<>();
            node.put("id", dept.getId());
            node.put("name",dept.getName());
            node.put("open", false);
            node.put("checked", false);
            if(dept.getChildren().size() != 0) {
                node.put("children",buildTree(dept.getChildren(), id));
            }
            result.add(node);
        }
    }

    return result;
}

public Specification<Dept> buildSpec1() {
    Specification<Dept> specification = new Specification<Dept>() {

        private static final long serialVersionUID = 1L;

        @Override
        public Predicate toPredicate(Root<Dept> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            HashSet<Predicate> rules=new HashSet<>();
            Predicate parent = cb.isNull(root.get("parent"));
            rules.add(parent);
            return cb.and(rules.toArray(new Predicate[rules.size()]));
        }

    };
    return specification;
}

顯示的效果。

上面修改並儲存後臺方法(因為修改和新增共用的一個方法,用id區分的)。

@Override
public Object save(DeptForm form) {
    try {
        Dept model = new Dept();
        Integer id = form.getId();
        if(id != null) {
            model = deptService.findById(id);
        }
        //父級選單id
        Integer parentId = form.getParentId();
        if(parentId == null) {
            model.setParent(null);
        }else {
            model.setParent(new Dept(parentId));
        }
        BeanUtils.copyProperties(form, model,"id", "parent");
        deptService.save(model);
        return new AjaxResult("資料儲存成功!");
    } catch (Exception e) {
        return new AjaxResult(false,"資料儲存失敗");
    }
}

設定節點操作(在載入資料方法tree.render中新增以下程式碼)。

edit: ['add', 'update', 'del'], //操作節點的圖示
operate: function(obj){
    var type = obj.type; //得到操作型別:add、edit、del
    var data = obj.data; //得到當前節點的資料
    var elem = obj.elem; //得到當前節點元素

    var id = data.id;
    var name = data.title;
    if(type === 'add'){ //增加節點
        $.post("dept/save", {parentId: id, name: "未命名"}, function (result) {
            tree.reload('treeId', {data: getData()});
        })
        //返回 key 值
        return ;
    } else if(type === 'update'){ //修改節點
        $.post("dept/update", {id: id, name: name}, function () {
            tree.reload('treeId', {data: getData()});
        })
    } else if(type === 'del'){ //刪除節點
        $.post("dept/delete", {id: id}, function () {
            tree.reload('treeId', {data: getData()});
        });
    };
}

其中operate為操作節點回撥方法。

obj.type為操作型別,add為新增,update為修改,edl為刪除。obj.data為操作節點後的資料。

新增節點後,向後臺傳送請求新增節點,save方法和上面修改方法一樣,id為新建節點的父級節點id。

修改節點,同樣,向後臺傳送修改請求,並傳遞物件的id,和修改後的資料作為引數。後臺響應方法。

@RequestMapping(value = "/update")
@ResponseBody
public Object update(DeptForm form) {
    try {
        Dept model = deptService.findById(form.getId());
        model.setName(form.getName());
        deptService.save(model);
        return new AjaxResult("資料儲存成功!");
    } catch (Exception e) {
        return new AjaxResult(false,"資料儲存失敗");
    }
}

刪除節點同理,傳遞刪除節點的id。刪除請求方法。

@RequestMapping(value="/delete")
@ResponseBody
public Object delete(Integer id) {
	try {
		deptService.deleteById(id);
		return new AjaxResult("資料刪除成功");
	} catch (Exception e) {
		return new AjaxResult(false,"資料刪除失敗");
	}
}

使用按鈕操作樹形選單。

現在頁面中定義兩個按鈕,給按鈕新增lay-demo=""屬性,並設定屬性值,JS通過這個屬性值,繫結點選事件。

<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept"><i class="layui-icon">&#xe654;</i>新增部門</button>
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">獲取選中節點</button>

繫結新增部門和獲取選中節點按鈕的點選事件的JS程式碼。

util.event('lay-demo', {
    addDept: function(othis){
        $.get('dept/edit', function(data) {
            layer.open({
                type: 1,
                title: '新增',
                area: ['530px'],
                content: data,
                btn: ['提交', '退出'],
                yes: function () {
                },
                success: function (layero, index) {
                    layui.use('form', function () {
                        var form = layui.form;
                        layero.addClass('layui-form');
                        var submitBtn = layero.find('.layui-layer-btn0');
                        submitBtn.attr('lay-filter', 'formVerify').attr('lay-submit', '');
                        layero.keydown(function (e) {
                            if (e.keyCode == 13) {
                                submitBtn.click();
                            }
                        });

                        form.on('submit(formVerify)', function (data) {
                            $.post('dept/save', data.field, function (result) {
                                if (result.success) {
                                    layer.close(index);
                                    tree.reload('treeId', {data: getData()});
                                }
                                layer.msg(result.msg, {offset: 'rb'});
                            });
                            return false;
                        });
                    });
                }
            })
        })
    },
    gain: function () {
        var checkData = tree.getChecked('treeId');
        var str = JSON.stringify(checkData);
        $.post('dept/checkedGain', {data: str}, function () {
        });
        layer.alert(JSON.stringify(checkData), {shade:0});
    }
});

新增部門按鈕點選事件,先傳送請求到後臺,跳轉到eidt新增頁面,edit.html新增頁面程式碼,和上面的show.html顯示部門詳情頁面差不多。上級部門同樣使用的LayUI下拉樹顯示的,下拉樹資料請求方法,和上面的詳情頁面下拉樹請求方法一致。LayUI下拉樹TreeSelect的使用。新增後的儲存方法也和上面的儲存方法一致。

後臺請求方法程式碼,跳轉到edit頁面。

@RequestMapping(value = "/edit")
public void edit(){
    
}

edit.html頁面完整程式碼如下。

<meta charset="UTF-8" />
<style type="text/css">
    .myData .layui-form-item{
        margin: 20px 100px 10px 45px;
    }
    .myData .layui-form-label{
        width: 85px;
    }
    .layui-input-block {
        margin-left: 120px;
    }
</style>
<form class="layui-form myData" action="save" method="post" lay-filter="stuform">

    <div class="layui-form-item">
        <label class="layui-form-label">上級部門:</label>
        <div class="layui-input-block">
            <input type="text" name="parentId" id="tree2" lay-filter="tree2" class="layui-input" />
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label">部門名稱:</label>
        <div class="layui-input-block">
            <input type="text" name="name" lay-verify="required" class="layui-input" />
        </div>
    </div>
    <div class="layui-form-item" >
        <label class="layui-form-label">部門負責人:</label>
        <div class="layui-input-block">
            <input type="text" name="deptName" class="layui-input" />
        </div>
    </div>
    <div class="layui-form-item" >
        <label class="layui-form-label">電話:</label>
        <div class="layui-input-block">
            <input type="text" name="phone" class="layui-input" />
        </div>
    </div>
    <div class="layui-form-item" >
        <label class="layui-form-label">編號:</label>
        <div class="layui-input-block">
            <input type="text" name="number" class="layui-input" />
        </div>
    </div>
    <div class="layui-form-item" >
        <label class="layui-form-label">排序:</label>
        <div class="layui-input-block">
            <input type="text" name="idx" value="0" class="layui-input" />
        </div>
    </div>
</form>

<script th:inline="javascript">
    layui.use(["treeSelect", "form"], function () {
        var form = layui.form;
        form.render('select');
        var treeSelect = layui.treeSelect;
        treeSelect.render({
            // 選擇器
            elem: '#tree2',
            // 資料
            data: 'dept/treeSelect',
            // 非同步載入方式:get/post,預設get
            type: 'post',
            // 佔位符
            placeholder: '上級選單',
            // 是否開啟搜尋功能:true/false,預設false
            search: true,
            // 一些可定製的樣式
            style: {
                folder: {
                    enable: true
                },
                line: {
                    enable: true
                }
            },
            // 載入完成後的回撥函式
            success: function (d) {
            }
        });
    });
</script>

頁面效果。

獲取選中節點按鈕點選事件。如果專案需要儲存資料時,就需要獲取到選中節點的資料了。這裡可以獲取到選中節點的資料,之後當引數傳遞到後臺。傳遞到後臺是一個JSON資料的字串,需要轉換一下,這裡給推薦大家兩個很好用的JSON轉換工具net.sf.json.JSONObjectAlibaba Fastjson。這裡用的是Alibaba Fastjson,需要引入以下依賴。

<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.47</version>
</dependency>

這裡用於輸出,新建了一個和tree的json資料的鍵名稱一樣的工具類DeptTree,程式碼如下。

import java.util.ArrayList;
import java.util.List;

public class DeptTree {
    private Integer id;
    private String title;
    private boolean checked;
    private boolean spread;
    private List<DeptTree> children = new ArrayList<>();

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public List<DeptTree> getChildren() {
        return children;
    }

    public void setChildren(List<DeptTree> children) {
        this.children = children;
    }

    public boolean isChecked() {
        return checked;
    }

    public void setChecked(boolean checked) {
        this.checked = checked;
    }

    public boolean isSpread() {
        return spread;
    }

    public void setSpread(boolean spread) {
        this.spread = spread;
    }
}

後臺接收到傳遞過來的JSON資料字串,轉換後輸出方法。

@RequestMapping(value = "/checkedGain")
@ResponseBody
public void checkedGain(String data){
    List<DeptTree> array2 = JSONArray.parseArray(data, DeptTree.class);
    treeData(array2);
}

//遞迴輸出選中資料
private void treeData(List<DeptTree> array2) {
    for (DeptTree tree: array2){
        System.out.println(tree.getTitle()+"==="+tree.getId());
        if(tree.getChildren() != null){
            treeData(tree.getChildren());
        }
    }
}

選中節點,點選獲取選中節點資料。

後臺對應方法接收到資料,轉換後輸出結果。

資料拿到了,之後儲存方法就簡單了。

後臺方法程式碼基本都在上面了,頁面全部程式碼。

<style type="text/css">
    #dept_main, #dept_particulars{
        width: 48.5%;
        display: inline-block;
        vertical-align: top;
        padding: 20px;
        background: white;
        box-sizing: border-box;
    }
    #dept_tree{
        margin-top: 20px;
    }
</style>

<div id="dept_main" style="margin-right: 2%;">
    <fieldset class="layui-elem-field layui-field-title">
        <legend>所有部門</legend>
    </fieldset>
    <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept"><i class="layui-icon">&#xe654;</i>新增部門</button>
    <button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">獲取選中節點</button>
    <div id="dept_tree">

    </div>
</div>
<div id="dept_particulars">
    <fieldset class="layui-elem-field layui-field-title">
        <legend>部門詳情</legend>
    </fieldset>
    <div id="dept_home">
        <div class="layui-tree-emptyText">無資料</div>
    </div>
</div>

<script type="text/javascript">
    layui.use(['tree', 'util', 'layer'], function() {
        var tree = layui.tree;
        var util = layui.util;
        var layer = layui.layer;
        tree.render({
            elem: '#dept_tree',
            data: getData(),
            id: 'treeId',
            showCheckbox: true,     //時候顯示覆選框
            onlyIconControl: true,
            edit: ['add', 'update', 'del'], //操作節點的圖示
            click: function (obj) {
                var id = obj.data.id;
                $("#dept_home").load("dept/show?id="+id);
            },
            operate: function(obj){
                var type = obj.type; //得到操作型別:add、edit、del
                var data = obj.data; //得到當前節點的資料
                var elem = obj.elem; //得到當前節點元素

                var id = data.id;
                var name = data.title;
                if(type === 'add'){ //增加節點
                    $.post("dept/save", {parentId: id, name: "未命名"}, function (result) {
                        tree.reload('treeId', {data: getData()});
                    })
                    //返回 key 值
                    return ;
                } else if(type === 'update'){ //修改節點
                    $.post("dept/update", {id: id, name: name}, function () {
                        tree.reload('treeId', {data: getData()});
                    })
                } else if(type === 'del'){ //刪除節點
                    $.post("dept/delete", {id: id}, function () {
                        tree.reload('treeId', {data: getData()});
                    });
                };
            }
        });

        util.event('lay-demo', {
            addDept: function(othis){
                $.get('dept/edit', function(data) {
                    layer.open({
                        type: 1,
                        title: '新增',
                        area: ['530px'],
                        content: data,
                        btn: ['提交', '退出'],
                        yes: function () {
                        },
                        success: function (layero, index) {
                            layui.use('form', function () {
                                var form = layui.form;
                                layero.addClass('layui-form');
                                var submitBtn = layero.find('.layui-layer-btn0');
                                submitBtn.attr('lay-filter', 'formVerify').attr('lay-submit', '');
                                layero.keydown(function (e) {
                                    if (e.keyCode == 13) {
                                        submitBtn.click();
                                    }
                                });

                                form.on('submit(formVerify)', function (data) {
                                    $.post('dept/save', data.field, function (result) {
                                        if (result.success) {
                                            layer.close(index);
                                            tree.reload('treeId', {data: getData()});
                                        }
                                        layer.msg(result.msg, {offset: 'rb'});
                                    });
                                    return false;
                                });
                            });
                        }
                    })
                })
            },
            gain: function () {
                var checkData = tree.getChecked('treeId');
                var str = JSON.stringify(checkData);
                $.post('dept/checkedGain', {data: str}, function () {
                });
                layer.alert(JSON.stringify(checkData), {shade:0});
            }
        });
    });

    function getData(){
        var data = [];
        $.ajax({
            url: "dept/treeload",    //後臺資料請求地址
            type: "post",
            async:false,
            success: function(resut){
                data = resut;
            }
        });
        return data;
    }
    
</script>

如果對你有幫助,點贊關注一下唄^_^,留下你的足跡。

相關文章