in

Corey Roth and Friends Blogs

Group site for developer blogs dealing with (usually) Ionic, .NET, SharePoint, Office 365, Mobile Development, and other Microsoft products, as well as some discussion of general programming related concepts.

Kyle Kelin on .Net

Disable a Button When the User Clicks It

A common solution that I had to implement recently is users on a client's site were double clicking buttons and causing issues. In addition to causing issues users weren't sure if the site was working correctly on long running processes. The JavaScript code I wrote to solve this problem can be divided into two segments. One part handles buttons that make asynchronous calls and another part that handles buttons that cause post-backs. For the buttons that cause post-backs we loop through all buttons and assign the CanSubmitFunction as the click event for that button. In the CanSubmitFunction we keep track of if the user has clicked the button before and if they have we display an alert and prevent the button from submitting. I should mention that I originally tried to disable the button. But doing this prevents the button from submitting and trying to force a submit is difficult to say the least.

 

// wire up the disable click event

var buttonControls = document.getElementsByTagName("input");

for (i = 0; i < buttonControls.length; i++) {

// if this input type is button, disable

if (buttonControls[i].type == "submit") {

addClickEvent(buttonControls[i], CanSubmitForm);

}

}

 

function addClickEvent(obj, fn) {

if (obj.addEventListener) {

obj.addEventListener('click', fn, false);

} else if (obj.attachEvent) {

obj.attachEvent('onclick', fn);

}

 

}

 

var isSubmitted = false;

function CanSubmitForm() {

var canSubmit = false;

if (!isSubmitted) {

isSubmitted = true;

canSubmit = true;

}

else {

alert("Please wait for page to load before making another selection.");

}

return canSubmit;

}

 

For buttons that makes asynchronous calls we can disable the button. In addition to disabling the button we change the cursor so it shows the hourglass. I think the code below is pretty self-explanatory. One issue I do have with this solution is having to different types of behaviors on the buttons throughout the site. I may change the asynchronous code show it also displays an alert when the user clicks on the button twice.

// wire the callbacks for the Ajax events

var prm = Sys.WebForms.PageRequestManager.getInstance();

prm.add_initializeRequest(InitializeRequest);

prm.add_endRequest(EndRequest);

//--------------------------------------

 

function InitializeRequest(sender, args) {

document.body.style.cursor = "wait";

var buttonControls = document.getElementsByTagName("input");

 

for (i = 0; i < buttonControls.length; i++) {

// if this input type is button, disable

if (buttonControls[i].type == "submit") {

buttonControls[i].disabled = true;

}

}

}

 

function EndRequest(sender, args) {

document.body.style.cursor = "default";

var buttonControls = document.getElementsByTagName("input");

 

for (i = 0; i < buttonControls.length; i++) {

// if this input type is button, enable

if (buttonControls[i].type == "submit") {

buttonControls[i].disabled = false;

}

}

}

 

The solution is deployed to an existing SharePoint site so it needed to work for all buttons instead of specifying each button by name. You can see above I made use of the unobtrusive JavaScript pattern to make this possible. We also need to put this code in a JavaScript file and add it to the master page that the SharePoint site is using. One more thing to note is I had the JavaScript file reference just above the closing tag to ensure that all the DOM elements have been loaded before the JavaScript code executes.

*Warning - This has not been tested in Firefox. This was a closed intranet and not a requirement for this solution. Though I doubt it would take long to make this code cross-browser compatible.

 

Comments

 

JamesAshley said:

In a lot of ways, this looks like exactly the reason that I don't do consulting.  You wind up forced to do hacked-up crap like this.

This is the sort of thing that any half-way decent JS framework handles for you.

This is a *prime* example of why you just install a JS framework and use it.  You apologize to the client later, if they object.

I know some of the politics that were involved in this decision, and I do appreciate them.  They were stupid.  This was totally a situation where the client was milking the consultant, and the consultant needed to grow a pair of balls and crank out some code.

Sometimes, you have to cowboy-code.  Throwing jquery, dojo, or mootools (for example) at this would have left you in a much better position.

Esp. since this particular client is already inclined to FOSS.

There are almost definitely cases where this approach is valid.  I believe this was not one of them.

Don't re-invent the wheel if you don't have to.

January 22, 2009 10:31 PM

Leave a Comment

(required)  
(optional)
(required)  
Add

About KyleKelin

Kyle Kelin has been implementing software in the Microsoft space for the past 6 years mainly as a consultant. His interests are SharePoint, .NET, JQuery, and Silverlight.
2019.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems