Note: This post is part of a long-running series of posts covering the union of jQuery and ASP.NET: jQuery for the ASP.NET Developer.

Topics in this series range all the way from using jQuery to enhance UpdatePanels to using jQuery up to completely manage rendering and interaction in the browser with ASP.NET only acting as a backend API. If the post you're viewing now is something that interests you, be sure to check out the rest of the posts in this series.

Validation Sticker

You’ve probably noticed that Jörn Zaefferer’s jQuery validation plugin has been gaining momentum in the ASP.NET community lately. Between Microsoft’s implied endorsement via ASP.NET MVC 2.0 integration and the plugin’s recent inclusion on the Microsoft AJAX CDN, adoption is only increasing. Unfortunately for those who don’t or can’t use ASP.NET MVC yet, using the validation plugin within WebForms applications can be tricky.

Because the WebForms Postback model requires that the entire page be contained within a single form element, form submissions that shouldn’t trigger validation are likely. ASP.NET’s built-in validation controls solve this with ValidationGroups and the CausesValidation property, but that doesn’t help if you’d prefer to use the jQuery validation plugin.

However, there are a couple relatively easy workarounds that make it possible to use the jQuery validation plugin on WebForms pages, without re-architecting the page or its forms. In this post, I’ll show you why the WebForms page structure is a problem, how to make jQuery validation work with it, and an example of implementing those workarounds.

Note: I want to preface this by saying that you should never rely entirely on client-side validation. The jQuery validation plugin can be a great replacement for the client-side part of the ASP.NET Validators, but it is not a complete replacement on its own. Use responsibly!


<form> over function

When it comes to using jQuery validation, the trouble with WebForms is that it requires all of the ASP.NET controls on a page to be contained within a single form element. That doesn’t lead to any problems in simple demos, but things are more complicated when it comes to real-world pages. They often require multiple logical forms on the same page, and that’s where the problems start.

For example, consider the common scenario of having both a login form and a customer information form on the same page. We’ve probably all seen something like this before:

<form id="form1" runat="server">
  <fieldset>
    <legend>Returning customer?  Login here</legend>
 
    <label for="Username">Email:</label>
    <asp:TextBox runat="server" ID="Username" />
 
    <label for="Password">Password:</label>
    <asp:TextBox runat="server" ID="Password" TextMode="Password" />
 
    <asp:Button runat="server" ID="Login" Text="Login" />
  </fieldset>
 
  <fieldset id="BillingInfo">
    <legend>New customer?  Provide the following</legend>
 
    <label for="FirstName">First Name:</label>
    <asp:TextBox runat="server" ID="FirstName" CssClass="required" />
 
    <label for="LastName">Last Name:</label>
    <asp:TextBox runat="server" ID="LastName" CssClass="required" />
 
    <label for="Address">Address:</label>
    <asp:TextBox runat="server" ID="Address" CssClass="required" />
 
    <label for="City">City:</label>
    <asp:TextBox runat="server" ID="City" CssClass="required" />
 
    <label for="State">State:</label>
    <asp:TextBox runat="server" ID="State" CssClass="required" />
 
    <label for="Zip">Zip:</label>
    <asp:TextBox runat="server" ID="Zip" CssClass="required" />
 
    <asp:Button runat="server" ID="Order" Text="Submit Order" />
  </fieldset>
</form>

In most web frameworks, you would divide both logical forms into separate form elements, but WebForms requires both to remain joined within its single form element. This means that clicking either of the Button controls will submit both logical forms together.

Once applied to a form through its default usage, the jQuery validation plugin will attempt to validate all of the elements on that form any time it is submitted. That automation is usually handy, but it means users trying to submit our login form will be denied due to validation failing on the unrelated fields below.

Since using separate form elements containing WebForms controls isn’t realistic, we need to tackle this on the client-side and find a way to make jQuery validation more WebForms-friendly.

Taming jQuery validation

To remedy this problem, we first need to prevent the jQuery validation plugin from automatically triggering on every form submission. The initializer’s onsubmit property allows us to do just that:

$(document).ready(function() {
  // Initialize validation on the entire ASP.NET form
  $("#form1").validate({
    // This prevents validation from running on every
    //  form submission by default.
    onsubmit: false
  });
});

That fixes our problem of the login form triggering unwanted validation in the form below, but it creates another issue. Now, neither of the forms will validate when submitted.

Taking control with on-demand validation

Instead of relying on the plugin to automatically validate form submissions, you may also use a less widely known method for triggering the validation on-demand. When added to a page, one of the new methods that jQuery validation exposes on the jQuery object is valid().

When valid() is called on the jQuery object returned from selecting a “validated” form element, it will trigger validation on every field within the form and return a Boolean value indicating whether or not the form is valid.

$(document).ready(function() {
  $("#form1").validate({
    onsubmit: false
  });
 
  $("#Order").click(function(evt) {
    // Validate the form and retain the result.
    var isValid = $("#form1").valid();
 
    // If the form didn't validate, prevent the
    //  form submission.
    if (!isValid)
      evt.preventDefault();
  });
});

At first glance, this code might look incomplete to you. We care about more than just preventing form submissions when the form fails validation; we must also indicate the validation errors to the user.

Fortunately, the valid() method has the very useful side effect of displaying the plugin’s configured validation errors for any fields it finds to fail validation.

From the user’s perspective, this implementation is the same as the original one using the default usage. This method just happens to also have the added benefit of actually allowing returning users to log in.

To be continued…

This solution is a good start, but has (at least) two flaws.

First, it doesn’t handle keyboard triggered form submissions. What happens if the user hits the enter key in one of the TextBoxes?

Second, what if we want to also validate the login form? If validation rules are added to that form’s fields, we’ll have exactly the opposite problem as what we started with. Valid submissions in the lower form will be prevented by validation failures on the upper form.

For solutions to both of those problems, be sure to read my followup post: Emulate ASP.NET WebForms validation groups with jQuery validation.

Download the Source

Download WebForms-jq-validation.zip