利用JavaScript实现任意行、列的锁定

浏览: 2365

行、列锁定是客户经常会对报表提的需求,确实,对于一张记录比较多的报表是非常有必要做行、列锁定的。下面的方法实现了任意行、列(排除数据列)的锁定。

接下来说一下,我的实现思路。首先是要通过HTML项目增加一个DIV,包住列表或交叉表,然后通过js控制锁定行、列。基本布局如下图所示

Clipboard Image.png

其中“DIV开始”HTML项目内容如下

<DIV style="OVERFLOW: auto; WIDTH: 400px;HEIGHT: 350px">

DIV结束内容如下

</DIV>

利用两个HTML项目拼成一个指定大小而且产生滚动条的DIV包住列表,当列表的款或者高超过DIV中设置的高度或宽度时,将产生滚动条。

建议:将HTML项目的说明属性填写清楚,这样很容易看出那个HTML项目是干啥的,当用的HTML项目较多时填写其说明属性还是非常有必要的。

注意:上图是将DIV结束和锁定脚本两个HTML项目放到列表下了,若列表没有分页则脚本能正常执行,若列表存在分页则脚本不会被执行,只有到末页时才能执行。因为默认情况下列表下的内容是在列表的最后一行结束后才调用的(可以在产生分页的列表后加一个图表看看效果)。若处理的列表存在分页,则需要把DIV结束和锁定脚本移动到页脚处,因为页脚不管有没有分页都回生成。如下图

Clipboard Image.png

接下来找到列表的名称属性,为其设置一个值,这里我们设置为locktable,如下图所示

Clipboard Image.png

锁定脚本HTML项目内容如下

<style type="text/css">
.lockRow {
POSITION: relative;
border-width: 1px;
top: expression( this . offsetParent . offsetParent . scrollTop );
Z-INDEX: 5;
}

.lockRow td {
POSITION: relative;
}

.lockColumn {
Z-INDEX: 4;
POSITION: relative;
left: expression( this . parentElement . offsetParent . parentElement . scrollLeft );
}
.crossHeader
{
Z-INDEX: 6;
POSITION: relative;
left: expression( this . parentElement . offsetParent . parentElement . scrollLeft );
}
</style>
<script>
function getTable(sortTableId, rvContent)
{
var sortTable;
var tables = rvContent.getElementsByTagName("table");
for (var i = 0; i < tables.length; i++)
{
if (tables[i].getAttribute("LID") == sortTableId)
{
sortTable = tables[i];
break;
}
}
return sortTable;
}
function getRVContent()
{
var objName = getObjectName();
return eval("document.getElementById('RVContent" + objName + "');");
}
function getObjectName()
{
return document.getElementById("cv.id").value;
}
function initLockTable(table_id, lockRows, lockColumns)
{
var lockRows = lockRows;
var lockColumns = lockColumns;
var table = getTable(table_id, getRVContent());
table.style.position = "relative";
var tabRows = table.rows.length;
table.style.display = "inline";
//处理表头锁定
for (var i = 0; i < lockRows; i++)
{
table.rows[i].className = "lockRow";
}
dealLockCell(table, 0, tabRows, lockColumns, 0)
}
function dealLockCell(table, beginRow, rowsLength, lockColumns, spans)
{
var lastRowNum = beginRow + rowsLength;
var rowSpanCount = 0;
for (var i = beginRow; i < lastRowNum; i++)
{
for (var j = 0; j < lockColumns; j++)
{
if (table.rows[i].cells[j].type == "datavalue")
{
if (j > 0)
{
continue;
}
}
if (i == 0 && j == 0)
{
var crossHeader = table.rows[0].cells[0];
crossHeader.className = "ml crossHeader";
crossHeader.style.borderWidth = 1;
crossHeader.style.borderBottomWidth = 0;
for (var k = 1; k < crossHeader.rowSpan; k++)
{
var nod = crossHeader.cloneNode(true);
nod.rowSpan = 1;
nod.style.borderTopWidth = 0;
nod.style.borderBottomWidth = 0;
nod.innerText = " ";
table.rows[k].insertBefore(nod, table.rows[k].cells[0]);
}
j = j + crossHeader.colSpan;
i = i + crossHeader.rowSpan - 1;
table.rows[i].cells[0].style.borderBottomWidth = 1;
crossHeader.rowSpan = 1;
} else
{
if (table.rows[i].cells[j].rowSpan > 1)
{
table.rows[i].cells[j].className = "ml lockColumn";
rowSpanCount = rowSpanCount + 1;
} else
{
table.rows[i].cells[j].className = "ml lockColumn";
}
}
}
if (rowSpanCount > 0)
{
i = dealLockCell(table, (i + 1), table.rows[i].cells[0].rowSpan - 1, lockColumns - 1, rowSpanCount);
rowSpanCount = 0;
}
}
return beginRow + rowsLength - 1;
}
initLockTable("locktable", 2, 2);
</script>

该脚本前面利用CSS设置了行、列、和交叉表头所用到的样式,可以根据实际要求对此进行修改。

JS脚本用到了getTable、getRVContent、getObjectName、initLockTable、dealLockCell这几个函数。其中getTable、getRVContent、getObjectName这几个在一起的报表中就用到了,实际上新增的是initLockTable和dealLockCell

initLockTable是锁定的初始化函数,需要传递三个参数,第一个就是表的名称,即列表或交叉表的名称,第二个参数是锁定的行数,第三个是锁定的列数,若之锁定行,则此参数传0。

dealLockCell是用递归算法来处理列锁定,以此来实现任意数的列锁定,写这个函数还是费了不少劲呢,呵呵。



在Cognos 10 中,table的名称定义有所变化,对应的JS需要一点小的修改。

方法如下:

把原贴代码中这行进行修改

initLockTable("locktable", 2, 2);

如果是从ReportStudio中测试运行,改成

initLockTable("locktableRS", 2, 2);

如果是从Cognos Viewer中运行,改成

initLockTable("locktable_NS_", 2, 2);

即可。

推荐 0
本文由 hupingzhi 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册