whmr_soft的gravatar头像
whmr_soft 2017-03-21 12:43:17
写个公共的zTree弹出选择的demo

其实写这种树结构选择的公共组件,如果项目是用的jsp, 这个倒是蛮好写的,直接用自定义标签就可以实现了,jsp页面调用自定义标签,然后在自定义标签.tag里面写操作数结构的共性代码

本来我也想直接套用之前项目里面的自定义标签来实现的,但是现在这个项目全都是用的html+veloctity,所有这里jsp的自定义标签.tag就无法使用了,以前没用过veloctity这玩意,思考了下,最后根据jsp里面的自定义标签的方式在html里面用自定义属性实现了公共树结构的选中

注:demo代码用的springmvc+html+jquery+layer+zTree+velocity来实现的

springmvc(java)、html(页面)、jquery(js框架)、layer(弹出层组件)、zTree(树插件)、velocity(模板引擎)

1.写一个子父级关系的entity

public class TestMenu{
        
        //菜单id
	private Long menuId;
        //菜单名称
	private String menuName;
        //父亲级id
	private Long menuParentId;
	//子集集合
	private ArrayList<TestMenu> subList;

        public TestMenu(){
             super();
        ​}

        public TestMenu(Long menuId,Long menuParentId){
             super();
             this.menuId = menuId;
             this.menuParentId = menuParentId;

        ​}

        //生成对应的get  set方法
}

2.service还得写接口和实现还得写mybatis和dao或者Mapper,太麻烦了,这里就不写接口和查询的代码了(只需递归查询出一个数据集合就可以了)

3.写一个TestController类,zTree通过ajax来拿数据

@Controller
@RequestMapping("/test")
public class TestController {

        @Autowired 
	private TestService service; 

        @RequestMapping("/menuTree")
	@ResponseBody
	public Object menuTree() {
                //调用service查询出树的集合
                List<TestMenu> list = service.findList();
		return list;
	}
}

4.写一个需要树选择操作的测试页面test.html(该页面用的自定义元素属性)

<!-- 引用公共代码页面 -->
#parse("/treeSelect.html")
<!-- 添加菜单对话框开始 -->
<div id="menu_add_dialog" class="ibox-content" style="display: none;">
	<form class="form-horizontal m-t">
		<div class="form-group">
			<label class="col-sm-3 control-label">选择上级菜单:<span class="text-danger">*</span></label>
			<div class="col-sm-8">
				<input type="hidden" id="menuParentId" name="menuParentId" />
				<input readonly="readonly" type="text" id="menuParentName" class="form-control" placeholder="点击选择上级菜单"
				tagName="treeSelect" treeId="menuId" treePid="menuParentId" treeName="menuName" 
				subList="subList" toInput="menuParentId" 
				treeUrl="/test/menuTree.htm" selectMultiple="false"  />
			</div>
		</div>
		
	</form>
</div>

元素属性解释看下图(图片html代码对应上面test.html页面,js代码对应下面treeSelect.html页面)

写个公共的zTree弹出选择的demo

 

5.写一个公共的树选择的页面treeSelect.html(弹出窗口及操作树选择代码都写在这个页面),该页面供需要树选择操作的页面引用

<!-- 选择菜单对话框开始 -->
<div id="trre_data_init_dialog" class="ibox-content" style="display: none;">
	<form class="form-horizontal m-t">
		<div class="form-group">
			<div class="col-sm-8">
				<div class="zTreeDemoBackground left">
			        <ul id="tree_ul_id" class="ztree"></ul>
			    </div>
			</div>
		</div>
	</form>
</div>
<!-- 选择菜单对话框开始  -->
<script type="text/javascript">
jQuery(function () {
	
	//接收点击元素对象
	var objDocument = null;
	//单选或多选
	var checkEnable = false;
	//点击该元素,弹出tree选中窗口
	$("input[tagName='treeSelect']").click(function(){
		loadTreeData($(this));
	});
	
	//加载数据
	function loadTreeData(obj) {
			//回调
			var cb = {};
			//判断是单选还是多选,单选时设置回调里面的单击事件
			if(obj.attr("selectMultiple")=="true"){
				checkEnable = true;
			}else{
				cb = {onClick: zTreeOnClick};
			}
			//配置seting
			var setting = {
		        view: { selectedMulti: false },
		        check: { enable: checkEnable},
		        data: { 
		        	key : {
		        		children : obj.attr("subList"),
		        		name : obj.attr("treeName")
		        	},
		        	simpleData: { 
		        		enable: true, 
		        		idKey : obj.attr("treeId"),
		        		pIDKey : obj.attr("treePid")
		        	} 
		        },
		        callback: cb
		    };
		
			objDocument = obj;
			// 加载数据
			ajax(basePath + obj.attr("treeUrl"), 'POST', {}, function(result) {
				if(result.code == 0) {
					var zNodes = result.data;
					//将数据绑定到ztree
					$.fn.zTree.init($("#tree_ul_id"), setting, zNodes);
					//弹出树的选中窗口
					openTreeDialog();
				} else {
					layer.alert("树结构加载失败");
				}
			});
			
		
	}
	
	//点击节点
	function zTreeOnClick(event, treeId, treeNode) {
	
	       //将点击的节点id和name赋值给需要绑定的元素
	       $("#"+objDocument.attr("id")).val(treeNode[objDocument.attr("treeName")]);
	       $("#"+objDocument.attr("toInput")).val(treeNode[objDocument.attr("treeId")]);
	       //执行关闭 (关闭layer弹出窗口)
	       layer.close($("#trre_data_init_dialog").parent().parent().attr("times")); 
	}
	
	//弹出窗口
	function openTreeDialog() {
		//获取隐藏的tree  div
		var div = jQuery('#trre_data_init_dialog');
		var treeObj = $.fn.zTree.getZTreeObj("tree_ul_id");
		var nodes = treeObj.getNodes();
		
		//多选时回显(将之前选择的节点勾选上)
		var ids = $("#"+objDocument.attr("toInput")).val();
		var idArr = ids.split(",");
		var arrayNodes = treeObj.transformToArray(nodes);
        if(checkEnable){
        	for (var i = 0; i < arrayNodes.length; i++) {
        		for(var j = 0; j < idArr.length; j++){
            		if(arrayNodes[i][objDocument.attr("treeId")]==idArr[j]){
            			treeObj.checkNode(arrayNodes[i],true,false);
            		}
            	}
        	}
        }
		
		
        for (var i = 0; i < nodes.length; i++) { //设置节点展开
            treeObj.expandNode(nodes[i], true, false, true);
            
        }
        
		//判断弹出单选还是多选
        if(checkEnable){
        	layer.open({
			  	type: 1,
			  	shift: 5,
		  		title: '请选择',
			  	area: ['350px', '450px'],
			  	skin : 'layui-layer-lan',
			  	content: div,
			  	zIndex : 108,
			  	btn : [ '确定','取消'],
			  	yes : function(index, layero) {
			  		nodes = treeObj.getCheckedNodes(true);
			  		if(nodes.length==0){
			  			layer.msg('请选择对应节点');
			  		}else{
			  			var zId = "",zName="";
			  			for (var i = 0; i < nodes.length; i++) {
				  			
				  			 if(i < nodes.length-1){
				  				 zId+=nodes[i][objDocument.attr("treeId")]+",";
				  				 zName+=nodes[i][objDocument.attr("treeName")]+",";
				  			 }else{
				  				 zId+=nodes[i][objDocument.attr("treeId")];
				  				 zName+=nodes[i][objDocument.attr("treeName")];
				  			 }
				  		}
			  			//将选中的节点id和name赋值给需要绑定的元素
			  			$("#"+objDocument.attr("id")).val(zName);
			  		    $("#"+objDocument.attr("toInput")).val(zId);
			  			//执行关闭  (关闭layer弹出窗口)
			  		    layer.close(index); 
			  			
			  		}
			  		 
			  	}
			  
			});
        }else{
        	//单选时,直接点击对应节点,就执行回调里面的点击事件,所以不需要上面多选里面的yes函数
        	layer.open({
			  	type: 1,
			  	shift: 5,
		  		title: '请选择',
			  	area: ['350px', '450px'],
			  	skin : 'layui-layer-lan',
			  	content: div,
			  	zIndex : 101,
			  	btn : [ '取消']
			  
			});
        }
		
	}
	
});

</script>

有了treeSelect.html的共性代码,其他需要操作树结构选择的页面,只需要按照以下代码写,就能给页面添加上树结构的选择了(且下面的元素和属性值都可以动态配置了,这样就成了公共的树结构选择了,不管是菜单表或者是地区这些有子父级关系表,都可以直接按照下面模板代码写了,只需要配置各自的属性名和查询的url就行了)

<!-- 引用公共代码页面 -->
#parse("/treeSelect.html")
<!-- 添加菜单对话框开始 -->
<div id="menu_add_dialog" class="ibox-content" style="display: none;">
    <form class="form-horizontal m-t">
        <div class="form-group">
            <label class="col-sm-3 control-label">上级菜单:<span class="text-danger">*</span></label>
            <div class="col-sm-8">
                <input type="hidden" id="menuParentId" name="menuParentId" />
                <input readonly="readonly" type="text" id="menuParentName" class="form-control" placeholder="点击选择菜单"
                tagName="treeSelect" treeId="menuId" treePid="menuParentId" treeName="menuName" 
                subList="subList" toInput="menuParentId" 
                treeUrl="/system/menu/menuTree.htm" selectMultiple="false"  />

            </div>
        </div>
        
    </form>
</div>


打赏
最近浏览
wz520135  LV7 2022年11月16日
wwwww8781  LV1 2022年2月16日
aa123rfesaf 2021年1月27日
暂无贡献等级
BearQian 2020年12月14日
暂无贡献等级
2366567504  LV5 2020年6月20日
dixueping 2020年6月12日
暂无贡献等级
gaaraa  LV1 2020年4月20日
zhoubb  LV1 2020年4月12日
洗好碗123 2019年12月5日
暂无贡献等级
stone9712 2019年10月22日
暂无贡献等级
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友