1、功能实现的关键点
1)TR元素的id、pid值的命名规则:以TR_开头,将每一层数据集中记录的索引加在前缀的后面,各层索引之间用下划线(_)隔开,比如TR_0_0_3。
2)控制数据行显示/隐藏的JavaScript代码。
2、显示数据行的Freemarker模板
<#macro showSub pId trID _level>
<#-- 如果父ID为空,则取顶层的记录 -->
<#if pId?has_content>
<#local subList = serviceHelper.findSubOrganizations(pId) >
<#else>
<#assign subList = serviceHelper.findTopOrganizations() >
</#if>
<#list subList as item>
<#local subList2 = serviceHelper.findSubOrganizations(item.orgId)>
<#-- 行编号 -->
<#if trID?has_content>
<#local subId = "${trID}_${item_index?string('####')}">
<#else>
<#local subId = "${item_index?string('####')}">
</#if>
<tr id="TR_${subId}" <#if trID?has_content> pid="TR_${trID}" </#if> class="<#if rowIndex%2 == 0>bg1<#else>bg1</#if>" οndblclick="showDetails('orgView.action?orgId=${item.orgId}')" style="display:<#if _level?number-1 gt expandDepth>none</#if>">
<td style="text-align:left;text-indent:${(_level?number - 1)*20}pt;">
<#-- 有下级节点才显示加/减号的图片 -->
<#if subList2?has_content>
<#if _level?number gt expandDepth>
<img src="images/dtree/nolines_plus.gif" id="IMG_${subId}" border="0" οnclick="javascript:showHiddenNode(this, 'TR_${subId}')" style="cursor:hand;" align="absmiddle">
<#else>
<img src="images/dtree/nolines_minus.gif" id="IMG_${subId}" border="0" οnclick="javascript:showHiddenNode(this, 'TR_${subId}')" style="cursor:hand;" align="absmiddle">
</#if>
</#if>
<a href="#" οncοntextmenu="showContextMenu('orgContextMenu', '${item.orgId}')">${item.name?if_exists?html} </a></td>
<td>${item.shortName?if_exists?html} </td>
<td>${item.contactor?if_exists?html} </td>
<td>${item.telephone?if_exists?html} </td>
<td>${item.fax?if_exists?html} </td>
</tr>
<#assign rowIndex = rowIndex + 1>
<@showSub item.orgId "${subId}" "${_level?number+1}"/>
</#list>
</#macro>
<#assign rowIndex = 0>
<#assign expandDepth = 1> <#-- 默认展开的层数,层数大于该值时将被隐藏 -->
<table border="0" cellspacing="0" cellpadding="0" class="width100">
<tr>
<td style="padding-top:0px;">
<table border="0" cellspacing="0" cellpadding="2" class="list" width="100%">
<tr class="top" height="25">
<td nowrap>组织名称</td>
<td width="70">简称</td>
<td width="70">联系人</td>
<td width="100">联系电话</td>
<td width="100">传真</td>
</tr>
<@showSub "" "" "1" />
</table>
</td>
</tr>
</table>
3、获取数据的DAO方法
public List findSubOrganizations(String parentOrgId) {
return find("from Organization where parentOrgId='" + parentOrgId + "'");
}
public List findTopOrganizations() {
return find("from Organization where parentOrgId is null or parentOrgId=''");
}
4、控制数据行显示/隐藏的JavaScript代码
//显示或隐藏树形Table的子节点数据 function showHiddenNode(imgObj,trId){ var imgSrc = imgObj.src.toLowerCase(); if(imgSrc.indexOf("nolines_minus.gif") != -1){ //隐藏 imgObj.src = "images/dtree/nolines_plus.gif"; jQuery("tr[id^=" + trId + "_]").css("display", "none"); }else{ //显示 imgObj.src = "images/dtree/nolines_minus.gif"; //显示第一层的子节点 var trs = jQuery("tr[pid=" + trId + "]"); trs.css("display", ""); //显示更深层的子节点 for(var i=0;i<trs.length;i++){ showHiddenSub(trs[i].id); } } } //递归检查下一级节点是否需要显示 function showHiddenSub(trId){ var imgObj = document.getElementById("IMG_" + trId.replace("TR_","")); if(imgObj == null) return; var imgSrc = imgObj.src.toLowerCase(); if(imgSrc.indexOf("nolines_minus.gif") != -1){//下级节点是展开的,则需要显示出来 var trs = jQuery("tr[pid=" + trId + "]"); trs.css("display", ""); for(var i=0;i<trs.length;i++){ showHiddenSub(trs[i].id); } } }
5、显示效果如图一所示
6、演示程序
看附件