某些处理响应时间较长,为了防止用户重复连续点击提交按钮,我们通常会在点击之后 disable 此按钮。
在 ASP.NET 2.0 中 asp:button 默认使用客户端浏览器的提交机制即呈现为 input type=submit,
如果直接设置 onclientclick="this.disabled=true" ,将无法执行提交。
解决方法:
只有设置 UseSubmitBehavior=false,按钮呈现为 input type=button,然后添加脚本
曾想当然的认为可以在 form 的 onsumit 中 disable input type=submit
注:ASP时代更常用此方案,可以同时对一个form具有多个提交按钮作出统一的“响应”
经测试,发现虽然可以回发页面,但是却无法触发服务器端的 Click 事件。
原来,当点击 input type=submit 按钮时,如果其 disabled=false(正常状态),那么浏览器会同时提交此按钮
(Request.Form 集合中可以查询到此按钮的value),而 disabled=true(禁用),浏览不会提交此按钮的value。
而 ASP.NET 内部则检索是否有Request.Form中有对应的name匹配当然页面WebControl.UnquieID 来确定谁提交了改页面,由此引发注册的服务器事件。
Updated 已经实现 2007年7月11日
让 ASP.NET 2.0 的 Sumbit Button 支持 禁用(灰化)提交
对于,input type=button ,浏览器永远都不提交此按钮给服务器,对于此类型提交,需要有一个隐藏域
input type=hidden name=__EVENTTARGET 来存储谁提交了此页面。
完整测试代码:
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(1000 * 2);
}
protected void Page_Load(object sender, EventArgs e)
{
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript">
function chk(frm) {
frm.Button2.disabled =true;
frm.Button2.value='submitting';
}
</script>
</head>
<body>
<form id="form1" runat="server" onsubmit="chk(this)">
<div>
<asp:Button ID="Button1" UseSubmitBehavior="false" runat="server" OnClientClick="this.value='submitting';this.disabled=true;" OnClick="Button1_Click" Text="Test1" />
<asp:Button ID="Button2" runat="server" OnClick="Button1_Click" Text="Test2" />
<asp:Button ID="Button3" runat="server" OnClientClick="this.value='sorry, the form cant be submitted.';this.disabled=true;" OnClick="Button1_Click" Text="Test3" />
</div>
</form>
</body>
</html>
http://www.cnblogs.com/Jinglecat/archive/2007/07/10/811946.html
==================================================
上篇文章 禁用(灰化) Button 后提交的问题 讨论了 ASP.NET 2.0 中 UseSubmitBehavior=true 即使通过 form onsumit 处理也无法有效实现完成提交前的灰化功能
今天闲时无聊,根据上篇文章的分析,
注:ASP时代更常用此方案,可以同时对一个form具有多个提交按钮作出统一的“响应”
经测试,发现虽然可以回发页面,但是却无法触发服务器端的 Click 事件。
(Request.Form 集合中可以查询到此按钮的value),而 disabled=true(禁用),浏览不会提交此按钮的value。
而 ASP.NET 内部则检索是否有Request.Form中有对应的name匹配当然页面WebControl.UnquieID 来确定谁提交了改页面,由此引发注册的服务器事件。
对于,input type=button ,浏览器永远都不提交此按钮给服务器,对于此类型提交,需要有一个隐藏域
input type=hidden name=__EVENTTARGET 来存储谁提交了此页面。
硬是将其实现了,主要技巧是通过手动的添加了一个隐藏域其 name=__EVENTTARGET,并设置其 value=提交按钮.name,这样 ASP.NET 就可以识别哪个按钮执行的提交,进而引发注册的服务器端事件。
与直接设置 UseSubmitBehavior=false 相比,此方法反而显得有点繁琐。
测试代码:
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
Response.Write("Fired by : " + ((Button)sender).ID);
System.Threading.Thread.Sleep(1000 * 2);
}
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("<pre>");
foreach (string key in Context.Request.Form.AllKeys) {
Context.Response.Write(String.Format("{0}/t/t:{1}/n", key, Request.Form[key]));
}
Response.Write("</pre>");
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>DisableButtonBeforePostByDeceiveSubmitButton</title>
<script type="text/javascript">
function chk(frm) {
//debugger;
var et = document.getElementById("__EVENTTARGET");
var btn, btns;
if(et) btns = document.getElementsByName(et.value);
btn = (btns && btns.length > 0) ? btns[0] : btns;
if(btn) {
btn.value = 'submitting';
btn.disabled =true;
}
return true;
}
function markWhoSumbit(whoiseName)
{
var btn = document.getElementById("__EVENTTARGET");
if(!btn) {
btn = document.createElement("input");
btn.type="hidden";
btn.name="__EVENTTARGET";
btn.id="__EVENTTARGET";
document.forms[0].appendChild(btn);
}
btn.value=whoiseName;
}
</script>
</head>
<body>
<form id="form1" onsubmit="return chk(this);" runat="server">
<div>
<asp:Button ID="Button2" runat="server" OnClick="Button1_Click" OnClientClick="markWhoSumbit(this.name)" Text="Test2" />
<asp:Button ID="Button3" runat="server" OnClientClick="this.value='sorry, the form cant be submitted.';this.disabled=true;" OnClick="Button1_Click" Text="Test3" />
<asp:Button ID="Button4" runat="server" OnClick="Button1_Click" Text="Test4" />
<asp:Button ID="Button5" runat="server" OnClick="Button1_Click" OnClientClick="markWhoSumbit(this.name)" Text="Test5" />
</div>
</form>
</body>
</html>
===================================================
Readonly和Disabled的区别
Readonly只针对input(text / password)和textarea有效,而disabled对于所有的表单元素都有效,包括select, radio, checkbox, button等。但是表单元素在使用了disabled后,当我们将表单以POST或GET的方式提交的话,这个元素的值不会被传递出去,而readonly会将该值传递出去(这种情况出现在我们将某个表单中的textarea元素设置为disabled或readonly,但是submit button却是可以使用的)。
一般比较常用的情况是:
①在某个表单中为用户预填了某个唯一识别代码,不允许用户改动,但是在提交时需要传递该值,此时应该将它的属性设置为readonly
②经常遇到当用户正式提交了表单后需要等待管理员的信息验证,这就不允许用户再更改表单中的数据,而是只能够查看,由于disabled的作用元素范围大,所以此时应该使用disabled,但同时应该注意的是要将submit button也disabled掉,否则只要用户按了这个按钮,如果在数据库操作页面中没有做完整性检测的话,数据库中的值就会被清除。如果说在这种情况下用readonly来代替disabled的话,若表单中只有input(text / password)和textarea元素,那还是可以的,如果存在其他发元素,比如select,用户可以在重新改写值后按回车键进行提交(回车是默认的submit触发按键)
③我们常常在用户按了提交按钮后,利用javascript将提交按钮disabled掉,这样可以防止网络条件比较差的环境下,用户反复点提交按钮导致数据冗余地存入数据库。