Accessing Objects with Periods in their Names

Did you know that periods (.) are valid characters in XFA object names? On the surface, this may seem innocent but it’s really kind of strange when you think about it — especially when it comes to writing scripts: How would you access the properties or methods of an object if had a period in its name?

Consider a simple form with a button and a text field which is named "TheText.Field". Notice the period in the text field’s name. If you wanted to write a little line of script in the button’s Click event which set the text field’s value to some arbitrary text, you would not be able to write the following:

TheText.Field = "text" // FormCalc

It would produce an error because the script engine would think that you’re referencing an object named "Field" which is a child of a parent object named "TheText" when you’re actually trying to reference the "TheText.Field" object.

If XFA allows for periods in object names, there must be a way to access them correctly. To find the answer, one of the things you can do is a little test which exposes the text field’s SOM expression (say, in the text field’s Enter event):

xfa.host.messageBox($.somExpression) // FormCalc

Doing this for the text field would give the following result:

xfa[0].form[0].form1[0].#subform[0].TheText\.Field[0]

Notice the backslash which precedes the period in the "TheText.Field" name: Backslashes are used to escape period characters in XFA names in SOM expressions.

Knowing this important detail, you could change the earlier script to the following:

$.parent.resolveNode("TheText\.Field") = "text" // FormCalc

and everything would work just fine. The resolveNode method is necessary in this case since the script engine doesn’t support backslashes in statements in FormCalc (and neither in JavaScript for that matter).

Finally, don’t forget that backslashes in strings in JavaScript are used to escape other characters such as "\n" for a new line character. This means that when you write the object’s name in the resolveNode method call, be sure to escape the backslash itself in order to give the correct expression to the resolveNode method:

this.parent.resolveNode("TheText\\.Field").rawValue = "text"; // JavaScript