User availability check usability improvements
AJAX, ASP.NET, CSS, UI By Dave Ward on July 9th, 2007This is a follow-up post, building on the foundation laid in ASP.NET AJAX username availability check. In this post, I assume you’ve read and understood the first post.
After originally implementing AJAX username availability checking in my applications, I noticed an edge case scenario that replayed itself too often to ignore. The availability check could potentially take longer than a particularly fast user would need to complete the form. To avoid any trouble in that scenario, I wanted to add a progress indicator to the checking process and disable the submit button’s until an available username was selected.
Adding the progress indicator
For the progress indicator, I basically copied the technique described in my CSS style as AJAX progress indicator post. I added another background image CSS class, progress:
.progress { background-image: url(spinner.gif); }
Then, added this client script to the page:
// Hook the InitializeRequest event. Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(Init); function Init(sender, args) { // Change div's CSS class and text content. $get('UserAvailability').className = 'progress'; $get('UserAvailability').innerHTML = 'Checking availability...'; }
This causes the div’s class to change to a spinning progress indicator animation when the partial postback begins, and changes the div’s text content to clarify what’s going on.
At the completion of the postback, the div’s content will be replaced by what’s generated in code-behind, so there’s no need to do anything on the client side for endRequest. The server-generated content will overwrite this temporary change and automatically replace the progress indicator with the username’s availability.
Preventing invalid submissions
I decided to declaratively start the button control off disabled, so that it defaults to blocking submissions until an available username is selected. Since I want to be able to manipulate its Enabled property in partial postbacks, I also enclosed it in an UpdatePanel:
<asp:UpdatePanel runat="server" ID="up2"> <ContentTemplate> <asp:Button runat="server" ID="Button1" Text="Sign me up!" Enabled="false" /> </ContentTemplate> </asp:UpdatePanel>
Next, I updated the username availability check to update the button’s enabled state appropriately:
if (Membership.GetUser(Username.Text) != null) { UserAvailability.InnerText = "Username taken, sorry."; UserAvailability.Attributes.Add("class", "taken"); Button1.Enabled = false; } else { UserAvailability.InnerText = "Username available!"; UserAvailability.Attributes.Add("class", "available"); Button1.Enabled = true; }
Now, at the same time the availability check’s result is displayed, the button will also be enabled or disabled depending on the availability of the username.
Because only the username TextBox, the availability div, and the Button are enclosed in UpdatePanels, only their contents will be replaced by partial postbacks. This is crucial so that other elements of the form aren’t reverted to their pre-postback state after the availability check. If your page has other UpdatePanels, make sure to set your UpdateModes and Triggers to properly isolate partial postback results.
Watch out for partial postbacks
Finally, I decided that I should also disable the submit button during availability checks. If a user chose an available username, but then changed it to something unavailable, they could sneak a submit in during the availability check’s callback. To prevent this I disabled the submit button, in the same InitializeRequest handler that displays the progress indicator:
$get('Button1').disabled = true;
This simply disables the button as soon as the partial postback begins. If the username ends up being available, the newly rendered button will be enabled, else it will remain disabled until the user chooses an available username.
In other words, no one with JavaScript enabled should be able to submit a registration for an invalid username now.
Bringing it all together
There are still several more improvements that could be made. For example, if the username is unavailable, we could suggest a few available variants of that username. However, I’m happy with these improvements as a solid first step toward improving the baseline user experience on my registration forms.
To clarify all of my rambling, convoluted source code snippets, here are the aspx, c#, css, and image files used throughout these two posts:
Similar posts
What do you think? Your comments are welcome.
I appreciate all of your comments, questions, and other feedback, but please try to stay on topic. If you have a question unrelated to this post, I recommend posting on the ASP.NET forums instead.
If you're replying to an existing comment, please use the threading feature. To do this, click the "Reply to this" link underneath the comment you're replying to.



Smart stuff, but don’t you think a (custom) validator would be the way to go here? Although, the current validators don’t always work correctly in an UpdatePanel.
I think you may be right about that. I’ll give some thought to rewriting that to work within the framework of a custom validator.
Thanks for the suggestion.
I am having trouble adapting the code to work within a templated create new user wizard. I keep getting the error Error ‘UserAvailability’ is not declared. A command like (CType(CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl(“cboCountry”), DropDownList)).SelectedValue is not working either. Any help would be appreciated.
I’m not quite sure exactly what you’re asking. Could you email me some code (or post it here, using <pre> tags)?
Hi,
This is a really interesting tutorial, but I’m wondering – how would I do this using Visual Basic, instead of C#?
Oops, nevermind – I feel a little blind. I didn’t catch that that’s a piece of Javascript.
Perfect. Exactly what I was looking for. Looks like there’s one extra angle bracket in the asp file, right above the update panel. seems to be causing this issue when you fire a build.
Error 1 Content (‘<‘) does not match any properties within a ‘System.Web.UI.UpdatePanel’, make sure it is well-formed. C:\Users\admin\Desktop\AJAXUsernameCheck\Default.aspx 24
Removed it and it worked perfectly. You might want to change that in the uploaded zip.
Thanks for putting this out.
Fixed. Thank you for letting me know about that.
>>
Perfect. Exactly what I was looking for. Looks like there’s one extra angle bracket in the aspx file, right above the update panel. seems to be causing this issue when you fire a build.
Error 1 Content (’< ') does not match any properties within a ‘System.Web.UI.UpdatePanel’, make sure it is well-formed. C:\Users\admin\Desktop\AJAXUsernameCheck\Default.aspx 24
Removed it and it worked perfectly. You might want to change that in the uploaded zip.
Thanks for putting this out.
>>
>>
Fixed. Thank you for letting me know about that.
>>
Thanks!!
Dear Dave,
First checked your code stand-alone… But when I implemented it in a converted createuserwizard, it failed on the JScript…
CreateUser changes the IDs of the DIVs, so I went to the compiled code, found the changed IDs, and changed the JScript refs to them – for UserAvail and the Button…
Hope this will help others…
Lars
Code dosent work when implemented using master pages
and code is added in child page
You’ll need to pay extra attention to your ClientIDs in a master page scenario. Take a look at this post and its comments, for some ideas: http://encosia.com/2007/08/08/robust-aspnet-control-referencing-in-javascript/
I am trying to use this in a DetailsView. When I click my save button (Insert command) the javascript function InitializeRequest fires again causing the “Checking availability…” to show again in my again(already been verified). Trying to figure out why the (CommandName= Insert) is causing the InitializeRequest to happen again. This is probably really evident but been working hard and in a brain frazzle, I appreciate your help.
You’ll need to check args.get_postBackElement().id in your InitializeRequest handler and only trigger that indicator when it’s Username (or whatever your username field’s ID is).
HI
Thanks for the your great post, but i m facing problem to implement it. It’s working perfectly but problem is that when i click any button on my register page that casue for post back than the result will dislplay on my page other wise do nt show user availbility. I want to implement in my page that when a user type his user name in the UserName text box and go to other text box, it’s show massage immidaitely tht massge.But it this case i have make post back, text change event not working perfectly. Please help me!!!