Welcome to Professional ASP.NET - Chris Love's Official Blog Sign in | Join | Help

Chris Love's Official ASP.NET Blog

Chris Love's Helpful tips, tricks and pragmatic development knowledge for the ASP.NET world.
Add to Technorati Favorites


ASP Insider Follow Me On Twitter
jQuery Tutorial: Validation with the jQuery UI Tabs Widget

This is so long overdue, but I told Dave Ward last Summer I would post this Blog and well I have not been so good on that commitment. If you want to validate a form that is organized using the jQuery UI Tabs widget you probably need to perform validation as the user switches between tabs. In fact there may be many times you may need to validate a section of a form or a page as the user navigates through various areas. This technique can be used in any of those cases.

Specifically when using tabs there you may need to validate user supplied data before they are allowed to change tabs. The classical case is a wizard where the user steps through each step to reach  a completed state. Typically the wizard will have buttons to go forward and backwards. The user may also want to manually select tabs (not covered here) so validation needs to be performed in both these instances. In this example I am going to assume you have basic familiarity with the jQuery UI Tabs widget and the Validation plugin.

First the wizard markup. This example will use a super simple wizard that collects a user’s name on the first tab and their phone number on the second tab. But you should be able to extrapolate the functionality to forms of any size. If you are not familiar with how the jQuery UI Tab widget works, I recommend reviewing the documentation.

The following markup is the form used in this example:

<form id="MultiTabValidation" action="MultiTabValidation.aspx" method="post">
<div id="tabs">
<ul>
<li><a href="#FirstTab">General Information</a></li>
<li><a href="#PhoneTab">Phone Information</a></li>
</ul>
<div id="FirstTab">
<fieldset>
<legend>User Information</legend>
<ul>
<li>
<label for="txtName">
Name</label><input type="text" id="txtFirstName" class="required"></input></li>
<li>
<button id="btnToPhoneNumber" name="btnToPhoneNumber" type="button">
Next ></button></li>
</ul>
</fieldset>
</div>
<div id="PhoneTab">
<fieldset>
<legend>Phone Number</legend>
<ul>
<li>
<label for="txtPhone">
Phone</label><input type="text" id="txtPhone" class="phone required"></input></li>
<li>
<button id="btnToGeneral" name="btnToGeneral" type="button">
< Prev</button>
<button id="btnSubmit" name="btnSubmit" type="button">
Submit</button></li>
</ul>
</fieldset>
</div>
</div>
</form>

The example requires both the First Name and the Phone number be supplied. It also requires the phone number to conform to a standard US phone number format. There is a forward button on the first tab and a backward on the second along with a final submission button. Just a simple demonstration form organized in a tabbed format.

If you are not familiar with the jQuery Validation plugin syntax the validation is mapped to the input fields by adding a CSS class to the input’s class attribute. The plugin ships with many common validation rules included, but you can extend them as you need for your application. This demonstration uses the require and phone rules. And as you should have guessed class=”required” tells the jQuery Validation plugin that field is required. Adding phone (class=”required phone”) tells the plugin the input is required and should be a valid US phone number.

Now reference the latest jQuery library however you like. You will also need to reference the jQuery Validation Plugin, I also reference the additional-methods.js file for good measure ;). I place all this at the bottom of the page as usual.

Finally I add a script block that contains a $(document).ready(function(){}); and a helper plugin called validateTab. In the page’s ready function I define the validation behavior, I will return to this later.

The validateTab plugin is where the cool stuff happens anyway. It accepts one parameter, toTab, which is the index of the tab to navigate if validation succeeds. But before navigation validation must be performed. An isValid parameter is defined and set === true. This is use to determine if navigation van occur at the end of the plugin.

You may be telling yourself I made a typo above, but no I did not. In JavaScript you can use === to test for real equality and !== real inequality. Using the traditional == or != only tests for what Douglas Crockford calls truthy, meaning in JavaScript it can produce false positives in many instances. So using === is the best practice to test for quality in JavaScript.

Next, since this is a plugin $(this) is the jQuery object reference to the DOM element (the current tab in this case) being validated. Calling the jQuery find() function passing in selectors to grab all form input fields (using ‘input, select’ should get references to all the user input fields). Chaining the jQuery each() function and passing in an anonymous function to check validation gives us a place to check for valid user input on each input element.

jQuery.fn.validateTab = function (toTab) {

var isValid = true;

$(this).find("input, select").each(function () {
if (isValid) {
isValid = $(this).valid();
} else {
$(this).valid();
}
});

if (isValid) {

if (!toTab) {
toTab = 0;

}

$("#tabs").tabs('select', toTab);
}
return false;
}

Inside the anonymous function $(this) refers to the input element to validate, not the tab. Since the page references the jQuery validation plugin you can simply call the valid() function against the input element like $(this).valid(); and it will return true if the input passes its associated validation rules, or false if it does not. If isValid === true then validation is performed and the result is set to the isValid variable. If isValid is already false then it is not set again. You have to do this incase you are looping through elements and one is invalid but followed by a valid element. You still should check validation even if you have crossed a bad value. You should always let users know just how much is wrong!

If all the elements on the tab pass validation (isValid === true) then you can programatically select the desired tab using the following line:

$("#tabs").tabs('select', toTab);

In the document.ready function there are click event handlers for any buttons that navigate between tabs. Each event handler calls the jQuery PreventDefault function to keep the form from doing its default actions. It also calls the validateTab plugin function described above, passing in the target tab’s index against the button’s parent tab.

$(document).ready(function () {

$('#btnToPhoneNumber').click(function (e) {
e.preventDefault();
$("#FirstTab").validateTab(1);
});

$('#btnToGeneral').click(function (e) {
e.preventDefault();
$("#PhoneTab").validateTab(0);
});


});

The nice thing about performing validation by hand is no other tabs have validation performed on them. This means you have more control over the entire process and that performing validation on tab 1 does not perform validation on tab n. If validation were performed on the entire page the user experience would be fairly low because as each new tab is displayed to the user it would be littered with a collection of validation messages.

You can fire individual element validation anytime you need, giving you the freedom to validate anything you need on the page whenever you want. One of the many, lesser known features of the jQuery Validation Plugin.

Posted: Wednesday, May 12, 2010 9:25 AM

by Chris Love

Comments

jquery or prototype said:

hey, great tut... I just read a few jquery and prototype validation tutorials and I'm not sure which one is actually better. The code part is not too far off, but perfomance wise and credibility wise, which do YOU think is better? some people tell me prototype is dead, but yet I still find plenty of resources for it (or at least just a handful of users of it).
# May 12, 2010 4:56 PM

Sanjeev Agarwal said:

Daily tech links for .net and related technologies - May 13-16, 2010 Web Development Integrating Twitter

# May 13, 2010 5:59 AM

J&#246;rn Zaefferer said:

The valid()-method works for multiple elements, so you can just use: var isValid = $(this).find(":input").valid();
# May 17, 2010 9:50 AM

Icsbcn said:

It does not work!!!
# May 27, 2010 4:43 AM

Chris Love said:

Icsbcn you are going to have to be much more specific than that ;) I have a screen shot above showing it work.

# May 28, 2010 7:46 AM

Maksuda said:

Hi Chirs: I tried to run your code but gave me error when I clicked on Prev or Next button - isValid = $(this).valid() Error msg is- Microsoft JScript runtime error: Object doesn't support this property or method. Any idea what causing the error? Maksuda
# April 8, 2011 4:55 PM

Chris Love said:

Maksuda, typically this mean the method, valid() in this case, is not loaded. You need to have the jQuery validation plugin loaded before it is used. Sometimes I get that error message when there is a typo somewhere in my code. I would check the javascript console in the IE (F12) developer tools or Firebug to see where the error is.

# April 11, 2011 6:28 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS