I have a asp.net app that I want to disable the buttons as soon as they are clicked in order to prevent multiple submissions. I'd like to use jquery for this as the site already liberally uses it anyway.
What I've tried is:
$(document).ready(function () {
$("#aspnetForm").submit(function () {
$('input[type=submit]', $(this)).attr("disabled", "disabled");
})
});
The above will disable the button, and the page submits, but the asp.net button on click handler is never called. Simply removing the above and the buttons work as normal.
Is there a better way? Or, rather, what am I doing wrong?
UPDATE
Okay, I finally had a little time to put a very simple page together.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="SubTest.aspx.cs" Inherits="MyTesting.SubTest" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$("#form1").submit(function () {
$('input[type=submit]', $(this)).attr("disabled", "disabled");
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
<asp:Button ID="Button2" runat="server" onclick="Button2_Click" Text="Button 2" />
</div>
</form>
</body>
</html>
The code behind looks like:
using System;
namespace MyTesting {
public partial class SubTest : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
if (IsPostBack) {
// this will execute when any button is pressed
Response.Write("postback");
}
}
protected void Button1_Click(object sender, EventArgs e) {
// never executes
System.Threading.Thread.Sleep(1000);
Response.Write("Button 1 clicked<br />");
} // method::Button1_Click
protected void Button2_Click(object sender, EventArgs e) {
// never executes
System.Threading.Thread.Sleep(1000);
Response.Write("Button 2 clicked<br />");
} // method::Button2_Click
}
}
When you click on a button it obviously disables the buttons, but NEITHER of the button clicks are run.
Rendered HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title>
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$("#form1").submit(function () {
$('input[type=submit]', $(this)).attr("disabled", "disabled");
});
});
</script>
</head>
<body>
<form name="form1" method="post" action="SubTest.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTcxODU4OTc0MWRkParC5rVFUblFs8AkhNMEtFAWlU4=" />
</div>
<div>
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAwKB57WhCAKM54rGBgK7q7GGCC6LlWKFoij9FIBVuI0HOVju/fTy" />
</div>
<div>
<input type="submit" name="Button1" value="Button" id="Button1" />
<input type="submit" name="Button2" value="Button 2" id="Button2" />
</div>
</form>
</body>
</html>
You can do it a slightly different way, like this:
$(function () {
$("#aspnetForm").submit(function () {
$('input[type=submit]').click(function() { return false; });
});
});
What this does is makes future clicks ineffective, basically making them do nothing. When you disable an input, it also removes the key/value pair from being submitted with the <form>, so your server-side action which is triggered by it doesn't work.
It's worth noting, in jQuery 1.4.3 you'll be able to shorten this down to:
$(function () {
$("#aspnetForm").submit(function () {
$('input[type=submit]').click(false);
});
});
The approach of disabling the button before the submit has two effects: -
a) The button takes on the disabled appearance.
b) The button's value is not posted in the form parameters.
If the button's value is not being posted to the server, ASP.Net does not know which button was pressed and thus it does not run the relevent OnClick handler.
To verify add the following to your code behind
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("Load " + IsPostBack + "<br />");
foreach (string s in Request.Form.AllKeys)
{
Response.Write(string.Format("s:'{0}' = {1}<br />", s, Request.Form[s]));
}
}
And then run the page (both with J.S. to disable the buttons and without).
If the button's value is not being posted to the server, ASP.Net does not know which button was pressed and thus it does not run the relevent OnClick handler.
Just another observation. Alternatively, you can lock UI with a nice overlay busy message.
The Mark-up part:
$(function() { // when document has loaded
($.unblockUI); //unlock UI
//Show busy message on click event and disable UI
$('#btnHelloWorld').click(function() {
$.blockUI({ message: '<h4><img src="busy.gif" />Please wait...</h4>' });
});
});
<asp:Button ID="btnHelloWorld" runat="server" Text="Hello World" /><br/>
The Code behind:
Protected Sub btnHelloWorld_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnHelloWorld.Click
Label1.Text = "Hello World"
Threading.Thread.Sleep(5000)
End Sub
Check out jQuery BlockUI Plugin
I just wanted to add an additional resolution. We decided to just completely remove the button once it was clicked and replace it with some text.
To do this we did:
$(function () {
$(".DisableButton").click(function () {
$(this).hide();
$(this).after('<p>Please Wait. Retrieving information. This may take up to 60 seconds.</p>');
});
});
Note that this hides the button then injects some html after the buttons code. Hiding it allows .Net to go ahead and run the onclick handler during post back while removing it as a clickable thing on the screen.
Add this attribute to your button:
usesubmitbehavior="False"
This will insert something like the following into onclick:
javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$Main$Tabs$SaveTab$Cancel", "", true, "", "", false, false))
This code will cause a post back even if the button is disabled. Showing a confirmation dialog and allowing the post back to be cancelled gets a little more interesting:
var click = $("[id$='_Cancel']")[0].onclick;
$("[id$='_Cancel']")[0].onclick = null;
$("[id$='_Cancel']").bind('click', function (event) { addFeeSchedule.onCancelClick(event) });
$("[id$='_Cancel']").bind('click', click);
In order to prevent the post back from occurring immediately, remove the onclick code inserted by .net and bind it after your own function using jQuery. Use event.stopImmediatePropagation(), to prevent the post back:
onCancelClick: function (event) {
var confirmResponse;
confirmResponse = confirm('No fee schedule will be created.\n\nAre you sure you want to cancel?');
if (confirmResponse == true) {
showWait();
event.target.disabled = 'true';
} else {
event.stopImmediatePropagation();
}
},
The answer provided by Nick Craver is by far the best solution that I've found anywhere on the net. There is one situation, however, where the solution does not work well - when the form contains submit buttons within an UpdatePanel with it's UpdateMode property set to "Conditional" and/or ChildrenAsTriggers property set to false.
In these situations, the contents of the update panels are not automatically refreshed when the async postback has completed. So if these update panels contained any submit buttons then the given solution would effectively leave these buttons permanently disabled.
The following enhancement to the solution handles this problem by re-enabling the buttons after an async, or 'partial', postback:
var canProcessClicks = true;
if (typeof (Sys) != 'undefined') {
// handle partial-postback
var requestManager = Sys.WebForms.PageRequestManager.getInstance();
requestManager .add_initializeRequest(function() {
// postback started
canProcessClicks = false;
});
requestManager .add_endRequest(function() {
// postback completed
canProcessClicks = true;
});
}
$(function () {
$('input[type=submit]').on("click", function () {
return canProcessClicks ;
});
$("#aspnetForm").submit(function () {
if (typeof (Sys) != 'undefined' && Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {
// this is an async postback so ignore because this is already handled
} else {
// full postback started
canProcessClicks = false;
}
});
});
For this you have to use input button attribute disable all the controls
<script language="javascript" type="text/javascript">
function MyDisableFunction() {
alert(`Now You Postback Start`);
$(":input").attr("disabled", true);
return true;
}
</script>
Fore more detail check this link
Related
I'm looking for a custom user control similar to http://www.how-to-asp.net/messagebox-control-aspnet/ but having the ability to be displayed as a popup. The message box should have the capability of being invoked from code behind in asp.net 4 with event hooks to bind the "ok" and "cancel" button.
I'm familiar with Ajax Toolkit and JQuery.
A reference and or sample in a similar direction would be very helpful.
Thanks!
Use jQuery UI. They have great examples. I use the dialog all the time.
You can view their source and here is an example of one.
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Dialog - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<script>
$(function() {
$( "#dialog" ).dialog();
});
</script>
</head>
<body>
<div id="dialog" title="Basic dialog">
<p>This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.</p>
</div>
</body>
You are able to customize this anyway you want. The link will show you how to do this.
EDIT: Since you want to open it in the behind code, I'll show you my jQuery and how I call it in the behind code. I use this to send emails.
function sendEmail() {
$("#email").dialog({
modal: true,
width: 700,
buttons: {
"Send": function () {
var btn = document.getElementById("<%=lbSend.ClientID %>");
if (btn) btn.click();
$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close");
}
}
);
jQuery("#email").parent().appendTo(jQuery("form:first"));
};
Then in the behind code.
protected void btnEmail_Click(object sender, EventArgs e)
{
//this calls the jQuery function.
Page.ClientScript.RegisterStartupScript(this.GetType(), "Call my function", "sendEmail();", true);
}
In my experience, it's usually a sign of a bad design if you want to open something on the client side from the server side code behind. Are you sure that's what you need?
But assuming you do, you can use the ModalPopupExtender from the Ajax Control Tookit. It can be opened from client or server side. Here's a sample:
<ajaxToolkit:ModalPopupExtender ID="MPE" runat="server"
TargetControlID="LinkButton1" ClientIdMode="Static"
PopupControlID="Panel1" />
The PopupControlID should be the ID of a panel that you want to appear as a popup. You can put buttons on that panel if you need to. From the code behind, it's as simple as this...
MPE.Show();
To show it from JavaScript (assuming jQuery), make sure you set the ClientIdMode to Static, then call it...
$('#MPE').show();
public void Message(String msg)
{
string script = "window.onload = function(){ alert('";
script += msg;
script += "');";
script += "window.location = '";
script += "'; }";
ClientScript.RegisterStartupScript(this.GetType(), "Redirect", script, true);
}
I'm maintaining an ASP .Net Application that seems somehow duplicate a records e.g. using a page add-user. I was unable to reproduce but I found some code that do something crazy like, on submit:
if(crazy-code()){
__doPostBack() // 2nd
}
and crazy-code also do something like
function crazy-code()
{
...
__doPostBack() // 1st
...
return true;
}
To find out this piece of code is causing the problem, I have been trying to fire both __doPostBack but I was unable to do it.
In theory, what should always happens is when it fire the (1st) __doPostBack, it should send the request and stop/ignore any client code afterward.
if __doPostBack is fired twice, what will be the reasons? the browsers? the speed? ???
The __doPostBack() call will submit the form and it should not call the second one.
I might be wrong, but I think you can reproduce your issue if you hit "Submit" on your web page and after the page reloads hit "F5". Depending on the browser, it will ask something like "resend the from data?". Select "Yes" and check whether your records have been duplicated.
In any case, i think you need to add the checks for duplicated values when you insert the data on the server side.
I was able to create a testing code. in FF and chrome seems to work fine (1 submit) but the IE9 (and compatibility version) seems to hit 1, 2 or 3 times.
NOTE: the submit() cause the postback.
CASE 1. delay in Javascript
Page:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>testing</title>
<script type="text/javascript">
function submitForm() {
document.forms[0].submit();
alert("delay");
document.forms[0].submit();
}
</script>
</head>
<body>
<form id="form1" name="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server" Width="220px"></asp:TextBox>
<button onclick="submitForm(this)">CLICK</button>
<br />
<asp:Label ID="Label1" runat="server"></asp:Label>
</div>
</form>
</body>
</html>
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
if(IsPostBack)
{
incrementVal();
}
}
private void incrementVal()
{
var val = (int)(Session["val_" + TextBox1.Text] ?? 0);
val++;
Label1.Text += TextBox1.Text + ": " + val.ToString("00") + " - " + DateTime.Now.ToLongTimeString() + "<br/>";
Session["val_" + TextBox1.Text] = val;
}
CASE 2: Slow Response
remove JS Alert:
function submitForm() {
document.forms[0].submit();
document.forms[0].submit();
}
add delay in the server side:
if(IsPostBack)
{
incrementVal();
Thread.Sleep(500);
}
I'm looking for a simple, efficient way to get the position of the browser vertical scrollbar and save it into a session variable in an ASP page.
What I'm trying to do is when the user changes a page I've the scroll position stored in a session variable so that when the user returns to the page the page will scroll to their last position.
Is there a way to do this? I've seen examples of persisting the scroll position on postback but nothing yet doing exactly what I'm trying to do :(
If anyone can point me in the right direction id be grateful.
EDIT:
Ok so based on the example below I noticed that when the user clicks a row in my gridview they navigate to the next page but my event handler never gets fired.
This leads me to suspect that the scroll position wasn't being saved, I'm guessing the form isn't being submitted)
My event handler looks like :
Protected Sub save(ByVal sender As Object, ByVal e As EventArgs) Handles ScrollPosition.ValueChanged
Session.Add("ScrollPosition", ScrollPosition.Value)
End Sub
I figured it was easiest to use the valueChanged event to grab the value and put it into the session
Next my Script.... I'm trying to do it based on my very limited knowledge of Jquery!
<script type="text/javascript">
$(function () {
//Retrieve and use the existing scroll position from the hidden field
var scrollPosition = $('#<%= ScrollPosition.ClientID %>').val();
$(window).scrollTop(scrollPosition);
/*
//Handle the main forms submit event and store the scroll position
$('#<%= form1.ClientID %>').submit(function () {
var currentScrollPosition = $(window).scrollTop();
$('#<%= ScrollPosition.ClientID %>').val(currentScrollPosition);
});
*/
});
$(document).ready(function () {
$("#gvTickets").click(function () {
var currentScrollPosition = $(window).scrollTop();
$('#<%= ScrollPosition.ClientID %>').val(currentScrollPosition);
})
});
</script>
The idea behind the script is that when a row in gvTickets is clicked the scroll position will be stored which should trigger my value changed event handler
I'm not getting any errors but neither am I getting the desired behaviour :(
Also in my page load I have :
If Not IsPostBack Then
If (Session("ScrollPosition") = Nothing) Then
ScrollPosition.Value = 0
Session("ScrollPosition") = 0
Else
ScrollPosition.Value = Session("ScrollPosition")
End If
Try storing the scroll position on submit of the form in a HiddenField control.
The HiddenField control will then be available in your code behind, so you can store the value as required.
You can then use the value from the HiddenField control to set the scroll position when the page loads.
See an example below (uses JQuery):
Markup
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<!-- Set the path to JQuery here -->
<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
//Add some line breaks
for (i = 0; i < 1000; i++) {
$('body').prepend('<br/>');
}
//Retrieve and use the existing scroll position from the hidden field
var scrollPosition = $('#<%= ScrollPosition.ClientID %>').val();
$(window).scrollTop(scrollPosition);
//Handle the main forms submit event and store the scroll position
$('#<%= form1.ClientID %>').submit(function () {
var currentScrollPosition = $(window).scrollTop();
$('#<%= ScrollPosition.ClientID %>').val(currentScrollPosition);
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<div style="position:fixed;top:0px;left:0px;">
<asp:HiddenField ID="ScrollPosition" runat="server" Value="0" />
<asp:Button ID="Button1" runat="server" Text="Post Back" OnClick="Button1_Click" />
<asp:Label ID="CurrentScrollPosition" runat="server"></asp:Label>
</div>
</div>
</form>
</body>
</html>
Code Behind
protected void Button1_Click(object sender, EventArgs e)
{
CurrentScrollPosition.Text = string.Format("Scroll position: {0}", ScrollPosition.Value);
}
Edit (Based on comments)
Try handling the window scroll event, updating the hidden field whenever the scroll position changes:
<script type="text/javascript">
$(function () {
$(window).scroll(function () {
var currentScrollPosition = $(window).scrollTop();
$('#<%= ScrollPosition.ClientID %>').val(currentScrollPosition);
});
});
</script>
Edit
For me, the following code sets the scroll position hidden field to 0 on load. Then on subsequent post backs stores the value in the hidden field in the "ScrollPosition" session variable.
I am then able to print the scroll position out to the screen. See below:
The control firing the postback in my example is a Button, however any control could initiate the postback and it will still function in the same manner.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Default to 0
ScrollPosition.Value = "0";
//If ScrollPosition session variable is null, store the default
//Else set the scroll position to the value stored in session.
if (Session["ScrollPosition"] == null)
{
Session.Add("ScrollPosition", ScrollPosition.Value);
}
else
{
ScrollPosition.Value = Session["ScrollPosition"].ToString();
}
}
else
{
//On subsequent postbacks store the new scroll position
Session.Add("ScrollPosition", ScrollPosition.Value);
}
OutputScrollPosition();
}
private void OutputScrollPosition()
{
CurrentScrollPosition.Text = string.Format("Scroll position: {0}", Session["ScrollPosition"]);
}
Hope this helps.
I have been experiencing some very strange behavior using html buttons with the onserverclick attribute. What I am trying to do is use jQuery to designate the default button on the page. By default button I mean the button that is "clicked" when a user hits enter. In testing, I would hit enter while in an input field and sometimes the intended "default" button was clicked and the server side method defined in the corresponding onserverclick attribute was hit. Other times a post back was made without hitting the server method. In order to isolate the issue I created a minimal test case and found some very interesting results.
client side:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript" src="/scripts/jquery-1.4.min.js"></script>
</head>
<body>
<form id="form1" runat="server">
<asp:Label ID="_response" runat="server"></asp:Label>
<input id="input1" type="text" />
<input id="input2" type="text" />
<button id="first" type="button" class="defaultBtn" runat="server" onserverclick="ServerMethod1">test1</button>
<button id="second" type="button" runat="server" onserverclick="ServerMethod2">test2</button>
</form>
<script type="text/javascript">
jQuery('form input').keyup(
function(e) {
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
$('button.defaultBtn').click();
return true;
}
}
);
</script>
</body>
</html>
server side:
public partial class admin_spikes_ButtonSubmitTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ServerMethod1(object sender, EventArgs e)
{
_response.Text = "server method1 was hit";
}
protected void ServerMethod2(object sender, EventArgs e)
{
_response.Text = "server method2 was hit";
}
}
What I found was that everything worked as expected with this code except when I removed one of the input elements. In Firefox 3.6 and IE 8 when only one input exists on the page, hitting enter does not trigger the onserverclick, it makes a post back without even being jQuery "clicked" or actually "clicked". You can test this by starting with two inputs and clicking "test2". This will output "server method2 was hit". Then just hit enter and the output will be "server method1 was hit. Now take away an input and run the same test. Click "test2" see the results, then hit enter and you will see that nothing will change because the "test1" method was never hit. Does anyone know what is going on?
Thanks
p.s. Chrome worked as expected
Try this:
jQuery('form input').keyup(
function(e) {
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
$('#__EVENTTARGET').val($('.defaultBtn').attr('name') );
document.forms[0].submit();
return true;
}
}
);
Or you may use the DefaultButton form's attribute:
<asp:Form runat="server" id="form1" DefaultButton="first">
...
</asp:Form>
Like every other web developer on the planet, I have an issue with users double clicking the submit button on my forms. My understanding is that the conventional way to handle this issue, is to disable the button immediately after the first click, however when I do this, it doesn't post.
I did do some research on this, god knows there's enough information, but other questions like Disable button on form submission, disabling the button appears to work. The original poster of Disable button after submit appears to have had the same problem as me, but there is no mention on how/if he resolved it.
Here's some code on how to repeat it (tested in IE8 Beta2, but had same problem in IE7)
My aspx code
<%# Page Language="C#" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<script language="javascript" type="text/javascript">
function btn_onClick()
{
var chk = document.getElementById("chk");
if(chk.checked)
{
var btn = document.getElementById("btn");
btn.disabled = true;
}
}
</script>
<body>
<form id="form1" runat="server">
<asp:Literal ID="lit" Text="--:--:--" runat="server" />
<br />
<asp:Button ID="btn" Text="Submit" runat="server" />
<br />
<input type="checkbox" id="chk" />Disable button on first click
</form>
</body>
</html>
My cs code
using System;
public partial class _Default : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
btn.Click += new EventHandler(btn_Click);
btn.OnClientClick = "btn_onClick();";
}
void btn_Click(object sender, EventArgs e)
{
lit.Text = DateTime.Now.ToString("HH:mm:ss");
}
}
Notice that when you click the button, a postback occurs, and the time is updated. But when you check the check box, the next time you click the button, the button is disabled (as expected), but never does the postback.
WHAT THE HECK AM I MISSING HERE???
Thanks in advance.
I think you're just missing this tag:
UseSubmitBehavior="false"
Try it like this:
<asp:Button ID="btnUpdate" runat="server" UseSubmitBehavior="false" OnClientClick="if(Page_ClientValidate()) { this.disabled = true; } else {return false;}" Text = "Update" CssClass="button" OnClick="btnUpdate_Click" ValidationGroup="vgNew"/>
Explanation
UseSubmitBehavior="false" converts submit button to normal button (<input type="button">). If you don't want this to happen, you can hide submit button and immediately insert disabled button on its place. Because this happens so quickly it will look as button becoming disabled to user. Details are at the blog of Josh Stodola.
Code example (jQuery):
$("#<%= btnSubmit.ClientID %>").click(function()
{
$(this)
.hide()
.after('<input type="button" value="Please Wait..." disabled="disabled" />');
});
fallen888 is right, your approach doesn't work cross-browser. I use this little snippet to prevent double-click.
"Disabling" HTML controls doesn't always produce consistent behavior in all major browsers. So I try to stay away from doing that on the client-side, because (working with the ASP.NET model) you need to keep track of element's state on client and server in that case.
What I'd do is move button off the visible part of the window by switching the button's className to a CSS class that contains the following:
.hiddenButton
{
position: absolute;
top: -1000px;
left: -1000px;
}
Now, what to put in place of the button?
Either an image that looks like a disabled button
Or just plain text that says "Please wait..."
And this can be done the same way but in reverse. Start with the element being hidden at page load and then switch to a visible className on form submit.
We use the following JQuery script, to disable all buttons (input type=submit and button), when one button is clicked.
We just included the script in a global JavaScript file, so we don't have to do remember anything when creating new buttons.
$(document).ready(function() {
$(":button,:submit").bind("click", function() {
setTimeout(function() {
$(":button,:submit").attr("disabled", "true");
}, 0);
});
});
This script could easily be extended with a check for Page_ClientValidate().
document.getElementById('form1').onsubmit = function() {
document.getElementById('btn').disabled = true;
};
This is the correct and simple way to do this:
It works in all browsers (unlike the accepted solution above).
Create a helper method in your application (say in a Utlity Namespace):
Public Shared Sub PreventMultipleClicks(ByRef button As System.Web.UI.WebControls.Button, ByRef page As System.Web.UI.Page)
button.Attributes.Add("onclick", "this.disabled=true;" + page.ClientScript.GetPostBackEventReference(button, String.Empty).ToString)
End Sub
Now from the code behind of each of your web pages you can simply call:
Utility.PreventMultipleClicks(button1, page)
where button1 is the the button you want to prevent multiple clicks.
What this does is simply sets the on click handler to: this.disabled=true
and then appends the buttons own post back handler, so we get:
onclick="this.disabled=true";__doPostBack('ID$ID','');"
This does not break the default behaviour of the page and works in all browsers as expected.
Enjoy!
FOR JQUERY USERS
You will get into all sorts of problems trying to add javascript directly to the onClick event on ASP.NET buttons when using jQuery event listeners.
I found the best way to disable buttons and get the postback to work was to do something like this:
$(buttonID).bind('click', function (e) {
if (ValidateForm(e)) {
//client side validation ok!
//disable the button:
$(buttonID).attr("disabled", true);
//force a postback:
try {
__doPostBack($(buttonID).attr("name"), "");
return true;
} catch (err) {
return true;
}
}
//client side validation failed!
return false;
});
Where ValidateForm is your custom validation function which returns true or false if your form validates client side.
And buttonID is the id of your button such as '#button1'
For debugging purposes, what happens if you put an else clause against the if(chk.checked)?
Make sure that your javascript function returns true (or a value that would evaluate to boolean true), otherwise the form won't get submitted.
function btn_click()
var chk = document.getElementById("chk");
if(chk.checked)
{
var btn = document.getElementById("btn");
btn.disabled = true;
return true; //this enables the controls action to propagate
}
else return false; //this prevents it from propagating
}
One can also try the following way to prevent double clicking of the "SUBMIT" Button:
.buttonload {
background-color: lightgrey; /* Grey background */
border: none; /* Remove borders */
color: black; /* Black text */
padding: 12px 24px; /* Some padding */
font-size: 16px; /* Set a font-size */
}
/* Add a right margin to each icon */
.fa {
margin-left: -12px;
margin-right: 8px;
}
<!DOCTYPE html>
<html>
<head>
<!-- Add icon library -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<script type="text/javascript">
$(function () {
SubmitButton = $("#btn");
SubmitButton.on("click", function () {
result = ValidateRecords();
if (result) {
$(this)
.hide()
.after('<button disabled class="buttonload"><i class= "fa fa-spinner fa-spin"></i>Processing Data...</button >');
}
});
});
function ValidateRecords() {
var DateTime = document.getElementById('lit').value;
if (!DateTime.trim()) {
return false;
}
else {
return true;
}
}
</script>
</body>
</html>
EXPLANATION(In Order of Code Appearance above):
CSS : Handles the spinner element used as part of the icon tag in the replaced button.
Adding the Icon Library in header is mandatory in case if you want to use the icon class fa-spinner.
In the script tag Validate method is called to check if all the mandatory form elements are filled prior clicking the submit button
Post the validation is successful, I am hiding the submit button[.hide()] and replacing with another button[.after()].
Setting the DISABLED property on the new button is mandatory or else it will work as an active button.
NOTE: I have used Button to replace the submit Button. But you can use input text or any other suitable element as per your requirements