Validation, Business and Functional

The recent discussion of Form Validation – How do you do it?, had me wondering just what might be involved in creating an easy to use validation framework. It’s a task that might seem easy, but when you get down to all the special cases it’s anything but. ColdFusion is a language designed around rapid development, so why not attempt to create a Validation framework modeled around the idea that new rules can be added easily? Ok, that’s probably the case with any such framework, but it should be easy for a dynamic here. Today I’m mostly just brainstorming what I’d want and possible implementations. Over the next few days I’ll try to implement this.

So what should it be able to do? Well, Jeff’s post stated some very important requirements that I’d say are all must haves. To reiterate some of the points though, it should be able to validate entire business objects (cfcs with getters/setters OR named structs), it should be able to have a “strict” mode where it validates everything or a mode where only set fields are validated. It should be able to validate forms via ajax (funcational validation), as well as single fields via ajax. It should also be able to validate from the client side and return error messages (json/html) or validate on the server side and get back some sort of error collection.

We want this to be as easy to use as possible, so the validation rules should only exist in a single place. The ajax features should also automatically call the associated validation rules. One of the difficulties with ajax is always that it requires twice the work by definition, but what if by some convention both Javascript and validation could be written for us? Here’s what I’m talking about.

<form id="register" validate="onsubmit" message="before">
   <div class="group" id="required">
      <span id="register-first_name-field">
         <label for="register-first_name">First Name</label>
         <input type="text" id="register-first_name" name="user[first_name]" />
      </span>
      <span id="register-username-field">
         <label for="register-username">Username</label>
         <input type="text" id="register-username" validate="onkeyup" name="user[username]" />
      </span>
      <span id="register-email-field">
         <label for="register-email">Email</label>
         <input type="text" id="register-email" validate="onchange" name="user[email]" />
      </span>
   </div>
   <span>
      <input type="submit"/>
   </span>
</form>

This basic form would be the basis for how the front end would work. Based on the metadata we’re marking up on the form (namely those “validate” attributes). The idea is that a form has basic validation rules associated with it — when to validate it and where to put the return values. Each field in the form would then inherit the validation rules defined in the form, but could also overwrite them. For instance, this form would validate everything on submit by default, and place and error messages “before” the field they’re for. Other options might include “after”, “top” or “bottom” for the very top of the form, or “above” and “below” for errors to be put at the top of the current grouping. The HTML will require some kind of hooks for where to place these messages of course, which is where some the convention markup comes into place. The before/after messages would look for the formid-fieldid-field element and place it in an element before that. Top/Bottom would look for the formid and place based on that, and the grouping option would look for an element with the class of group that’s a parent element.

Now how would this know where to submit to for validation? That’s another easy convention to handle. Let say there’s three possible things that can be validated via ajax on a form — an entire form, a single object from a form or a single field from a form. Creating URLs for these to submit to might end up with something like this:

http://localhost/validate (validate.index)
http://localhost/validate/object (validate.object?object=objName)
http://localhost/validate/object/field (validate.field?object=objName&field=fieldName)

Using Coldcourse you could create these without much trouble, and the javascript could discover the validation URL to use based on the form field names. The fields are named in the form object[field] which is a Ruby on Rails/ColdFusion on Wheels convention. On the server side these are converted to structures before we ever have to start working with them. This validate controller would then call up some sort of ValidationService where the real meat of the work happens. The controller then knows to return the errors it gets back to the javascript handler based on some sort of Javascript view template.

This is just brainstorming at this point, but looks easy enough to implement. If there’s anything I’m overlooking, or any suggestions with this so far feel free to comment.

Tomorrow: start planning the service layer!


 
 
 

4 Responses to “Validation, Business and Functional”

  1. I’d been thinking about doing something similar as part of an actual form generator off and on over the past few months.

    I was about to get serious about it when all this information about Scorpio started coming out. When I read about the new cfajaxproxy tag, which would allow you to call CFC methods via AJAX, I realized that I’d better wait and see what that tag can do: if it lives up to its promise, you could write a single set of validation algorithms that could be used to do both client-side and server-side validation.

    One comment about your plans: displaying validation errors next to the form elements that failed their validation tests is nice, but it could be a problem for those who use screen readers, as the screen reader may not be aware that new text has been displayed and that it needs to read it off. Not saying you need to scrap the idea, but you might want to provide a means for certain users to get their validation errors via a JavaScript pop-up box (which I believe most screen readers will acknowledge and read off).

    Sounds like you’re off to a good start, though.

  2. Don’t use expandos; add the class “validate”. You can even do “validate-email” and such.

  3. @Brian
    Good point! I hadn’t thought about screen readers for that case. I’d probably handle that case in the same way i’d do for if javascript was disabled — redisplay the entire form in the updated state with the errors in there already. The problem with that though is that i’d have to have the markup in the form generation part, or create a form generator like you mentioned. I like the idea in theory of having a form generator, but it’d have to be very close sytanx to the actual form. As cool as it would be to have a generator that does everything you want, I don’t want to get edged into a corner where I’m not implementing what I want because it wouldn’t be easy with the builder.

    Definitely have to watch the ajaxproxy though. I agree it could make things even easier for validation.

    @Ziggy
    You’re probably right. Having a new attribute wouldn’t validate in xhtml strict I don’t think. Doing everything with classes would work though. I’d probably edge away from adding the datatypes in javascript though, just because I’d like to have all information about the objects validation rules in one place.

  4. @ziggy

    I agree with you.. Don’t use the expandos.