客户端实现类似于DataGrid的输入表格控件
客户端实现类似于DataGrid的输入表格控件 在aspx中,当使用DataGrid提交数据时,客户每输入一条记录,就会向服务端提交一次数据,所以当提交数据较多时,效率就会很低,如果在客户端将这些数据'打包',再上传到服务端,这样就可以一次上传多条数据。 所以基本思路就是在客户端获取所有的输入数据,将数据转换成以逗号分隔的字符串,将字符串传到服务器,在服务端将字符串拆成数组(用split函数),再写入数据库中。所有,提交到服务器只有一次。 这个控件还有一些缺陷:删掉一行数据时,可能使IE死掉。 只能在写在网页中,不能写成js文件后再引用,可能是代码中包含了window.alert方法,我想这个问题是可以解决的,如果有哪位高手解决了,麻烦通知一下,谢了。还有一个解决方法,将代码写成inc文件,代码用<script>.....</script>,再引用:<!-- #include virtual='../script/ClientDataGrid.inc'>,这样运行时,代码就会自动加到网页上。 这个控件的功能都写再备注里,大家也可以扩展一些功能。如果有哪位高手作了改进请一定通知一下,谢了。
代码如下:
<script language='javascript'>
/// 客户端DataGrid
/// Author : Curllion Zhang
/// 2005-7-29
//-----------------------------------表格对象-------------------------------------------
//注意:
// 1、创建该对象时,一定要设定对象的ID值为此象的ID
// 2、如果指定了单元格的CSS,则被选中的行的CSS不起作用
//
function ClientDataGrid(ColCount,TitleRow,TitleRowHeigh,RowHeight,ColWidths,PostCols,InputCols,TextBoxs,Parent)
{
this.ColCount = ColCount; //列数量
this.TitleRow = new Array(ColCount); //表格标题
this.TitleRowHeigh = TitleRowHeigh; //表格标题的行高
this.RowHeight = RowHeight; //行高
this.ColWidths = new Array(ColCount); //表示列宽的数组,单位px
this.Cellspacing; //单元格间格
this.Cellpadding; //单元格空白
this.Border; //边框
this.Width; //控件宽度
this.Height; //控件高度
this.BorderColor; //表格边框颜色,文本
this.CSS; //指定CSS,文本
this.TitleCSS; //指定标题CSS
this.TitleItemCSS; //指定标题单元格的CSS
this.RowCSS; //指定行的CSS
this.ItemCSS; //指定单元格CSS,如果指定了单元格的CSS,则被选中的行的CSS不起作用
this.SelectedCSS; //被选定行的CSS
this.PostCols = new Array(ColCount); //数组,表示当前要上传的列,如果是1,则表示要上传
this.InputCols = new Array(ColCount); //数组,表示当前要上传的列,如果是1,则表示要输入
if(TextBoxs == null)
this.TextBoxs = null;
else
{
//与此类关联的input控件,数据将会从此控件中提交
this.TextBoxs = new Array(TextBoxs.length);
for(var i = 0; i< TextBoxs.length ;i++)
{
this.TextBoxs[i] = TextBoxs[i];
}
}
this.SelectedIndex = -1; //选择索引,-1表示没有行被选中
this.DeleteEnable = true; //是否显示删除按钮
this.RowCount = 0; //行数
this.Rows = new Array(); //行集合
this.Parent = Parent; //此控件的父控件
this.ID='dg'; //本控件的ID
for(var i = 0; i< ColCount;i++)
{
if(ColWidths == null)
this.ColWidths[i] = 60; //指定默认行高为60,也可以用字符串指定为百分数
else
this.ColWidths[i] = ColWidths[i];
this.TitleRow[i] = TitleRow[i];
if(PostCols == null)
this.PostCols[i] = 0; //默认是没有列要上传
else
this.PostCols[i] = PostCols[i];
if(InputCols == null)
this.InputCols[i] = 0; //默认是没有列要上传
else
this.InputCols[i] = InputCols[i];
}
}
//画出表格
ClientDataGrid.prototype.Draw = function(ID)
{
this.ID=ID;
var str = '<table rules='all' id = '' + ID + '_datagrid' ' +
(this.Border !=null?('border=' + this.Border):'') + ' ' +
(this.Cellspace !=null?('cellspace=' + this.Cellspace):'') + ' ' +
(this.Cellpadding !=null?('cellpadding=' +this.Cellpadding):'') + ' ' +
(this.Width !=null?('width=' + this.Width):'') + ' ' +
(this.Height !=null?('height=' + this.Height):'') + ' ' +
(this.BorderColor !=null?('bordercolor=' + this.BorderColor):'') + ' ' +
(this.CSS !=null?('style='' + this.CSS + '''):'') + '>';
//画标题
str = str + '<tr ' + (this.TitleCSS!=null?('style='' + this.TitleCSS + '''):'') + '>';
for(var i = 0;i<this.ColCount;i++)
{
str = str + '<td ' + (this.ColWidths[i]!=null?('width=' + this.ColWidths[i]):'') + ' ' +
(this.TitleItemCSS!=null?('style='' + this.TitleItemCSS + '' '):'') + '>' + this.TitleRow[i] + '</td>';
}
str = str + '<td ' + (this.TitleItemCSS!=null?('style='' + this.TitleItemCSS + '' '):'') + '>选中</td>';
str = str + '<td ' + (this.TitleItemCSS!=null?('style='' + this.TitleItemCSS + '' '):'') + '>删除</td>';
str = str + '</tr>' ;
//画单元格
for(var i = 0 ; i < this.RowCount; i++)
{
str = str + '<tr id = 'row'+ i + '' ' + (this.RowHeight!=null?('height=' + this.RowHeight):'') + ' ' +
(this.RowCSS!=null?('style='' + this.RowCSS + '''):'') + '>';
for(var j=0;j<this.ColCount;j++)
{
if(this.InputCols[j] == 1)
str = str + '<td ' + (this.ItemCSS!=null?('style='' + this.ItemCSS + '' '):'') + '><input language='javascript' type=text value='' + this.Rows[i].Data[j] + '' onblur=''+this.ID+'.CellChange('+j+','+i+',this.value)'></td>';
if(this.InputCols[j] == 0)
str = str + '<td ' + (this.ItemCSS!=null?('style='' + this.ItemCSS + '' '):'') + '>' + this.Rows[i].Data[j] + '</td>';
}
str = str + '<td ' + (this.ItemCSS!=null?('style='' + this.ItemCSS + '' '):'') + '><input language='javascript' type=button value='选中' onclick='' + this.ID + '.SelectRow(' + i + ')'></td>';
str = str + '<td ' + (this.ItemCSS!=null?('style='' + this.ItemCSS + '' '):'') + '><input language='javascript' type=button value='删除' onclick='' + this.ID + '.DeleteRowAt('+ i + ')'></td>';
str = str + '</tr>';
}
str = str + '</table>';
this.Parent.innerHTML = str;
//写到TextBoxs中
var k = 0;
for(var j=0;j<this.ColCount;j++)
{
if(this.PostCols[j] == 0)
continue;
tmp = '';
for(var i=0;i<this.RowCount;i++)
{
tmp = tmp + this.Rows[i].Data[j] + ',';
}
this.TextBoxs[k].value = tmp.substr(0,tmp.length-1);
k++;
}
}
//在指定位置插入一行
ClientDataGrid.prototype.InsertRowAt = function(index,dataRow)
{
tmpRows = this.Rows.slice(0,index).concat(new Array(dataRow)).concat(this.Rows.slice(index,this.RowCount+1));
this.Rows = tmpRows;
this.RowCount++;
this.SelectedIndex = -1;
}
//在指定位置插入多行
ClientDataGrid.prototype.InsertRowsAt = function(index,dataRows)
{
tmpRows = this.Rows.slice(0,index).concat(dataRows).concat(this.Rows.slice(index,this.RowCount+1));
this.Rows = tmpRows;
this.RowCount = this.RowCount + dataRows.length;
this.SelectedIndex = -1;
}
//在最后面插入一行
ClientDataGrid.prototype.InsertRow = function(dataRow)
{
this.Rows = this.Rows.concat(new Array(dataRow))
this.RowCount++;
}
//再最后面插入多行
ClientDataGrid.prototype.InsertRows = function(dataRows)
{
this.Rows = this.Rows.concat(dataRows);
this.RowCount = this.RowCount + dataRows.length;
this.SelectedIndex = -1;
}
//选中一行
ClientDataGrid.prototype.SelectRow = function(index)
{
this.SelectedIndex = index;
//因为标题行不算,所以从1开始
for(var i = 1 ;i<=this.RowCount ;i++)
{
var tmpCSS = '';
if(i==this.SelectedIndex + 1)
{
if(this.SelectedCSS != null)
tmpCSS = 'window.document.all(\'' + this.ID + '_datagrid\').rows(' + i + ').style.cssText=''+ this.SelectedCSS +''';
else
tmpCSS = 'window.document.all(\'' + this.ID + '_datagrid\').rows(' + i + ').style.cssText=''';
}
else
{
if(this.RowCSS != null)
tmpCSS = 'window.document.all(\'' + this.ID + '_datagrid\').rows(' + i + ').style.cssText=''+ this.RowCSS +''';
else
tmpCSS = 'window.document.all(\'' + this.ID + '_datagrid\').rows(' + i + ').style.cssText=''';
}
eval(tmpCSS);
}
}
//更改表格的值
ClientDataGrid.prototype.CellChange = function(x,y,value)
{
//先改变对象的值
this.Rows[y].Data[x] = value;
//写到TextBoxs中
var k = 0;
for(var j=0;j<this.ColCount;j++)
{
if(this.PostCols[j] == 0)
continue;
tmp = '';
for(var i=0;i<this.RowCount;i++)
{
tmp = tmp + this.Rows[i].Data[j] + ',';
}
this.TextBoxs[k].value = tmp.substr(0,tmp.length-1);
k++;
}
}
//删除指定位置的行,如果删除过快,就IE就会死掉,所以放用户确认一下,并且再重绘时,先清掉,防止宕掉
ClientDataGrid.prototype.DeleteRowAt = function(index)
{
if(confirm('确认要删除吧?'))
{
this.Parent.innerHTML = '';
this.SelectedIndex = -1;
if(index < 0 || index >= this.RowCount)
{
window.alert('指定的位置没有行');
return;
}
tmpRows = this.Rows.slice(0,index).concat(this.Rows.slice(index+1,this.RowCount));
this.Rows = tmpRows;
this.RowCount--;
//eval('window.document.all(\'' + this.ID + '_datagrid\').deleteRow(' + index + ');')
this.Draw(this.ID);
}
}
//-----------------------------------行对象------------------------------
function DataRow(Data)
{
this.ItemCount = Data.length; //一行的元素个数
this.Data = new Array(); //记录数据
for(var i = 0 ;i<this.ItemCount ;i++)
{
this.Data[i] = Data[i];
}
}
</script>
如何使用,例如
<script language='javascript'>
var textBoxs = new Array(document.Form1.pfy ,document.Form1.presult);
var colWidths = new Array('80px','180px',null);
var dg = new ClientDataGrid(3,new Array('代码','费用类型','金额'),25,25,colWidths,new Array(1,0,1),new Array(0,0,1),textBoxs,document.all('fylist'));
dg.Width = 455;
dg.CSS = 'background-color:White;border-color:#CC9966;border-width:1px;border-style:None;border-collapse:collapse;';
dg.TitleCSS = 'color:#FFFFCC;background-color:#990000;font-weight:bold;';
dg.BorderColor = '#CC9966';
dg.SelectedCSS = 'color:#663399;background-color:#FFCC66;';
dg.Draw('dg');
//这是插入代码,大家可以改成其它的,看看是不是和DataGrid的第一种样式一样呀
function B_insert_onclick()
{
var tmpRows = new Array();
for (i = 0 ;i < Form1.LBExpenss.length ;i ++)
{
if(Form1.LBExpenss.options[i].selected)
{
tmpRows = tmpRows.concat(new Array(new DataRow(new Array(Form1.LBExpenss.options[i].value,Form1.LBExpenss.options[i].text,''))));
}
}
if(dg.SelectedIndex != -1)
dg.InsertRowsAt(dg.SelectedIndex,tmpRows);
else
dg.InsertRows(tmpRows);
dg.Draw('dg');
}
</script>