kendoUi_treeview


前兩天用kendoUI的treeView做了一個給用戶角色分配菜單權限的功能,廢了老大的勁,寫來說明一下,

做出效果如圖:

業務流程:點擊”分配菜單權限“按鈕,彈出一個新的window,並顯示出所有的菜單選項,菜單分子父兩級,因為這里是修改權限,

顯示時,根據行選的用戶已有權限需要默認打鈎,點擊“提交查詢”按鈕,form提交,根據勾選情況,入庫。

下面說說一下實現代碼:

 1,首先,自定義分配菜單權限按鈕,grid 右邊一欄為command,

command : [ 
                        {
                            
                            text : "分配菜單權限",
                            
                            click: function(e) {
                                // e.target is the DOM element representing the button
                                var tr = $(e.target).closest("tr"); // get the current table row (tr)
                                // get the data bound to the current table row
                                var data = this.dataItem(tr);
                                showTree(data.id).data("kendoWindow").open();
}
}, { name :
"edit", text : { edit : "信息修改", cancel : "關閉", update : "提交" } }, { name : "destroy", text : "刪除" } ],

 解釋:通過var tr = $(e.target).closest("tr"); var data = this.dataItem(tr); 獲得的data對應每一行的一跳數據,格式是json,幾對應后台的JavaBean

並將沒一行的主鍵可獲取 以作為標示,這里data.id  即為點擊對應那一行的role的id

 2,彈出窗口,展示菜單menu樹形結構: showTree(data.id).data("kendoWindow").open();

showTree是一個方法 如下:
function showTree(roleId){
        return $("#menuTree").kendoWindow({
            width: "300px",
            height : "300px",
            position: {
                top: 100,
                left: 500
              },
            title: "分配菜單權限",
            visible: false,
            content: 'role/menuTreePage.do?roleId='+roleId,
            activate : function(){

            },
            close : function(){
                console.log("清除樹");
                $("#treeview").data("kendoTreeView").destroy();
            }
        });
    }
menuTree 為在此grid 的jsp中定義的一個占位div

<div id="menuTree"></div>
即通過這個div生成一個彈窗kendoWindow,而這個彈窗中的內容實際上顯示的是另外一個jsp頁面rolemenu.jsp,content: 'role/menuTreePage.do?roleId='+roleId,
通過這個屬性的配置將另一個jsp中的內容包裹到kendoWindow中,rolemenu.jsp中真正的菜單menu的樹形結構
3,樹形結構的配置
<body>
<div id="treeview" class="demo-section"></div>
<form id="treeForm" action="<spring:url value='/role/assignMenus.do' />" method="post" onsubmit="return  false;">
    <input type="hidden" name="menuIds" id="result" /> 
    <input type="hidden" name="roleId" id="roleId" value="${roleId}"/> 
    <input id="formSub" type="submit" />
</form>
<script type="text/javascript">
$(function() {
    var homogeneous = new kendo.data.HierarchicalDataSource({
        transport : {
            read : {
                url : "role/menuTree.do",
                dataType : "json",
                data: function() {
                    var uproleId= $("#roleId").val();
                    return {roleId:uproleId}
                  }
            }
        },
        schema : {
            model : {
                id : "id",
                hasChildren : "hasChildren",
                children:"items",
                expanded : true,
                checked : "checked"
            },
        }
    });
    
    $("#treeview").kendoTreeView({
        //loadOnDemand : false,// 延遲加載,默認是true,這里設置false是因為在初始化閉合的時候,如果選中根元素,是不法獲取子節點id的
        dataSource : homogeneous,
        dataTextField : "name",
        checkboxes : {
            checkChildren : true
        }
    });


    var options = {
        success : function(data) {
            console.log(data);
            //location.href = "http://localhost:8085/csop_monitor/index.do";
            $("#menuTree").data("kendoWindow").close();
        }
    };

    $("#formSub").click(function() {
        var result = $("#result").val();
        var oldRs = $("#oldResult").val();
        if(result == ""){
            $("#menuTree").data("kendoWindow").close();
            return false;
        }else{
                $("#result").val(result);        
        }
        //alert("re="+result);
        $("#treeForm").ajaxSubmit(options);

    });
    


// show checked node IDs on datasource change
$("#treeview").data("kendoTreeView").dataSource.bind("change",    getChangeValue);

function getChangeValue(){

    var checkedNodes = [],
    treeView = $("#treeview").data("kendoTreeView"),
    message;
    checkedNodeIds(treeView.dataSource.view(), checkedNodes);


    if (checkedNodes.length > 0)
        message = checkedNodes.join(",");
    $("#result").val(message);
    console.log("改變后result : " + $("#result").val());
}

//function that gathers IDs of checked nodes
function checkedNodeIds(nodes, checkedNodes) {
    for (var i = 0; i < nodes.length; i++) {
        if (nodes[i].checked) {
            console.log("checked node : " + nodes[i].id);
            checkedNodes.push(nodes[i].id);
        }

        if (nodes[i].hasChildren) {
            checkedNodeIds(nodes[i].children.view(), checkedNodes);
        }

    }
}




});
</script>
</body>
 
         
         
        

treeView的完成,首先定義個個datasource,我這里定義了一個 HierarchicalDataSource,這個本身就是一個樹形結構的datasouce

值得注意的是schema的配置

schema : {
            model : {
                id : "id",
                hasChildren : "hasChildren",
                children:"items",
                expanded : true,
                checked : "checked"
            },
        }

hasChildren,children,checked 都對應后台傳遞過來的javabean中的屬性

checked,hasChildren 為Boolean類型

children 如果有,會自動生成一個樹形,但是這個有一個問題就是JavaBean中必須定義為items,否則treeview找不到,我不知道是不是treeview那邊還需要配置一個屬性。

checked 由於我的樹形前有checkbox,如果未true,kendo也會自動選中,

然后就簡單了 ,同樣通過一個div來顯示treeview

 

<div id="treeview" class="demo-section"></div>
 $("#treeview").kendoTreeView...
這樣就可以顯示了,后台對menus的操作等下再說
我這里還定義了一個form,用於提交,用戶進行選擇,操作之后的數據保存,通過tree的change事件保存下所選的menuIds,即可,
通過這個方法 getChangeValue,這里不再贅述。
最后:后台獲取menus
思路:首先抓取所有的menus,再通過roleID查詢這個角色所擁有的menu權限找到對應的menu,將checked 設為true
@RequestMapping("/menuTree.do")
	@ResponseBody
	public List<SysMenuDto>  menuListTree(@RequestParam(value = "roleId", required = false) String roleId) {
		List<SysMenuDto> menuDtos = roleService.getRoleMenuTreeForUpdate(roleId);
		return menuDtos;
	}
 
        
@Override
	public List<SysMenuDto> getRoleMenuTreeForUpdate(String roleId) {
		Role role=roleDao.get(roleId, Role.class);
		List<SysMenu> roleRoleMenus = new ArrayList<SysMenu>();
		Iterator<RoleMenuMap> it = role.getRoleMenuMaps().iterator();
		while (it.hasNext()) {
			RoleMenuMap roleMenuMap = it.next();
			roleRoleMenus.add(roleMenuMap.getMenu());
		}
		List<SysMenu> menus=menuDao.listRootMenus();
		List<SysMenuDto> menuDtos=new ArrayList<>();
		for (SysMenu SysMenu : menus) {
			SysMenuDto menuDto=new SysMenuDto().convertToDto(SysMenu);
			
			if(roleRoleMenus.contains(SysMenu)){
				menuDto.setChecked(true);
			}else{
				menuDto.setChecked(false);
			}
			List<SysMenu> chiledMenus=SysMenu.getChildren();
			if(chiledMenus!=null&&chiledMenus.size()>0){
				for(int i=0;i<chiledMenus.size();i++){
					SysMenu childMenu=chiledMenus.get(i);
					if(roleRoleMenus.contains(childMenu)){
						menuDto.getItems().get(i).setChecked(true);
					}else{
						menuDto.getItems().get(i).setChecked(false);
					}
				}
				
			}
			menuDtos.add(menuDto);
		}
		return menuDtos;
	}

 

 menuDto

	private String name;

	private String url;

	private String desc;

	private int order;

	private String createdTime;

	private String parentId;
	
	private String parentName;

	private List<SysMenuDto> items = new ArrayList<>();
	
	private boolean hasChildren;
	
	private boolean checked;

	@Override
	public SysMenuDto convert(SysMenu o) {
		this.setId(o.getId());
		this.setCreatedTime(DateUtils.date2String(o.getCreatedTime()));
		this.setDesc(o.getDesc());
		this.setName(o.getName());
		this.setUrl(o.getUrl());
		this.setOrder(o.getOrder());
		this.setParentId(o.getParent() == null ? null : o.getParent().getId());
		this.setParentName(o.getParent() == null ? "無" : o.getParent().getName());
		List<SysMenu> sysMenus = o.getChildren();
		for (SysMenu sysMenu : sysMenus) {
			items.add(new SysMenuDto().convert(sysMenu));
		}
		this.hasChildren = sysMenus != null && sysMenus.size() > 0 ? true : false;
		return this;
	}
	
	
	public SysMenu convertToEntity(SysMenu menu) {
		//menu.setId(this.getId());
		menu.setDesc(this.desc);
		menu.setName(this.name);
		menu.setUrl(this.url);
		menu.setOrder(this.order);
		//menu.setParent(parent);
		//menu.setChildren(children);

		return menu;
	}


//getter and setter .....

附:兩個完整jsp代碼

 

role.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>  
<%@ taglib prefix='spring' uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<head>
<script src="<spring:url value='/resources/js/plugins/jquery.form.js' />"></script>
<script type="text/javascript">

$(function() {
    
    var prefix = "role";
    
    var dataSource = new kendo.data.DataSource({
        type: "odata",
        pageSize : 20,
        serverPaging: true,//服務器端是否進行分頁查詢
        serverFiltering: true,
        transport : {
            read : {
                url : prefix + '/showRoles.do',
                dataType : "json",
            },
            update: {
                url: prefix + '/save.do',
                dataType: "json", 
                contentType:"application/x-www-form-urlencoded",
                type : "post",
            },
            destroy: {
              url: prefix + '/delete.do',
              contentType:"application/x-www-form-urlencoded",
              type : "post",
            },
            create: {
                url: prefix + '/save.do',
                dataType: "json",
                contentType:"application/x-www-form-urlencoded",
                type : "post",
            },
            parameterMap: function(data, type) {
                if (type !== "read" && data) {
                   // return kendo.stringify(data);
                }
                return data;
            }
        },
        schema : {
            model : {
                id : "id",
                fields : {
                    id : {type : "string"},
                    name : {type : "string"},
                    status : {
                        type : "string",
                        defaultValue:"激活"
                        },
                    desc : {type : "string"},
                }
            }
        },
        //after create update destory. reload the datasource(reflesh page)
        requestEnd: function(e) {
            var response = e.response;
            var type = e.type;
            if(type != "read"){
        
                this.read();
            }
        }
    });
    $("#grid").kendoGrid({
            dataSource : dataSource,
            sortable : false,
            selectable : "multiple",// 多選
            height : 500,
            navigatable: true,
             editable: true,
            toolbar : [ 
                {
                    name : "create",
                    text : "新增角色"
                }
            ],
            pageable : {
                pageSize : 20,// 一頁顯示多少行數據
                previousNext : true,// 是否允許有上一頁、下一頁、首頁、尾頁摁扭
                numeric : true,// 是否顯示翻頁處的頁數按鈕
                buttonCount : 5,// 限制頁數按鈕的顯示個數
                input : false,// 是否顯示輸入頁數的文本框
                refresh : true,// 是否允許刷新頁面
                pageSizes : true,// 是否允許調整一頁顯示的行數,可設置[5, 10, 15]
                messages : {
                    display : "顯示  {0}-{1} 條數據 總共 {2} 條數據",
                    empty : "沒有數據",
                    itemsPerPage : "選擇顯示行數",
                    refresh : "刷新",
                    previous : "上一頁",
                    next : "下一頁",
                    last : "尾頁",
                    first : "首頁"
                }
            },
            columns : [ // 顯示列定義
                {
                    field : "name",
                    width : 100,
                    title : "角色名"
                }, {
                    field : "desc",
                    width : 120,
                    title : "描述"
                }, {
                    field : "status",
                    width : 80,
                    title : "啟動狀態",
                    editor : activeDownEditor,
                    template : "#=status#"
                }, {
                    command : [ 
                        {
                            
                            text : "分配菜單權限",
                            
                            click: function(e) {
                                // e.target is the DOM element representing the button
                                var tr = $(e.target).closest("tr"); // get the current table row (tr)
                                // get the data bound to the current table row
                                var data = this.dataItem(tr);
                                var menuIds = [];
                                console.log(data);
                                if(data.roleMenuMapDtos != null)
                                    for(var i = 0; i < data.roleMenuMapDtos.length; i++){
                                        menuIds.push(data.roleMenuMapDtos[i].menu.id);
                                    }
                                showTree(data.id, menuIds).data("kendoWindow").open();
                              }
                        }, {
                            name : "edit",
                            text : {
                                edit : "信息修改",
                                cancel : "關閉",
                                update : "提交"
                            }
                        }, {
                            name : "destroy",
                            text : "刪除"
                        } 
                    ],
                    title : "操作",
                    width : "160px"
                } ],
                editable : {// 設置可以在列表中進行編輯數據
                    // 設置刪除時顯示的確認信息
                    confirmation : "您確定要進行刪除操作嗎?",
                    destroy : true,// 不允許刪除
                    mode : "popup",// 設置編輯形式為彈出框(popup)還是在列表中(inline)
                    //template: kendo.template($("#editTemplate").html())//設置彈出框中加載的內容,設置此項mode必須是popup
                },
                groupable : false
        });
    
    var data = [
                { text: "激活", value: "激活" },
                { text: "凍結", value: "凍結" }
            ];
    
    function activeDownEditor(container, options){
//        console.log(options);
        var status = options.model.status;
        var rolestatusDroplist=$('<input required  data-text-field="text" data-value-field="value" data-bind="value:' + options.field + '"/>')
        .appendTo(container).kendoDropDownList({
            dataTextField: "text",
            dataValueField: "value",
            dataSource : data
        });
        rolestatusDroplist.data("kendoDropDownList").select(function(dataItem) {
            return dataItem.text === status;
        });
    }
    function showTree(roleId, menuIds){
        return $("#menuTree").kendoWindow({
            width: "300px",
            height : "300px",
            position: {
                top: 100,
                left: 500
              },
            title: "分配菜單權限",
            visible: false,
            content: 'role/menuTreePage.do?roleId='+roleId,
            activate : function(){
                 $("#roleId").val(roleId);
                //var treeview = $("#treeview").data("kendoTreeView");
                //console.log("role.reosurce : " + menuIds);
                //var nodes = treeview.dataSource.view();
                //if(menuIds.length > 0)
                //checkedNodes(nodes, menuIds);
                //treeview.updateIndeterminate();
                
                //if (checkedNodes.length > 0) 
                 //   message = menuIds.join(",");
              //  $("#oldResult").val(message);
               
              //  console.log("roleId : " + $("#roleId").val() + "    oldresult : " + $("#oldResult").val());
            },
            close : function(){
                console.log("清除樹");
                $("#treeview").data("kendoTreeView").destroy();
            }
        });
    }
    
    function checkedNodes(nodes, checkedNodesID) {
        //console.log("nodes=---"+nodes);
        for (var i = 0; i < checkedNodesID.length; i++) {
            for(var j = 0; j < nodes.length; j++){
            //console.log("node id : " + nodes[j].id + "   checked Id : " + checkedNodesID[i]);
                if(nodes[j].id == checkedNodesID[i]){
                    nodes[j].checked = true;
                    console.log("node.id : " + nodes[j].id + "    node.name : " + nodes[j].name + " is checked : " + nodes[j].checked);
//                    console.log(nodes[j].name + "   " + nodes[j].hasChildren);
                    if(nodes[j].hasChildren)
                        checkedNodes(nodes[j].children.view(),checkedNodesID);
                }else{
                    nodes[j].checked = false;
                    }
            }
        }
    }
    /*
    function chilrenChecked(children){
        for(var i = 0; i < children.length; i++){
            children[i].checked = true;
            console.log("children name : " + children[i].name + "    checked : " + children[i].checked);
        }
    }*/

    //for rolemenu





    
    
});

</script>
</head>
<body>
<div id="menuTree"></div>
<div id="example" class="k-content">
        <div id="clientsDb">
            <div id="grid" style="height: 380px"></div>
        </div>
</div>
<div id="dialog"></div>
</body>

rolemenu.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>  
<%@ taglib prefix='spring' uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<head>
<script src="<spring:url value='/resources/js/plugins/jquery.form.js' />"></script>

</head>
<body>
<div id="treeview" class="demo-section"></div>
<form id="treeForm" action="<spring:url value='/role/assignMenus.do' />" method="post" onsubmit="return  false;">
    <input type="hidden" name="menuIds" id="result" /> 
    <input type="hidden" name="roleId" id="roleId" value="${roleId}"/> 
    <input id="formSub" type="submit" />
</form>
<script type="text/javascript">
$(function() {
    var homogeneous = new kendo.data.HierarchicalDataSource({
        transport : {
            read : {
                url : "role/menuTree.do",
                dataType : "json",
                data: function() {
                    var uproleId= $("#roleId").val();
                    return {roleId:uproleId}
                  }
            }
        },
        schema : {
            model : {
                id : "id",
                hasChildren : "hasChildren",
                children:"items",
                expanded : true,
                checked : "checked"
            },
        }
    });
    
    $("#treeview").kendoTreeView({
        //loadOnDemand : false,// 延遲加載,默認是true,這里設置false是因為在初始化閉合的時候,如果選中根元素,是不法獲取子節點id的
        dataSource : homogeneous,
        dataTextField : "name",
        checkboxes : {
            checkChildren : true
        }
    });


    var options = {
        success : function(data) {
            console.log(data);
            //location.href = "http://localhost:8085/csop_monitor/index.do";
            $("#menuTree").data("kendoWindow").close();
        }
    };

    $("#formSub").click(function() {
        var result = $("#result").val();
        var oldRs = $("#oldResult").val();
        if(result == ""){
            $("#menuTree").data("kendoWindow").close();
            return false;
        }else{
                $("#result").val(result);        
        }
        //alert("re="+result);
        $("#treeForm").ajaxSubmit(options);

    });
    


// show checked node IDs on datasource change
$("#treeview").data("kendoTreeView").dataSource.bind("change",    getChangeValue);

function getChangeValue(){
    //console.log("改變前result : " + $("#oldResult").val());
    var checkedNodes = [],
    treeView = $("#treeview").data("kendoTreeView"),
    message;
    
    //console.log("treeView : " + treeView.dataSource.view().length > 0);
    checkedNodeIds(treeView.dataSource.view(), checkedNodes);
    //console.log(checkedNodes);

    if (checkedNodes.length > 0)
        message = checkedNodes.join(",");

    //alert("message="+message);

    $("#result").val(message);
    console.log("改變后result : " + $("#result").val());
}

//function that gathers IDs of checked nodes
function checkedNodeIds(nodes, checkedNodes) {
    for (var i = 0; i < nodes.length; i++) {
//        console.log(nodes[i]);
//        console.log(nodes[i].checked);
        if (nodes[i].checked) {
            console.log("checked node : " + nodes[i].id);
            checkedNodes.push(nodes[i].id);
        }

        if (nodes[i].hasChildren) {
            checkedNodeIds(nodes[i].children.view(), checkedNodes);
        }
        // console.log("node.id : " + nodes[i].id + " node.name : " +
        // nodes[i].name);
    }
}




});
</script>
</body>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM