Document Your Form Template

Many of us are creating forms with lots of script and complex logic.  The good side of this is that we are able to generate some pretty cool form fill experiences.  But how maintainable are the forms we create?  If another form developer inherited my form and was asked to make a few changes, would they be able to?  Or would they end up staring at a mass of objects and scripts in Designer and give up?  Unless your objective is to create built-in job security it would seem like a good idea to make your forms as maintainable as possible.  Toward this end, I have two suggestions: a) build good frameworks and b) (the topic of this post) provide great documentation.

Create Frameworks

If you are developing a series of forms and have logic that is re-usable, encapsulate that code in script objects.  Turn these script objects into fragments and reference them from your forms.  There are hopefully two outcomes from this exercise:

  • The framework itself can be heavily documented to facilitate easy usage and also proper maintenance
  • The amount of script logic that lives outside the framework will be minimized

If these are true, then editing forms becomes reasonable because the average form author does not need to know the internals of the framework — they just need to know how to use the framework.  They can modify forms with confidence because there isn’t much script and the script is easy to understand.

Document your Script

This area is harder.  The problem with documenting script is that it is fragmented throughout your form.  An individual script may be well documented, but where does it fit in the overall context?  When you open an unfamiliar form, there’s bound to be lots of routine, innocuous script, but then there are likely a small number of scripts that are key to how the form operates.  There is no easy way to get the big picture of how logic flows in your form.

My project for the last few days has been trying to figure out how we could make use of JavaDoc comments to build a documentation map for a form.   There are two sides to this problem. One is figuring out conventions for adding the comments.  The other aspect is figuring out how to harvest them and generate documentation. 

Not surprisingly, my first crack at a harvesting tool is… a form.  This sample form will load an XFA/PDF and generate a report from the script it finds inside (Be patient — loading a large form takes a long time).  Here is a sample report generated from the survey form I created for a previous blog entry.  (and here is the survey form with updated/improved internal documentation).  Going through the exercise of documenting a form, harvesting the documentation and generating a report forced me to deal with some issues that are unique to this environment.

Commenting on scripts vs. commenting on objects

Normally JavaDoc comments are used to describe classes, interfaces, functions and variables.  This makes sense for our script objects.  e.g. this  script fragment should work nicely with a harvesting tool:

/**
* function handleError(err) — return an error message and if
* in Acrobat, raise the console window with the error
* @param err – the error object thrown by the script engine
* @return – a human readable message extracted from the error object
* @author John Brinkman
http://blogs.adobe.com/formfeed/
*/

function handleError(err)
{

}

For this case I was able to fairly easily extract the comment and the function definition.  Just scan past the end of the comment up to the first "{" or ";" characters. (now you understand my fascination with complex regular expressions).  A good harvester tool could extract the function declaration even without the structured comment — just locate the function(){} syntax.

But how do we document a calculation? or a click event?  There’s no function/object that is the target for the documentation fragment.  There are also no parameters or return values to describe.  In this case, I chose to support a single JavaDoc comment for the script, and for the syntax portion emit the first 5 lines of script that follow the comment.  Instead of supporting @param, I added a custom tag called @reference where the script author can describe dependencies for a particular script. e.g.

Survey.DefineSurvey.Sections::initialize – (JavaScript, client)
/**
* Sections is the container subform that holds a series of survey
* section definitions. The initialization script makes this subform
* initially hidden.  It will be made visible as the user reaches
* this stage of survey definition.
* @reference _Section.count — If there are already section
* definitions, make this subform visible.
*/
this.presence = _Section.count == 0 ? "hidden" : "visible";

Harvesting Information outside the script

In the case of documenting forms, there is lots of information outside the actual JavaDoc that is relevant to the report. In our case, information about the context of the script is very important.   What form object is hosting the script? What event? Is it FormCalc?  All these pieces and more need to be pulled into the report.

Order of Report

When generating the report, I had to choose between two ways to order the report:

  1. Order the report by object (in document order).  E.g. list all the scripts for the first object encountered and then search for the next object with script.
  2. Order the report according to the (approximate) order in which script will execute.  Then a field’s initialize event will appear early in the report and its layout:ready event will appear much later in the report.

I chose to go with option 2.  My guess is that this order will be best for trying to decipher form logic.

Forms with no structured comments

You’re not likely to uncover many forms that have structured comments in them.  Yet we still ought to be able to generate a decent report.  We  harvest all the script context information and the report will contain the first 5 lines of each script.  For each script summary you can click on the "+" button to see the entire script.

Noise

There are many scripts that you do not want included in your report.  e.g. if your form has enter/exit scripts on every field, and the scripts are the same each time, we do not need to report on each and every script.  It just clutters the report.  I added an @ignore directive that allows the form author to exclude these scripts.

FormCalc

Unfortunately, structured comments are not legal syntax in FormCalc. For FC, the harvester looks for blocks of 2 or more lines that start with "///".  E.g.

Survey.DefineSurvey.Sections.Section.Questions.Question.QuestionNumber::calculate – (FormCalc, client)

///
/// Assign Question number based on subform index
///
Question.index+1

JavaDoc Completeness

The harvester supports only a fraction of the JavaDoc directives: @param, @return, @reference, @ignore, @author.  In the descriptive text you can use <br> and <p> elements to force line/paragraph breaks.

Resources

If you are new to the idea of JavaDocs, check out the JavaDoc tool home page.  I noticed that there is also a Google project to support JavaDocs for JavaScript here.

Futures

Unfortunately, documenting script is not really enough to make complete sense of the way a form works.  There are many other aspects that you might want to describe.  Maybe there is a clever data binding strategy.  Maybe you’d want to describe various inputs — the use of certain datasets.   Maybe there is complex binding that modifies form behaviour.  Maybe the form makes use of WSDL definitions.  To begin to describe all these things we need to be able to place comments in more places in the template.  One obvious place would be under the <desc> element of both <field> and <subform>.  But then we need a way in Designer for adding those comments.

Feedback

I’d be interested in hearing from people whether template documentation is a problem that interests them.  Is there more you’d like to do?  Ideas to build on what I’ve described here?  Let me know please.