The Scripting Object Model (SOM) is one of the backbones of the XFA Specification. The SOM provides a structure for referencing objects and properties in our forms.
A SOM expression is simply the reference in a script to another object. If the objects are in the same container, then the SOM expression can be as simple as the object’s name. If however, the objects are in different subforms or pages, then a fuller SOM expression will be needed.
The Scripting Object Model Expression Specification states:
XFA-Scripting Object Model (XFA-SOM) is a model for referencing values, properties and methods within a particular Document Object Model (DOM). A DOM structures all objects and properties in memory as a tree hierarchy. XFA-SOM expressions provide easy access to these objects and properties through a straightforward object reference syntax.
There are two basic types of SOM expression:
- Relative SOM expression, which references an object relative to the object containing the script.
For example “TextField1“.
- Absolute SOM expression, which references an object from the root node (xfa).
For example “xfa.form.form1.page2.Subform1.TextField1“.
In most circumstances a relative SOM expression is perfectly adequate and would be the normal approach when referencing objects.
We have an example form that demonstrates the various approaches to SOM expressions.
When you open the form in Acrobat or Reader, you can hover over the SOM expressions in the script and the corresponding objects will be highlighted. This will help you to understand the SOM expressions.
[UPDATE] Jono Moore spotted an error in the script in the button on page 4. It was a debugging line that was not deleted. The form has been updated. Thanks Jono!
[UPDATE] John Brinkman has provided very valuable assistance in improving the performance by using xfa.resolveNodes(). Thanks John!
Because the SOM expression uses an object’s name, it stands to reason that the SOM expressions will be heavily influenced by how you name your objects in your forms. It is important to establish a naming convention that suits your requirements and then apply this consistently in your forms.
xfa.resolveNode is a search. For example, xfa.resolveNode(“TextField1″); will search for TextField1 object. The search will start in the current container and work its way up the hierarchy tree. The first occurrence of TextField1 that is found will be used. This is not an efficient way to script and there will be a performance hit. In addition it may not return the instance of TextField1 that you are expecting.
xfa.resolveNode is also used when you are referencing an object that has the same name as other objects in the same container, for example TextField1. In the hierarchy you would see TextField1, TextField1, TextField1, etc. The number in square brackets shows the instance number of each object. When using FormCalc you can just use TextField1 directly in the SOM expression.
This is a another good reason to name objects uniquely, as you drag them onto the form. This can eliminate the need to resolve the node.
However there are other situations when you will need to resolve nodes, for example, if you are referencing an object that is in an unnamed container/page/subform. The script needs to resolve the unnamed container in order to access the object inside. This would also apply if there are several containers with the same name. Again, another good reason to name containers as you go.
Also if you are trying to reference a particular instance in a repeating object, then you would need to resolve that particular instance.
John Brinkman’s blog clearly explains the benefits in using xfa.resolveNodes() to return a list of multiple nodes. We have extended the sample form to highlight this method.
We would strongly recommend that you read this post in particular.
Getting the SOM Expression Right!
LiveCycle Designer ES2 has a great feature, which makes it very easy to automatically insert the correct SOM expression for an object.
When the Script Editor is active, if you press and hold the Control key, you will notice that the mouse changes to a ‘V’ when it hovers over an object.
- Step 1: Select the object that you want to have script in one of its events.
- Step 2: Click into the Script Editor to make it active. Select the event that you want to script.
- Step 3: Next you hover over the mouse over the event that you want to reference in your script.
- Step 4: Press and hold the Control key. When the mouse changes to a ‘V’, you can click the object.
- Step 5: LiveCycle Designer will insert a relative SOM expression for that object. The relative reference will be as qualified as is necessary, depending on the structure of your form.
The Control and Click covers most situations. If you want an absolute reference, then you would hold Control+Shift and Click.
If LiveCycle determines that the object cannot be uniquely referenced, it will automatically use xfa.resolveNode() to resolve the node. It is worth spending a little time to correct the issue and then reinsert a relative reference without the xfa.resolveNode().
Here is a quick example of creating relative references in LiveCycle Designer:
Adobe has a number of technical reference documents that will be of help to you.
You can access the XFA Specifications here.
In order to get a fuller understanding of SOM expressions, you should read the Scripting Object Model Expression Specification.
You should also download the LiveCycle Designer ES2 Scripting Reference.
Be sure to check out the dynamic demonstration of SOM expressions. It contains more information on SOM expressions and how to use them correctly. We would welcome feedback and suggestions. Where we get requests, we will extend the form with additional examples.