Simplified Form Errors

One of the most frustrating experiences on the Web is filling out forms. When mistakes are made, the user is often left guessing what they need to correct. We've taken an approach that shows the user in no uncertain terms what needs to be fixed.

The problem

Most forms require validation — checks to see that required fields have been filled out with the right information. But when a mistake was made, how do you let the user know? The approaches taken by many sites leave much to be desired.

  • Show the error messages on a different screen than the form. The user has to remember what was wrong when they go back to correct the form. Often when they go back, their form information is now missing.
  • Validate one field at a time. The user is told to fix their email address, but when they do, they’re told they also need to include their phone number.
  • List the errors at the top of the form. The user needs to scan the form matching the error with the appropriate fields.
  • Highlight the erroneous fields. The fields are often highlighted by changing the colors. Visitors with vision disabilities, with text browsers, or browsing from non-color devices have trouble figuring out which fields were wrong.
  • Show an icon or symbol next to the offending fields. The user isn’t expecting those icons, so they aren’t looking for them.

Simplified

Here’s how we simplified the error screen.

  • Show all of the errors on the form itself so the user doesn’t have to remember what the errors were in order to correct them.
  • Fill in the information the user has already entered so they don’t need to re-enter it.
  • Show the user a summary of everything that needs to be changed, right at the top of the form. This way, they don’t need to hunt through the form looking for error messages.
  • Show an error icon in the summary of errors and repeat that icon after each field that is filled in wrong. The user immediately associates the icon with the errors and can quickly find them in the form.
  • Surround the field with a colored box and repeat the error message right next to the field. The colored box draws attention to the missing information and the error text explains exactly why that field is highlighted. The user doesn’t need to look back up at the error list to understand why this field is marked.
  • Use three different indicators to show which fields have a problem. By not relying on images or color to show the problem fields, we’re increasing the odds that the messages are accessible to more people.

We’ve provided a demo of the simplified form. Go take a look.

The code

In addition to simply showing the form layout, we’ve also written up an example in PHP. The form validation is simple, but it’s easy to adapt this to your own validation needs or to another programming language like ASP or Perl.


<?php
// Create an empty array to hold the error messages.
$arrErrors = array();
//Only validate if the Submit button was clicked.
if (!empty($_POST['Submit'])) {
    
// Each time there's an error, add an error message to the error array
    // using the field name as the key.
    
if ($_POST['name']=='')
        
$arrErrors['name'] = 'Please provide your name.';
    if (
$_POST['email']=='')
        
$arrErrors['email'] = 'A valid email address is required.';
    if (
$_POST['phone']=='')
        
$arrErrors['phone'] = 'Please provide your phone number.';
    if (
count($arrErrors) == 0) {
        
// If the error array is empty, there were no errors.
        // Insert form processing here.
    
} else {
        
// The error array had something in it. There was an error.
        // Start adding error text to an error string.
        
$strError = '<div class="formerror"><p><img src="/images/triangle_error.gif" width="16" height="16" hspace="5" alt="">Please check the following and try again:</p><ul>';
        
// Get each error and add it to the error string
        // as a list item.
        
foreach ($arrErrors as $error) {
            
$strError .= "<li>$error</li>";
        }
        
$strError .= '</ul></div>';
    }
}
?>

<style>
label {
  width: 80px;
  text-align: right;
  float: left;
}

.formerror {
  border: 1px solid red;
  background-color : #FFCCCC;
  width: auto;
  padding: 5px 0;
}

.errortext {
  padding-left: 80px;
  font: bold smaller sans-serif;
}
</style>

<?php echo $strError; ?>
<form method="post" action="<?php echo $PHP_SELF; ?>">
<!--
For every form field, we do the following...

Check to see if there's an error message for this form field. If there is,
add the formerror class to the surrounding paragraph block. The formerror
class contains the highlighted box.

Insert the contents of what the user submitted bak into the form field.

Check again to see if this field has an error message. If it does, show
the error icon and the error message next to the field.
-->
<p<?php if (!empty($arrErrors['name'])) echo ' class="formerror"'; ?>>
    <label for="name">Name:</label>
    <input name="name" type="text" id="name" value="<?php echo $_POST['name'] ?>">
    <?php if (!empty($arrErrors['name'])) echo '<img src="/images/triangle_error.gif" width="16" height="16" hspace="5" alt=""><br /><span class="errortext">'.$arrErrors['name'].'</span>'; ?>
</p>
<p<?php if (!empty($arrErrors['email'])) echo ' class="formerror"'; ?>>
    <label for="email">Email:</label>
    <input name="email" type="text" id="email" value="<?php echo $_POST['email'] ?>">
    <?php if (!empty($arrErrors['email'])) echo '<img src="/images/triangle_error.gif" width="16" height="16" hspace="5" alt=""><br /><span class="errortext">'.$arrErrors['email'].'</span>'; ?>
</p>
<p<?php if (!empty($arrErrors['phone'])) echo ' class="formerror"'; ?>>
    <label for="phone">Phone:</label>
    <input name="phone" type="text" id="phone" value="<?php echo $_POST['phone'] ?>">
    <?php if (!empty($arrErrors['phone'])) echo '<img src="/images/triangle_error.gif" width="16" height="16" hspace="5" alt=""><br /><span class="errortext">'.$arrErrors['phone'].'</span>'; ?>
</p>
<p>
    <input type="submit" name="Submit" value="Submit">
</p>
</form>

Comments

25 comments so far. Add yours

By BillSaysThis Jul 17, 2003 10:42 AM

Error (typo) alert: "When we simply something, we show it off here." Simply is meant, I expect, I to be simplify. LOL

By BillSaysThis Jul 17, 2003 10:47 AM

Also, how about a separate RSS feed for this? The first article is excellent.

By Adam Rice Jul 17, 2003 1:09 PM

Hmm, no reality-checking on the e-mail address or phone number. I realize that is somewhat outside the scope of this post.

By Adam Kalsey Jul 17, 2003 3:10 PM

Bill...
Typo fixed, thanks. That's what happens when you launch at 2am.

There is an RSS feed, but it's being held in an undisclosed location... I'm acutally trying to decide what content to include in the feed. Since articles will be posted pretty randomly, I don't want someone grabbing a full-text feed every 15 minutes. It might be weeks between articles, so that would simply waste bandwidth. So for now, feel free to subscribe to http://kalsey.com/simplified/rss.xml but be aware that the contents of the feed will proably change.

Adam...
That's right, the purpose of this isn't to show robust form validation. The validator only actually checks to see if there's anything (even a space) in the fields. A real form validator would check the formats of email addresses and phone numbers to see if they are real.

What I hope that people get out of this is that they can create user friendly form validation without hassle. The techniques that I'd expect people to use are what you can see in the screenshot, not what you see in the PHP. The only reason for including the PHP at all was so that you can see how simple the backend actually is.

By BillSaysThis Jul 17, 2003 5:00 PM

Thanks, Adam. The only reason I would want the RSS is to know that a new article is posted, since longterm I don't know that you want to keep mentioning them in the main blog. So just an excerpt in the RSS is more than fine, and I will set SharpReader to only check once per day.

By Marcus Jul 17, 2003 7:00 PM

Great article! How about an example that uses JavaScript to display the error icons OnChange().

By Adam Kalsey Jul 17, 2003 9:59 PM

I think you mean onblur. I've never been a fan of onblur validation. Just because I tab through a field doesn't mean that I have no intention of filling that field out. Validation should happen as a result of a positive action on the part of the user.

From Pseudo Design Jul 18, 2003 9:45 AM

Forms have to be one of the most annoying things about websites. I really do hate filling out any type of form, even login forms. I can only imagine how "civilian" web users feel about forms. Therefore, when I create forms on my websites I try to make them as quick as possible. Quick you ask? Yes, I said quick and let me explain how everyone should make their forms quick. Read more in Forms that make sense.

By Phillip Harrington Jul 18, 2003 11:37 AM

Why test for the submit button? This has always pissed me off about PHP developers.
if ($submit)... ugh!
Just say if (!empty($_POST))
Otherwise, your idea is solid. I have a class that handles the server side stuff (and I'm happy to email it to you for purusal), but your suggestions are spot on for user interface.

By Phillip Harrington Jul 18, 2003 12:06 PM

The reason to *not* test for the submit button, and specifically to not test for the value of a submit button, is in the case of the one input, one submit button form where the user types in the input and then types their "enter" key. Or a one input, two button form where they click "enter". $submit will be empty.

Proof: http://repster.com/dev/empty-submit.php

Further more, if you must name your submit button, please don't name it "submit", otherwise you'll go nuts trying to figure out why you can't say
this.form.submit();
later in JavaScript. Obviously "Submit" is OK.

From Kalsey Consulting Group :: Measure Twice Jul 18, 2003 12:07 PM

Thoughts on how to arrange fields on Web forms to make them easier to use. Read more in More Form usability.

By Phillip Harrington Jul 18, 2003 12:08 PM

But enough ranting, I'm really looking forward to this series of articles!

By Adam Kalsey Jul 18, 2003 12:51 PM

Phillip, the reason for testing for the submit button is to allow more than one submit button with different actions. For instance, Save and Cancel. Save stores the information in the database and goes back to the main screen, Cancel simply returns to the main screen. Just checking to see if a form was posted can't do that.

IE doesn't set the value of the submit button when the enter key is pressed, but Mozilla does.

But once again, the intent here isn't to show how to handle forms using PHP. It's to show how to notify the user of errors they made.

From synapse Jul 19, 2003 6:10 AM

Adam Kalsey starts a new set of features on simplifying the user experience - with example and code. Well worth your time. Read more in Simplified Forms.

By Phillip Harrington Jul 19, 2003 2:45 PM

You're right - this was not the place for my knee jerk reaction about submit buttons. And again, from a usability persective, these are great suggestions on many levels. I'm just a troglodyte about certain topics.
Having said that - can the 2 button form can still be sumbitted with the "enter" key? If so which value is passed?

By Phillip Harrington Jul 19, 2003 2:50 PM

OK I tinkered more. In Mozilla, if you have a two button form, and only type "enter". The form is submitted, and the first value of multiple submit buttons with the same name is passed as the value for that variable.

By Lyle - Croc O' Lyle Jul 21, 2003 6:03 PM

Why do the field labels disappear when there's an error? Standards dictate that all form fields should have a label.

By Adam Kalsey Jul 23, 2003 11:42 AM

I don't see the fields disappear on an error. What browser are you using? Certain versions of Mozilla have a bug that causes text inside the Label element not to be shown at times.

By Adam Kalsey Jul 24, 2003 4:21 PM

The problem Lyle was having is an apparent CSS bug in IE. Go figure. The float: left on the field label was causing it to disappear. So I'm using a CSS hack to make IE ignore the float on the label and now it works fine.

By Richard Soderberg Jul 27, 2003 3:20 PM

Looks remarkably similar to the error-handling I implemented at DataBuilt, way back when. We did server-side and client-side both -- should still be up on the web!

By Michael Alderete Jul 29, 2003 9:00 AM

Thanks for the great example, both visual and the back-end code.

Even though a couple people have picked nits with the PHP you included, it's quite valuable to be able to illustrate that it's not a huge task to do your web forms this way, instead of the problem ways you describe at the beginning of the article.

The reason why people do forms the problem ways is because it's easier, or it's the first solution that comes to mind. Just showing them the outline of a better way is often enough to change their thinking. (OK, maybe I'm projecting here; it worked for *me*. ;-)

By J.Shell Jul 31, 2003 7:46 AM

Nice article. I've been using Zope and a product called "Formulator." There are other kits like it out there for other languages/frameworks/servers. Basically - using Formulator (or something like it), you can design a form as smart widgets - instead of just an integer field, it can be an integer field with the range of 0 to 50. I like it because it takes care of both rendering (for most of my forms, I can just use a single loop to draw all of the fields) and validation.

Lately, I've been doing only one of the error displays that you've mentioned - displaying them up top, or displaying them next to the field. And I haven't been doing the greatest job at highlighting. I'll start applying both inline and uptop to my code from now on, and do the highlighting.

But I highly recommend looking into a Form Helper kit. ASP.NET has the concept built in, it seems. But for other systems - it's very helpful to be able to describe and define a form, its widgets, validation, etc, in the same place - outside of the code that will be responsible for display and validation. My applications have become a lot stronger since moving to such a system (mostly because I'd tend to be lazy/stressed and often punt on manual validation as one of those "I'll get back to it..." things).

From Kalsey Consulting Group :: Measure Twice Jul 31, 2003 9:34 AM

Shortcomings of form validation toolkits. Read more in Form validation tools.

By Tom Davies Sep 10, 2003 6:50 AM

The PEAR library comes with an HTML_QuickForm package that allows for some useful form validation and error displaying. So far I am pretty happy with it. If you are interested check it out at: http://pear.php.net/package/HTML_QuickForm

It should get you most of the way there.

By Flemming Mahler Nov 25, 2003 10:50 PM

Have you been past the Google AdSense login page recently (https://google.com/adsense/)? Try entering an invalid login and see what happens. While it isn’t exactly like the suggestion here, it is awfully close :)


Add your comments

This discussion has been closed. Thanks for all the comments.

What is this?

Everybody says they could do it better. We're proving it. When we simplify something, we show it off here.

About Us

Kalsey Consulting Group helps companies build Web sites that solve real business problems. We create sites that are a joy to use and easy to maintain. For more information about how we can help your business, ask us.

Recently

Sprout Test (May 7)
A test post for Sprout widgets.
Product Leadership (May 3)
An anthology of product leadership writing.
Fighting Monster patent claims (Apr 16)
The patent bully picked on the wrong little guy.
Peavy's pine tar (Apr 6)
Jake Peavy's cheating
Bush and Morgan on inner city baseball (Mar 30)
Morgan and Bush discuss the role of baseball in the inner cities.
Not a fork (Mar 27)
We have no intention of forking Drupal. That would be nuts. So what are we doing then?
Eating our dogfood in the sausage factory (Mar 26)
Recursive development for the new Drupal powered community platform.

Subscribe to this site's feed.

Elsewhere

Feed Crier
Get alerted by IM when your favorite web sites and feeds are updated.
SacStarts
The Sacramento technology startup community.
Pinewood Freak
Pinewood Derby tips and tricks
Del.icio.us
My tagstream at del.icio.us.
Waddlespot
My son's Club Penguin community. News, blogs, tips, and tricks.

Contact

Adam Kalsey

Mobile: 916.600.2497

Email: adam AT kalsey.com

AIM or Skype: akalsey

PGP Key

©1999-2008 Adam Kalsey.
Content management by Movable Type.