ASP.Net Validators And The DOM

The ASP.Net Validation engine does not seem to play nicely with CSS and the DOM. By this, I mean that if you add a validator to the DOM, ASP.Net injects elements into the DOM. Then, it applies it's own inline styles to those injected elements.

For example, a simple Required Field Validator control will add an entirely new element node to the DOM. Something like this

<asp:RequiredFieldValidator ID="valPassword" runat="server" ErrorMessage="The password is a required field" ControlToValidate="txtPassword" />

Will result in this

<span id="ctl00_ContentPlaceHolder1_txtPassword_rev5" style="color:Red;visibility:hidden;">The password is a required field</span>

This is rather ugly and quite unhelpful.

Notice the inline style of visibility:hidden. The Visibility style simply makes the element invisible - it still takes up space in the DOM. This means the validation span will most likely actually appear as a blank space in your DOM to the right (or below) the form field it is validating. I find this frustrating and annoying because I like to have total control of my DOM.

We can make this happen using the same ASP.Net Validation controls. We just need to tweak it a little.

Take this snippet for example

<asp:RequiredFieldValidator ID="valPassword" runat="server" Display="Dynamic" ControlToValidate="txtPassword">
	<span class="validation active">The password is a required field</span>
</asp:RequiredFieldValidator>

Notice that the validator now wraps around a span element. Also, the Display attribute has been applied to the validator. Now, let's make a change in our CSS so that the span is formatted how we want.

.validation {
    display: none;

    &.active {
        display: inline;
    }
}

This is written in LESS, but it's saying that an element with a class of validation should always be hidden. Unless, that same element also has a class of active. If it does, the element should be displayed inline.

The Display="Dynamic" attribute setting will force the validation element to be display: hidden by default. So the rendered validator code now looks like this.

<span id="ctl00_ContentPlaceHolder1_FieldNameForValidation" style="color:Red;display:none;">
	 <span class="validation active">The password is a required field</span>
</span>

So now we have validation that is only visible when it is required. Perfect!

Til next time...