随着Ajax技术的广泛运用,很多以前很难通过HTML实现的客户端功能,现在都可以尝试了。本人由于实际项目的需要,开发了这么一个Ajax类似Excel表格输入控件。近两个星期、超过2000余行原创JavaScript代码,现在整理出来与技术广大朋友共享。
首先需要说明的是,开发过程采用了许多Prototype与scriptaculous的方法和组件。
要实现上下行、左右列均可固定,只有中间行列可滚动的表格,需要将整个表格划分成16个部分,具体如下:
#
left fixed columns
scrollable columns
right fixed columns
1
top fixed rows
2
scrollable rows
3
bottom fixed rows
这16个单元格内又放置16个表格。其中又有8个单元格又要分别放在8个可滚动的DIV内。
buildFixedTable: function() {
return Builder.node("TABLE", {cellSpacing:'0', cellPadding:'0', style:'table-layout:fixed;border-collapse:collapse;margin:0;'});
},
buildRelativeDiv: function() {
return Builder.node("DIV", {style:'position:relative; overflow:hidden;'});
},
第一个function运用builder创建一个表格,注意table-layou:fixed非常重要。
第二个function运用builder创建一个可滚动的DIV,注意overflow:hidden,因为我们需要提供单独的垂直滚动条,统一负责四个垂直方向的DIV的滚动。也需要提供单独的水平滚动条,统一负责四个水平方向的DIV的滚动。
另外,我们需要给每个区域标注一下。首先,四个列区域分别为no,left,center,right;四个行区域分别为header,top,buffer,footer。这样行列组合成每个区域的标识。例如top行的四个区域的标识分别为:no-top,left-top,center-top,right-top。同时为每个行赋予相应区域的标识。
例如如果要取任一单元格所在行的数据,只需要提供区域名和所在区域的行号即可。实现如下:
getRowData: function(rowIndex, area, rowId) {
var data = new Array(0);
if (rowId == "inserted") {
data[0] = null; //important, can't be ""
} else
data[0] = rowId;
if (area == "footer") {
return data;
}
var getFunction = null;
if (this.leftFixedColumns > 0) {
getFunction = ("_get-left-" + area + "-row-data").camelize();
eval("this." + getFunction + "(rowIndex, data);");
}
getFunction = ("_get-center-" + area + "-row-data").camelize();
eval("this." + getFunction + "(rowIndex, data);");
if (this.rightFixedColumns > 0) {
getFunction = ("_get-right-" + area + "-row-data").camelize();
eval("this." + getFunction + "(rowIndex, data);");
}
return data;
},
这里利用javascript的反射机制调用相应的方法,例如_getLeftTopRowData,_getCenterTopRowData,_getRightTopRowData,_getLeftBufferRowData,_getCenterBufferRowData,_getRightBufferRowData。
同样的方法有很多,如getColCells(取得任一单元格所在列的数据)、getNoCell(取得任一单元格所在行的序号单元格)、getAdjustedColIndex(取得任一单元格所在列的全局列号)、getAdjustedRowIndex(取得任一单元格所在行的全局行号)、setRowCssClass(设置任一单元格所在行的css样式)等。