最近这次的2个大模块需求产品还是狠用心的写了,也协调了设计做了一个大致的页面,交付到我这边的html基本上该有的都有了,剩下的前端与后端的工作就我这个java一手做了。
这次的页面上有个树形展示,要求输入内容检索节点高亮,先上一张效果图吧:
蓝色加粗是树形检索高亮效果,绿色白字是节点选中效果。
我这边的树形数据实际不是来源一张表,而是4张表,还没算关系表。顶级节点在项目表,二级节点楼栋在楼栋表,三级节点单元在单元表,子节点房间在房间表。这里的加载用到的是异步,ztree节点上增加了一个自定义属性nodetype,请求接口是一个,出来的节点数据是一个,但是实际我在后台serviceimpl层是根据节点nodetype和id一起做的查询。后台的代码我就不贴了,贴前端的吧:
树形的初始化
var setting = {
view: {
selectedMulti: false,
showIcon:false,
fontCss: function (treeId, treeNode) {
var fCss = {};
var hightlight = treeNode.highlight;
var hover = treeNode.isHover;
//console.log("hover:"+hover);
//console.log("hightlight:"+hightlight);
if(hightlight == undefined){
if(!!hover){
fCss = {color: "#fff","background-color":"#48C8C4","font-weight": "bold"};
}else{
fCss = {color: "#000","background-color":"#fff","font-weight": "normal"};
}
}else{
if(!!hightlight){
//console.log("++++++");
if(hover){
//console.log("++++++-------------");
fCss = {color: "#fff","background-color":"#48C8C4","font-weight": "bold"};
}else{
fCss = {color: "#44aff0", "font-weight": "bold"};
}
if(isRemove){
//console.log("++++++111111111111111111111111");
fCss = {color: "#44aff0", "background-color":"#fff","font-weight": "bold"};
isRemove = false;
}
}else{
//console.log("-----------------")
if(hover){
//console.log("2222222-");
fCss = {color: "#fff","background-color":"#48C8C4","font-weight": "bold"};
}else{
fCss = {color: "#000","background-color":"#fff","font-weight": "normal"};
}
}
}
return fCss;
}
},
async: {
enable: true,
url:"../energy/getCompanyHouseTreeData?company_id="+indexSelCompany,
autoParam:["id","level","node_type"],
otherParam:{"otherParam":"zTreeAsyncTest"},
type:"post",
dataFilter: filter
},
callback: {
beforeClick: beforeClick,
beforeAsync: beforeAsync,
onAsyncError: onAsyncError,
onAsyncSuccess: onAsyncSuccess
}
};
zNodes = [{id:selCompany, pId:0,parrentId:0, name:selCompanyName, open:false,isParent:true,node_type:1}]
$.fn.zTree.init($("#treeDemo"), setting, zNodes);
//treeObj = $.fn.zTree.init($("#treeDemo"), setting);
treeObj = $.fn.zTree.getZTreeObj("treeDemo");
//点击根节点,让它执行各节点展开异步加载
$("#treeDemo_1_switch").click();
初始化定义的几个回调
//这个过滤有点坑,api上回有一个正则判断,过滤的逻辑。直接导致的是我每次都有一个undefined的节点,目前还不台清楚这个回调的用处,所以直接干掉里面的
function filter(treeId, parentNode, childNodes) {
return null;
}
//这个回调就是节点点击前的,本来可以用onclick的,用这个发现也挺好,能满足目前的要求,这里面的addRemoveSelectStyle就是设置新旧节点样式清除与增加的,配合view里的fontCss,fontCss里处理高亮跟hover一定要判断清楚哦
function beforeClick(treeId, treeNode) {
if(treeNode != null){
pageInit = false;
selNodeId = treeNode.id;
node_type = treeNode.node_type;
//设置点选
addRemoveSelectStyle(treeNode);
oldNode = treeNode;
webStorage.set("selNodeId",selNodeId);
webStorage.set("node_type",node_type);
showRoomKxPage();
queryData();
}
if(node_type != 4){
if (!treeNode.isParent) {
layer.msg("请选择父节点");
return false;
} else {
return true;
}
}
}
//同步前
function beforeAsync(treeId, treeNode) {
return true;
}
//同步错误回调
function onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) {
}
//这个就是异步加载的关键方法,这个方法回自动调用初始化里定义的url,并且传约定的参数,data就是你的ajax返回的,然后就是配合节点的addNodes方法增加节点了
function onAsyncSuccess(event, treeId, treeNode, data) {
if(data != null && data != ""){
var jsonData = eval("[" + data + "]");
//alert("dt:" + jsonData[0].companyTree);
var reTreeArr = jsonData[0].companyTree;
var treeData = [];
if(reTreeArr != null && reTreeArr.length > 0){
for (var i = 0; i < reTreeArr.length; i++) {
var tmpNode = reTreeArr[i];
var childNode = {};
childNode["id"] = tmpNode.id;
childNode["pId"] = tmpNode.parentId;
childNode["name"] = tmpNode.nodeName;
childNode["node_type"] = tmpNode.nodeType;
if(tmpNode.nodeType != 4){
childNode["isParent"] = true;
}
treeData.push(childNode);
}
}
if(treeNode == undefined){
treeObj.addNodes(null,treeData,true);// 如果是根节点,那么就在null后面加载数据
}else{
treeObj.addNodes(treeNode,treeData,true);//如果是加载子节点,那么就是父节点下面加载
}
expandTreeAll(treeNode);
}else{
layer.msg("数据加载错误");
}
}
树形模糊查询与高亮设置
//树形模糊查询,这个就是input输入框oninput调用的方法,跟随内容输入反应,不用按搜索/回车,搞得好像狠聪明一样
function searchFun() {
var inVal = $("#roomCodeIn").val();
var allNode = treeObj.transformToArray(treeObj.getNodes());
if(inVal != null && inVal != ''){
//console.log("---"+allNode + "---length:"+allNode.length);
var conNodes = treeObj.getNodesByParamFuzzy("name", inVal, null);//搜索含有value关键字的节点
console.log(conNodes);
highlightAndExpand_ztree(conNodes,allNode);
}else{
highlightAndExpand_ztree(null,allNode);
}
}
//高亮设置节点,这个的逻辑实际就是把全部节点跟要高亮的节点都设置属性后做节点更新,其实方法可以优化下,做全部节点清除样式时判断下是否被高亮包含,如果有可以不做样式清除
function highlightAndExpand_ztree(highlightNodes,allNode) {
//先把全部节点更新为普通样式
for(var i = 0; i < allNode.length; i++) {
allNode[i].highlight = false;
treeObj.updateNode(allNode[i]);
}
//把指定节点的样式更新为高亮显示,并展开
if(highlightNodes != null) {
for(var i = 0; i < highlightNodes.length; i++) {
//高亮显示节点
highlightNodes[i].highlight = true; //设置
treeObj.updateNode(highlightNodes[i]); //执行
}
}
}
前端的处理基本就这样了,关于ztree的集成这里就不写了。按照官网demo做就ok了。
后台的java接口思路前面说过了,这里就不贴了,贴了也就是dao的调用,sql那肯定是不适用的,呵呵。