Stefan Cameron on Forms
Building intelligent forms using Adobe LiveCycle Designer

Call Script Object Functions Later

I hope you all had a great holiday! There’s suddenly lots of activity on my blog today so I assume most of you are back at it too.

To kick things off in 2009, I thought I would start with a short but significant post on calling script object functions at a later time using Acrobat’s app.setTimeOut JavaScript API. (app.setInterval is similar but requires a little more handling, to ensure you don’t leave the timer running when the form is closed, so I won’t cover that here. Check-out this sample if you’re curious.)

I had long thought this wasn’t possible but recently discovered that it was, while helping-out one of my readers, in Acrobat/Reader 9.

Theory

The app.setTimeOut API requires that the first parameter be a string which is the script to be evaluated and executed when the timer expires. The second parameter is the number of milliseconds the host application (Acrobat) should wait before interpreting the script in the context of the document which set the timer. This means that the “this” object is an AcroForm Doc object.

Given that an AcroForm Doc object has an xfa property (“defined only if the document is an XML form, that is, if the document was created in LiveCycle Designer“) which is “the root node of the underlying XFA model,” it follows that you can access properties of the XFA form contained within the PDF document from the AcroForm API. After all, that’s how I managed to get invalid fields to flash red in a previous sample.

By the way, if you’re writing AcroForm scripts and you want to verify whether the current document is an XFA-PDF (a PDF that contains an XFA form) or just a straight PDF document, you can simply test for (typeof pdfDoc.xfa == “undefined”). If it’s true, it means you just have a plain PDF.

When you put all of this together, it follows that you can effectively execute a script object function “later” as long as you address it properly using normal SOM expression rules. Since script objects are loaded into the Form DOM at runtime, you can access them via the xfa.form property. Once you’ve accessed the Form DOM, the first object you’ll need to reference is your root subform (the object at the very top of the tree, usually named “form1”, in Designer’s Hierarchy palette) and from there, your script object.

Note that the AcroForm app object is only available when the host application running the PDF is Acrobat/Reader so this won’t work if you render your form as HTML using LiveCycle Forms ES, for example.

Sample

If you had a function foo() in a script object “MyScripts” defined on the root subform “form1”, you would access it like this:

xfa.form.form1.MyScripts.foo();

If you didn’t know (or didn’t want to know) the name of the root subform ahead of time (say this function is accessed from a fragment which is used in many different forms), you could refer to it like this:

xfa.form.resolveNode("#subform[0]").MyScripts.foo();

Finally, to call it 1 second later, you would simply do this:

app.setTimeOut('xfa.form.resolveNode("#subform[0]").MyScripts.foo();', 1000);

Minimum Requirements: I’ve only tried this with Acrobat/Reader 9 however the JavaScript for Acrobat 9 Reference claims that the xfa property is available since Acrobat/Reader 6.0.2. I’ll leave it up to you to try it out in previous versions. Please report back if you find that it works prior to Acrobat/Reader 9.

Updated: January 5, 2009


Posted by Stefan Cameron on January 5th, 2009
Filed under AcroForm Objects,Scripting
Both comments and pings are currently closed.

Comments are closed.