Stefan Cameron on Forms
Building intelligent forms using Adobe LiveCycle Designer

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.

Schema Data Connection

The first step is to connect the form to a schema which we can obtain from the Movie Service:

<movieList>
    <movie>
        <movieId/>
        <title/>
        <cost/>
        <actorName/>
        <catName/>
    </movie>
    <movie>
        <movieId/>
        <title/>
        <cost/>
        <actorName/>
        <catName/>
    </movie>
</movieList>

Save this structure to an XML file named “movieCatalog-schema.xml” somewhere where you can reference it later from your form in Designer. (It’s important that you save it as-is with the duplicated <movie> element since this will indicate to the Data Connection Wizard that the <movie> element is repeatable.)

Create a new blank form in Designer and then create a new data connection using the Data Connection Wizard available from the Data View palette’s menu button. On the first page, set the name to “MovieCatalogDC” and choose “Sample XML File”:

On the next page, choose the “movieCatalog-schema.xml” file you saved earlier and click “Finish”. You should now have a schema data connection in your form (note that Designer inferred the possible structure of the schema based on the sample XML file we provided for the data connection):

This data connection will help us set the correct bindings later.

Page Header

Next we’ll create a simple header for the form by adding a text object to the Master Page. Switch to the Master Pages tab and drag a text object onto it. Place it at the top-left and set the text to “MAX 2008 Movie Catalog”.

To make sure that what we’ll put on the body pages (in the Design View) doesn’t show-up over-top our header, make sure that the content area starts below the header text object:

Movie Listing Table

Back on the Design View, we now need to create a table which we’ll use to display the listings from the catalog. This is where that schema data connection will come-in handy as we’ll see a little later.

Our table will display 4 columns: title, actor name, category name and cost. Drag a table object onto the top-left corner of the page and give it 1 header row, 1 body row and 4 columns:

We want the table to take-up the entire width of the page but we also want the first column, title, to be wider than the other 3 since the title is usually longer than names or a dollar amount. Start by making the last 3 columns a little wider by dragging the column separator between the 2nd and 3rd and 3rd and 4th columns to the right, leaving some room to make the first column wider. Then drag the column separator between the 1st and 2nd column to the right until it won’t move anymore, which indicates that it’s the widest the first column can be made while keeping the table constrained to the page’s width.

Now double-click in each header cell and rename them to “Title”, “Actor”, “Category” and “Cost” from left to right.

(Here I’ve also set a linear-to-bottom background gradient color on the header row.)

Next, we need to set some fields into the table row where the movie data will go since they’re only text objects by default. The first 3 columns need to be text fields and the last one should be a numeric field since it’ll contain a dollar amount.

Using the Hierarchy palette, select the “Cell1”, “Cell2” and “Cell3” objects in the “Row1” table row and change their object type (using the Object palette) to “Text Field”. While they’re still selected, set their Value Type to “Read Only”.

Now select the last cell in “Row1”, “Cell4”, and change its object type to “Numeric Field”. While it’s still selected, set its Value Type to “Read Only”, its Data Format to “Float” and click on the “Patterns…” button on the Object palette’s Field tab. In there, set the Display pattern to “numeric.currency{}” and set the Data pattern to “numeric.decimal{}”:

This will let the field accept a decimal number as its data and will cause it to be displayed with a currency symbol (e.g. “25.50” is displayed as “$25.50”).

Finally, rename “Table1” to “Listing” and “Row1” to “MovieRow”. Inside “MovieRow”, rename “Cell1” to “Title”, “Cell2” to “Actor”, “Cell3” to “Category” and “Cell4” to “Cost”.

Schema Data Bindings

The next thing on the list is setting the data bindings into the schema data connection we created earlier. This will ensure that when data is merged into the form, after being retrieved from the Movie Service, that instances of the MovieRow table row are created accordingly and the Title, Actor, Category and Cost fields they contain populated with the right data for a particular movie.

Select the MovieRow table row object and set its binding by choosing “MovieCatalogDC > movie” from the binding popup button next to the Default Binding property. This will set the binding to “$.movie[*]”:

(The button next to the field that contains “$.movie[*]” is the binding popup button.)

This binding, with the “[*]” syntax, indicates that the MovieRow object will bind to all occurrences of the <movie> data group nodes in the data that gets merged into the form.

Finally, make the MovieRow repeatable with no min, no max but 1 initial instance:

The initial instance is essential in getting around a bug with the Form Guide Repeater Data Grid panel layout which we’ll be using in part 3 of this tutorial.

The last bindings we need to set are on the Title, Actor, Category and Cost fields that make-up the MovieRow. Set them as follows:

  • Title: “$.title”
  • Actor: “$.actorName”
  • Category: “$.catName”
  • Cost: “$.cost”

You can set these bindings manually or you can use the binding popup button to select the appropriate node from the MovieCatalogDC data connection. If you use the binding popup button, you’ll likely get the Binding Properties dialog, in which case you should choose to not to update any related properties as follows:

Under certain circumstances, the schema may contain more information about a particular element which could be automatically applied to the field such as name, caption and default value. Since we’ve already setup the fields ourselves (and since our sample XML schema didn’t have much information to start with), we don’t need this functionality.

Form Guide Only Objects

The final step in the form design is to include 4 objects which we’ll use only in the form guide that we’ll create in part 3 of this tutorial. We’ll need a listbox to hold the actor names, one to hold the category names, we’ll need a numeric field to hold the movie count and we’ll need a button that the user will click to fetch the movies that match the actor and/or category they will have selected in the lists (if any).

This is simpler to setup than it sounds. All we need to do is drag a new subform into the page (below the Listing table) and place two listboxes, one numeric field and one button inside. Rename the subform to “GuideObjects”.

Rename one listbox to “ActorList” and the other to “CategoryList”. Rename the numeric field to “MatchCount” and the button to “GetMovies”.

Set the ActorList field’s caption to “Choose an Actor (optional):” and the CategoryList field’s caption to “Choose a Category (optional):”. Set both field’s Value Type to “Read Only” since we don’t want the user to be able to interact with the listboxes until actor and category data are loaded into them (in the Form Guide, which we’ll see later in part 3).

Set the MatchCount field’s caption to “Number of matches:” and set its Value Type to “Read Only” as well since we’ll just be reporting the total number of movies that matched the criteria (actor and/or category or neither) and we won’t want the user to edit the result.

The bindings on both listboxes and the numeric field will be “None” by default which is fine. There’s no node in the schema to bind them to and we don’t need to bind them anyway.

Set the GetMovies button’s caption to “Get Movies”.

Finally, to make sure all the guide-only objects are hidden in the form, set the Initialize script of the GuideObjects subform to hide itself if the context isn’t the Form Guide. You can determine what the context is by checking the value of the xfa.host.name property. If it’s “Flash”, then you know the script is executing within the context of the Form Guide, not Acrobat. This will be very important in part 2 when we write the ActionScript code necessary to fetch the data from the Movie Service:

if (xfa.host.name != "Flash")
    this.presence = "hidden";

This is what the form should look like now:

(Note that the exact placement of the objects within the GuideObjects subform doesn’t matter since they’ll be positioned correctly in the Form Guide and won’t be displayed on the form itself.)

Getting Rid of the Page Subform

To ensure that our Listing table is free to expand and roll-out onto additional pages if there are a lot of movies returned in the listing, we need to move the Listing table and the GuideObjects subform out of the page subform and into the root subform (“movieList” at the top of the Hierarchy tree). We could just make the unnamed page subform flowed but that would introduce an extra level of subform hierarchy that just isn’t needed.

This can be done simply by right-clicking on the unnamed page subform “(untitled Subform) (page 1)” object in the Hierarchy palette and choosing the “Unwrap Subform” command. The hierarchy should now look like this:

Testing the Form

Before we go on to part 2 we should make sure that what we’ve done so far works correctly. To test our form, we simply need to merge-in some movie data from the Movie Service to make sure that it gets displayed properly in the Listing table.

You can get the full movie catalog listing simply by hitting this URL:

http://forms.stefcameron.com/services/movies/

Save what you get into an XML file named “movieCatalog-sample.xml” and set it as the Preview Data File for the form using the Form Properties dialog.

Now preview the form using the “Preview PDF” tab. You should get something that looks like this:

After you’ve determined that the table is functioning correctly (which means that the bindings are working as expected), you should remove the Preview Data File setting since it’ll interfere with the Form Guide’s function later on. (A Preview Data File can be used to initialize data in a form guide however, in this case, we don’t want all the movie data to be there already; we want to query the Movie Service for it in real-time based on any actor and/or category settings the user may have specified.)

Solution to Part 1

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

Download Part 1 [zip]

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


Posted by Stefan Cameron on November 17th, 2008
Filed under Conferences,Data Binding,Designer,Scripting,Tables,Tutorials,XFA
Both comments and pings are currently closed.

Comments are closed.