A better validation pattern for 9.1 forms

Today I’d like to go back again to revisit some functionality introduced in Reader 9.1 (XFA 3.0).  In 9.1 we added some enhancements specifically designed to improve the form validation user experience — and to allow validations to happen with less JavaScript code.  Specifically:

  • Message Handling options (described here)
  • The validation state change event (described here)

Prior to these enhancements, users were avoiding the use of validation scripts because they didn’t like the message boxes that popped up on every validation failure.  But now we have control over those message boxes, and, as we’ll see, there are lots of good reasons to like using validation scripts.

First things first, turn off the message boxes.  There’s a new designer dialog for this:

Designer dialog box showing a setting where the author can specify that validations do not display message boxes.

Great! now we don’t get those pesky dialogs showing up every time.  But now, of course, it’s up to you to find some other way to convey to the user that they have invalid fields in their form.  This is where the validationState event comes in.  It fires when the form opens, and it fires again every time a field validation changes from valid to invalid or vice versa.  The expected use of validationState is to change the appearance of the form to flag invalid fields. 

One more important piece of the puzzle: field.errorText. When a field is in a valid state, this text is and empty string.  When the field is invalid, it is populated with validation error text.

Take the example where we expect a numeric field to have a value greater than zero.  The validation script looks like this:

encapsulation.A1.B.C.D::validate-(JavaScript, client)
this.rawValue> 0;

The validationState event will set the border color and the toolTip text:

encapsulation.A1.B.C.D::validationState-(JavaScript, client)
this.borderColor = this.errorText? "255,0,0" : "0,0,0";
this.assist.toolTip.value = this.errorText;

Setting the toolTip value is important for visually impaired or color-blind users who won’t notice a change in border color. (There’s another topic waiting on designing a good validation experience that works with assistive technologies).

Hopefully this looks pretty clean and easy to code.  It’s important to contrast this approach with the alternative — just to make sure you’re convinced.

The Alternative

The alternative to field-by-field validation is to centralize form validation in one big script.  The big validation script then gets invoked by some user action – usually a form submit or print or validation button. Working with the same example, this script would look like:

encapsulation.validate::click-(JavaScript, client)
var field = A.B.C.D;
var bValid = field.isNull || (field.rawValue> 0);
if (bValid) {
     field.borderColor = "0,0,0";
     field.assist.toolTip.value = "";
} else {
     field.borderColor = "255,0,0";
     field.assist.toolTip.value = "The value of D must be greater than zero";
}

Here is a sample form that has both styles of validation.  And here are some reasons why you should prefer field-by-field validation:

  • Less code.  Three lines of code vs. nine. In a form with hundreds of fields, this difference becomes compounded
  • Better user experience — immediate feedback when fields become valid or invalid
  • Form processor is aware of the invalid field and will automatically prevent form submission
  • External validation scripts need to also enforce null/mandatory fields.  In the field-by-field approach, mandatory is enforced without any script.
  • Encapsulation: A term from our object-oriented design textbooks.  In this context it means that the field definition (including business logic and messages) is self-contained.  The benefits of encapsulation include:
  • Notice that the second example references the field by it’s SOM expression: A.B.C.D; There are any number of edit operations that could change that expression: moving a field, unwrapping a subform, renaming a subform or field etc.  If any of these operations happen, the script will need to be updated.  In the first example, there is no SOM expression needed and the script can remain the same through all thos edit operations.
  • Use fragments.  If you want the field to be included in a form fragment, you need to make sure that the validation logic is included with the field.  When the logic is encapsulated, this is not a problem.  When the validation logic is outside the field, it’s much harder to find ways to have the logic accompany the field.

Not Ready for 9.1?

Assuming you’re now convinced that field-by-field validation is what you want, you might still be in a situation where you can’t assume your users have 9.1.  In that case, I’d encourage you to check out some of my older blog posts that included a script framework that allowed field-by-field validation without the 9.1 enhancements.  The most recent version of that framework was included in this blog post.

5 Responses to A better validation pattern for 9.1 forms

  1. scott says:

    Hi John,

    Is there any plans for the ‘next’ version of Livecycle Designer? I hope so since I really like using it.

    • Scott:
      Well, I’m under strict orders not to divulge product futures. But I don’t think it’s much of a secret that there will be an updated Designer in the next version of the LiveCycle server product. I can’t give you dates and specifics about that product release. But I can say that I’m looking forward to it :-)

      John

  2. scott says:

    Fair enough. I mainly was worried that maybe livecycle updates were slowing down since I haven’t read about any wish lists, or hints of a new version. I think it’s the best form creation software and hope adobe continues to improve upon it.

    I would really like to convince the large company I do contract work for to do their data collection using PDF forms, but there are some improvements that would make such a thing much easier. Many of the improvements I’m looking for are things done in the SmartForm Composer software by Avoka.

    When we collect data in our forms, we need to validate as much of the data as we can before it is submitted. But rather than hardcode any validation rules in the PDF, it would be nice if there was a nice way for the PDF to be able to reference our validation rules that reside outside of the PDF, so that these rules are easy to change without touching the PDF and can also be applied to multiple PDFs with a single rule. Using web services could possibly be used, except that a warning message appears.

  3. Scott:
    I think you’ll enjoy the enhancements in the next version of Designer.

    The topic of importing external business rules is interesting to me. Most of all, I’d like to know what format you’d like the rules to be defined in?
    If you have rules that can be executed by JavaScript, it should be possible to import them and wire them up to field validations. i.e. It should be possible for field validation scripts to look up validation logic from a central rules engine implemented in a script object.
    But back to the main question — what’s your preferred format for expressing business rules?
    John

  4. scott says:

    I’m excited to hear that there will be another version of Designer and will be looking forward to it as always.

    As for the data collection, we currently send out surveys to hundreds of companies to fill in their monthly and/or annual data. A web page to perform this works well since we could easily update the survey without having to resend out the survey to each company. and also the web page could read it’s validations from a central database, rather than be hardcoded in each web page.

    The advantage of a PDF is that one can enter their data completely without a constant internet connection, and also the user can print the entire survey form nicely on a 8 1/2×11 paper with and without the data. And also, PDF survey forms could be created by non-programmers.

    However, once you begin to add validation, it starts to require code (possibly by a programmer), and also begins to embed (hide) business rules within a PDF. So ideally, it would be nice if there was a way that a non-programmer could easily add different validation checks to the PDF.

    Maybe the simplest solution is to simply add a standard library of javascript functions to all PDFs, and then the non-programmer could simply be required to only use those functions to perform any validation checks. Then this will make it easy for the programmers to adjust the standard library of validation functions.

    But some validation checks might require comparing data against data they entered in the previous month. In this case, one of the standard functions could use a web service to retrieve that value. but then that starts to require an internet connection. So i’m not quite sure of the best solution. But one thing I’ve noticed is that any call to any external source will notify the user (because of security issues i guess), that it’s doing so, and it would be nice to be able to turn that off.

    I may have to think about this some more