Change Background Color of Invalid Controls (ASP.NET Validator) September 16, 2009
Posted by codinglifestyle in ASP.NET.Tags: background, border, custom, style, validator
trackback
I was working with a customer who has invested a lot in redoing the validation in their web application. I accedentially suggested wouldn’t it be nice if we could change the background or border of the field in question. The customer loved this idea which meant I’d just created more work for myself. After searching about I wasn’t finding this done for me, so I actually had to write some code instead of cutting and pasting.
If you set a breakpoint on WebForm_OnSubmit and step in you can check out the .NET validator script. Key thing here is a global array called Page_Validators. From here it is fairly trivial to test and change something about the control in question.
function fnOnUpdateValidators()
{
for (var i = 0; i < Page_Validators.length; i++)
{
var val = Page_Validators[i];
var ctrl = document.getElementById(val.controltovalidate);
if (ctrl != null && ctrl.style != null)
{
if (!val.isvalid)
ctrl.style.background=“#FFAAAA”;
else
ctrl.style.backgroundColor = “”;
}
}
}
Of course, one problem is if the control already had a background color, it would be lost. This can be circumvented by storing the old value in an attribute or elsewhere. Also, custom validators are a special case so you will need to add the appropriate changes for fields validated in a custom way.
To make sure my function is called I use the deprecated Page.RegisterOnSubmitStatement(“val”, “fnOnUpdateValidators();”). This will call my function after the validators have fired so the isvalid is up to date.
I have founds a more elegant way of reaching the same result:
var OriginalValidatorUpdateDisplay = null;
function NewValidatorUpdateDisplay(val) {
OriginalValidatorUpdateDisplay(val);
if (val.controltovalidate) {
document.getElementById(val.controltovalidate).style.backgroundColor = val.isvalid ? ” : ‘#FFAAAA’;
}
}
if (typeof (ValidatorUpdateDisplay) == ‘function’) {
OriginalValidatorUpdateDisplay = ValidatorUpdateDisplay;
ValidatorUpdateDisplay = NewValidatorUpdateDisplay;
}
This way the background color is also updated when the value of the control is changed, instead of only when the form is submitted.
Just to comment on Sil’s post, we can see the last few lines of his code are executed at startup. What he is doing is storing Microsoft’s function ValidatorUpdateDisplay in a global variable and replacing it with our own. Our version, NewValidatorUpdateDisplay calls the old version and then executes our custom code to change the background color. Great work!
A caveat to this is currently ValidatorUpdateDisplay is not reliably called if you are doing anything funny (like pressing a button which inserts a value to a textbox with a required field validator… the background color won’t dynamically change in this instance). Also, be mindful that if you have multiple validators on the same field my code and Sil’s code will clobber the previous validator. For example, one may be a regular expression validator which fails and the next is a required field validator which passes. In this case, the field will appear to be valid as the required field validator clobbered the regular expression validator.
Awesome! Much better than some of the code behind stuff I’ve seen around to do this.
To prevent the clobbering of multiple validators on a field, maybe you can test the type of validator before attaching the new event. Or just check an array of validators (ids) and only attach the new event if it matches.