Back to another of the 9.1 enhancements intended to help you write less code: propagating events. See here for an overview. Again, now that we have a Design tool capable of authoring these and now that the 9.1 Reader is more common, we should have a closer look.
For starters, here is the sample form I’ll be referencing. As you try the form you will notice a couple of behaviors:
- as you move your mouse over fields, they are highlighted
- invalid fields get a thick red border
The punchline here is that there are 14 text fields on the form, but only one each of a mouseEnter, mouseExit and validationState event scripts. These events are defined on the root subform and apply to all descendent objects. This is a great technique for minimizing code in your form. A highly recommended form design technique.
But now the bad news… So far, this functionality has not been easy to get at through Designer. In the ES2 designer there was a check box to make an event propagate. But the script dialog didn’t allow field events to be defined in the context of a subform. Then because of the confusion this functionality caused, the checkbox was removed from the Desginer that shipped with Acrobat 10. This functionality should re-emerge in a future version of Designer.
In order to make it easier to get at this functionality, I have written a macro that will add propagating events to subforms. The UI appears like this:
After you run the macro, the event and script will be added to your subform. Now, the tricky part — to edit the script you need to do two things: 1) close/re-open the form. Yeah, macros are still beta, and Designer doesn’t pick up on the changes made by the macro. 2) on the script dialog for the subform, choose to show: "events with scripts".
One interesting thing to note is that it is valid to have two or more of the same event defined on a subform. e.g. you could have both a propagating enter event as well as a non-propagating enter event.
The Deep End
When changing the display of an object to show an error state, it’s a bit of a challenge to revert the object back to its original state. e.g. If you change the border color or border thickness you need to know the original color and thickness in order to restore the original state of the field.
Well, not really. You’ll see the validationState script in the sample uses a different technique to restore the original display. The script removes the border and assist elements from the field. To understand why this works you need to understand the relationship between the form and the template. The template is the definition of a form you see in Designer. At runtime, we merge the template objects with data and create form objects. A form field is then a sparsely defined object that has a pointer back to a template field.
When we execute script that changes the color of a border, we modify the form definition of the border and override the default border properties found in the template. Removing the border from the form field means that we have removed the override and the field then reverts to the definition found in the template.