easyui-combotree实现树形结构的下拉控件,并实现节点回显

项目开发,临时的一个需求,将8000条数据整成树形机构的下拉控件,网上找了资料,可以使用easyUI的combotree实现

看了官网资料,combotree需要的数据必须是json数据,json的key为 id,text,children,用的是jsonarray生成json数据

例如:{'id':1000,"text":root,"children":[{"id":1001,"text":root1,"children":[{"id":1002,"text":root2,"children":[{}]}]}]}

根节点下面有多个子节点的结构

这样的话:就是一个map容器里面放置List<Map>的结构

后台代码

package flink.net.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.util.WebUtils;

import com.ylink.mfo.action.form.UserInfo;
import com.ylink.mfo.msg.rsp.RspA9011;

import flink.consant.Constants;

public class MyBranchUtils {
	//获取当前用户所在机构的所有子机构信息
    //参数list是机构信息所有记录
	public static Map<String, Object> getCombotreeInfo(List<RspA9011> list,HttpServletRequest request){
		Map<String,Object> map = new HashMap<String, Object>();
		UserInfo userInfo = (UserInfo)WebUtils.getSessionAttribute(request, Constants.SESSION_USER);
		for (RspA9011 rspA9011 : list) {
			if(rspA9011.getBranch_id().equals(userInfo.getBranchId())){
				map.put("id", rspA9011.getBranch_id());
				map.put("text", rspA9011.getBranch_name());
				map.put("children", MyBranchUtils.getChildrenRoleInfo(rspA9011.getBranch_id(), list));
			}
		}
		return map;
	}
	
	//通过父机构号递归获取子孙机构
	public static List<Map<String,Object>>  getChildrenRoleInfo(String parentId,List<RspA9011> list){
		List<Map<String,Object>> total = new ArrayList<Map<String,Object>>();
		for (RspA9011 rspA9011 : list) {
			if(rspA9011.getParent_branch_id().equals(parentId)){
				Map<String,Object> map = new HashMap<String, Object>();
				map.put("id", rspA9011.getBranch_id());
				map.put("text", rspA9011.getBranch_name());
				map.put("children", getChildrenRoleInfo(rspA9011.getBranch_id(), list));
				total.add(map);
			}
		}
		return total;
	}
}

 

说明1:RspA9001类,是一个对应数据库表(机构号,当前机构名称,父机构号)的实体,实体的属性定义如下:

branch_id : 机构号

branch_name: 机构名称

parent_branch_id: 父机构号

 说明2: 方法getCombotreeInfo有两个参数list是机构信息的所有记录数,request请求用来获取当前用户的机构号,返回的是Map<List>结构的数据,传回到前台时候,需要用Json工具类转json数据。

写回json数据,原生的servelet方式,BusinessMap.BRANCH_INFO_LIST是所有机构记录的list

  
		response.setContentType("text/javascript;charset=utf-8");
    	response.setCharacterEncoding("utf-8");
      	JSONArray fromObject = new JSONArray();
    	if(BusinessMap.BRANCH_INFO_LIST.size()>0){
    		Map<String, Object> combotreeInfo = MyBranchUtils.getCombotreeInfo(BusinessMap.BRANCH_INFO_LIST, request);
    		fromObject = JSONArray.fromObject(combotreeInfo);
    	}
        response.getWriter().print(fromObject);
        response.getWriter().flush();
        response.getWriter().close();
        return null;
	

前台js加载数据

页面:


<select id="branch_id" class="easyui-combotree" method="get" style="width: 160px;"></select>
	

ajax获取数据

和后台使用ajax交互,因为多个页面用到了机构下拉列表,所以就在主页面加载时候的,请求了一次后台,缓存在主页面上,后面子页面都从主页面取值,当然,也可以ajax获取成功后,初始化combotree

       //载入json机构信息
		var loginBranchInfo;
		$.ajax({
			type:'get',
			url:CONTEXT_PATH+'/sysConfig.do?action=jsonBranchInfo',
			dataType:'json',
			success:function(data){
				loginBranchInfo = data;
                //这里也可以直接初始化combotree
			},
			error:function(){
				alert('机构信息加载失败');
			}
		});

子页面初始化combotree:

子页面获取主页面数据

var jsonBranchData  = window.parent.loginBranchInfo;

$('#branch_id').combotree
	            ({ 	
	                data:jsonBranchData,
	                valueField: 'id',
	                textField: 'text',
	                required: false,
	                editable: true,
	                onLoadSuccess: function (node, data) {
	                    $('#branch_id').combotree('tree').tree("collapseAll"); 
	                }
	        });

其他初始化方式

官网上的方式:将上面的data改为一个url,填入后台一个地址,返回的是json数据就行

其他功能实现

1. 实现数据回显

如果是页面回显,触发onLoadSuccess事件,可以遍历所有节点,只要节点的值和param.[参数]相同,就选中这个节点,

在触发onSelect事件,设置选中的文本是节点的text,这个有点问题,只能看,不能再次点击,如果再次点击的话,combotree的值是空的。

不过,应该可以这样,onSelect 后将具体的值,赋给一个隐藏的input,使用这个input提交。

onLoadSuccess: function (node, data) {
    	//回显时,默认选中的值
    	var root  =  $("#branch_id").combotree('tree').tree('getRoot');
    	var childrens = $("#branch_id").combotree('tree').tree('getChildren',root.target);
    	childrens.push(root);
    	for(var i=0;i<childrens.length;i++){
    		if(childrens[i].id == '${param.branchId}'){
    			var thisnode = $("#branch_id").combotree('tree').tree('find',childrens[i].id);
    			$("#branch_id").combotree('tree').tree('select',thisnode.target);
    		}
    	}
         $('#branch_id').combotree('tree').tree("collapseAll"); 
    },
    onSelect:function(node){
    	$("#branch_id").combotree('setText',node.text);
    }

2. 输入框输入,能够查询到对应的子节点

要实现输入select框查询到对应的节点,需要将editable改为true,网上找了些js方法实现,实现如下

 $(".combo-text").bind("input propertychange", function() {  
			 $('#branch_id').combotree('tree').tree("search",$(this).val());  
	            if($(this).val()=="" || null==$(this).val()){  
	                $('#branch_id').combotree('tree').tree("expandAll");  
	            }  
	        
	        }); 

search方法定义,网上找的

(function($) {  
  
    $.extend($.fn.tree.methods, {  
  
        search: function(jqTree, searchText) {  
            // easyui tree的tree对象。可以通过tree.methodName(jqTree)方式调用easyui tree的方法  
            var tree = this;  
            // 获取所有的树节点  
            var nodeList = getAllNodes(jqTree, tree);  
            // 如果没有搜索条件,则展示所有树节点  
            searchText = $.trim(searchText);  
            if (searchText == "") {  
                for (var i=0; i<nodeList.length; i++){  
                    $(".tree-node-targeted", nodeList[i].target).removeClass("tree-node-targeted");  
                    $(nodeList[i].target).show();  
                }  
                // 展开已选择的节点(如果之前选择了)  
                var selectedNode = tree.getSelected(jqTree);  
                if (selectedNode) {  
                    tree.expandTo(jqTree, selectedNode.target);  
                }  
                return;  
            }  
            // 搜索匹配的节点并高亮显示  
            var matchedNodeList = [];  
            if (nodeList && nodeList.length>0) {  
                var node = null;  
                for (var i=0; i<nodeList.length; i++){  
                    node = nodeList[i];  
                    if (isMatch(searchText, node.text)) {  
                        matchedNodeList.push(node);  
                    }  
                }  
                // 隐藏所有节点  
                for (var i=0; i<nodeList.length; i++){  
                    $(".tree-node-targeted", nodeList[i].target).removeClass("tree-node-targeted");  
                    $(nodeList[i].target).hide();  
                }  
                // 折叠所有节点  
                tree.collapseAll(jqTree);  
                // 展示所有匹配的节点以及父节点  
                for (var i=0; i<matchedNodeList.length; i++){  
                    showMatchedNode(jqTree, tree, matchedNodeList[i]);  
                }  
            }  
        },  
        showChildren: function(jqTree, node) {  
            // easyui tree的tree对象。可以通过tree.methodName(jqTree)方式调用easyui tree的方法  
            var tree = this;  
            // 展示子节点  
            if (!tree.isLeaf(jqTree, node.target)) {  
                var children = tree.getChildren(jqTree, node.target);  
                if (children && children.length>0) {  
                    for (var i=0; i<nodeList.length; i++){  
                        if ($(children[i].target).is(":hidden")) {  
                            $(children[i].target).show();  
                        }  
                    }  
                }  
            }  
        },  
        scrollTo:function(jqTree, param) {  
            // easyui tree的tree对象。可以通过tree.methodName(jqTree)方式调用easyui tree的方法  
            var tree = this;  
            // 如果node为空,则获取当前选中的node  
            var targetNode = param && param.targetNode ? param.targetNode : tree.getSelected(jqTree);  
            if (targetNode != null) {  
                // 判断节点是否在可视区域  
                var root = tree.getRoot(jqTree);  
                var $targetNode = $(targetNode.target);  
                var container = param && param.treeContainer ? param.treeContainer : jqTree.parent();  
                var containerH = container.height();  
                var nodeOffsetHeight = $targetNode.offset().top - container.offset().top;  
                if (nodeOffsetHeight > (containerH - 30)) {  
                    var scrollHeight = container.scrollTop() + nodeOffsetHeight - containerH + 30;  
                    container.scrollTop(scrollHeight);  
                }  
            }  
        }  
    });  
    function showMatchedNode(jqTree, tree, node) {  
        // 展示所有父节点  
        $(node.target).show();  
        $(".tree-title", node.target).addClass("tree-node-targeted");  
        var pNode = node;  
        while ((pNode = tree.getParent(jqTree, pNode.target))) {  
            $(pNode.target).show();  
        }  
        // 展开到该节点  
        tree.expandTo(jqTree, node.target);  
        // 如果是非叶子节点,需折叠该节点的所有子节点  
        if (!tree.isLeaf(jqTree, node.target)) {  
            tree.collapse(jqTree, node.target);  
        }  
    }  
    function isMatch(searchText, targetText) {  
        return $.trim(targetText)!="" && targetText.indexOf(searchText)!=-1;  
    }  
    function getAllNodes(jqTree, tree) {  
        var allNodeList = jqTree.data("allNodeList");  
        if (!allNodeList) {  
            var roots = tree.getRoots(jqTree);  
            allNodeList = getChildNodeList(jqTree, tree, roots);  
            jqTree.data("allNodeList", allNodeList);  
        }  
        return allNodeList;  
    }  
    function getChildNodeList(jqTree, tree, nodes) {  
        var childNodeList = [];  
        if (nodes && nodes.length>0) {  
            var node = null;  
            for (var i=0; i<nodes.length; i++){  
                node = nodes[i];  
                childNodeList.push(node);  
                if (!tree.isLeaf(jqTree, node.target)) {  
                    var children = tree.getChildren(jqTree, node.target);  
                    childNodeList = childNodeList.concat(getChildNodeList(jqTree, tree, children));  
                }  
            }  
        }  
        return childNodeList;  
    }  
    })(jQuery);

 

 

 

 

 

 


 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值