About your host

Photo of your host - Charles Vallance Charles Vallance is a web developer with a slight case of OCD when it comes to nice clean standards compliant html and code.

Badges

twitter / cvallance
My articles have been featured in The Morning Brew - Daily .NET News and Views

Tag Cloud

more tags...
posted @ Monday, August 06, 2007 11:08 PM

I've been doing a bit of experimentation with Castle Validation recently and thought I should write about a few of my findings... also found a couple of oddities here and there which Hammett squashed very quickly.

Setting up the validation rules was as easy as 1, 2, 3. It was just a matter of adding some validation attributes to my public properties in my ActiveRecord classes. Eg.

[Property]
[ValidateNonEmpty("First name is required")]
public string FirstName {
    get { return _firstname; }
    set { _firstname = value; }
}

I could quite easily dictate how the validation errors were rendered to the user after server side validation but the client side validation was another story.

When a rule fails, it basically throws a div after the form element. A little bit like this:

<label for="user_FirstName">    
    <span>First name<sup>*</sup></span>
    <input id="user_firstname" name="user.firstname" value="" class="required validation-failed" title="First name is required." type="text">
    <div class="validation-advice" id="advice-required-user_firstname" style="opacity: 0.999999;">First name is required.</div>
</label>

The first thing you'll notice (actually, probably not actually without seeing my css) is that this is going to severly stuff up my look and flow. Things get even more higgle-te-piggle-te when you have the immediate set to true on the formtag.

[NOTE] My print screen button doesn't seem to be working right now, weird, but I'll get some screen shots up as soon as I can.

At this stage you're probably all thinking - big deal, suck it up buddy and use your css fu to style div.validation-advice! And that's a fair call... if you stop reading here.

Say you have this:

[Property]
[ValidateNonEmpty("Email is required", ExecutionOrder=1)]
[ValidateEmail("Email isn't a valid format", ExecutionOrder=2)]
[ValidateIsUnique("Email already exists, visit forgot password page to reset your password.", ExecutionOrder=3)]
public string Email {
    get { return _email; }
    set { _email = value; }
}

Now when you ommit an email address, you get this in the rendered div:

<div class="validation-advice" id="advice-required-user_email" style="opacity: 0.999999;">Email is required. Email isn't a valid format.</div>

Now if you enter something in the email field but its not a valid email address you get this:

<div class="validation-advice" id="advice-validate-email-user_email" style="opacity: 0.999999;">Email is required. Email isn't a valid format.</div>

[NOTE] ValidateIsUnique doesn't display because this is done server side.

Now this isn't ideal to say the least. It is because the castle client side validation uses the title of the input for the error message... and this obviously can only contain one string.

But not to worry my friends, I found a way around it! :-) Albiet, in my opinion, an ugly one.

Using this post here, I experimented with inserting my own .validation-adivce elements with the id's given to me when castle rendered its own client side validation. So after a bit of experimentation, I found it all working fine and dandy.

So this code here, which contains several rules and looks extremely bloated, makes the castle client side validation work more to my liking:

<ul class="validation-errors">
    <li id="advice-required-user_firstname" class="validation-advice" style="display: none;">First name is required</li>
    <li id="advice-required-user_lastname" class="validation-advice" style="display: none;">Last name is required</li>
    <li id="advice-required-user_email" class="validation-advice" style="display: none;">Email address is required</li>
    <li id="advice-validate-email-user_email" class="validation-advice" style="display: none;">Email address is not valid</li>
    <li id="advice-required-user_dateofbirth" class="validation-advice" style="display: none;">Date of birth is required</li>
    <li id="advice-validate-date-user_dateofbirth" class="validation-advice" style="display: none;">Date of birth is not valid</li>
    <li id="advice-required-user_password" class="validation-advice" style="display: none;">Password is required</li>
    <li id="advice-validate-min-length-3-user_password" class="validation-advice" style="display: none;">Password must be between 3 & 12 characters</li>
    <li id="advice-validate-max-length-12-user_password" class="validation-advice" style="display: none;">Password must be between 3 & 12 characters</li>
    <li id="advice-required-user_confirmation" class="validation-advice" style="display: none;">Password confirmation is required</li>
    <li id="advice-validate-same-as-password-user_confirmation" class="validation-advice" style="display: none;">Passwords don't match</li>
</ul>

I wonder if I could write some sort of component that could spit out that code for me... maybe I shall look into that when I return from skiing. Yowl!

Technorati Tags:

And then he said...

No comments posted yet.

And then I said...

Title *
Name *
Email
Url
Comment *  
Please add 2 and 1 and type the answer here: