Saturday, August 30, 2008

Ajax.NET: Disable buttons until postback finishes

When developing Web Forms in ASP.NET it is usually the case that we have multiple postbacks on a page. When there are Ajax calls as well it can easily happen that we can have multiple outstanding postbacks - e.g. postback by dropdown list immediately followed by a button click, or simply multiple button clicks. Due to various reasons those calls can end up in different sequence on the server (e.g. network latency). For some we might not care, but for some the sequence might be important.
What I'm showing here is a simple client solution to the problem. It will simply disable buttons while the postback ends thus preventing user to click on them until the postback had finished.


<script language="javascript" type="text/javascript">
//on the page submit we want to disable buttons until the call is finished
// and then reenable them
(function() {
//add on the page load event that will register our scripts
//for all significant events
Sys.Application.add_load(setupButtonDisablers);

function setupButtonDisablers() {
//subscribe to on page load and submit events
//on page load we will enable buttons
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(onPageLoad);
//on page submit we will disable them
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(onSubmit);
//remove setup code so it will never be called again
Sys.Application.remove_load(setupButtonDisablers);
}

//on page load - enable all the relevant buttons
function onPageLoad() {
findAndEnable('<%= MyButton1.ClientId %>');
findAndEnable('<%= MyButton2.ClientId %>');
}

//on page submit - disable all the relevant buttons
function onSubmit() {
findAndDisable('<%= MyButton1.ClientId %>');
findAndDisable('<%= MyButton2.ClientId %>');
}

function findAndDisable(id) {
findAndSetDisabledProperty(id, true);
}

function findAndEnable(id) {
findAndSetDisabledProperty(id, false);
}

//finds and sets disabled property of a searched control
function findAndSetDisabledProperty(id, value) {
var control = $get(id);
if (control) {
control.disabled = value;
}
}
})();
</script>


This is fairly simple code, without comments it would be really short. What it does is subscribing to page submit and load events and is disabling and enabling buttons respectively. Just put it somewhere on a part of the page that will be loaded first time the page loads.
You can make this more complicated if you need to do something specific depending on which element caused the postback by using different signature for onSubmit function. Here is documentation for the beginRequest event. Basically it will accept sender and args and you can use args.get_postBackElement() for example and make decisions what to do with your page elements then - hide them, disable them, animate them, whatever.

And at the end, remember that despite all the effort done on the client side you will always have to handle any eventuality on the server. Always remember, any client input is evil and it has to be validated - in this case postback sequence.

Thursday, August 28, 2008

XML Schema for Install.rdf available on Codeplex

I just published the first version of the XML Schema for the Install.rdf file (Mozilla Add on Install Manifest file) on Codeplex. More information on the file is here: Install.rdf on Mozilla Developer Center. The schemes are published under MPL 1.1 license.
Add on Manager enabled XUL applications (Firefox, Mozilla, Songbird, Flock, ...) are using install.rdf file to get description of the add on being installed. With this schemas you can get better support in your favourite IDE. Here are some screenshots from my Visual Studio:
You can see more screenshots on the project's wiki.
Most of the elements have regex validation, and wherever I could I added some enumeration support as seen on the picture above. However there might be errors so if you find any please report them on project's issue tracking.
All suggestions are welcome. I added discussion thread just for that purpose. If you know how to setup your favourite IDE to use this files add them there and I will update wiki accordingly. I have already added instructions for Visual Studio.
In future I plan to add more features - wizards, possibly some kind of management tools, etc. However this is in probably distant future since I don't have much time. What you could expect in the near future is XUL schema under MPL license. I'm half way there so I hope I'll publish it in next couple of weeks.