Stefan Cameron on Forms
Building intelligent forms using Adobe LiveCycle Designer

Home

Adobe Developer Week

I just got word of this free online event this week at Adobe.

Here’s the blurb:

Join us to learn about the Adobe engagement platform, including Flex, and other Adobe technologies by attending Adobe Developer Week. This free, week-long event features live, online sessions presented by Adobe technology experts. See live demos and get your questions answered by the experts during interactive Q & A sessions. Register online at the Adobe website.

While there are lots of very interesting sessions, these are the ones I found, after a quick search, which are related to LiveCycle:

Don’t wait to sign-up for sessions — spots are limited and they’re going fast!


Posted by Stefan Cameron on June 13th, 2006
Filed under Conferences,General

AcroForm Objects

Today I thought I would tackle the subject of AcroForm Objects — objects available via scripting in the Acrobat Form Object Model — because they offer unique possibilities for your forms when they’re running in Acrobat in the PDF format.

Just to be clear, AcroForms are specific to Acrobat and therefore this functionality doesn’t apply when rendering your forms to a target other than PDF (e.g. when using LiveCycle Forms to render your XFA Forms as HTML).

First, let’s explain what XFA (XML Forms Architecture — a W3C Submission) does: It lets you describe a form, using a defined set of rules that govern an XML structure, which can target many different clients (e.g. PDF, HTML, etc.) — as long these clients support the XFA format. Today, the Adobe LiveCycle Designer targets PDF out-of-the-box and, along with LiveCycle Forms, targets HTML.

The fact that XFA is always translated into a format which can be understood by a client with which a user interacts in order to fill a form and possibly submit its data to a receiver means that the scripts you write in your XFA forms get executed in the target client application (such as Acrobat or a web browser). If the target client also contains a Scripting Object Model — like Acrobat does — there may be ways that you can take advantage of specific functionality exposed by the client which is hosting your XFA forms.

This brings us to the topic at hand: Acrobat’s Form (AcroForm) Object Scripting Model. If you’re designing your form only to target PDF (or you add code to your form to detect when your form is being hosted by Acrobat using xfa.host.name, for example), you can get access to the Acrobat app, Document and Field objects, amongst others, and do some really cool things like have a field with invalid data start flashing red when the user attempts to submit the form’s data.

xfa.host

When writing scripts in an XFA form, you have access to the special xfa.host object. This object gives you access to methods which are specific to the application hosting your form (such as Acrobat, a form server or a web browser). For example, the

xfa.host.name

property tells you the name of the application hosting your form at the time the script is interpreted. If your form is being viewed/hosted in Acrobat, this property will return “Acrobat” while it’ll return the name of the browser if it has been served to a web browser. Furthermore, it’ll return “Presentation Agent” if the script was flagged to run on the server and the server application serving the form to PDF or HTML is Adobe’s LiveCycle Forms product.

xfa.host also gives you access to other properties and functions such as

xfa.host.messageBox // displays a dialog box on the screen
xfa.host.validationsEnabled // turns the form's validations on/off with a single call

but take note that not all functions and properties are available on all hosts (e.g. since a server host can’t display a dialog which requires user input, the xfa.host.messageBox function is only supported on client hosts like Acrobat and web browsers).

You can obtain more information on xfa.host on page 185 of the Adobe XML Form Object Model Reference.

Acrobat app Object

Since the scripts you write in functions and events within an XFA form are interpreted by and executed within the context of Acrobat’s Scripting Engine, you have access to a special object called app. This object gives you access to the collection of active documents and plugins, amongst other things, and lets you display alert messages

app.alert("Hello world!");

and even set Acrobat into full screen mode with a red background!

app.fs.backgroundColor = color.red;
app.fs.isFullScreen = true;

Note that while color.red isn’t an object provided by the XFA Scripting Object Model, it still exists within the context of your scripts because the scripts are ultimately interpreted and executed within Acrobat. You can get more information on the app object in the Acrobat JavaScript Scripting Reference.

xfa.event

This is a special object which exists only via the XFA Plugin which executes XFA scripts on XFA object events inside Acrobat. Whenever an event occurs (such as the click of a button or a field gaining input focus), your script has access to the xfa.event object which gives lots of important information about the event.

For example, if you want to know the value that was selected in a list box or a drop down list in order to change the state of another object on your form, you would script against the list box’s or drop down list’s Change event. If you used the following code to get the value of the item that the user selected:

this.rawValue

you would get the previously-selected value because the object’s rawValue property isn’t updated until after the Change event has occurred. In order to get the information you need, you must use the following code:

xfa.event.newText

which will give you the value of the item the user just selected.

xfa.event also gives you access to a very useful property called target: In Acrobat, this property specifies the Acrobat Document object (which contains the Acrobat Field object which wraps the XFA object whose event is being scripted). This means that you can get at the Acrobat Document object for the “active document” just by using:

event.target

(Note that you don’t need — and shouldn’t use — the “xfa” prefix when accessing the “event.target” property — I don’t know why yet but you’ll have trouble using it if you use the “xfa.event.target” syntax.)

Using this information, you can:

event.target.zoom *= 2; // increase the zoom level two-fold
event.target.zoomType = zoomtype.fitW; // zoom to page-width level
event.target.zoomType = zoomtype.fitH; // zoom to page-height level

or you can use the getField method to get an Acrobat Field object and do some more interesting things.

You can get more information on the Document and Field objects in the Acrobat JavaScript Scripting Reference.

Putting it all Into Perspective

To tie this all together, I’ve drawn-up a simplified version of the Scripting Object Model the way I picture it in my head:

Scripting Object Model (simplified)

This image illustrates how things work from the perspective of a script running within an XFA Event or an XFA Script Object Function (note that you don’t have access to the xfa.event object there unless you pass it into the function by calling it from an XFA Event). You can see how, from the XFA object, you can get to the:

  • Acrobat app object (directly);
  • Acrobat Document object (via event.target or the app object);
  • Acrobat Field object (via the Document object);
  • xfa.host object (directly).

Hopefully this post will have given you a general idea of the Acrobat-specific tools at your disposal when you’re writing XFA scripts using the JavaScript language. Please note, however, that changes may occur to the way XFA Form Objects are hosted within Acrobat in future releases and therefore using the AcroForm Object Model should be a last resort if an XFA equivalent simply isn’t available.

Updated: August 30, 2006


Posted by Stefan Cameron on June 10th, 2006
Filed under AcroForm Objects,Scripting

XFA SOM Expression Generator

Have you ever had trouble figuring-out what the SOM expression is for a particular object which you’re trying to address within your script?

If so, here’s a tip that might come in handy the next time you’re stumped:

With the input focus (the “I” beam) set within the event you’re scripting on the Script Editor palette in Designer, hold-down the Control key and move your mouse over the canvas. Notice that as you hover over objects, the mouse pointer switches to a “V” cursor. If you click, the full SOM expression for the object you clicked will be automatically inserted into your script. But that’s not all! The generated SOM expression will be automatically formatted to work with your script’s language settings:

If you haven’t named the “page 1” subform and you pick an object on it, you’ll get the following code if your script’s language is FormCalc:

form1.#subform[0].myField

If your script’s language is JavaScript, you’ll get the following code (for the same object):

xfa.resolveNode("form1.#subform[0].myField")

Note that if you click on the object on which you’re scripting the event, “$” will be inserted for a FormCalc script and “this” will be inserted for a JavaScript script.


Posted by Stefan Cameron on June 5th, 2006
Filed under Script Editor,Scripting

Phoenix Was Awesome!

Well, the 37th BFMA Symposium is already over and it seems like it went by way too fast!

I just wanted to thank all the members that came to see us at our Vendor Suite and pulled us asside in the halls to ask questions and give us feedback. Although the sessions I attended were all very interesting and beneficial, the best part was getting to meet you in person and talking about your issues and being challenged to find solutions to your problems (especially with Designer).

Here are some of my memories of Phoenix:

BFMAPhoenixMay2006_1.JPG

Scottsdale was a really nice place to shop!

BFMAPhoenixMay2006_2.JPG

A cactus almost as tall as a palm tree! Back home, a cactus is considered a bonsai since they don’t grow to be more than 2 inches tall.

BFMAPhoenixMay2006_3.JPG

This flower seems to be everywhere on the side of the roads in Phoenix — beats the dead brown bushes and ashphalt we have on ours…

BFMAPhoenixMay2006_4.JPG

The entrance to the Adobe Vendor Suite at the symposium hotel.

BFMAPhoenixMay2006_5.JPG

This was where the symposium took place — a really nice resort with lots of family-oriented activities.

BFMAPhoenixMay2006_6.JPG

Cameron, AZ. Who knew there was a town named after me? 😉

BFMAPhoenixMay2006_7.JPG

The Grand Canyon — pictures don’t do it justice! Absolutely spectacular!

BFMAPhoenixMay2006_8.JPG

Another view of the Grand Canyon.


Posted by Stefan Cameron on May 30th, 2006
Filed under BFMA Symposium,Conferences

Remove, Remerge

There’s a bug currently logged against Acrobat 7.x where removing an instance of a dynamic subform, using the Instance Manager (IM)’s removeInstance(int) method, doesn’t cause an update to the IM’s count of currently instantiated subforms.

OK, so maybe that was a little too technical so I’ll try to simplify: In Acrobat 7.x, when you remove an instance of a dynamic subform using the IM’s removeInstance(int) method and then check the number of remaining instances using the count property, the number you’ll get won’t reflect the number that remains.

Adobe is aware of this bug and will hopefully be providing a fix for it in an up-coming release.

Fortunately, there’s a simple work-around (and even if the bug gets fixed in a future release, you should probably be checking the version of Acrobat that’s running your form to determine whether you need to be using the work-around or not):

_DynamicSubformInstanceManager.removeInstance(3);

// Force a remerge of the form's current data set with its template
//  to cause an update to the "count" property of all IMs
xfa.form.remerge();

Calling the Form object’s remerge() method will “force the remerging of the data model and template model to re-create the form model”, as explained in the Adobe XML Form Object Model Reference. This means that the form’s current data set will be remerged with the template (the form objects like dynamic subforms, fields, etc.). The result will be a form that looks exactly the same as it did in its state just prior to calling xfa.form.remerge() but with all IMs properly updated to the current number of dynamic subforms which they’re managing, thus correctly updating each IM’s count property.

Even if this problem is addressed in a future release, you’ll want to check the version of Acrobat that’s running your form in order to know whether it has the fix or not (in JavaScript as follows):

// get the host's version as a string and split it into an array
var oVerArray = xfa.host.version.split(".");

if (oVerArray[0] == "7")
  xfa.form.remerge();

Or more simply:

if (xfa.host.version.split(".")[0] == "7")
  xfa.form.remerge();

Posted by Stefan Cameron on May 25th, 2006
Filed under Instance Manager,Scripting