AcroForm Field Name Generator

So you’ve read my previous post about “AcroForm Objects”:http://blogs.adobe.com/formbuilder/2006/06/acroform_objects.html and now you’re wondering what you do with that stuff. Those more adventurous might even have tried to use the _event.target.getField_ method to do something cool.

If you’re going to do things on the application or the document without attempting to affect a specific field, it’s pretty straight-forward: You just call methods on the _app_ (Acrobat Application) or _event.target_ (Acrobat Document) objects. Getting an AcroForm Field object, however, isn’t as simple as you may think because of the naming conventions used when the Acrobat Form objects are created, based on the XFA Form objects.

Let’s say you have a field, named “MyField”, parented to the second page, named “Page2″, of your form, named “form1″. For some reason, you need to access that field’s pertaining AcroForm Field object. If you tried

bc. event.target.getField(“MyField”)

you wouldn’t get very far because the actual name of the field is:

bc. form1[0].Page2[0].MyField[0]

Basically, each AcroForm Field object is named with a _verbose_ form of the “XFA SOM Expression”:http://blogs.adobe.com/formbuilder/2006/06/som_expression_generator.html of its pertaining XFA Form object (also known as a *Fully-Qualified SOM Expression*).


To help with generating the correct AcroForm Field name for a given XFA Form object, I thought I would write a little bit of script which outputs the Fully-Qualified SOM Expression (which is the AcroForm Field name) for a given XFA Form object:bc.. // Returns the fully-qualified name for the specified object.// This means the name always specifies the index.// Therefore, if the name is specified, it’s “name[index]”.// If the name isn’t specified, it’s “#className[index]”.function GetVerboseFieldName(oNode){// Unnamed nodes have default names which their class name// (“subform”, “field”, etc.) with a “#” prefix.// Unfortunately, oNode.name won’t return this if the node// doesn’t have a specific name. It’ll just return an empty// string. Also, oNode.index will be undefined. If it weren’t// for oNode.index being undefined in this case, we could’ve// done something like// SOM = “#” + oNode.className + “[” + oNode.index + “]”// but we’ll have to use the somExpression property instead// and extract the name out of it because this will return// the “#” name with the correct index.// Since somExpression returns the name and index for the// object in all cases (whether the name is specified or// not), we can use the following syntax in all cases:var nPos = oNode.somExpression.lastIndexOf(“.”);// If the field has a name, check to see if it has any periods in its name.// If that’s the case, they’ll be escaped with backslashes and we need to// look for another period.if (oNode.name != null && oNode.name.length > 0){while (nPos > 0){if (oNode.somExpression.charAt(nPos – 1) == “\\”){// we found an escaped period, keep lookingnPos = oNode.somExpression.lastIndexOf(“.”, nPos – 1);}else{// stop looking since we have an unescaped periodbreak;}}}if (nPos >= 0){// get everything after the last “.” to the endreturn oNode.somExpression.substr(nPos + 1);}else{// in this case, the SOM expression is a single name (unlikely// but theoretically possible)return oNode.somExpression;}}// Returns the Fully-Qualified SOM Expression for the specified field.function GetFQSOMExp(oField){var sFQFieldName = GetVerboseFieldName(oField);var oParentNode = oField.parent;// The absolute root of the XFA Object Model is the xfa object// which contains a single form object, which then contains// what the Hierarchy palette shows as being the “root// subform” (“form1″ by default). So we stop when we reach// xfa.form.while (oParentNode != xfa.form){sFQFieldName = GetVerboseFieldName(oParentNode) +”.” + sFQFieldName;oParentNode = oParentNode.parent;}return sFQFieldName;}p. You can now take this code and either place it directly inside the event in which you need an XFA Form object’s pertaining AcroForm Field name and call it directly or you can place it in a form-wide Script Object where you can access the code from anywhere.With this code, changing an XFA Button object’s _highlight_ property such that it gets an outline rectangle when clicked (as opposed to the default which is an inverted fill color) is as easy as this (in JavaScript in the button’s Enter event, assuming you’ve placed the above code directly inside the Enter event):bc. event.target.getField(GetFQSOMExp(this)).highlight =highlight.o;Beautiful? I think so. Get the “Acrobat JavaScript Scripting Reference”:http://partners.adobe.com/public/developer/acrobat/sdk/index_doc.html#js and go crazy! Just remember: This functionality is *only available when your form is loaded in Acrobat*.====*Updated:* February 14, 2007 — Added support for “objects with periods in their names”:http://blogs.adobe.com/formbuilder/2007/02/access_obj_period_in_name.html.