This is an extension to Mohammed Nour El-Din's blog post on the jQuery Validation Plug-in; however, for ASP.NET Forms. Why Forms? Well, ASP.NET MVC is still beta and I sure most of our employers are NOT willing to support a beta product in a production environment. Therefore, until MVC is production ready and supported by the enterprise, we must make accommodations (hacks/workarounds) to support non-out-of-box scenarios. Besides, jQuery is awesome, and get this, it is now supported and encouraged by Microsoft.
Just to sure, I assume that if you are reading this blog entry you are familiar with jQuery, the jQuery Plug-in, ASP.NET, and client-side programming with ASP.NET. If not, Google the respective topic.
All of my statement's here are from my experience using the jQuery Validation Plug-in with ASP.NET. I have tried many different ways to make the plugin work with ASP.NET; however, I find that the following implementation fulfills my requirements the best.
The jQuery Validation Plug-in (and jQuery in general) follows the method of Convention over Configuration. The plug-in extensively uses and input control's name attribute by conversion so the user does not have to configure the plug-in to work; therefore, it just works. The plug-in also assumes that a control's name and id attributes are the same. In the ASP.NET world, this is not the case out-of-the-box. Out-of-the-box, a control's name attribute replaces the underscore (_) character with a US currency sign ($). The strategic reasons as to why ASP.NET implements this convention are out of scope for this post; however, you can find must more on Microsoft.com or via Google.
For these examples, I am using jQuery 1.2.6, the Validation Plug-in, the jQuery Forms Plug-in and ASP.NET 3.5. The following are my external JavaScript references:
1 <script language="javascript" type="text/javascript" src="jquery-1.2.6.pack.js">script>
2 <script language="javascript" type="text/javascript" src="jquery-validate/jquery.validate.js">script>
3 <script language="javascript" type="text/javascript" src="jquery-validate/lib/jquery.form.js">script>
The following are my styles:
1 <style type="text/css">
2 div.field-container { margin: 5px; }
3 label.labelField { width: 100px; display: block; float: left; }
4 label.error { font: bold 11px Verdana; color: Red; font-style:italic; padding-left: 10px; display: block; }
5 input[type=text], input[type=password] { border: 1px solid #7b9ebd; }
6 input:focus { border: 1px dotted black; }
7 input.error { border: 1px dotted red; }
8 style>
The following is the markup for the ASP.NET controls:
1 <div class="field-container">
2 <label class="labelField">
3 <span>First Name:span>
4 label>
5 <asp:TextBox ID="txtFirstName" runat="server" />
6 div>
7
8 <div class="field-container">
9 <label class="labelField">
10 <span>Last Name:span>
11 label>
12 <asp:TextBox runat="server" ID="txtLastName" />
13 div>
14
15 <div class="field-container">
16 <label class="labelField">
17 <span>User Name:span>
18 label>
19 <asp:TextBox runat="server" ID="txtUserName" />
20 div>
21
22 <div class="field-container">
23 <label class="labelField">
24 <span>Email:span>
25 label>
26 <asp:TextBox runat="server" ID="txtEmail" />
27 div>
28
29 <div class="field-container">
30 <label class="labelField">
31 <span>Password:span>
32 label>
33 <asp:TextBox runat="server" ID="txtPassword" TextMode="Password" />
34 div>
35
36 <div class="field-container">
37 <label class="labelField">
38 <span>Web Site:span>
39 label>
40 <asp:TextBox runat="server" ID="txtWebsite" class="url" />
41 div>
Okay, now to the meat. The following is the JavaScript code that I use to create, add, and extend the Validate Plug-in:
1 <script language="javascript" type="text/javascript">
2 // object containing asp.net control ids
3 var _pageFields = {
4 form: '<%= Master.FormMaster.ClientID %>',
5 firstName: '<%= txtFirstName.ClientID %>',
6 lastName: '<%= txtLastName.ClientID %>',
7 userName: '<%= txtUserName.ClientID %>',
8 email: '<%= txtEmail.ClientID %>',
9 password: '<%= txtPassword.ClientID %>',
10 webSite: '<%= txtWebsite.ClientID %>'
11 };
12
13 $(document).ready(function() {
14 var addOption = function(selector, /* jQuery Selector */
15 isRule /* true: rule | false: message */,
16 optionObject, /* json-formmated object to pass to the validate jQuery extension */
17 optionsToAdd /* rule or message options object*/
18 ) {
19 var $element = $(selector);
20 if (!$element[0]) return;
21 var key = (!!isRule) ? 'rules' : 'messages';
22 optionObject[key][$element.attr('name')] = optionsToAdd;
23 };
24
25 // temp options object for use with validate jQuery extension
26 var options = { rules: {}, messages: {} };
27
28 // add first name options to options object
29 addOption('#' + _pageFields.firstName, true, options, {
30 required: true,
31 minlength: 2
32 });
33 addOption('#' + _pageFields.firstName, false, options, {
34 required: 'Please enter a First Name.',
35 minlength: 'Your First Name must consist of at least 2 characters.'
36 });
37
38 // add last name options to options object
39 addOption('#' + _pageFields.lastName, true, options, {
40 required: true,
41 minlength: 2
42 });
43 addOption('#' + _pageFields.lastName, false, options, {
44 required: 'Please enter a Last Name.',
45 minlength: 'Your Last Name must consist of at least 2 characters.'
46 });
47
48 // add user name options to options object
49 addOption('#' + _pageFields.userName, true, options, {
50 required: true, minlength: 2
51 });
52 addOption('#' + _pageFields.userName, false, options, {
53 required: 'Please enter a User Name.',
54 minlength: 'Your User Name must consist of at least 2 characters.'
55 });
56
57 // add email options to options object
58 addOption('#' + _pageFields.email, true, options, {
59 required: true,
60 minlength: 2
61 });
62 addOption('#' + _pageFields.email, false, options, {
63 required: 'Please enter an Email.',
64 minlength: 'Your Email must consist of at least 2 characters.'
65 });
66
67 // add password options to options object
68 addOption('#' + _pageFields.password, true, options, {
69 required: true,
70 minlength: 8
71 });
72 addOption('#' + _pageFields.password, false, options, {
73 required: 'Please enter a Password.',
74 minlength: 'Your Password must consist of at least 8 characters.'
75 });
76
77 // add website options to options object
78 addOption('#' + _pageFields.webSite, true, options, {
79 url: true
80 });
81
82 $('#' + _pageFields.form).validate(options);
83 });
84 script>
Okay, so all I am doing here is creating a client-side object that contains the ASP.NET generated client IDs for the HTML input controls (lines: 1 - 11). I know, it's ugly, but it's what I find to be the best implementation.
Then I use jQuery's 'When the DOM is ready, do this...' function - $(document).ready(function(){}); (starting line: 13).
Within the anonymous function passed to ready, I create a new function 'addOption' (line: 14), As you can see from the code, there are four function parameters. The parameters are self-documented; however, I have also include in-line comments. All that t function does is add a rule or message referencing the respective jQuery wrapped selector object as the rule or message object key. Again, I assume that you are familiar with the jQuery Validation Plug-in and the members/properties of the rules and messages option object. WHAT did he say? Check it out the home page: jQuery plugin: Validation and documentation: Plugins/Validation.
Okay, so I describe the process of using ASP.NET Forms controls with the jQuery Validation Plug-in using a very code-centric strategy. Sometimes you must experiment and experience the discomforts before you can actually get ASP.NET to cooperate with jQuery; however, don't let this discourage you. jQuery is here to stay and it is a very powerful JavaScript library.
BTW, I am using the awesome Visual Studio Plug-in CopySourceAsHtml (CSAH) to copy my source from Visual Studio to my HTML editior as HTML formatted markup. Check it out...
My intent was to write this blog entry so that I don't loose my finding somewhere on my hard drive. I hope these efforts help someone else out there. Thanks for reading...