Custom behavior on ASP.NET client-side validation

Let’s say you want to trigger special behavior when ASP.NET client side validation is triggered – something other than displaying an error message. In my case, I needed to change the border color of the offending control(s). There is no built in way to do this right now, so far as I’ve been able to find, unless I wanted to write custom Javascript code for every single input field on the site — no thanks.

For my solution to work, you cannot use LinkButton controls: this is because LinkButton controls don’t trigger the ASP.NET form‘s submit event. This solution is based on this Stack Overflow question, which gives us this to start with:

$('form').submit(function () {
    if (typeof Page_Validators != 'undefined') {
        $.each(Page_Validators, function () {
            if (!this.isvalid) {
                $("#" + this.controltovalidate).addClass("InvalidControl");
            } else {
                $("#" + this.controltovalidate).removeClass("InvalidControl");
            }
        });
    }
});

There is one large problem with this method, however – if you have more than one validator on a control, then whatever the status of the last validator in the array is will determine the final state of the control. Here are my modifications to get around this problem:

$('form').submit(function () {
    if (typeof Page_Validators != 'undefined') {
        $.each(Page_Validators, function () {
            var controlIsValid = true;
            var validators = document.getElementById(this.controltovalidate).Validators;

            //if there is more than one validator, and we're looking at the 
            //last one in the array, then let's do our own custom validation
            if (validators.length > 1 && this == validators[validators.length - 1]) {
                for (var i = 0; i < validators.length; i++) {
                    if (!validators[i].isvalid) {
                        controlIsValid = false;
                    }
                }
            } else if (validators.length == 1) {
                controlIsValid = this.isvalid;
            }

            if (!controlIsValid) {
                $("#" + this.controltovalidate).addClass("InvalidControl");
            } else {
                $("#" + this.controltovalidate).removeClass("InvalidControl");
            }
        });
    }
});

But this iteration has a problem too. The CompareValidator control registers itself with both the control it’s checking, and the control it’s comparing against, but it’s only in the Page_Validators array once. In my case, I have a Password and a Confirm Password field. Both are required, and both need to match. The above code meant that the control we’re comparing to (Password) is altogether skipped. That brings us to our final iteration:

$('form').submit(function () {
    if (typeof Page_Validators != 'undefined') {
        $.each(Page_Validators, function () {
            var controlIsValid = true;
            var validators = document.getElementById(this.controltovalidate).Validators;

            //check to see if any of the validators are CompareValidators
            for (var v = 0; v < validators.length; v++) {
                //if we find one and this control is not the subject of the validator, but the control to compare against...
                if (validators[v].hasOwnProperty("controltocompare") && this.controltovalidate == validators[v].controltocompare) {
                    //...then remove the validator from our array
                    validators.pop(validators[v]);
                }
            }

            //if there is more than one validator, and we're looking at the 
            //last one in the array, then let's do our own custom validation
            if (validators.length > 1 && this == validators[validators.length - 1]) {
                for (var i = 0; i < validators.length; i++) {
                    if (!validators[i].isvalid) {
                        controlIsValid = false;
                    }
                }
            } else if (validators.length == 1) {
                controlIsValid = this.isvalid;
            }

            if (!controlIsValid) {
                $("#" + this.controltovalidate).addClass("InvalidControl");
            } else {
                $("#" + this.controltovalidate).removeClass("InvalidControl");
            }
        });
    }
});
About Kelly Carter

I'm a freelance web developer, doing business under the name Rainworks Web Development. I'm a skeptical technophile, voracious reader, softcore gamer, and haphazard tinkerer. I have a long-term partner, a cat, and no time for glass ceilings.

Speak Your Mind

*