Instantiating Subforms at Runtime

Something that’s often desired, when working with dynamic forms, is to let the user specify, at run time (in Acrobat), how many lines of information are required to specify what they want.

The classic example is a Purchase Order form on which there are objects (usually buttons) which let you add and remove item lines from the section of the form which calculates the total cost of the order based on how many items are being ordered and the quantity and cost of each item.

In order to achieve this, the use of the *Instance Manager* is required. The Instance Manager is an object which exists only on _repeatable_ subforms (this could be a subform which is parented to a _flowed_ subform and set to repeat for each data item or it could be a row in a table — since rows and tables are, essentially, subforms). With this special object, you can modify the set of instances of a repeatable (dynamic) subform.


You can access the Instance Manager in two ways. The first is by accessing the object from the dynamic (repeatable) subform:bc.. // append a new instance of DynSubform within its parent containerDynSubform.instanceManager.addInstance(true);// ensure that the new instance is included in// subsequent calculationsxfa.form.recalculate(true);p. The second is by using the shortcut “underscore” syntax (note that this syntax is supported if the form is rendered to PDF):bc.. // remove the third instance (zero-based) of DynSubform_DynSubform.removeInstance(2);// work-around for Acrobat 7.x bug (reported) where number of// instances isn’t properly updated after calling removeInstancexfa.form.remerge();p. The drawback to using the first syntax is that there must always be at least one instance of the dynamic subform which exists. If you have a form which must initially not have any instances of a particular dynamic subform, then you need to use the second syntax with the underscore since that special object is always “available” to you regardless of the current number of instances of the dynamic subform in question.It’s also important to pay special attention to the minimum, maximum and initial number of instances of a dynamic subform. This is set on the Object palette’s Binding tab once you’ve specified that the subform is to _Repeat for Each Data Item_. The min and max limits must be repected at all times when using the Instance Manager. For example, if you set a min count of 1 and attempt to remove the last instance of a dynamic subform, an exception will be thrown which will result in a script error. You can check the current number of instances by using the Instance Manager’s _count_ property and compare it to, for example,bc.. // get the minimum number of instances that can be instantiated_DynSubform.minp. There are other things you can do with the Instance Manager such as setting the number of instances (using its _setInstance(int)_ method), move instances around (using its _moveInstance(int, int)_ method) etc. These are covered in detail in the “Adobe XML Form Object Model Reference”:http://www.adobe.com/devnet/livecycle/designing_forms.html (located in the XML section). Check-out the _Manipulating instances of a subform_ section on page 675.

8 Responses to Instantiating Subforms at Runtime

  1. Manuel says:

    Thanks! Your example form helped clear some questions I had. The LiveCycle Dev. Center is great, but your content here is definitely helpful.

  2. dave says:

    Where can I find help designing a form using a script to validate the date and apply the tax if the form is files after a certain day of the month. In other words, if it is past the 20th of the month, a 10% penalty is applied to the total.

  3. Dave,You can achieve this simply by using the following JavaScript code in the total field’s Calculate script:

    var oToday = new Date();if (oToday.getDate() > 20)  SubTotal.rawValue * 1.10;else  SubTotal.rawValue;

    where “SubTotal.rawValue” either retrieves the sub total of the order or is the summation equation itself.This script sets the Total field’s value to 10% more if the current day of the month is greater than the 20th.

  4. Iulia says:

    Hi Stefan,I have a question related to how we can save such a form (after it was filled by the user).If you design a form with Adobe Acrobat Professional there is a setting you can do to enable users to save the form (Advanced menu > Enable User Rights in Acrobat Reader). But since creating dynamic forms is only possible in LiveCycle Designer I cannot make the same setting and buying licenses of Acrobat Reader Extensions for all users is not an option.I tried to add a Submit button on the form which sends PDF (connected to an ASP.NET application). I click on it but nothing happens. I also tried to put a simple button which runs the following Javascript on mouse up:—– form1.#subform[0].Button1::mouseUp: – (JavaScript, client) ———————————–// Saving the form is done at the application level, so you need to invoke the// Acrobat app model.App.executeMenuItem(“SaveAs”); // The end user will be prompted to specify a// file name.// However, you must save the form silently if the form needs to be certified// and the certificate must be trusted for privileged JavaScript.var mydoc = event.target;mydoc.saveAs(); Nothing happens either.Can you tell me please if there is another solution? Please note I need to save the entire pdf, not only the data entered by the user.Thanks in advance,Iulia

  5. Iulia,The command you’re referring to (“Advanced | Enable Usage Rights in Adobe Reader”) in Acrobat Pro 8.0 can still be used with dynamic forms created in Designer (you can even use an earlier version of Designer like 7.1 if you wish).Simply create the form in Designer, save it as a Dynamic PDF form and open it in Acrobat Pro 8.0. That command will then be available to you and you’ll be able to save the form with Usage Rights enabled (e.g. data save) such that the user will be able to save the entire PDF along with the data using the Adobe Reader.

  6. Iulia says:

    Hi Stefan,You are so right! Thank you very much.I succeeded to save the form using the Acrobat Reader “Save” button, but I now have another question: I wanted to add a “Save” button to the form and when it is clicked to hide it and save the form (with the “Save” button hidden).For starters, I tried to put app.execMenuItem(“Save”) on the button click event but again, nothing happens.Can you shed some light on this, too? And can you indicate a help file or something similar to describe the pdf form structure objects (like xfa)?Thank you,Iulia

  7. Iulia says:

    Hi,Never mind about the help file; I found it on http://partners.adobe.com/public/developer/en/xml/Adobe_XML_Form_Object_Model_Reference.pdfHowever, the question related to adding a Save button to the form still remains.Many thanks,Iulia

  8. Iulia,Unfortunately, I don’t think you’ll be able to save the form silently using a button on a form.The problem with a silent save (i.e. just “save” instead of “save as”) is that it’s a security risk to the person using the form since they don’t know that it’s happening.You can, however, trigger a “save as” action from a button like this (in JavaScript only):

    app.execMenuItem(“SaveAs”);

    If you want to hide the save button prior to the save, you would just need to add this line prior to executing the menu item:

    this.presence = “invisible”;

    You can find more information on app.execMenuItem and its restrictions in the JavaScript for Acrobat API Reference, page 120.