Tag Archive for 'form'

Do you suffer from premature validation?

Seesmic Form Validation Error

It seems like everyone is getting form validation wrong.

Seesmic is a social vlogging app that's built in Flex and is currently in alpha testing. I got invited a few moments ago and went to sign up. On the site, I clicked in the First Name field and started to type. And stopped just as quickly, because, after the first letter, the field went red. Mousing over the error, I saw a message informing me that the First Name field must be greater than two characters long.

Ah.

You see, my name actually happens to be longer than two characters (though I guess my friend R Blank won't be signing up anytime soon) and I was in the process of typing it when I got distracted by the erroneous error message and stopped. Paradoxically, by stopping, I validated the error message's raison d'etre. Could it be that there are quantum mechanics at work here? :P

Seriously, though, as I've mentioned before, this is not the way to do form validation.

When implementing forms, you should Prevent, Not Scold. This is why validation is important. Validation is meant to prevent you from making mistakes instead of letting you make them and then scolding you about them.

However, implemented incorrectly, form validation can violate the Innocent Until Proven Guilty principle and present a usability anti-pattern, which I'm calling Scold Unfairly.

I remember a great example of Scold Unfairly (though not related to forms) in Windows XP a while ago. Before they changed the message, Windows would scold you quite harshly when it started up if you hadn't shut it down properly. Unfortunately, it would also do this when it crashed/Blue Screened. In other words, it would scold you for not shutting down properly when you hadn't done anything. Of course, this made Windows look quite dumb.

Similarly, you shouldn't Scold Unfairly when implementing form validation.

The ultimate no-no is to initially present a form to a user with all sorts of validation errors. Believe me, I've seen this done. The user hasn't done anything and thus could not possibly have made a mistake yet. Remember, the user is Innocent Until Proven Guilty.

One step up from that is scolding prematurely. No one likes premature validation. And it seems that Seesmic's form validation in this case gets a little too excited too quickly.

Technically, it is triggering the validation based on the wrong user gesture. Validation is tied to the text box's change event. Instead, it should be tied to the focusOut event so that it fires when the user leaves the field. Leaving the field is a strong indication that the user has finalized the contents of the field. It is the right time to carry out initial validation. Of course, the change event should still be listened for on fields that already have validation errors so that once the validation rule is met, the user is instantly notified and rewarded with the removal of the validation error.

For more details on how to properly implement validation in forms in general (but with examples specifically for Flex), take a look at the following resources:

Better form validation in Flex

Flex comes with a built-in form validation system that unfortunately uses mystery meat tooltips to display component validation errors.

To see what I mean, take a look at the example I wrote a while back in the Validating Data Quick Start.

Mystery Meat Error Messages

If you tab around that example, you may notice that you are probably doing something wrong (as indicated by the red borders around the form items that begin to appear) but you have no idea what you're doing wrong. In order to find out, you have to mouse over the form field. Only then does a tooltip appear to tell you what the problem is.

Needless to say, having the user switch input devices and exert additional effort in order to see a form validation error does not make for good ergonomics or usability.

A better alternative is to actually display the error message beside the control.

You can, of course, do this simply by having the error message in a label.

For example:

<mx:FormItem label="Your name">
    <mx:HBox>
        <mx:TextInput id="yourName" change="validateNotEmptyTextInput(yourName);" focusOut="validateNotEmptyTextInput(yourName);"/>
        <mx:Label id="yourNameError" visible="false" text="Your name cannot be empty."/>
    </mx:HBox>
</mx:FormItem>

The validateNotEmptyTextInput() method, in this example, is not a Flex Validator (as used in my Validation Quick Start), but a simple method.

For example:

private function validateNotEmptyTextInput(target:TextInput):void
{
    (this[target.name+"Error"] as Label).visible = (target.text == "");
}

In the above example, I'm using a pragmatic naming convention to create a generic validation method that works with TextInput components. Nothing too spectacular visually, but usability-wise already better than the default Flex behavior.

Creating an error Label for each component, though, is not very practical. We can overcome this limitation and add a little visual flare by using the Flex error tooltip instead of a label.

Kyle Quevillon has a post in which he details how to use the Flex Tooltip Manager to create Error Tooltips. Referring to Kyle's post, we can alter the validateNotEmptyTextInput() method as follows:

// If the TextInput is empty, display an error message.
if (target.text == "")
{
    // Has the error message ToolTip already been created?
    // (A reference to created ToolTip instances is saved in a hash called errorMessageToolTips.)
    var toolTipExists:Boolean = errorMessageToolTips.hasOwnProperty(target.name);
 
    if (toolTipExists)
    {
        // Error message ToolTip has already been created, just show it.
        (errorMessages[target.name] as ToolTip).visible = true;
    }
    else
    {
        // Create the ToolTip instance.
        var pt:Point = new Point(target.x, target.y);
        pt = target.contentToGlobal(pt);
        var errorTip:ToolTip = ToolTipManager.createToolTip(errorMessages[target.name] + " cannot be empty", pt.x + target.width + 5, pt.y) as ToolTip;
        errorTip.setStyle("styleName", "errorTip");
 
        // Save a reference to the error message ToolTip in a hash for later use.
        errorMessages[target.name] = errorTip;
    }
}
else
{
    // TextInput is valid. Hide the error message if one exists.
    if (toolTipExists)
    {
        (errorMessageToolTips[target.name] as ToolTip).visible = false;
    }
}
 

Where errorMessages is a hash of personalized messages:

errorMessages =
{
    yourName: "Your name",
    yourEmail: "Your email",
    phone: "The phone number"
}

Thus, we no longer need the Label component but there is a catch: we still need the HBox (or a container of some sort) if the TextInput is in a FormItem. Otherwise, contentToGlobal() returns an incorrect value when trying to position the error message.

So the new FormItem looks something like this:

<mx:FormItem label="Your name">
    <mx:HBox>
        <mx:TextInput id="yourName" change="validateNotEmptyTextInput(yourName);" focusOut="validateNotEmptyTextInput(yourName);"/>
    </mx:HBox>
</mx:FormItem>

And the resulting validation errors both look nice and are functional.

Better Flex Validation Errors

(In the above example, I modified the errorTip style to make the message boxes slightly shorter than usual by setting the paddingTop and paddingBottom properties to 2.)

To summarize, I'm not a big fan of the mystery meat validation error tooltips in Flex. Displaying validation errors on the form itself leads to better usability as users do not have to exert additional effort to find out what they did incorrectly.

Update: Someone has filed a bug about this very issue in the public Flex Bug and Issue Management System. I've left a comment on the bug and linked it to this post.






Bad Behavior has blocked 0 access attempts in the last 7 days.