最近公司要做一组数据操作,需要实现的效果是。显示每个公司每个季度的产品,并求和,但是里面的产品数量是需要可以编辑的。
就像编辑Excel一样,双击单元格,然后编辑数据,编辑完啦,还要更新到库里去
最近公司要做一组数据操作,需要实现的效果是。显示每个公司每个季度的产品,并求和,但是里面的产品数量是需要可以编辑的。
就像编辑Excel一样,双击单元格,然后编辑数据,编辑完啦,还要更新到库里去。
刚开始想到的是用GridView去实现,这样显示数据和编辑数据方便,但是问题来了,我怎么像Excel一样双击就可以编辑呢,GridView是需要点击“编辑”按钮,才可以编辑的,和需求相差很大啊。而且还要实现很好的用户体验,不要全部页面的刷新,那样很不好的。。。
考虑到这个,就直接用Ajax吧。用Ajax显示数据很简单,直接用js写一个table,或者在Ajax方法里面写就OK啦,但是要实现编辑,怎么弄呢?
和同事商量以后,决定用如下的方法解决。
同样是table,但是显示数据的是HTML的文本框,双击的时候才可以编辑,这个好实现。
显示数据的时候,设置input type="text"的样式为不显示边框就可以啦,双击的时候改变样式显示边框就ok啦。
按照这样的算法,主要的代码如下:
Code
function fun_GetCompanyList(type)
{
//利用ajax类里面的方法得到想要的数据,然后在GetProgram_Target_CallBack函数里面显示table
Program_Target.GetProgram_Target("产品1",type,GetProgram_Target_CallBack);
}
function GetProgram_Target_CallBack(response)
{
if(response!=null)
{
var ds=response.value;
if(ds!=null && typeof(ds)=="object" && ds.Tables!=null)
{
var strHtml="<br><table id='tabCompany' width=100% border=1px; borderColor=#0099ff >";
strHtml=strHtml+"<tr><td>公司ID</td><td>Q1</td><td>Q2</td><td>Q3</td><td>Q4</td><td>合计</td></tr>";
//读取回发事件得到的值,显示table
for(var i=0;i<ds.Tables[0].Rows.length;i++)
{
var id=""+ds.Tables[0].Rows[i].COMPANY_ID;
var q1=""+ds.Tables[0].Rows[i].Q1;
var q2=""+ds.Tables[0].Rows[i].Q2;
var q3=""+ds.Tables[0].Rows[i].Q3;
var q4=""+ds.Tables[0].Rows[i].Q4;
var total=ds.Tables[0].Rows[i].Total;
strHtml=strHtml+"<tr>
strHtml=strHtml+"<td><input type=text readonly=true id="+id+" size='3' value='"+id+"' ondblclick='fun_ChangeValue(this)' onblur='fun_UpdateValue(this)' /></td>";
strHtml=strHtml+"</td><td><input type=text readonly=true id="+id+"_Q1 size='3' value="+q1+" ondblclick='fun_ChangeValue(this)' onblur='fun_UpdateValue(this)' /></td>";
strHtml=strHtml+"</td><td><input type=text readonly=true id="+id+"_Q2 size='3' value="+q2+" ondblclick='fun_ChangeValue(this)' onblur='fun_UpdateValue(this)' /></td>";
strHtml=strHtml+"</td><td><input type=text readonly=true id="+id+"_Q3 size='3' value="+q3+" ondblclick='fun_ChangeValue(this)' onblur='fun_UpdateValue(this)' /></td>";
strHtml=strHtml+"</td><td><input type=text readonly=true id="+id+"_Q4 size='3' value="+q4+" ondblclick='fun_ChangeValue(this)' onblur='fun_UpdateValue(this)' /></td>";
strHtml=strHtml+"</td><td><input type=text readonly=true id="+id+"_Total size='3' value="+total+"/></td></tr>";
}
strHtml=strHtml+"</table>";
//这里把table写到需要显示的DIV里面
document.getElementById("<%=divCompanyList.ClientID %>").innerHTML=strHtml;
}
}
//fieldset1,这个是像Winform一样的GroupBox
document.getElementById("fieldset1").style.display="block";
}
文本框的样式首先设置为不显示边框
Code
<style>
TD input
{
border:0px;
}
#tabCompany td
{
background:white;
text-align:center;
}
</style>
然后在 function fun_ChangeValue(obj)里面设置文本框的边框为红色。
obj.style.border="1px solid red";
在失去焦点的事件中判断修改前后的值是否有变化,如果有,就更新。
如果没有就直接obj.style.border="0px solid white";,本来table的背景色就是白色,所以把文本框的边框设为白色就看不到咯
把做出来的结果给经理审核,了解了流程后,经理提示,为什么不直接在编辑的时候才显示为文本框呢,这样比全部是文本框的性能肯定要好,排版也好一点。
最后做出来的效果,如图所示:
,最后把公司简称加进来啦,双击时,td值转到text里面,然后构造一个text,边框为醒目的红色,编辑完后,提交更新到库里,然后再读出来。
Ps:
在构造text的时候,光标不能跟进来,focus()函数就可以设置光标了。但是还有一个问题,发现没
光标是在text的最前面的,如果文本框里面有值,那样的效果就不太好啦,在text的onfocus事件里面调用一个方法'cc()',移动光标到数据的后面。
Code
<script language=javascript>
function cc()
{
var e = event.srcElement;
var r =e.createTextRange();
r.moveStart('character',e.value.length);
r.collapse(true);
r.select();
}
</script>
到现在为止,构造text的字符串变成了
Code
var strHtml="<input type=text size=5 style='border:1px solid red' onfocus='cc()' onblur='fun_UpdateValue(this)' id='txtCompanyID'value='"+obj.innerText+"' />";
//obj.innerText 为双击的td的值,
//注意,获得td的值,不能用value,而需要用innerText
最后还是解决啦,