Wednesday, June 24, 2009

ASP.NET user name availability check using WCSF Validation Bundle

An average web site offering membership and protected content for its members requires users to sign up by visiting a sign-up or register page that allows a user to enter some information and create an account. A couple of pieces if information that users are commonly asked to enter are a User name or Login name and user's email. One potential problem with such user input is checking that entered login name and/or email address are available for registration and haven't been used by other users. When it's the case multiple attempts of entering available values can be very annoying and frustrating for users even making them to refuse registration on a web site. So improving user experience when validating login name and email is quite an important task.

There is a number of ways of how to implement a user input validation and display an error message, for instance that one suggested by Dave Ward. In this post I am going to show you another relatively simple and elegant solution that provides with both  reliability and reasonably pleasant user experience.

The solution is based on using a ServerSideValidationExtender control from Web Client Software Factory validation bundle. The ServerSideValidationExtender control allows asynchronious invocation of a server-side validation handler that performs a validation right after a user finished entering data without a postback thus signifcantly improving the user experience at the same time leveraging robustness and security of server-side validation.

Code example

For this example I will be using a really simple markup code:

<asp:Label ID="lblEmail" runat="server" Text="Email: ">
<asp:TextBox ID="txtEmail" runat="server">
<asp:CustomValidator ID="cvEmail" runat="server"
ErrorMessage="Email is already used"
ControlToValidate="txtEmail"
onservervalidate="cvEmail_ServerValidate" />
<wcsf:ServerSideValidationExtender ID="ssveEmail"
TargetControlID="cvEmail"
ValidateEmptyText="false" runat="server" />
<br />
<asp:Label ID="lblLogin" runat="server" Text="Login: ">
<asp:TextBox ID="txtLogin" runat="server">
<asp:CustomValidator ID="cvLogin" runat="server"
ErrorMessage="Login name is already used"
ControlToValidate="txtLogin"
onservervalidate="cvEmail_ServerValidate" />
<wcsf:ServerSideValidationExtender ID="ssveLogin"
TargetControlID="cvLogin"
ValidateEmptyText="false" runat="server" />
<br />
<asp:Button ID="cmdRegister" runat="server" Text="Register" />

that effectively results in that UI in a browser:


For each TextBox control requiring asynchronious server-side validation I've added a CustomValidator control and a ServerSideValidationExtender that has its TargetID property set to an ID of a corresponding CustomValidator control.

Next I've added some code to the validation handlers for the CustomValidator controls to the page's code behind and that's it:

protected void cvEmail_ServerValidate(object source,
ServerValidateEventArgs args)
{
args.IsValid = string.IsNullOrEmpty(
Membership.GetUserNameByEmail(args.Value));
}

protected void cvLogin_ServerValidate(object source,
ServerValidateEventArgs args)
{
args.IsValid = Membership.GetUser(args.Value) == null;
}

Note that the IsValid equals true when a user can not be found. The server-side validation handler is being executed asynchroniously every time a corresponding TextBox loses its focus and if validation has failed (meaning that a user was found and login name or email is not available) a corresponding error message is displayed immediately on the page without a postback so a user does not have to click a submit button and wait for the page to render again to see the result of the validation.


The only trick here is that in the server-side validation handler we can only access a value of the control being validated because values of other controls on the page haven't been updated on the server side (no postback, remember?!).

Note. In the production code you may want to add some layout and styling to your HTML markup, and of course there will be perhaps other input boxes on a form with may be more validator controls but the approach won't change: no additional code required, the same well-known validation pattern but with nicer user experience. I would also recommend to implement a simple but very useful change to the ServerSideValidationExtender control suggested by Jarod Ferguson.

Monday, June 22, 2009

How to set programmatically a value of a watermarked TextBox via JavaScript

There is an updated version of the article for the latest Ajax Control Toolkit release: http://blog.turlov.com/2010/05/how-to-set-programmatically-value-of.html

If you use ASP.NET AJAX and AJAX Control Toolkit you may find it useful to decorate some of your TextBox controls on a page with a TextBoxWatermark AJAX extender control from the AJAX Control Toolkit. It's fairly easy to use and a nice tool for improving both the page look and user experience.

However if you need to set a value of a TextBox decorated with the TextBoxWatermark extender programmatically via JavaScript on the client-side you may notice that the behavior of the watermarked TextBox is different. If you use the regular way to set a value like this:

$get(textBoxId).value = someText;

then the value displayed in the TextBox on the page will change to the set value but the watermarked look will still be present and other AJAX Control Toolkit TextBox extenders (like a Calendar extender, for instance) will not recognize the new value.

This happens because the TextBoxWatermark extender can not recognize and intercept your JavaScript operation since it's designed to serve user interactions. However there is a correct way of programmatic access to the TextBox's value. We modify the code above like that:

var textBox = $get(textBoxId);
if (textBox.AjaxControlToolkitTextBoxWrapper) {
textBox.AjaxControlToolkitTextBoxWrapper.set_Value(someText);
}
else {
textBox.value = someText;
}

The explanation is that most of the TextBox extenders from the AJAX Control Toolkit including a TextBoxWatermark extender use a special proxy class AjaxControlToolkitTextBoxWrapper to manipulate with the input elements. The proxy adds a special property AjaxControlToolkitTextBoxWrapper to the input element that contains a reference to itself allowing to access the value of the input element correctly. Similarly, if you need to get a value of a watermarked TextBox you do it like this:

var textBox = $get(textBoxId), text;
if (textBox.AjaxControlToolkitTextBoxWrapper) {
text = textBox.AjaxControlToolkitTextBoxWrapper.get_Value();
}
else {
text = textBox.value;
}

Tuesday, June 2, 2009

New version of ASP.NET AJAX Control Toolkit released

The new release of ASP.NET AJAX Control Toolkit is available for download. Bertrand Le Roy has written a very informative post about it. What particularly concerns me in this new release is that a Color Picker extender is now included in the Ajax Control Toolkit. Hooray!

Along with the new Toolkit release there come a whole bunch of new tutorials and videos among them there are one particularly nice tutorial about the Color Picker extender and an excellent video tutorial by Joe Stagner. Thank you folks for such a great job!

What that means for the Color Picker Extender users is that they don't have to download it separately from Codeplex anymore because it is included in the Ajax Control Toolkit. For those who can not switch to the new version of ACT yet the original Color Picker Extender control will continue to be available on Codeplex. During the next few days I will prepare and upload a new release synced up with the Ajax Control Toolkit.

It is also very interesting to read people's opinions about the new release of ACT that they write in response to blog posts and on Codeplex. In general the responses are positive however some folks complain about something, mostly about insignificant things or because they missed something. I would like to remind everybody that Ajax Control Toolkit is completely a community initiative (with of course the initial kick-off help from Microsoft) and people who work on it take time for it out of their families and other important things so let's be more tolerant and if you've come across something really bad please use the Issue Tracker.

In particular I was interested in reading responses about the ColorPicker (but of course ;-)). Interestingly all the complaints were about how its look and feel, not about functionality. I admit that the UI it provides is rather simplistic but here is my question back: where have you all folks been since the control was published almost a year ago and I was asking for your feedbacks and suggestions? Since then it's been downloaded more then 2000 times (and I don't count downloads of ACT source code) and almost no one except just a few people suggested anything about improving it. I take it as everybody has been satisfied. However now with a bit more visibility I suggest if you folks really want some progress with what concerns you please speak up.