Thursday, September 4, 2008

Extending ASP.NET validation on the client side

One of the more annoying shortcomings of standard ASP.NET validation is it's lack of support for extending the the UI on the client side. For example, there is no way to set the css class of the input control when validation fails. I was working on some javascript to fix this when I came across an article that did just about the same thing. Combining my work with Scott's yields a bit more efficient javascript:
ValidatorUpdateIsValid  = function() {
 Page_IsValid =  AllValidatorsValid(Page_Validators);
 SetValidatorStyles();
}

SetValidatorStyles  = function() {
  var i;
  // clear all
  for (i = 0;  i < Page_Validators.length; i++) {
   var inputControl = document.getElementById(Page_Validators[i].controltovalidate);
   if( null != inputControl ) {
     WebForm_RemoveClassName(inputControl, 'error');
   }
 }
  // set invalid
  for (i = 0;  i < Page_Validators.length; i++) {
   inputControl =  document.getElementById(Page_Validators[i].controltovalidate);
   if( null != inputControl && !Page_Validators[i].isvalid ) {
        WebForm_AppendToClassName(inputControl, 'error');
   }
 }
}
ValidatorUpdateIsValid is part of the ASP.NET validation client script. It's invoked once whenever client side validation functions are triggered. For example after a field's value has been opdated (OnChange). This makes it the ideal place to hook into ASP.NEt client side validation. Hooking in to JavaScript is quite easy since in JavaScript any function can be redeclared. The last declaration is the one that is used. By inserting the script in the page content the function ValidatorUpdateIsValid is guaranteed to override the ASP.NET function that is loaded in the page header. I've packaged the script in a control that can be dropped into any (master) page to extend existing validation controls. I'll post the sources and a sample asap.

[11 okt 2010] Updated source code as suggested by Markus.

11 comments:

Mani said...

But when I use it with AJAX, I am getting the following error.

"The State Information is Invalid for this page and might be corrupted."

Do you have any idea how we can avoid this?

Marnix said...

Hi Mani,

What kind of AJAX are you doing on the page? Are you using an UpdatePanel?

Mani said...

Yes, but never mind. That is because of something else. your code works great. Thanks

Mani said...

Yes. I am using update panel. But I figured out that the error caused by some other code. Your code works great. Thanks

Travis said...

Thanks a ton for this code - short and sweet and does exactly what I needed!

Just a quick note: for some reason I couldn't get the code to work when I copy/pasted it. Not sure why, perhaps a character issue with the conversion. But, I just retyped what you had and it worked perfectly.

Thanks!! =D

Markus said...

THIS is really smooth code! short and simple and does exactly what I want it to :) Thanx Marnix for this beauty!

In the HTML output, ASP.net places its JS references just after the \ tag. I needed some time until I realized that I have to place Marnix' code BELOW the JS references (this is: in the \ BELOW the \ tag), otherwise it can't override the ASP.net functions.

Chen said...

Nice post. I have a problem here. The script does not fire when my validation controls are inside UpdatePanel. Any ideas?

Marnix said...

@chen Make sure the script is the last in the page. If that doesn't solve it please let me know.

Markus said...

FIRST: Correct my post from August...:
In the HTML output, ASP.net places its JS references just after the FORM tag. I needed some time until I realized that I have to place Marnix' code BELOW the JS references (this is: in the BODY BELOW the FORM tag), otherwise it can't override the ASP.net functions.

SECOND: Today I encountered a problem with Marnix' code and after some research found out that this code fails as soon as there's a custom validator (exactly: any validator without .controltovalidate) >> inputControl is Null >> can't assign a CSS class.

Luckily there's an easy solution: Add if (inputControl!=null) just before WebForm_RemoveClassName and WebForm_AppendToClassName.
Hope this helps to make a superb solution even better...

Marnix said...

@Markus:

Thanks for the feedback. I'll update the source code.

Anonymous said...

Thanks for the info. Way fater then looking in the asp.net js files. Thanks