Stefan Cameron on Forms
Building intelligent forms using Adobe LiveCycle Designer

'Scripting' Category Archive

MAX 2008 Tutorial – Part 3 – Form Guide

Welcome to the third and final part of a three-part post series tutorial on importing data into a form guide and a PDF. The first part covered the form design, the second part covered the Flex code and the third part will cover designing and debugging the form guide that will complete the solution.

Form Guide Layout

The goal is to design a form guide which will provide two panels: one for user options and the other for results.

The first panel will expose the 4 fields inside the GuideObjects subform (which are only meant to be exposed in the form guide — hence why the GuideObjects subform has the Initialize script to hide it if the host isn’t “Flash”). The user will have the option to choose an actor and/or category for further filtering and will then click on the GetMovies button to execute the request on the Movie Service. When the requested XML is returned to the form guide, the GetMovies result handler will convert the XML into instances of MovieRow inside the Listing table.

The second panel will use a repeater layout to expose the Listing table’s contents within the form guide however this panel will only be accessible if the movie query returned 1 or more results.

Once the results are in, the user will then be able to switch (“flip”) to the PDF view which will show the Listing table in the form, from which the user could then print or archive the results.

Continue reading…


Posted by Stefan Cameron on November 19th, 2008
Filed under Acrobat,Bugs,Conferences,Debugging,Form Guides,Scripting,Tables,Tutorials

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.

Continue reading…


Posted by Stefan Cameron on November 18th, 2008
Filed under Conferences,Designer,Form Guides,Instance Manager,Scripting,Tables,Tutorials,XFA

MAX 2008 Tutorial – Part 1 – Designing the Form

This is the first part in a multi-part post series for Adobe MAX 2008 designed to show you how extend a form guide to import data from a website without using FlexBuilder. If you haven’t seen it already, I recommend you have a look at the demo on last Friday’s tutorial preview post to get a sense of what we’re going to be building. In this first part, we will build the form necessary to provide the print/archive capabilities for the Movie Catalog.

Throughout the tutorial, I will assume that you’ve used Designer already and you know about things like flowed vs positioned subforms. I will also assume that you’re familiar with Guide Builder’s interface for designing Form Guides.

Software Requirements

Before we get started, make sure you’re using Designer 8.2.1 SP1 and Guide Builder 8.2.1 SP1. You can download an evaluation version of Designer and Guide Builder when you download the Acrobat 9.0 Pro trial. If you haven’t installed SP1 yet, you can download it from here (note that you only need to install the Designer SP1 update — you don’t need Workbench or even LiveCycle ES to run through this tutorial).

If you already have Designer but you don’t have Acrobat, you can use Reader 9.0 to go through the tutorial.

Continue reading…


Posted by Stefan Cameron on November 17th, 2008
Filed under Conferences,Data Binding,Designer,Scripting,Tables,Tutorials,XFA

Digital Signature Field Status

Have you ever needed to verify the status of a digital signature (“DigSig”) field in a form? A typical scenario would be that a form is to be signed prior to being submitted and you don’t want the submit button to be available until the user has successfully signed the form. Unfortunately, the “lock fields after signing” feature, available as of Designer/Acrobat 8, won’t be enough in this case because it’ll only lock the fields after a signature has been applied; it won’t also make the submit button visible/enabled.

There’s a feature in Acrobat’s scripting object model that lets you determine the status of a DigSig field (i.e. whether it’s signed or not): It’s the AcroForm Field object’s signatureValidate() method which returns a status code indicating the state of the signature field. In particular, the method returns 0 if the DigSig field is empty (hasn’t been signed) and 4 if the DigSig applied is valid and the identify of the signer was verified.

Note: This method cannot validate the status of an XML Data Signature which is different from a traditional DigSig.

Accessing the AcroForm Field Object

To access the AcroForm Field object that represents the XFA DigSig field in your form, you have to use the AcroForm Doc object’s getField() method and give it the name of the field you’re looking for.

To access the Doc object, you simply need to access the event.target property in any XFA event. This property is the Doc object. From there, you call getField() and you give it the name of the DigSig field as it’s defined in the AcroForm DOM. That’s the tricky part: Your field’s full name is its SOM expression (shown here for a DigSig field in a page subform named “PageSubform1”):

xfa.form.form1.PageSubform1.SignatureField1

however its AcroForm Field Name looks like this:

form1[0].PageSubform1[0].SignatureField1[0]

Fortunately, I’ve already written some JavaScript that generates the above syntax: Copy and paste the script from my AcroForm Field Name Generator into your event and all you have to do in your script is call GetFQSOMExp(DigSigField) where “DigSigField” is the XFA DigSig field whose AcroForm Field name you can to get.

From there, you simply make a call to the signatureValidate() method:

var status = event.target.getField(GetFQSOMExp(DigSigField).signatureValidate();

switch (status)
{
    case 0:
    case 1:
        // not signed...
        break;

    case 2:
        // invalid signature...
        break;

    case 3:
        // valid but identity of signer cannot be verified...
        break;

    case 4:
        // valid signature...
        break;

    default:
        // error -- unexpected status code
        break;
}

PreSign and PostSign Events

A key component to making this work is the ability to verify the status of the signature after the user has interacted with the DigSig field. You may think of using either the Click or MouseUp events on the DigSig field however there’s a bug in Acrobat/Reader 9 (and older) that prevents the Click and MouseUp events from coming through if the user successfully applies a signature (if they cancel-out of the digital signature dialog that appears when they click in the DigSig field, the events fire but not if they apply a signature).

Fortunately, XFA 2.8 includes new PreSign and PostSign events which occur just before and immediately after clicking on the DigSig field and they behave correctly. The only drawback here is that they are only available for scripting in Designer 8.2 and only work in Acrobat/Reader 9 or greater.

Note that if you wanted to check for signature status on start-up, the DocReady event is the correct place to do it. Initialize, FormReady and LayoutReady events are too soon in the initialization sequence for signature status to be available.

Sample Form

Getting back to our use case where we want to show the submit button only once the user has signed the form, you would simply script the DigSig field’s PreSign event to show the button and then the PostSign event to check the status of the signature. If it’s not valid (the user didn’t apply a signature or there’s something wrong with the signature that was applied), you would then hide the submit button again.

The reason why you would show the submit button in PreSign and hide it again in PostSign is because showing the button in PostSign after applying a good signature would invalidate the signature’s status (the status would become “unknown”) because the form would be modified after signing. By showing the button after signing when it was hidden prior to it, the form would no longer be the state in which it was when it was signed (which is one reason for DigSigs in the first place — to ensure that the document is in the same state as which it was when the user signed it, otherwise the document may have been maliciously modified between the time when the user signed it and the time at which you received it).

Download sample [pdf]

(Note that you’ll need a digital ID to run the sample; if you don’t, you can easily create one in the digital signature dialog that appears when you click on the DigSig field.)

Sample Minimum Requirements: Designer 8.2, Acrobat 9.0


Posted by Stefan Cameron on November 5th, 2008
Filed under Acrobat,Bugs,Scripting,Tutorials,XFA

Handling List Selection Changes

This is something I get asked a lot so I thought I’d write a little tutorial on how to handle a selection change in a list object (drop down list or list box).

Single Selection Lists

All XFA events have an object that represents properties about the event currently in execution:

xfa.event

This object holds many interesting properties but the one that’s important here is the newText property which, for a list, contains the new selection.

It’s important to note that there are two types of list items: Ones that have text data only and ones that have both text and value data. By default, the Object palette creates lists with items that have text data only. On the Field tab, you can add/remove items and specify their text data while on the Binding tab, you can optionally set each item’s value data by checking the “Specify Item Values” box.

The xfa.event.newText property always returns the text data. You can access the value data associated with the new text data by using the list’s boundItem() method:

// get the value data associated with the new selected text data
var newValue = MyList.boundItem(xfa.event.newText);

For single selection lists, you can therefore use the text data or get the associated value data for the new selection and do something from there. The following code sample gets the new selected value data in a list object’s Change event and changes the list’s background color accordingly:

var newValue = this.boundItem(xfa.event.newText);

switch (newValue)
{
    case 1:
        this.fillColor = "255,0,0"; // red
        break;

    case 2:
        this.fillColor = "0,255,0"; // green
        break;

    case 3:
        this.fillColor = "0,0,255"; // blue
        break;
}

Multiple Selection Lists

List objects may also support a multiple selection of items. You can specify that the list supports multiple selection by setting the “Object palette > Field tab > Allow Multiple Selection” property but you cannot specify a default selection of multiple items using the Object palette (only a single default selection is supported though it still works for lists that allow multiple selections). You would have to use the list’s Initialize script to do that.

At runtime (e.g. in Acrobat/Reader), you may select multiple items in the list by using the Shift and Ctrl keyboard keys: Shift + Click will select all items from the last selected item to the item you click on and Ctrl + Click will add/remove individual (non-sequential) items to/from the selection.

Determining the selection in a multiple selection list is different from doing so in a single selection list because you have to deal with the fact that more than one item may be selected. There is also a difference in the event you must use in order to handle the change in selection: When you set the “Allow Multiple Selection” property, the “Object palette > Field tab > Commit On” property changed to allow only a setting of “Exit” (as of Designer 8.1; Designer 8.0 may have still allowed “Select” to be chosen however I recommend setting this property to “Exit” if you have the choice) which means that the change in selection — as far as the list is concerned — will only take place once the user exits the list (once they hit the Enter key, tab away or click away from the list) rather than immediately when they visually change the selection. The result is that you must handle the change in selection in the Exit Event rather than in the Change event as in single selection lists.

You can handle a change in single selection lists using the Exit event as well however for single selection lists, it’s usually preferable to handle the change immediately rather than once the user leaves the list. For multiple selection lists, the idea is that the user may click more than once to set the selection they want so you typically want to react to the change only once they’re done which is why the selection is only committed once the user exits the list.

Determining the set of selected items was really difficult leading up to Designer and Acrobat/Reader 8.0 when the new list object properties and methods were finally introduced. These new APIs make it much easier to deal with lists that contain multiple selections: Use the length property to iterate through the items, the getDisplayItem method to get the text data associated with an item, the getSaveItem method to get the value data associated with an item and the getItemState method to determine whether the item is selected or not.

Here’s our sample script from earlier that sets the background color of the list object after a change in the selection (in the list’s Change event) however this time the script is meant for the Exit event and the list supports multiple selection. The color values are combined if more than one is selected, producing more color combinations up to white (an RGB color value of “255,255,255”) then all 3 items are selected:

// array with 3 elements, all at zero initially
var rgb = new Array(0, 0, 0);

for (var i = 0; i < this.length; i++)
{
    if (this.getItemState(i))
    {
        // item is selected
        // item values are 1, 2 or 3 (1-based)
        // array elements are 0, 1 or 2 (0-based)
        rgb[this.getSaveItem(i) - 1] = 255;
    }
}

// Array.toString() produces a comma-delimited string containing the
//  values of the array elements so this will produce "255,0,255" if
//  items 1 and 3 are selected.
this.fillColor = rgb.toString();

If you give this a try, remember to create a list with 3 items (1, 2, 3) and place the script in the Exit event, not the Change event. Then remember to click away from the list once you’ve set the selection at runtime.

Multiple Item Default Selection

Setting a default selection of more than one item is unfortunately not something that Designer supports. To achieve this, you’ll need to set the list’s Initialize script to do the work. For example, to initialize a multiple selection list of 5 items where items 1, 4 and 5 are selected, you would do this (remember that list item indexes are 0-based, not 1-based) in the list’s Initialize event:

this.setItemState(0, true); // item 1
this.setItemState(3, true); // item 4
this.setItemState(4, true); // item 5

Sample

To see this in action in what you might consider a more realistic example, my “What About the Other Field?” tutorial uses single selection lists that show an “other” field when their “other” item is selected.


Posted by Stefan Cameron on October 27th, 2008
Filed under Acrobat,Designer,Events,Scripting,Tutorials,XFA