思路: 先查询出所有数据的根结点,并对每个根结点检查是不是有子结点,如果有子结点则在显示时增加"+"图片,没有则不添加.但用户点击"+"图片时,则通过AJAX调用逻辑流查询触发结点的所有子结点(采用递归方式,以每个子结点的父结点属性从上向下查询),并隐藏加载到触发结点后面(以TR形式添加,并设置每个子元素的paraTaskno属性为父结点taskno(其实仍是以递归方式,从上向下给每个子元素的paraTaskno属性设置父元素的id)
服务端数据: 仅查询根结点.
html代码:
<viewlist id="e587ead4-daa3-431e-a0ed-fac40e013850">
<h:form name="page_form" action="com.bos.mp.taskStatistics.TaskStatistics.flow" method="post">
<input type="hidden" name="_eosFlowAction" value="pageQuery" >
<h:hiddendata property="criteria" />
<h:hidden property="page/begin"/>
<h:hidden property="page/length"/>
<h:hidden property="page/count"/>
<h:hidden property="page/isCount"/>
<w:panel id="list_panel" width="100%" title="任务列表">
<table align="center" border="0" width="100%" class="EOS_table">
<tr id="table_header">
<th>
任务名称
</th>
<th>
项目名称
</th>
<th>
项目模块
</th>
<th>
工作占项目比率
</th>
<th>
负责人
</th>
<th>
审核人
</th>
<th>
计划开始日
</th>
<th>
计划完成日
</th>
<th>
任务状态
</th>
<th>
完成率(%)
</th>
<th>
更新日期
</th>
<th>
原因
</th>
<th>
实际完成率(%)
</th>
<th>
实际完成日
</th>
<th>
提前/滞后完成天数
</th>
</tr>
<w:checkGroup id="group1">
<l:iterate property="mpprojectfollows" id="id1">
<%
long temp = 0;
if(null != ((DataObject)pageContext.getAttribute("id1")).getString("proEndDate")){
DataObject t=(DataObject)pageContext.getAttribute("id1");
String d1 = ((DataObject)pageContext.getAttribute("id1")).getString("comDate") == null ? new SimpleDateFormat("yyyy-MM-dd").format(new Date()):((DataObject)pageContext.getAttribute("id1")).getString("comDate");
String d2 = ((DataObject)pageContext.getAttribute("id1")).getString("proEndDate");
temp = RetOrgInfo.daysDifference(d1,d2);
}
if(temp<0 && !((DataObject)pageContext.getAttribute("id1")).getString("taskStatus").equals("完成")){
out.print("<tr class='EOS_table_row' style='background-color:red;' id='"+((DataObject)pageContext.getAttribute("id1")).getString("taskno")+"'>");
}else if(temp<0 && ((DataObject)pageContext.getAttribute("id1")).getString("taskStatus").equals("完成")){
out.print("<tr class='EOS_table_row' style='background-color:orange;' id='"+((DataObject)pageContext.getAttribute("id1")).getString("taskno")+"'>");
}else if(temp>0 && ((DataObject)pageContext.getAttribute("id1")).getString("taskStatus").equals("完成")){
out.print("<tr class='EOS_table_row' style='background-color:green;' id='"+((DataObject)pageContext.getAttribute("id1")).getString("taskno")+"'>");
}else{
out.print("<tr class='EOS_table_row' id='"+((DataObject)pageContext.getAttribute("id1")).getString("taskno")+"'>");
}
%>
<td align="left" >
<l:present property="childTasks" iterateId="id1">
<img src="<%=request.getContextPath() %>/common/skins/default/images/grouppanel/grouppanel_open.gif" onclick="node_click('<b:write iterateId="id1" property="taskno"/>');"/>
</l:present>
<h:hidden iterateId="id1" property="paraTaskno"/>
<a href="#" onclick="javascript:showTaskDet('<b:write iterateId="id1" property="taskno"/>');"><b:write iterateId="id1" property="taskName"/></a>
</td>
<td align="center">
<b:write iterateId="id1" property="projectName"/>
</td>
<td align="center">
<b:write iterateId="id1" property="modName"/>
</td>
<td align="center">
<b:write iterateId="id1" property="taskRate"/>
<l:notEmpty iterateId="id1" property="taskRate">
%
</l:notEmpty>
</td>
<td align="center">
<b:write iterateId="id1" property="planPres"/>
</td>
<td align="center">
<b:write iterateId="id1" property="auditorName"/>
</td>
<td align="center">
<b:write iterateId="id1" property="proStarDate" formatPattern="yyyy-MM-dd"/>
</td>
<td align="center">
<b:write iterateId="id1" property="proEndDate" formatPattern="yyyy-MM-dd"/>
</td>
<td align="center">
<b:write iterateId="id1" property="taskStatus"/>
</td>
<td align="center">
<b:write iterateId="id1" property="actorRated"/>
</td>
<td align="center">
<b:write iterateId="id1" property="actorDate" formatPattern="yyyy-MM-dd"/>
</td>
<td align="center">
<b:write iterateId="id1" property="reason"/>
</td>
<td align="center">
<b:write iterateId="id1" property="auditRate"/>
</td>
<td align="center">
<b:write iterateId="id1" property="comDate" formatPattern="yyyy-MM-dd"/>
</td>
<td align="center">
<%
if(temp<0){
out.print("滞后"+Math.abs(temp)+"天");
}else if(temp>0 && ((DataObject)pageContext.getAttribute("id1")).getString("taskStatus").equals("完成")){
out.print("提前"+temp+"天");
}
%>
</td>
</tr>
</l:iterate>
</w:checkGroup>
<tr>
<td colspan="16" class="command_sort_area">
<div id="pageroot" align="right">
<l:equal property="page/isCount" targetValue="true">
共
<b:write property="page/count"/>
条记录 第
<b:write property="page/currentPage"/>
页/
<b:write property="page/totalPage"/>
页
</l:equal>
<l:equal property="page/isCount" targetValue="false">
第
<b:write property="page/currentPage"/>
页
</l:equal>
<input type="button" onclick="firstPage('page', 'pageQuery', null, null, 'page_form');" value="首页" <l:equal property="page/isFirst" targetValue="true">disabled</l:equal> >
<input type="button" onclick="prevPage('page', 'pageQuery', null, null, 'page_form');" value="上页" <l:equal property="page/isFirst" targetValue="true">disabled</l:equal> >
<input type="button" onclick="nextPage('page', 'pageQuery', null, null, 'page_form');" value="下页" <l:equal property="page/isLast" targetValue="true">disabled</l:equal> >
<l:equal property="page/isCount" targetValue="true">
<input type="button" onclick="lastPage('page', 'pageQuery', null, null, 'page_form');" value="尾页" <l:equal property="page/isLast" targetValue="true">disabled</l:equal> >
</l:equal>
</div>
</td>
</tr>
</table>
</w:panel>
</h:form>
</viewlist>
<script>
var jquery = jQuery.noConflict();
//主结点展开/收起
function node_click(taskid){
var el=jquery("#"+taskid).find("img")[0]//event.srcElement
var path=el.src.substr(el.src.lastIndexOf("/")+1)
var prifix=el.src.substr(0,el.src.lastIndexOf("/"))
if(path=="grouppanel_open.gif"){
//显示结点
var tr=jquery(el).closest("tr");
if(jquery(el).closest("tr").next().css("display")=="none"){
el.src=prifix+"/grouppanel_close.gif";
tr.nextAll("tr[paraTaskno='"+tr.attr("id")+"']").show();
}else{
readchildnodeByAjax(taskid);
jquery(el).trigger("click");
}
}else{
//隐藏结点
el.src=prifix+"/grouppanel_open.gif";
var tr=jquery(el).closest("tr");
recursion_node(tr,false);
}
}
//ajax读取子结点
function readchildnodeByAjax(taskid){
var myAjax=new Ajax("com.bos.mp.projectfollow.mpprojectfollowbiz.QueryTask.biz");
myAjax.addParam("criteria/_entity","com.bos.mp.projectfollow.dataset.ProTaskQryEntity");
myAjax.addParam("criteria/_expr[0]/paraTaskno",taskid);
myAjax.submit();
//获取"root/data/mpprojectfollows"结点数组
var nodes=myAjax.getXMLDom().selectNodes("root/data/mpprojectfollows");
for(var i=0;i<nodes.length;i++){
addElement(jquery("#"+taskid),nodes[i]);
}
}
/**
*动态增加tr结点,以请求的服务端数据来遍历添加结点
*template:html页面元素;node:服务端数据子实体
*/
function addElement(template,node){
var xml=jquery(node);
var template=addnode(template,xml)
var childnodes=xml.children("childTasks");
for(var i=0;i<childnodes.length&&jquery(xml.children("childTasks")[i]).text()!="";i++){
addElement(template,xml.children("childTasks")[i]);
}
}
/**
*以服务端的子实体对象(xml)构造一个结点添加到html元素(template)
*/
function addnode(template,xml){
var open_gif='<%=request.getContextPath() %>/common/skins/default/images/grouppanel/grouppanel_open.gif';
var close_gif="<%=request.getContextPath() %>/common/skins/default/images/grouppanel/grouppanel_close.gif"
//从模板结点构造出目标结点tr
var curtr=template.clone().insertAfter(template).hide()
.attr("id",jquery(xml.find("taskno")[0]).text())
.attr("paraTaskno",jquery(xml.find("paraTaskno")[0]).text());
//首个TD结点
var firsttd=jquery(curtr.children("td")[0]);
var td=jquery(curtr.children("td")[0]).css("padding-left",parseInt(firsttd.css("padding-left"))+10+"px")
.empty();
jquery("<a href='#'></a>").text(jquery(xml.find("taskName")[0]).text())
.bind("click",function(){
showTaskDet(jquery(xml.find("taskno")[0]).text());
}).appendTo(td);
var img=jquery("<img/>").prependTo(td);
if(jquery(xml.children("childTasks")[0]).text()!=""){
//非叶子结点,绑定事件
img.attr("src",open_gif);
img.bind("click",function(){
var path=jquery(this).attr("src");
var tr=jquery(this).closest("tr");
if(path==open_gif){
jquery(this).attr("src",close_gif);
recursion_node(tr,true);
}else{
jquery(this).attr("src",open_gif);
recursion_node(tr,false);
}
})
}else{
//叶子结点
img.attr("src",close_gif);
}
td.next().empty()//text(jquery(xml.find("projectName")[0]).text())
.next().empty()//text(jquery(xml.find("modName")[0]).text())
.next().text(jquery(xml.find("taskRate")[0]).text())
.next().text(jquery(xml.find("planPres")[0]).text())
.next().text(jquery(xml.find("auditorName")[0]).text())
.next().text(jquery(xml.find("proStarDate")[0]).text())
.next().text(jquery(xml.find("proEndDate")[0]).text())
.next().text(jquery(xml.find("taskStatus")[0]).text())
.next().text(jquery(xml.find("actorRated")[0]).text())
.next().text(jquery(xml.find("actorDate")[0]).text())
.next().text(jquery(xml.find("reason")[0]).text())
.next().text(jquery(xml.find("auditRate")[0]).text())
.next().text(jquery(xml.find("comDate")[0]).text())
.next().text("");
return curtr;
}
/**
*层叠递归方式显示或隐藏结点
* node:jquery对象;isshow:boolean值
*/
function recursion_node(node,isshow){
var open_gif='<%=request.getContextPath() %>/common/skins/default/images/grouppanel/grouppanel_open.gif';
var close_gif="<%=request.getContextPath() %>/common/skins/default/images/grouppanel/grouppanel_close.gif"
var nodes=node.nextAll("tr[paraTaskno='"+node.attr("id")+"']")
for(var i=0;i<nodes.length;i++){
recursion_node(jquery(nodes[i]),isshow);
if(!isshow){
jquery(nodes[i]).hide();
}else{
jquery(nodes[i]).show();
}
}
if(nodes.length>0){
jquery(node.find("img")[0]).attr("src",!isshow?open_gif:close_gif)
}
}
</script>
posted on 2011-04-01 17:39
紫蝶∏飛揚↗ 阅读(1372)
评论(0) 编辑 收藏 所属分类:
div+css+js代码 、
EOS