Multiple Top Level Subforms

I’m willing to bet that all the XFA form definitions you’ve looked at all have one top level subform.  Not surprising, because that’s what Designer
allows you to author.  But according to the XFA specification, there can be any number of top-level subforms below the <template> root.

Today I’ll briefly describe the processing rules for top-level subforms, provide a simple example where you might find them useful, and give you a couple of macros to make these easier to work with in Designer.

The Processing Rules

The rules are simple:

  • When there are multiple top-level subforms, only one is rendered.
  • We choose which subform to render based on which one best matches the data.  i.e. the template behaves like a choice subformSet: <subformSet relation="choice">. 
  • If no data is supplied, we render the first subform below the <template> element

A Sample

Suppose I want different variations of my form for printing and for interactive.  I construct my template so that it has top level subforms for both print and interactive.  Since the binding is all "by name", the form will render according to the name of the top level node in the data.  Try previewing the sample with these data files: interactive.xml, print.xml — or import these data files in Acrobat, and you’ll see the form change according to the data provided.  However, controlling print behavior with different data files is more applicable on the server than on the client. 

In order to force the form to use the print subform when printing from Acrobat/Reader, I added a pre-print event to the interactive root subform.  The script renames the top level node in the data, and forces a remerge.  This will cause the print operation to use the print subform.

interactive::prePrint – (JavaScript, client)
xfa.record.name = "print";
xfa.form.remerge();

Then to restore to the interactive view, I added a postPrint event to the print subform:

print::postPrint – (JavaScript, client)
xfa.record.name = "interactive";
xfa.form.remerge();

Design Experience

I’ve already hinted that Designer doesn’t really support multiple top-level subforms. But with a couple of handy macros, we can get by.

First problem is that there’s no easy way to create a new top level subform.  Here’s a macro to proide that functionality.  You’ll notice when you run the macro that there’s a problem.  The changes made by the macro don’t show up in the hierarchy.  This is a bug that will be fixed next release.  Meanwhile, closing and re-opening the form will workaround the issue.  Note that the macro to add the new top level subform also inserts a default master page (<pageSet>). Designer and the XFA runtime are generally very unhappy if they don’t have a set of master pages to work with.

Next problem is to figure out how to edit the new top level subform in Designer.  Here’s a macro to solve that problem. Since Designer always renders the first subform, this macro re-orders the top-level subforms so that you get a different top-level subform. Specifically, the macro re-orders the first subform to be last.  Just make sure that when you save the form that your preferred default subform is first in order.

Now, for the specific example of print and interactive variations, I could have implemented the solution in a number of different ways.  e.g. with a choice subformSet or with optional subforms at the second level in the hierarchy.  But the point was to bring to light some functionality that you might not otherwise been aware of.

7 Responses to Multiple Top Level Subforms

  1. Pingback: Tweets that mention Multiple Top Level Subforms « FormFeed -- Topsy.com

  2. c@tc.se says:

    Thanks, this is really useful, and it even works run-time (I took the liberty of adding an xfa.host.importData-button).

    As for the macros, the xfa docs (p. 319) says that you cannot use createNode to “create any of the following XML Form Object Model objects: /…/ subform”. Apparently, you can. (Perhaps due to me misunderstanding what the form object model really is…?)

    • The docs describe the runtime environment (acrobat/reader/server). Whereas the macro runs in the authoring environment (designer).
      The “form object model” is what I would commonly refer to as the “form dom” — the result of merging the form template with data. Think of the form dom as the runtime dom that inherits from the template.
      The design environment (macros) operates on the template definition — which is normally read-only at runtime.

      John

  3. radzmar says:

    Hi John,

    this is really cool stuff, great!
    Btw: I discovered, that there is no need to close and reopen the form after executing the macros.
    It’s enough to switch from the hierarchie view to another and back ;-).

  4. radzmar says:

    Hi again,

    beside your macro you also can create multiple top-level subforms easily by dublicating the neccessary parts in the template tds files that came with Designer.
    All you need a text editor ;-)

    9.0.0.0.20091029.1.607063.606300

    9.0.0.0.20091029.1.607063.606300

  5. Justin says:

    Hey John,

    Very clever idea. Would you suggest this as the best solution to use in my situation when I have a multi-page wizard form that has a series of next and back buttons (each of which navigates you to a new form page). When the user gets to the end of the process they will print the form but I’d like to merge all wizard pages into one page for printing. I’m not sure if I can do this with a script or if I’m better off using the process described here. What would you suggest?

    Justin

    • Justin:

      Good question. I don’t think there’s a clear-cut answer. But it’s useful to look at the pros/cons. If you re-flow your wizard content you will end up writing script to modify the appearance to make it suitable for print. If you have two “views”, one for data capture and one for print, you will end up duplicating lots of your design.
      So it boils down to effort. Which is easier to develop and maintain. This will depend on how close your wizard content is to the print view. Your wizard might be a different page size/orientation or there might not be a 1:1 correlation between panels and printed pages. In these cases it might be easier to use a separate print view.
      But also keep in mind that if your customer needs to review the printed result, then the closer it resembles the capture view, the easier it is to review.

      Good luck.

      John