Wednesday, September 10, 2008

Validation in the ASP.NET Ajax Control Toolkit TabContainer

The ASP.NET Ajax Control Toolkit contains a TabContainer control which allows the user to change tabs without a postback.

But what if you want to validate user input in the TabContainer? I could not find documentation or samples about this so had to try myself. With a little help from Bertrand Le Roy, here is what I found out:

There are two different use cases for validation and tab controls:

Sample TabContainer

1. The tabs all belong to one big user input that is validated as a whole. You would want to have one button below the tabs (e.g. "Save" or "Send"). This button would validate all controls on all the tabs.

2. The tabs are independent of each other, each containing independent user input. Each tab would have its own button, and if a button on a tab is pressed, only the controls on that tab should be validated.

If you just place ASP.NET validation controls into the different TabPanels, a click on a button will validate all of them. This is use case 1, where you want to validate all user input at once.

However, the user may be editing on tab 1, while he hasn't yet filled in a required field on tab 2. If the user now presses the button, client side validation will discover the required field on tab 2 isn't filled in and no postback occurs. The user won't see any visual indication of the validation error, because the validation control is on tab 2, which isn't visible.

ASP.NET validation controls support a property SetFocusOnError. This automatically sets the focus on an input control that failed validation. However ASP.NET isn't able to switch the tab in the TabContainer.

The solution for use case 1 is to insert a ValidationSummary next to the submit button, outside of the TabContainer. The ValidationSummary can alert the user to validation errors across all tabs.

For use case 2 with the independent tabs, ASP.NET's validation groups are the solution. Each validation control has a property ValidationGroup. Use a different validation group on each tab. The button on each tab should have its ValidationGroup property set to the same value as the validation controls on that tab. In the button's click event handler, be sure to call the page's Validate method with the validation group as a parameter, before checking Page.IsValid.

One more thing to note about user input in the TabContainer: There is a bug in the TabContainer which resets the active tab if you have a control on a tab with AutoPostBack set to true. To work around this issue, set the TabContainer's ActiveTab property in the handler of the autopostback event.

9 comments:

Anonymous said...

Can you post an example of this? Thanks.

Sven said...

Great! I had to deal with case 1 and you saved my day!

Anonymous said...

awesome.. you saved my day!!

Thoulfekar | ذوالفقار said...

nice tip. Thanks!

Hari Palakurthi said...

Also wanted to share an example for setting active Index when you have validators in different tabs. Thsi would apply to use case 1 and is little more sophisticated.

You can create javascript method such as:

function RunValidationsAndSetActiveTab() {
if (typeof (Page_Validators) == "undefined") return;
try {
var noOfValidators = Page_Validators.length;
for (var validatorIndex = 0; validatorIndex < noOfValidators; validatorIndex++) {
var validator = Page_Validators[validatorIndex];
ValidatorValidate(validator);
if (!validator.isvalid) {
var tabPanel = validator.parentElement.control;
var tabContainer = tabPanel.get_owner();
tabContainer.set_activeTabIndex(tabPanel.get_tabIndex());
break;
}
}
}
catch (Error) {
alert("Failed");
}
}

In the button that is used to submit all the tabs at once where each tab has set of validations you can call the above method on click of button on client side such as:

OnClientClick="RunValidationsAndSetActiveTab()"

Ryan said...

Great article, exactly what I was looking for! But what if the user is on Tab 1 and they click Tab 2 instead of clicking your Validation button? Could you have a client-side javascript function that calls the click method of your validate button?

Appreciate any input -

Ryan

Anonymous said...

We want to check something in server side and then with the check result to decide whether to show new tab panel or not !
How can you do that?

Anonymous said...

Thanks so much Martin. I was searching for a solution for such problem and your approach worked perfectly.

Anonymous said...

e cigarettes, electronic cigarette, e cig reviews, e cigarette, smokeless cigarettes, best electronic cigarettes