SIGN UP MEMBER LOGIN:    
ARTICLE

Disable an ASP.NET button during PostBack with AJAX loading background image

Posted by Bryian Tan Articles | AJAX in C# August 22, 2009
An article on how to disable the button control during PostBack.
Reader Level:

View this project in action

Introduction

There are times when our applications might take an extra few seconds to respond to a click event. Some users might get impatient and click on the button more than once. We can easily avoid this type of situation by disabling the submit button during PostBack on the page by using a client side script.

In this article, I will share with everyone on how to:

  1. Disable the button during PostBack with or without the present of validation control
  2. Change the button text value during PostBack
  3. Include an AJAX loading background image during PostBack
  4. How I avoided the 'Page_IsValid is undefined' JavaScript error
Using the Code

Before we begin, allow me to show you the structure of my project. You are welcome to download this demo.

Project Structure

Demo 1 - Without Validation Control

Here is the content of the Jscript.js

function
disableBtn(btnID, newText) {
    var btn = document.getElementById(btnID);
        setTimeout("setImage('"+btnID+"')", 10);
        btn.disabled = true;
        btn.value = newText;

function setImage(btnID) {

    var btn = document.getElementById(btnID);

    btn.style.background = 'url(12501270608.gif)';

}

Here is part of the Default.aspx page content.

<
table>

         <tr>

            <td></td>

            <td>                

                 <asp:button id="btnOne" tabIndex="0" Runat="server" Text="Submit"

                    onclick="btnOne_Click"

                    OnClientClick="disableBtn(this.id, 'Submitting...')"

                    UseSubmitBehavior="false" />              

            </td>

        </tr>

        <tr>

            <td colspan="2">

                <asp:Label ID="Label3" runat="server" Text=""></asp:Label></td>

        </tr>

    </table>  

<script type="text/javascript" src="JScript2.js"></script>

In Default.aspx page, I have a button and a label control. Let take a closer look at the button attributes.

OnClientClick="disableBtn(this.id, 'Submitting...')"
- Calls the JavaScript function by passing in the button ID and the new text value that I want it to display on click. UseSubmitBehavior="false" - Indicates that the button control should use the ASP.NET postback mechanism instead of client browser's submit mechanism ( UseSubmitBehavior Property )

For testing, I included these lines in the default.aspx.cs

protected
void btnOne_Click(object sender, EventArgs e)
{
    Thread.Sleep(2000);
    Label3.Text = sb.ToString();

}

Here how's the button will look like when someone click on it.

Demo 1 click Demo 1 Output

Demo 2 - With Validation Control

Here is the output from Default2.aspx

Demo 2 aspx Page

Ops... The button is still disabled after it failed the validation process. Let modify the JavaScript to fix this problem.

Here is the content of the new JavaScript with comments- Jscript2.js On 08/14/2009 - I found out that, in Firefox, if we hit the button and continue to the next page, and then hit the back button (or javascript:history(-1);)... the button control is still disabled. I have updated the JavaScript(JScript2) to enable the button onunload for browser other than Internet Explorer.

10/12/2009 -   I have updated the JavaScript(JScript2) to prevent double validation. <br /> <br />

11/14/2009 - Fix bug mentioned by CodeProject user, prodriguez13. The JavaScript will throw
    an error when the control to validate is not visible. To remedy this, on onload event, I have added DisableValidators function. This function is responsible to disable all the validators with controltovalidate === null.
*   I received a few requests on getting this script to work with Image button. I managed to put together a solution for it. Let me know if you find any bugs.
*   Tested on IE 7.0/8.0, FireFox, image would not show on Google Chrome, maybe someone can shed some light on this.


function ResetToDefault(btn, oldValue) {
btn.disabled = false;
btn.value = oldValue;
}
//browser properties
var Browser = {
Version: function() {
var version = 999;
if (navigator.appVersion.indexOf("MSIE") != -1) {
version = parseFloat(navigator.appVersion.split("MSIE")[1]); return version;
}
},
Name: navigator.appName,
isIE: function() {
if (navigator.appVersion.indexOf("MSIE") != -1) {
return true;
}
return false;
}
};

//Handle Page_Validators is not defined error
//http://www.velocityreviews.com/forums/t88987-pagevalidators-error.html
function HasPageValidators() {
var hasValidators = false;
try {
if (Page_Validators.length > 0) {
hasValidators = true;
}
}
catch (error) { }

return hasValidators;
}


function SetImage(btn) {

if (btn.type == "image") {
btn.src = null;
btn.style.width = '100px';
btn.style.height = '20px';
btn.style.backgroundImage = 'url(http://images.ysatech.com/ajax-loader.gif)';
}
else {
//somehow backgroundImage not working with IE 7
if (Browser.isIE() && Browser.Version() === 7) {
btn.style.background = 'url(http://images.ysatech.com/ajax-loader.gif)';
}
else {
btn.style.backgroundImage = 'url(http://images.ysatech.com/ajax-loader.gif)';
}
}
}

//enable the button and restore the original text value for browsers other than IE
function EnableOnUnload(btn, btnText) {
if (!Browser.isIE()) {
window.onunload = function() {
ResetToDefault(btn, btnText);
};
}
}

//check if the validator have any control to validate
function EnableValidator(validator) {
var controlToValidate = document.getElementById(validator.controltovalidate);

if (controlToValidate !== null) {
// alert(controlToValidate.id);
ValidatorEnable(validator);
return true;
}
ValidatorEnable(validator, false);

return false;
}

function disableBtn(btnID, newText) {
var btn = document.getElementById(btnID);
var oldValue = btn.value;
btn.disabled = true;
btn.value = newText;

//if validator control present
if (HasPageValidators()) {

Page_IsValid = null;

//http://sandblogaspnet.blogspot.com/2009/04/calling-validator-controls-from.html
//double check, if validator not null
if (Page_Validators !== 'undefined' && Page_Validators !== null) {
//Looping through the whole validation collection.
for (var i = 0; i < Page_Validators.length; i++) {

var validator = Page_Validators[i];

//check if control to validate is enable
if (EnableValidator(validator)) {

if (!Page_Validators[i].isvalid) { //if not valid
ResetToDefault(btn, oldValue); //break;
}
}
}

// else { //if valid
var isValidationOk = Page_IsValid;

alert('isValidationOk ' + isValidationOk);

EnableOnUnload(btn, btn.value);
if (isValidationOk !== null) {
if (isValidationOk) {
SetImage(btn);
__doPostBack(btnID, '');
// break;
}
else { //page not valid
btn.disabled = false;
}
}
// }

}
}
else { //regular, no validation control present
// setTimeout("SetImage('" + btn + "')", 5);
SetImage(btn);
btn.disabled = true; btn.value = newText;
EnableOnUnload(btn, btn.value);
}
}

//disable those validators where controltovalidate = null
function DisableValidators() {
//this will get rid of the Page_Validators is undefined error
if (typeof (Page_Validators) === 'undefined')
return;

if (Page_Validators !== 'undefined' && Page_Validators !== null) {
for (var i = 0; i < Page_Validators.length; i++) {
var validator2 = Page_Validators[i];
var controlToValidate2 = document.getElementById(validator2.controltovalidate);
if (controlToValidate2 === null) {
ValidatorEnable(validator2, false);
}
}
}
return false;
}

window.onload = DisableValidators;


Output from using the new JavaScript (JScript2.js)

Demo 2 OnClick fail Validation

Demo 2 OnClick Pass Validation

Demo 2 After PostBack

Conclusion

The main items in this project were the JavaScript (Jscript2) and the button attributes (OnClientClick, UseSubmitBehavior)

I hope someone will find this tutorial useful. If you think I still can improve this code, please leave me a feedback and share your thought.

Tested on IE 6.0/7.0 and Firefox 3.0.13.

Login to add your contents and source code to this article
share this article :
post comment
 

thanks for the code, very interesting stuff, especially with the image button...

------------------------------
Danny, San Jose Locksmith

Posted by danny dror Nov 23, 2009

yes, it works with Image Button. Please check updated code.

Thanks,
Bryian Tan

Posted by Bryian Tan Nov 14, 2009

Hi
  Nice article but can we do the same for Image Button in which can we change the image url "Processing image" some like.

Thanks
Ravi
mcamail2002@gmail.com

Posted by Ravi Singh Oct 30, 2009

Just create a onClientClick event and set the button to Enabled=False.

When your postback is done set your button to Enabled=True

Posted by Pontus Oct 22, 2009
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor
PREMIUM SPONSORS
  • Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
    The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
Become a Sponsor