Stefan Cameron on Forms
Building intelligent forms using Adobe LiveCycle Designer

MAX 2008 Tutorial – Part 2 – Flex Code

Welcome to the second in a three-part post series on importing data into a form guide (and, by extension, a PDF form). In the first part, we designed the XFA form that will provide us with the print/archive view of the movies retrieved from the Movie Service. The second part will focus on the special Flex code we will need to include in the form which will ultimately be executed by Flash when it runs in the form guide which we’ll design in part 3.

Flex Code in XFA Forms

The key to today’s tutorial is understanding when and where the script you write in an XFA form (JavaScript or FormCalc) is compiled or interpreted.

For starters, form guides don’t support the FormCalc language so that just isn’t an option.

JavaScript, on the other hand, has the nice property of looking a lot like ActionScript. In fact, the two languages have enough similarities that with very little modification, any JavaScript you write in an XFA form can be converted into ActionScript which runs in a Flex form guide (in the Flash Player).

Normally, when you write JavaScript code in your forms and you run the form in Acrobat, the script isn’t compiled when the XFA form is converted into the PDF file format and it’s only interpreted when the interpreter attempts to execute it (i.e. if there’s a syntax error somewhere in your script and you never run that code, you’ll never know about the error). When you generate a form guide based on your form, however, your JavaScript is actually compiled by the Flex compiler that generates the SWC (Flash Library) which defines your form guide.

Warning: Script object code seems to be loaded and interpreted by Acrobat in one shot, instead of on a per-access basis as in form object event scripts, and any syntax errors anywhere in the script object will cause all of the script in the script object to basically be ignored. If you have functions defined in a script object and you know you’re calling a function properly but you keep getting a “function is not defined” error, use the Script Editor’s Syntax Checker tool — you’ll probably find a syntax error somewhere. After you fix it, you should be able to access your script object functions.

It also appears that Acrobat/Reader 9.0 may now be attempting to parse (but not execute) all scripts on form load which may produce syntax errors in the JavaScript Console due to the differences between JavaScript and ActionScript syntax however in my experience so far, I haven’t hit a situation where my JavaScript stops executing because of this. Nonetheless, if you’re seeing strange behaviour, it might be a good idea to check the console to make sure things are running smoothly.

What you might not have realized is that if you know that a particular portion of script will only be executed within the context of a form guide, you can actually write Flex code in your XFA form! When you generate the form guide (either by previewing using GuideBuilder or by rendering the form as a form guide via LiveCycle Forms), your Flex code will be compiled as any other Flex code would be and it’ll be executed in the same way.

That opens-up a world of possibilities and the one we’re going to explore in this tutorial is the use of the mx.rpc.http.HTTPService class to fetch data from the Movie Service and insert the results into the Listing table within the form guide, thereby causing the data to be inserted into the Listing table within the PDF form when the user switches from the form guide to the PDF.

XFA Host Name = Flash

You might recall, in yesterday’s tutorial, that I talked about the xfa.host.name property returning “Flash” when your XFA code is executing within the context of a form guide (it returns “Acrobat” when its executed within the PDF because the form’s “host” is “Acrobat”).

This is the indicator we’ll use to “protect” the Flex code we’re going to write to make sure that it’s not executed within the PDF:

if (xfa.host.name == "Flash")
{
    // do some cool stuff in Flex/ActionScript
}

Note that the XFA model in a form guide works just the same as it does within the PDF with the exception that the form guide environment only supports a subset of XFA functionality (less than in the PDF but more than in HTML).

Our Own HTTPService

Since there will 3 requests made to the Movie Service, one for the actor list, one for the category list and another for the movie listings resulting from the chosen actor and/or category (if any), the first step to take is to create some reusable code within our form that makes use of the HTTPService object.

Open the form you designed yesterday and add a new script object by right-clicking on the root subform (“movieList”) and choosing the “Insert Script Object” command.

Name your script object “FlexHttpService” and paste the code from this text file into the script object.

You’ll notice that there are some statements in this script that aren’t regular JavaScript (namely the “import” statements to get access to the HTTPService and its result and fault event classes as well as the typing of variables like “service:HTTPService”). That’s because it’s ActionScript!

I’m assuming you know enough about Flex to be able to understand what’s going on but the gist of it is that the script object’s send() function takes a URL (to the Movie Service) and two functions, the first called when the request is successful and the second called if the request fails. If the request is successful, the result handler function is called with an XML variable as its parameter. This XML variable contains the movie listing we want to insert into the Listing table.

The FlexHttpService.send() function will be the reusable piece of code that we’ll use in the two listboxes and the button, each providing its own URL and result handlers.

It’s important to note that the actual result and fault handlers given to the HTTPService object instance are inline functions. This is essential since the call to HTTPService.send() is asynchronous. When the result comes back (later), context will be lost and the service won’t be able to find a function you defined in the FlexHttpService script object. Therefore, the handlers must be inline.

ActorList Initialize Script

With the FlexHttpService defined, it’s easier to write the rest of the code to fetch the list of actors.

We want the list of actors to be retrieved when the form guide initializes so we’ll put this script in the Initialize event of the ActorList field. In the result handler, we’ll simply iterate through the items in the XML object returned and, for each actor, add his/her name and ID as an item into the ActorList field in the form guide.

Note that accessing the ActorList field in the form guide within the result handler, which is out-of-context at this point, is done by using the full SOM expression to the field, starting with xfa.form (accessing the Form DOM), followed by the root subform name (“movieList”), followed by the path to the ActorList field.

Edit the ActorList field’s Initialize event and paste the code from this text file into it.

Basically, we first clear any existing list items and call the Movie Service with the appropriate URL. In the result handler, we add items into the ActorList and then enable the list so that the user can make a selection (we don’t want the list accessible until the items have been loaded).

CategoryList Initialize Script

The CategoryList field is much the same as the ActorList field however it’ll fetch the list of categories.

Edit the CategoryList field’s Initialize event and paste the code from this text file into it.

GetMovies Click Script

Finally, we just need to set the Click event script on the GetMovies button that will fetch the movies requested by the user (optionally filtering on actor and/or category).

This script is essentially the same as the first two however it’s a little more complex since the Listing table must be retrieved and then new instances of the MovieRow must be added and their fields (Title, Actor, Category and Cost) populated with data from each movie returned from the service. Additionally, the button is disabled once its clicked and only re-enabled when the result or fault handler is called to prevent the user from clicking multiple times while a request is pending (since HTTPService.send() is asynchronous) and the MatchCount field is populated with the number of rows added to the Listing table (this will be important when we design the form guide in part 3).

Edit the GetMovies button’s Click event and paste the code from this text file into it.

Solution to Part 2

Try not to peek at this before you attempt to build the form on your own…

Download Part 2 [zip]

Minimum Requirements: The form should work back to Designer 8.0 however it was designed with Designer 8.2.1 SP1.

Updated: November 22, 2008


Posted by Stefan Cameron on November 18th, 2008
Filed under Conferences,Designer,Form Guides,Instance Manager,Scripting,Tables,Tutorials,XFA
Both comments and pings are currently closed.

2 Responses to “MAX 2008 Tutorial – Part 2 – Flex Code”

  1. Igor Petrushenko on January 5th, 2009

    Hi,

    thank you for very interesting article.

    However I need a help regarding Flex

    I’m considering to use Flex in my online database application
    called http://www.MyTaskHelper.com
    Actually it mostly looks like Web-forms builder.
    So I want to use Flex for building forms.

    Do you suggest to doing it?

    Thank you,
    Sincerely,
    Igor Petrushenko
    CEO at http://www.MyTaskHelper.com

  2. Ivan on July 23rd, 2009

    Hi, Igor

    It’s very difficult question.
    You may want to ask it on Flex forums.

    However I think it’s not required to use Flex for your online database application.
    Because people mostly want to integrate HTML forms, like you do.