Working with Data Fragments

Many of you will be familiar with the idea of constructing a form using template fragments. Template fragments are a powerful way to construct a form experience with modular parts. But there are some workflows where template fragments do not (yet) have all the functionality we might like. In cases where the content of the form is determined at runtime, template fragments might not have the flexibility you need. Take the transpromo examples from earlier posts(here and here). In those samples, the advertisement was baked into he template.  But in real life the actual ad that gets inserted will change. On starting a new marketing campaign, a company may want to issue a new set of ads to embed in their output. The actual ad chosen will vary depending on data in the form. Is the client single? Insert the sports car ad. Do they have a new baby? Insert the minivan ad. Some of our customers are building these kinds of applications using what we call “stitching solutions”. They have written Java libraries that assemble XFA templates on-demand. Writing a Java solution is fine for some, but eventually we have to make this easier.

One of the solutions available using today’s LiveCycle products leverages the notion of data fragments (instead of template fragments). I use the term “data fragments” to refer to the idea of embedding rich content in data. You might be surprised at how much you can customize the look of your document via XML instance data. You can add images, rich text, hyperlinks, positioned text and even floating fields.

A solution that uses data fragments to place ads in statements might look like this:

  1. An application for authoring data fragments representing the advertisements
  2. An application for adding metadata to the ads and storing them in a repository
  3. A rules engine for selecting ads from the repository based on correlating transaction data with ad metadata
  4. Print engine to render the statements with the ads

I can’t give you the whole solution, but can offer a sample that would help you get started with parts 1 and 4:

  • AdGenerator.pdf: This is a PDF for generating a data fragment and adding it to statement data. (Ideally we’d define something fancier for designing data fragments – maybe a slick flash app side-by-side with the PDF.)
  • statement.xdp: A sample credit card statement that includes a placeholder subform to render the ad data fragment.

Here is a copy of AdGenerator.pdf, populated and ready to export data. (Please give special notice to the image artwork that I worked so hard on.)

Here is a copy of the resulting statement generated with the ad.

How AdGenerator.pdf works

The advertisement is a growable subform that holds:

  • An image field
  • A repeating subform housing rich text

The form has various field and button controls to add the image and to add and position the rich text.  To understand how to use the form, read the instructions on the form itself. The scripts are also well documented and a good source for discovering the techniques used.

Dynamic properties

The (x,y) placement of rich text and the size of the ad subform are controlled by dynamic properties. Authoring these means going into XML Source view and adding the appropriate <setProperty> elements. E.g.:

<field name="Image" w="203.2mm" h="25.4mm">
<setProperty target="h" ref="height"/>
<setProperty target="w" ref="width"/>

Repeating, positioned text

Another case where we had to use XML source mode: Having added the TextData subform as a positioned child of advertisement, add an <occur/> element to allow it to repeat:

<occur min="0" max="-1"/>

The buttons and fields that position the text will update both the text coordinates as well as the data that the text coordinates are dynamically bound to.

Data References

You can personalize the text on the ad by injecting data values inline with the text.

On loading transaction data, we populate a listbox with all the data values found in the instance data. Adding the data reference uses the same mechanism as floating fields in Designer. We inject a special <span/> element into the xhtml with an embedded data reference. E.g.:

<span xfa:embed="$data.Statement[0].AccountNumber[0]" />

Styling Rich Text

In order to style your rich text in Acrobat, you need to bring up the properties editor (ctl + e). To add a hyperlink, select some text and choose “Hyperlink…” from the context menu. (By the way, there seems to be a bug here.  Rich text editing never works for me in Designer preview.  I use standalone Acrobat — with Designer shut down).

6 Responses to Working with Data Fragments

  1. Hi John,Very cool post! Definitely in the “deep end” but it helps to think outside the LiveCycle Designer box when it comes to XFA capabilities.

  2. Stefan:Thanks for the comment.I probably should have prefaced the post with a “deep end” qualifier :-)John

  3. Bruce says:

    Hi John,Is it possible to use setProperty on a repeating field? I had hoped that if my subform was bound to something like $.pictureDetails.caption[*] then I would be able to use <setProperty target=”caption.value.text” ref=”$.text”>.ThanksBruce

  4. Bruce:Suppose you have data that looks like:<fields><f><c>Caption 1</c><val>value 1</val></f><f><c>Caption 2</c><val>value 2</val></f><f><c>Caption 3</c><val>value 3</val></f></fields>If you have a repeating subform bound to “fields.f[*]” and a field bound to “$.val”, then you can also bind your field caption using:<setProperty target=”caption.value.#text” ref=”c”/>Note that the binding expression is “c” and not “$.c”. This is because the setProperty directive gets executed relative to the data bound to the field value.”$.c” would attempt to locate the data as f.val.c, rather than f.c.Hope this helps.John

  5. Bruce says:

    Thanks John, I see what I was doing wrong but also for my button objects (which aren’t normally bound to anything) I have had to manually add a element, so that the setProperty has something to bound value to calculate a relative reference from.Seems a little strange but I think I can sort of see what is happening. Does that sound right?Bruce

  6. Bruce:Sounds right. For setProperty to use a relative binding reference, it needs to be in the context of a bound element. If your button field isn’t bound, then the setProperty command needs to either use an absolute reference, or needs to be hosted by another element. My first choice would be to place it in the subform containing the button.John