其实写这种树结构选择的公共组件,如果项目是用的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.写一个子父级关系的entitypublic class TestMenu{
//菜单id
private Long menuId;
//菜单名称
private String menuName;
//父亲级id
private Long menuParentId;
//子集集合
private ArrayList 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 list = service.findList();
return list;
}
}
4.写一个需要树选择操作的测试页面test.html(该页面用的自定义元素属性)
#parse("/treeSelect.html")
元素属性解释看下图(图片html代码对应上面test.html页面,js代码对应下面treeSelect.html页面)
5.写一个公共的树选择的页面treeSelect.html(弹出窗口及操作树选择代码都写在这个页面),该页面供需要树选择操作的页面引用
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 : [ '取消']
});
}
}
});
有了treeSelect.html的共性代码,其他需要操作树结构选择的页面,只需要按照以下代码写,就能给页面添加上树结构的选择了(且下面的元素和属性值都可以动态配置了,这样就成了公共的树结构选择了,不管是菜单表或者是地区这些有子父级关系表,都可以直接按照下面模板代码写了,只需要配置各自的属性名和查询的url就行了)
#parse("/treeSelect.html")
上级菜单:*
tagName="treeSelect" treeId="menuId" treePid="menuParentId" treeName="menuName"
subList="subList" toInput="menuParentId"
treeUrl="/system/menu/menuTree.htm" selectMultiple="false" />