Need to change the Rendered HTML Code for the RequiredFieldValidator

Okay, this problem is driving me crazy. In an application that I help develop we’re using the RequiredFieldValidator as shown below.

<asp:RequiredFieldValidator ID="rfvZipCode" runat="server" CssClass="TextErrorValidateField" ControlToValidate="txtZipCode" Text="The 'Zipcode' field is a required field." Display="Dynamic" ErrorMessage="The 'Zipcode' field is a required field." SetFocusOnError="true"></asp:RequiredFieldValidator>

The resulting HTML is rendered in a SPAN tag as shown below.

<span id="ctl00_cphPageContent_rfvZipCode" class="TextErrorValidateField" style="color:Red;display:none;">The 'Zipcode' field is a required field.</span>

Now, I like how the Display=“Dynamic” allows the error to appear on the blur event of the field, HOWEVER, I don’t like the rendered code to be shown in a SPAN tag. I’m much rather it be a DIV so that each error can be shown in a block level element. So my next thought was to just change the SPAN tag with a class of TextErrorValidateField into a block level element in my CSS as shown below.

SPAN.TextErrorValidateField { display: block; }

I even added a clear: right; for good measure however I’m pretty sure the JavaScript created by .NET automatically switches it back to display: inline when showing the error because if multiple errors exist they’re all shown as inline elements which is not what I want for this application. Now I can understand why they made them inline elements but in this case I want them to be block level elements. Does anyone know of a way for me to change the rendered code of the RequiredFieldValidator to make it a DIV rather than a SPAN apart from creating my own control?

WordBaron

There might be other ways (much simpler) but… here is one.


[ToolboxData("<{0}:MyRequiredFieldvalidator runat=server></{0}:MyRequiredFieldvalidator>")]
public class MyRequiredFieldvalidator : RequiredFieldValidator
{
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Div;
}
}
} 

That works yet doesn’t work. It works in the fact that yes, it does change the SPAN tag to a DIV tag like I wanted however it doesn’t behave like a DIV tag. Essentially, I believe this is the same problem I encountered when I tried to add the display: block; in the CSS. The problem happens when the client-side JavaScript sets the display of the element to “dynamic”. So, yes, the first part of the issue is solved, the required field validator now renders a DIV tag. Now is there a way to chance the rendered JavaScript to change the tag to a “display: block;” onblur rather than “display: dynamic;”? As of right now the end result of the viewable code is the same as it was when it was a SPAN tag.

You could go futzing around with the .NET javascript, but that is not really recommended as it can easily get overwritten.

Can you place the element in a wrapper div that is a block display? That might be the most workable solution.

Yeah, I don’t think that’s going to work because the way the Required field validators are working, the error messages only show up on the onblur event of the field. So essentially they go from “display: none;” to “display: dynamic;”. Since I have the error messages appearing at the top of the page when they occur a wrapper block level element that exists when the property for the error is “display: none;” would result in extra space for each element. And for some forms where there are 10+ required fields, that would result in a lot of empty space at the top of the page for the containers for the hidden error messages.

I was wondering if there was a way to change the JavaScript that the Required Field Validator renders.

Here is an example Here is an example of what it looks like when the errors get displayed. What I want is for each error to be on its own line in its own DIV where I can control the spacing in between them with CSS margins.

I’m with wwb, I would avoid messing with the .Net controls javascript.

Anyway I belive this is the function that sets the display of the validator

it might help! :slight_smile:


function ValidatorUpdateDisplay(val) {
	if (typeof(val.display) == "string") {
		if (val.display == "None") {
			return;
		}
		if (val.display == [b]"Dynamic"[/b]) {
			val.style.display = [b]val.isvalid ? "none" : "inline";
[/b]			return;
		}
	}
	if ((navigator.userAgent.indexOf("Mac") > -1) &&
		(navigator.userAgent.indexOf("MSIE") > -1)) {
		val.style.display = "inline";
	}
	val.style.visibility = [b]val.isvalid ? "hidden" : "visible";  [/b]// this is with val.display set to "static"

cheers,
rui

Do you have two validators foreach field. ?
What is rendering the star (*) and the what is rendering the error messages?

Have you considered using a Validation Summary Control on the top of the form?
I belive one could posibly make the Validation Summary render like the red bar you have on top of the form with the error messages.

cheers,
Rui

Eh! The ValidationSummary doesn’t display onblur… :stuck_out_tongue:

Yeah, if I could get the ValidationSummary to appear on the onblur I think I’d be all set! :slight_smile: But I already had checked that one out and couldn’t find anyway to do it.

The red asterisks are not part of the RequiredFieldValidator. The code that we’ve written simply shows those for any field that is required. It shows regardless of whether or not an error is displayed. So to answer your question, there is only one Required Field Validator per form element.

I guess I’m not sure what I need to do with that JavaScript code that you sent. That’s the code that .NET renders? If so, can it be changed or will I always be forced to have each error rendered as an inline element?

Hmm, you probably could get by using an Atlas UpdatePanel with the validation summary to make it appear. I have not tried it so I cannot really say if this will work.

The reason to avoid futzing with the .NET javascript is that it is stored in a site-wide folder (/aspnet_client/version) and can easily get overwritten when some admin applies patches, etc.

Not really sure where to go from here, save writing a custom validation stack or adjusting requirements to fit the environment.

I like this challenging problems! :slight_smile:
I think I got it. At lest it seams to work. And it could be one way to do it.

I used a CustomValidator and used the some javascript functions used by the RequiredFiledValidator. I call this functions to validate the control and depending on result I change the css class of the CustomValidator.

CSS


[color=#800000].valHidden[/color][color=#000000] {[/color][color=#ff0000]color[/color][color=#000000]:[/color][color=#0000ff]Red[/color][color=#000000]; [/color][color=#ff0000]display[/color][color=#000000]: [/color][color=#0000ff]none[/color][color=#000000];}[/color]
[color=#800000].valVisible[/color][color=#000000] {[/color][color=#ff0000]display[/color][color=#000000]:[/color][color=#0000ff]block[b]!important[/b][/color][size=1][size=2][color=#000000];}[/color][/size] 
[/size]

So the !important “thing” overrides the “inline” set by the validatiors javascript (the function I posted above).
I change the css class because it will also override the display:none; when the validator is hidden.

The javascript custom validation function


[color=#0000ff]function[/color][color=#000000] CustomRequiredFieldValidatorEvaluateIsValid(source, arguments) [/color]
{ 
arguments.IsValid = (ValidatorTrim(ValidatorGetValue(source.controltovalidate)) != ValidatorTrim(source.[b]initialvalue[/b]));
[color=#0000ff]if[/color] (arguments.IsValid)
source.className = [color=#800000]"valHidden"[/color];
[color=#0000ff]else[/color]
source.className = [color=#800000]"valVisible"[/color]; 
[size=1][size=2]}[/size]
[/size]

the ASPX code


[color=#0000ff][color=#0000ff]<[/color][color=#800000]div[/color][color=#0000ff]>[/color]
[color=#0000ff]<[/color][color=#800000]asp[/color][color=#0000ff]:[/color][color=#800000]TextBox[/color] [color=#ff0000]ID[/color][color=#0000ff]="txtLanguage"[/color] [color=#ff0000]runat[/color][color=#0000ff]="server"[/color] [color=#ff0000]Columns[/color][color=#0000ff]="22"[/color] [color=#ff0000]MaxLength[/color][color=#0000ff]="32"[/color] [color=#0000ff][color=#ff0000]Text[/color]="TheInitialValue"></[/color][color=#800000]asp[/color][color=#0000ff]:[/color][color=#800000]TextBox[/color][color=#0000ff]>[/color]
 
[color=#0000ff]<[/color][color=#800000]asp[/color][color=#0000ff]:[/color][color=#800000]CustomValidator[/color] [color=#ff0000]ID[/color][color=#0000ff]="CustomValidator1"[/color] [color=#ff0000]runat[/color][color=#0000ff]="server"[/color] [b][color=#ff0000]ClientValidationFunction[/color][color=#0000ff]="CustomRequiredFieldValidatorEvaluateIsValid"[/color][/b] [color=#ff0000]ControlToValidate[/color][color=#0000ff]="txtLanguage"[/color] [color=#ff0000]CssClass[/color][color=#0000ff]="valHidden"[/color] [color=#ff0000]Display[/color][color=#0000ff]="Dynamic"[/color] [color=#ff0000]OnServerValidate[/color][color=#0000ff]="CustomValidator1_ServerValidate"[/color]
[b][color=#ff0000]initialvalue[/color]="TheInitialValue"[/b]
[color=#ff0000]ValidateEmptyText[/color][color=#0000ff]="True">[/color]*[color=#0000ff]</[/color][color=#800000]asp[/color][color=#0000ff]:[/color][color=#800000]CustomValidator[/color][color=#0000ff]>[/color][b]Test Block[/b]
[color=#0000ff]</[/color][color=#800000]div[/color][color=#0000ff]>
[/color][/color]

what the RequiredFieldValidator does it to compare the its initialvalue attribute value with the input value of the control to validate.

So you set the ClientValidationFunction property of the CustomValidator to the name of javascript function posted above and add a initialvalue attribute to the CustomValidator with the value of the TextBox Text property.

To validate on the server-side you can do something like this


[color=#008080][color=#0000ff]protected[/color][color=#0000ff]void[/color][color=#000000] CustomValidator1_ServerValidate([/color][color=#0000ff]object[/color][color=#000000] source, [/color][color=#008080]ServerValidateEventArgs[/color][color=#000000] args)[/color][/color]{
 
[color=#008080][color=#008080]CustomValidator[/color] [/color]validator=source[color=#008080] [color=#0000ff]as[/color] [color=#008080]CustomValidator[/color];[/color]
 
[color=#008080][color=#008080]Control[/color] [/color]controlToValidate=validator[color=#008080].[/color]NamingContainer[color=#008080].[/color]FindControl(validator.ControlToValidate);
 
[color=#008080][color=#0000ff]if[/color] ( [color=#0000ff]typeof[/color][/color]([color=#008080][color=#008080]TextBox[/color][/color]) == controlToValidate.GetType() )
args.IsValid = ( ( [color=#008080][color=#008080]TextBox[/color] [/color])controlToValidate ).Text != validator.Attributes[[color=#008080][color=#800000]"initialvalue"[/color][/color]];
 
[color=#008080][color=#0000ff]else[/color] [color=#0000ff]if[/color] [/color]( [color=#008080][color=#0000ff]typeof[/color][/color](ListControl) == controlToValidate.GetType().BaseType )
args.IsValid = ( ( ListControl )controlToValidate ).SelectedValue != validator.Attributes[[color=#008080][color=#800000]"initialvalue"[/color][/color]];
}

If all works fine you should see the Test Block text drop to the line bellow the CustomValidator <span> tag.

cheers,
rui

^^^That is slick. One day I will learn to love JS.

^^^^
Ah! I’m a JS nullability!! All I did was an “if else”.
I will have to learn it some day to!!

WordBaron,

if you can’t find another solution and decide to go the way of my example.

I think its best to wrap it all in a Custom control derived from CustomValidator, and make a small javascript library that calls the Validators functions, and another for the server-side.

Having to do my example for every control you want to validate its a pain.

cheers,
rui

I attached the Validator javascript

Excuse me, but isn’t this exactly what display dynamic/static does? IIRC dynamic does not mean that javascript will execute on onblur (it will anyways), but rather that a span tag should be used instead of a div tag.

If you set Display=Static the validator will control the Visibility attribute instead, and use a DIV tag for the error text.

hi mouse,

The RequiredFieldValidator renders always has a span tag, no matter if its Display property is set to Dynamic or Static. The diference is that with Display set to Dynamic the RequiriedFieldValidator will change the display css property from none to inline and with Static will change the visibility css property from hidden to visible.

So, in terms of display effect in the browser with Display set to Static the RequiredFieldValidator will always take up space, while with Display set to Dynamic it will not take up space when “hidden”.

since <span> is an inline element giving it a left or right margin will not mater, you have to make it behave like a block element first by setting its display css property to block.

The problem is, how do you make the RequiredFiledValidator to not take up space when the Page is valid and behave like a block element when the Page is not valid?

You can’t. With Display=Dynamic the javascript validation fuctions will set the css display property to inline making the <span> tag behave like a inline element, and with Display=Static the validator it will always take up space. So, there is no way of making the span tag have a css display of none when the Page is valid and a css display of block when invalid.

cheers,
rui

pufa,

Thanks for all the help. I came to the same conclusion about using the CustomValidator to run the JavaScript. Between the inability to easily change the display property to block in the JS and the inability to turn off case sensitivity for the RegularExpressionValidators, I feel like the Field Validators are just so close to being what I need without actually being what I need. I see their big advantage as being both a client-side and server-side validation all-in-one, but until they go through a little more tweaking by MS, I think I’ll be forced to use the CustomValidator and still have to generate the JavaScript that I want to run. Luckily, I’ve already spent time in the past developing and tweaking a bunch of JS functions that allow me to both validate and format user entered data for a large number of formats. Now I just need to come up with complementary functions to also do it server-side should the user turn off JavaScript.

Also, thanks for explaining the difference to BenjyMouse. You beat me to the reply.

I’m surprised there isn’t an option in the Validators to set both the display type (inline or block) independently from the display visibility options (hidden or none).

The case sensitivity of the RegularExpression Validator is especially troubling because it makes all of my regexs almost twice as long in some cases (and much more difficult to read). I’ve decided to address that though by first converting things like email addresses and URLs to lowercase and then running a simpler regex against them. It seems to work pretty well thus far but I’m guessing that some inflexibilities in the Regex Validator will force me to go to the CustomValidator for that as well.

Thanks again for your help.

On regex sensitivity–IIRC, there is a /i option you can set that makes things case-insensitive . . .

I believe that you recall incorrectly. Althougth there are people that have created a validator that is not case sensitive.

http://www.users.bigpond.com/conceptdevelopment/Validation/InsensitiveRegularExpressionValidator/

^^^^The option does exist, at least in the .net end. See http://msdn2.microsoft.com/en-us/library/yd1hzczs.aspx

The problem is on the client side not on the server side.


var rx = new RegExp(val.validationexpression); // Case sensitive
var rx  = new RegExp(val.validationexpression, 'i'); // case insensitive

the first RegExp constructor is what its used in the Validators javascript.