Disable Validation on Hidden Controls

While working on a website this week I needed the ability to disable the form validation on a control that was hidden from view using a style sheet. e.g.

  1. <div style="display:none;">
  2.   <asp:TextBox runat="server" ID="foo" />
  3.   <asp:RequiredFieldValidator runat="server" ID="foo_req" ControlToValidate="foo" ErrorMessage="Required field" />
  4. </div>

After a little bit of searching, I found a ValidatorEnable method that comes with ASP:

  1. // Disable the valiation
  2. ValidatorEnable(document.getElementByID('<%= foo.ClientID %>'), false);
  3.  
  4. // Enable the validation
  5. ValidatorEnable(document.getElementByID('<%= foo.ClientID %>'), true);

Unfortunately I had a little trouble getting this to work. It would either not work altogether, work but then I couldn’t make the field visible again, or the validation was still working but because the element was hidden you just doesn’t see the error message (inevitably preventing the form from submitting).

Through a little bit of debugging I think I realized the issue; even though the ValidatorEnable method is supposed to accept a control reference (an actual DOM element through a call such as document.getElementById() then a true/false representing the enabled status) it doesn’t even touch an array I care passionately about: Page_Validators.

  1. var Page_Validators =  new Array(document.getElementById("ctl00_MainContentPlaceHolder_foo_req"), /*…*/);

You see, this little array is assigned by ASP and is used by the validation code that ASP provides. In it is a list of every validator that should be applied and which control it applies to. With every form submission, ASP loops through this array and checks to make sure everything is acceptable before proceeding (despite be thinking I disabled a few of them).

So what’s the solution? I decided to write my own method that takes this array in to consideration (and it appears to work very well). Is it the correct way? Not sure. Does it get the job done? Yes. (and that’s all I care about for now).

  1. function _ValidatorEnable(control, enabled) {
  2.   enabled = enabled || false;
  3.   ValidatorEnable(control, enabled);
  4.   control.style.visibility = !enabled ? 'hidden' : ''; // necessary?
  5.   if (typeof Page_Validators === 'undefined')
  6.       return;
  7.   for (var v = 0; v < Page_Validators.length; v++) {
  8.     var validator = Page_Validators[v];
  9.     if (validator.controltovalidate == control.id) {
  10.       validator.enabled = enabled;
  11.     }
  12.   }
  13. }

That’s what I came up with. Basically, in addition to calling a function that should always work, it also loops through the validator list (if existing) and finds any that relate to the control in question and sets them as enabled/disabled as well. I also have a little CSS style change in there that may or may not be necessary, but (as I mentioned) I was getting controls staying invisible on me and this was the best-fit solution (i.e. best hack).

If anyone else knows a better way, by all means please share it. I have yet to come up with a better way, or find a better solution out there (which is also why I’m making a post).

Flattr this!