一、
最近使用layui做了个项目,由于合同额小,也不需要太多繁琐复杂的处理,于是前端选用的layui。但是用到layui的树时,layui对树支持的不太好,后来找到了Dtree这个第三方插件。
二、
官网:http://www.wisdomelon.com/DTreeHelper/
里面有很多示例和使用帮助,我要实现的是,点一个input标签,然后打开一个树页面,选取一个节点,然后把选中的节点信息返回到input标签里。废话不多说,只说我是怎么用的。
三、
- 首先,下载dtree,如下图,放在项目静态文件目录
- 页面引入css,如下,你会看到,没有引入js,是因为,js可以用layui直接加载,后面提供方法;
- js,加载dtree,并且初始化树
layui.extend({
dtree : basePath + '/pack/dtree/dtree' // {/}的意思即代表采用自有路径,即不跟随 base 路径
}).use([ 'dtree', 'layer', 'jquery' ], function() {
var dtree = layui.dtree, layer = layui.layer, $ = layui.jquery;
var DTree = dtree.render({
// obj: $(layero).find("#openTree1"),
// 如果直接用elem加载不出来,则可以使用这个方式加载jquery的DOM
elem : "#demoTree",
url : basePath+ "/ach/common/initOrgTree",
method : 'POST',
initLevel: 2, // 指定初始展开节点级别
cache: false // 当取消节点缓存时,则每次加载子节点都会往服务器发送请求
});
// 绑定节点的双击
dtree.on("nodedblclick('demoTree')", function(obj) {
var index = parent.layer.getFrameIndex(window.name); //获取窗口索引
parent.setObject(obj.param);
parent.layer.close(index);
});
$('#commit').on('click', function() {
var obj = dtree.getNowParam("demoTree");
var index = parent.layer.getFrameIndex(window.name); //获取窗口索引
parent.setObject(obj);
parent.layer.close(index);
});
});
- 后台代码
controller:接收一个参数,就是当前节点id,来实现异步加载树。
@RequestMapping(value = "/initOrgTree", method = RequestMethod.POST)
@ResponseBody
public TreeResDto initOrgTree(String nodeId) {
TreeResDto res = new TreeResDto();
TreeStatusDto status = new TreeStatusDto();
status.setCode("200");
status.setMessage("成功");
res.setStatus(status);
List<TreeNodeDto> data = new ArrayList<TreeNodeDto>();
data = dtreeService.getData(nodeId);
res.setData(data);
return res;
}
service:
@Service("dtreeService")
@Lazy
@Transactional(readOnly = false)
public class DtreeServiceImpl implements DtreeService{
@Autowired
private DtreeDao dtreeDao;
@Override
public List<TreeNodeDto> getData(String id) {
List<TreeNodeDto> resList = new ArrayList<TreeNodeDto>();
if(StringUtils.isBlank(id)){
// 获取根节点
Map<String, Object> rootMap = dtreeDao.getRootNode();
TreeNodeDto rootNode = new TreeNodeDto();
rootNode.setId((String) rootMap.get("C_HID"));
rootNode.setTitle((String) rootMap.get("C_NAME"));
rootNode.setBasicData(rootMap);
rootNode.setParentId("-1");
rootNode.setIconClass("dtree-icon-home1");
rootNode.setLast(false);
List<Map<String, Object>> childrenList = dtreeDao.getChildrenNode((String)rootMap.get("C_HID"));
List<TreeNodeDto> childList = new ArrayList<TreeNodeDto>();
for (Map<String, Object> cMap : childrenList) {
TreeNodeDto child = new TreeNodeDto();
child.setId((String) cMap.get("C_HID"));
child.setTitle((String) cMap.get("C_NAME"));
child.setBasicData(cMap);
child.setParentId((String) cMap.get("parentId"));
child.setLast(false); // child.setLast((Boolean) cMap.get("hashChild"));
// 判断是否为公司
if("0".equals(cMap.get("C_TYPE"))){
child.setIconClass("dtree-icon-xiangmuxiaoxi");
}else{
child.setIconClass("dtree-icon-fenzhijigou");
}
childList.add(child);
}
rootNode.setChildren(childList);
resList.add(rootNode);
}else{
// 循环根节点查找子节点
List<Map<String, Object>> childrenList = dtreeDao.getChildrenNode(id);
for (Map<String, Object> cMap : childrenList) {
TreeNodeDto child = new TreeNodeDto();
child.setId((String) cMap.get("C_HID"));
child.setTitle((String) cMap.get("C_NAME"));
child.setBasicData(cMap);
child.setParentId((String) cMap.get("parentId"));
child.setLast(false); // child.setLast((Boolean) cMap.get("hashChild"));
// 判断是否为公司
if("0".equals(cMap.get("C_TYPE"))){
child.setIconClass("dtree-icon-xiangmuxiaoxi");
}else{
child.setIconClass("dtree-icon-fenzhijigou");
}
resList.add(child);
}
}
return resList;
}
}
dao:(这个可以忽略不看,因为low的让我自己都觉得丢人。。。)
@Repository
public class DtreeDaoImpl implements DtreeDao{
private JdbcOperator jdbcOperator = JdbcOperator.getInstance();
@Override
public Map<String, Object> getRootNode() {
StringBuilder sql = new StringBuilder();
sql.append("select * ");
sql.append("from TB_ORG_ORGUNIT ");
sql.append("where C_HID = '7f304de353c358egcfg267f023db8f25' ");
Map<String, Object> res = this.jdbcOperator.queryForMap(sql.toString());
return res;
}
@Override
public List<Map<String, Object>> getChildrenNode(String id) {
StringBuilder sql = new StringBuilder();
sql.append(" SELECT org_.C_OID,org_.C_NAME,org_.C_TYPE,org_.C_CODE,org_.C_EST_DATE,org_.C_LEVEL,");
sql.append(" org_.C_LOCATION_HID,org_.C_STATUS,org_.C_BEGIN_DATE,org_.C_END_DATE,org_.C_HID,relationTable.C_SUPERIOR_HID parentId ");
sql.append(" FROM TB_ORG_ORGUNIT org_, TB_ORG_UNITRELATION relationTable ");
sql.append(" WHERE org_.C_HID = relationTable.C_ORG_HID ");
sql.append(" AND relationTable.C_SUPERIOR_HID = :id ");//'7f304de353c358egcfg267f023db8f25'
sql.append(" AND relationTable.C_BEGIN_DATE <= :now ");
sql.append(" AND relationTable.C_END_DATE >= :now ");
sql.append(" AND org_.C_BEGIN_DATE <= :now ");
sql.append(" AND org_.C_END_DATE >= :now ");
sql.append(" AND org_.C_STATUS =1 ");
sql.append(" AND relationTable.C_STATUS =1 ");
sql.append(" ORDER BY relationTable.C_DISPLAYNO,org_.C_EST_DATE ");
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", id);
map.put("now", new Date());
List<Map<String, Object>> res = this.jdbcOperator.queryForMapList(sql.toString(), map);
return res;
}
}
dto:重要因为,就相当于,我把插件需要的那些关键名,封成javabean,返回给前端,这样,就不需要再一个个转了,可以直接拿过去用,另外需要的可根据自己的需要再新加。
public class TreeNodeDto{
/** 节点ID*/
private String id;
/** 上级节点ID*/
private String parentId;
/** 节点名称*/
private String title;
/** 是否最后一级节点*/
private Boolean last;
/** 自定义图标class*/
private String iconClass;
/** 表示用户自定义需要存储在树节点中的数据*/
private Object basicData;
/** 复选框集合*/
private List<CheckArr> checkArr = new ArrayList<CheckArr>();
// 子节点
private List<TreeNodeDto> children = new ArrayList<TreeNodeDto>();
(get,set方法...)
}
四、
效果:
ps:当前显示的是我根据当前登录人设置的默认。。。
嗯嗯,大概就是这样的效果了,双击,或者点击选中一个点确认选择,都是可以的
五、
综上,个人蛮喜欢layui的总体风格的,这个dtree也是非常的契合layui,总之,这个项目用起来还是挺爽的。
反正我爽了,你们要不要去爽一下?!哈哈