Stefan Cameron on Forms
Building intelligent forms using Adobe LiveCycle Designer

Restoring the State of your Form

This is a guest post from my colleague Anatole Matveief who works on XFA-related features in Acrobat. In this post, Anatole introduces a really cool feature available since Acrobat 8.0 and Designer 8.0 called “formstate” which allows you to persist non-data related changes to your forms and restore them when the form is subsequently re-opened.

Minimum requirements (to use the forms in this tutorial): Acrobat Standard 8.0, Designer 8.0

FormState

In Acrobat and Designer 8, Adobe introduced the concept of saving a form’s state in XFA Forms. First a quick review: An XFA Form file usually contains a template and data. When the form is opened, the template instructs the runtime engine (like Acrobat, Reader or the server) how to create the Form DOM given a set of data. The user can then interact with the form. After the user fills the form, Reader or Acrobat will save the data. When the form is then reopened, Acrobat or Reader will take the saved data and once again do the merge to create the form.

However, many customers encountered a problem: They wanted to save or persist an element of the form that was not bound to the data. For example maybe in the process of filling the form, some captions changed, or the color of fields changed. Or maybe the number of instances in an unbound subform changed. Since these changes were not bound to data they would not be restored the next time the form was opened, since only the data was saved.

In Acrobat 8 this changed. Now by default, the state of the form, or its formstate is saved. This means that all those changes in the form that happened at runtime that weren’t bound to data will be restored next time the form is opened.

Automatic State Restoration

As an example, open formstate-auto.pdf in Acrobat. Click on the “Change Country” button once or twice, which runs a script to change numerous properties on the form to make it into a US form or Canadian form. These include colors, captions, and the number of instances in a subform, values, and the items in a list. Now save the file. When you open the form again, the captions, colors number of instances, unbound field values, and list items will be as they were when you saved. This would not be the case prior to Acrobat 8.

Here is the setting in Designer 8.0 that controls this automatic form state saving:

In the XFA Language it’s the property in the root subform called “restoreState”. The default value is:

restoreState="auto"

Now, as with most good things in life, it’s not quite so simple. Now that form state is restored, we open up a potential security issue. What if someone gets your form, changes a caption from “Address” to “Password”, then changes another caption to read “SSN”? When they save the file, the next time your intended customer opens the file they’ll see the spoofed captions, not the captions the original author intended! That is, the author’s intent has been compromised. So how do we get around this issue?

Manual State Restoration

There is now also the option to restore formstate manually, specified in the XFA Language on the root subform as:

restoreState="manual"

Or in Designer by selecting the second radio as shown here:

What does this mean? This means that the form author decides, through script, what parts of the form will be restored when the file is reopened. In fact, for certified forms, this is the only way to restore form state. Certifying an XFA Form is disallowed if the formstate’s restoreState is set to “auto”.  (If for some reason the form does get certified, by a previous version of a product that doesn’t enforce this rule for example, Reader or Acrobat will not restore the formstate on open.) First let’s see an example using a form with restoreState=”manual”.

Open the file formstate-manual-noscript.pdf. Click the “Change Country” button once or twice, save, close and reopen the file. Notice that only values are restored. The properties changed by script are not. The exception to this rule are the unbound field values and the number of subform instances, as shown on the form. This means that even for restoreState=”manual”, unbound field values (where bind=”none”) and subform instances are restored.

So what do you do if you want to manually restore the form state? Thankfully, there is a simplified method to doing this by using script.

Open the file formstate-manual-script.pdf. Follow the same steps as before. When you reopen the file you’ll see that the entire state is restored. This is accomplished by placing this script on the Form:Ready event of the root subform:

// this script restores all the deltas manually.
var oList = this.getDeltas();
for (i=0; i < oList.length; i++)
{
    var oDelta = oList.item(i);
    oDelta.restore();
}

You can also be more selective about which fields, and even which properties within those fields you restore.

Open the file formstate-manual-script-partial.pdf. Follow the same steps as before. When you reopen the file you’ll see that only parts of the state are restored. This is accomplished by placing different scripts on different fields, and by not placing some scripts at all. For instance the form places the following script on the listbox to restore only the list items (it does not restore the color):

// this script restores the delta for the "items" (in XFA,
//  it's the <items> element) property of this listbox only.
// Ie the color is not restored but the items in the list are.

var oListDelta = this.getDelta("items");
oListDelta.restore();

You can use a similar script to restore only certain attributes of the field.

Technical Note: One important point here is that the script runs on the opening of the form when the formstate is being restored. The entire state of the form is always saved when the file is saved. But Acrobat/Reader will always check the script to restore only the parts of the form state that are specified. Why isn’t there a script to choose what part of the formstate to save? That wouldn’t be secure: A malicious person could intercept the form in transit, and inject additional information in the formstate before it reached its target. However if the script runs when the form is opened and state restored, then the script will ignore any section the author did not intend to be restored. Of course the security assurance works only if the form is certified, since certification ensures the integrity of the template, where the formstate restore script (which you implement) lives. Ie, the script which does the state restoration is covered by the certification, so we can be sure the script wasn’t tampered with.

Summary

The new formstate feature:

  • allows saving state in the form where that state is not bound to data — which is a good thing since you don’t necessarily want to “mess up” your data, which may need to comply to an XML schema, with formstate-related information.
  • has an automatic mode which just restores the entire state from the last time the file was saved.
  • has a manual restore mode, for added security. This manual mode:
    • is required if you plan on certifying your form
    • is made easier by the use of deltas
    • allows you to pick and choose exactly what parts of the formstate to restore.

Posted by Stefan Cameron on September 29th, 2008
Filed under Acrobat, Designer, Scripting, Tutorials, XFA
You can skip to the end and leave a response. Pinging is currently not allowed.

8 Responses to “Restoring the State of your Form”

  1. Jody on October 1st, 2008

    thanks very much for this! It happened to be the EXACT problem i was looking to solve when i cam to your site, and it was on the front page, no less. thank you again.

  2. Stefan Cameron on October 1st, 2008

    Jody,

    You’re very welcome. I’m glad you found it useful!

  3. Borja on October 14th, 2008

    Thanks! This article solve a problem I had. I’m a newbie in livecycle, and I found your blog really useful!

  4. E. Loralon on February 3rd, 2009

    This is wonderful article, which I am just discovering now and it has really helped me adjust some parts of my form that were not being restored when the form reopens.

    Thank you

  5. E. Loralon on March 30th, 2009

    Hi Stefan,

    Now I have come across a problem trying to restore a hidden on the master page of my dynamic form.

    Here is the scenario:

    I have on the master page of my form a hidden field, which gets visible when a check is on as desired by the form user. It shows works properly. After I fill the entire form, save it and close. When I re-open the same form only the fields on subform1 are restored and not those on the master page.

    How can I fix this problem?

  6. E. Loralon on March 31st, 2009

    Hi Stefan,

    Please help me with the below request. I am getting desperate.

    I am trying to do two things with a flowed form that I have.
    1) On a flowed form can I force to position a field in particular place at runtime?
    2) Is there a way to exclude an object placed on the master from being remerged or reset? I have a form with a data field on the master page, which gets reset every time the form reloads causing the said field to loose its data.

  7. Stefan Cameron on April 2nd, 2009

    E. Loralon,

    I looks like you asked the same question to John Brinkman and he has replied.

  8. E. Loralon on April 3rd, 2009

    Thank you very much Stefan,

    I was eagerly waiting for this answer.

Leave a Reply

Alternate Help: Unfortunately, I am not always able to keep track of older posts. Please feel free to continue discussions here or seek help at an Adobe Forum: Designer/Acrobat, Designer ES, Designer (v6-v8), XFA Forms, Acrobat, Reader.

If you're including scripts: To make sure your script and comment are properly interpreted, please make sure you replace any less-than ("<") characters with their character code equivalent: "&lt;" (without the quotes). Otherwise, your script and comment will inadvertently be cut short.