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({
             "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({
             "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>
原文地址:https://www.cnblogs.com/china2k/p/3795613.html