Stefan Cameron on Forms
Building intelligent forms using Adobe LiveCycle Designer

'Tutorials' Category Archive

Add, Recalculate

Here’s a little something that very important to know when working with dynamic subforms and using their Instance Managers (IMs) to add instances of them to a form: New subform instances aren’t automatically incorporated into the form’s calculations!

You would immediately notice this problem if you had a form which calculated a total based on line items which can be added or removed from the form. When you add a new line item using the IM’s addInstance(bool) method, the grand total of, say, the cost of all line items isn’t updated to reflect the data you enter into the new line item. This is because the new line item hasn’t been made part of the form’s set of calculation dependencies and is therefore not accounted for by your “grand total” calculation. As a matter of fact, until a call to xfa.form.recalculate() is made, none of the new instances added will be included in the form’s calculations.

To demonstrate this, I’ve created a sample form which has a “line item” section to which line items can be added. As line items are added and their costs changed, the grand total fields at the bottom calculate the total cost of the order: One grand total field performs its calculation using the FormCalc SUM function and a SOM Expression identifying the collection of fields to total while the other uses the LineItem dynamic subform’s IM object to calculate the grand total. Finally, there’s a check box at the top of the repeating “line item” section which, when checked, will cause the “Add Item” button to execute the xfa.form.recalculate(true) statement after adding a new line item. To see the difference, play around with the form by adding line items with the check box both checked and unchecked.

Note that this issue was addressed in Acrobat/Reader 8.0. Therefore, if your form targets this version (or later) of Acrobat/Reader, you shouldn’t need the recalculate() workaround.

Download Sample [zip]

Minimum Requirements: Designer 7.x, Acrobat 7.x.

Updated Nov 19, 2009 — Added note about the issue being resolved in Acrobat/Reader 8.0+.


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

Data-Nominated Subforms

I thought I would post a little sample on data-nominated subforms tonight. This is a new feature, introduced in Designer 7.1, which can be a very powerful tool.

Since the feature essentially lets you define expressions against values from data being loaded into a form in order to control which subform, from a specified set (subform set containing subforms), will be used for the record currently being loaded into the form, you can do very interesting things. For example, you might have a table which lists data. Maybe you would like to use a row which has a yellow background to identify data which is not important, one with an orange background for data that’s important and one with a red background for data that’s very important. This can be easily achieved using Data-Nominated Subforms.

I’ve created a little sample based on the movie data I used for the Conditional Breaks Sample I posted a few days ago. In this sample, I have a subform set which contains 3 subforms, each capable of binding to a movie record. The twist is that I want to use the green subform for comedies, the red one for action movies and the blue one for dramas.

Download Sample [zip]

Minimum Requirements: Designer 7.1, Acrobat Pro 7.0.5.

Note: A basic understanding of Data Binding is required for this sample.

The trick in getting this to work is to first create a data connection which represents the data you’re loading into the form.

Then you need to create the subforms which each contain fields with names set to the data node names from a movie record so that Normal (“implicit”) binding works correctly once the subform is picked for the record.

The next step is to wrap all subforms into a subform set. You can do this by selecting them all in the Hierarchy palette and then choosing Wrap in Subform Set from the context menu.

At this point you’re almost done. All that’s missing are the expressions which tell the Object Model which subform from within the subform set to use for a particular data record.

The Data-Nominated Subform feature is accessed by selecting the subform set and going to the Object palette’s Subform Set tab. There, you’ll find a Type property from which you can select the Select One Subform From Alternatives item. When you select this option, an Edit Alternatives button will appear. Click on that to open the Data-Nominated Subform dialog. In there, you would elect to Choose Subform Using Expression, select your data connection from the drop down list and then specify an expression like

category == "Comedy"

for the “$record.movie” binding (which establishes the scope for your expression) on the comedy subform.

When you preview the form (if you just run it in Acrobat, you’ll have to import the data into the form using the commands under the File menu), you’ll see that the comedy subform is used only for records which have a “Comedy” category name.


Posted by Stefan Cameron on May 10th, 2006
Filed under Data-Nominated Subforms,Tutorials

Conditional Breaks

Some of you have requested a sample of the new Conditional Breaks feature in Designer 7.1.

This feature allows you to set conditions, based on imported data, which determine when breaks should occur.

For example, you may have data that you want to list by category and every time the category changes, you’d like to start the new category on a new page. Or, you may have a separator that you want to insert in between sets of data on your form.

I’ve created a little sample which demonstrates the Conditional Breaks feature by listing some movie data where each time the category changes, a new page starts. Don’t forget to import the data.xml file into the form when you open it in Acrobat.

Download Sample [zip]

Minimum Requirements: Designer 7.1, Acrobat 7.0.5.

Note: A basic understanding of Data Binding is required for this sample.

Since breaks are only really useful inside flowed subforms (there’s no point setting breaks on a subform inside a positioned container since the data won’t flow — it’ll all stay in one place instead of flowing left-to-right, top-to-bottom, for example), you can only get to the Conditional Break settings on the Object palette’s Pagination tab if you select a subform inside a flowed container (subform). The only exception is selecting a row or a section within a Table object since the content of Tables is always flowed.

Typically, after creating a new form, you would add a positioned subform (let’s call it the ContentSubform) to the page and add the fields you need into it. You would then make the page subform flowed (set the Content property on the Object palette’s Subform tab to Flowed), then select the ContentSubform and click on the Edit button on the Object palette’s Pagination tab. This will open the Conditional Breaks Dialog where you can add multiple conditions for that subform’s breaks.

In my sample, the data represents movies and each movie record has the following information:

  • Category
  • Title
  • Actor

Since I wanted to create a report-style form where a change in category breaks to a new page and a change in the actor’s name is preceeded by a separator, I created a movie subform which lists the data and then two other subforms:

  1. NewCategorySF which I want to insert every time the category changes.
  2. NewActorSF which I want to insert every time the actor’s name changes.

I then specified two conditional breaks on the movie subform:

  1. The first one checks for a change in the category data. When a change occurs, the layout will break to the top of a new instance of the “page 1” subform and, before starting to list the data for the new category, insert an instance of the NewCategorySF subform. This is what we call a Break Before Conditional Break (since the break occurs before the new record, which contains the new category name, is inserted into the form). Notice that the NewCategorySF subform is listed as a Leader for the Conditional Break because it’s meant to be inserted after the break but before the new record gets inserted into the form.
  2. The second checks for a change in the actor data. When a change occurs, the layout will not actually break because we simply want to use the Conditional Break to know when to insert the NewActorSF to separate the data set into sub-groups of actors. In this case, I specified NewActorSF to be a Leader for the Conditional Break because I wanted it to show-up after the actual break but before the new record is inserted into the form. You may wonder why I didn’t make it a Trailer but in this case, there wouldn’t be any difference since there isn’t an actual “physical” break in the data flow (to a new page or content area, for example).

Also notice that the NewCategorySF and NewActorSF subforms are both set to Repeat for Each Data Item (you can set this on the Object palette’s Binding tab) with a Min Count of 1 so that they always appear before the very first data record is inserted into the form. Otherwise, they wouldn’t appear until the first Conditional Break occurs.


Posted by Stefan Cameron on May 6th, 2006
Filed under Conditional Breaks,Tutorials

Samples! Give Me Samples!

One of the best places to look for Designer samples is on the LiveCycle Designer Samples Site. There, you’ll find lots of samples demonstrating various Designer techniques and features.

Although new samples are constantly be posted to the Designer Samples Site, they can’t always cover all topics or address all of our customer’s questions/issues. As such, I’ll be posting some of my own samples to my blog. Look for them under the Samples category.


Posted by Stefan Cameron on May 6th, 2006
Filed under Tutorials