Posts in Category "Tutorials"

Connecting a Form to a Database

In response to “Lala”:http://blogs.adobe.com/formbuilder/2006/08/importing_data_in_acrobat_1.html#comment-28257 and “malik”:http://blogs.adobe.com/formbuilder/2006/08/importing_data_in_acrobat_1.html#comment-29712′s questions on connecting a form to a database (whether it’s Microsoft Access, MySQL, etc. doesn’t really matter), I decided to write a little tutorial on how to do it.

Even if you already know how to do it, I encourage you to *pay special attention* to the section on *Auto-Incremented Table Columns* because it might help you understand and resolve some of the issues you may have already run into.

Continue reading…

Making a Table of Contents

One of the hottest topics on the “Designer Forums”:http://www.adobeforums.com/cgi-bin/webx/.3bb7d189 these days seems to be methods by which one can add a table of contents to their form. Since there are many different ways to achieve this, I thought I would post a little sample to demonstrate how this can be done.

Of primary concern when adding a table of contents to your form is ensuring that the links provided to the form’s various pages/sections remain valid at all times. Static forms whose page set never changes don’t really need to worry about this but dynamic forms do. That is, regardless of whether content pages are added, re-ordered or even deleted from your dynamic form, you need to ensure that when a TOC link is clicked, the user is taken to the correct page pertaining to the topic they selected.

The best way of ensuring that TOC links don’t get broken as a result of changes to the form’s pages is by using layout information provided by the *XFA Layout Model*. This model provides information such as an object’s actual dimensions (width/height), the page on which it is located as well as a few other interesting pieces of information.

By using the

bc. xfa.layout.absPage

we’re able to get the page number on which an object is currently located, taking into account the various pages which may have been inserted or removed in-between the TOC page and the page in question. Taking that page number and assigning it to the

bc. xfa.host.currentPage

property then sets the current page to the one on which is located the object in quetsion.

“Download Sample [pdf]“:http://blogs.adobe.com/formbuilder/samples/TOCUsingXFALayoutModel.pdf

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

Continue reading…

Invalid Flashing Fields 2.0

A colleague of mine here at Adobe pointed-out today that the use of the AcroForm Document object’s _getField_ method wasn’t necessary in the script I used for my original “Invalid Flashing Fields”:http://blogs.adobe.com/formbuilder/2006/06/invalid_flashing_fields.html sample.

There’s an alternative which uses _xfa.form.resolveNode_ in the _app.setInterval_ script. _xfa.form.resolveNode_ takes a SOM Expression and returns a reference to an XFA node. What’s more is that this API call can be made from within the context of the “AcroForm”:http://blogs.adobe.com/formbuilder/2006/06/acroform_objects.html Scripting Object Model.

The _app.setInterval_ script therefore changes from this:

bc. moFlashTimerID = app.setInterval(
“var f = ==== this.getField(‘” +
GetAcroFormFieldName(oField) + “‘); ==
== ” +
“if (color.equal(f.fillColor, color.red))” +
“{ f.fillColor = [" + moAcroFieldFillColor.toString() + "]; }” +
“else” +
“{ f.fillColor = color.red; }”,
500);

to this:

bc. moFlashTimerID = app.setInterval(
“var f = ==== xfa.form.resolveNode(‘” +
oField.somExpression + “‘); ==
== ” +
“if (f.ui.oneOfChild.border.fill.color.value == ’255,0,0′)” +
“{ f.ui.oneOfChild.border.fill.color.value = ’232,232,232′; }” +
“else” +
“{ f.ui.oneOfChild.border.fill.color.value = ’255,0,0′; }”,
500);

Also note the changes in the way the color values are compared and assigned (whereby the newer version uses more familiar XFA script rather than the AcroForm script from the first version).

Since the use of the “AcroForm”:http://blogs.adobe.com/formbuilder/2006/06/acroform_objects.html Scripting Object Model should *always* be secondary to using the XFA Scripting Object Model (because AcroForm objects are, after all, in a separate Object Model which may change separately from the XFA Scripting Object Model), I wanted to highlight this alternative which makes more extensive use of the XFA Scripting Object Model than the first version did.

“Download Sample [pdf]“:http://blogs.adobe.com/formbuilder/samples/AcroFormObjects/InvalidFlashingFields-WithoutAFGetField.pdf

*Minimum Requirements:* Designer 7.1, Acrobat 7.0.5.

Tracking Mouse Clicks

I just recently received another “comment from Zack”:http://blogs.adobe.com/formbuilder/2006/08/autolocalizing_your_forms.html#comment-18302. This time, he was wondering about how one would go about tracking mouse clicks on an image field.

I had never attempted to do that so I took it on as a challenge and thought I would share the results in this post.

I knew from the start that XFA alone wasn’t going to be able to handle this simply because (to my knowledge) it doesn’t provide any information as to the position of the mouse pointer when an event occurs. The most logical place I thought would’ve provided the information — the _Event Pseudo Model_ (the xfa.event object available in all XFA events) — didn’t live up to my expectations. Thankfully, XFA at least provides a Click event so that I could know when the image got clicked.

The next logical place to look was in Acrobat’s Scripting Object Model (in the “AcroForm Objects”:http://blogs.adobe.com/formbuilder/2006/06/acroform_objects.html). In the Acrobat Document object, I found what I was looking for: the _mouseX_ and _mouseY_ properties which provided the location of the mouse with respect to the document window.

The last thing I needed was information about the dimensions and location (within the Acrobat Document Object’s coordinate space) of the image field and the Acrobat Field object’s _rect_ property would give me just that.

The combination of the XFA Click event, the Acrobat Document object’s mouseX and mouseY properties and the Field object’s rect property was just what I needed to get this to work.

Of course, I soon discovered that I had another problem to figure-out: The behaviour of an image field in a PDF form running in Acrobat is that when clicked, it opens a browse dialog that lets you pick the content for the field. Unfortunately, there isn’t any way to suppress that dialog other than making the image field read-only or by using a static image object but then both alternatives prevent the Click event from firing. So I needed some clever way to capture a mouse click over an image (whether it was a field or a static object) and I decided to use a button with a transparent fill and no border (so it was essentially transparent). Since buttons are fields just like image fields, the mouseX, mouseY and rect properties would still be available for the button and if I sized the button to fit the image and placed it over-top, I would essentially end-up with an HTML <map>.

“Download Sample [pdf]“:http://blogs.adobe.com/formbuilder/samples/AcroFormObjects/TrackingMouseClicks.pdf

*Minimum Requirements:* Designer 7.1, Acrobat 7.0.5.

Continue reading…

Auto-Localizing Your Forms

A few days ago, I posted about Designer 7.1′s new “Dynamic Properties”:http://blogs.adobe.com/formbuilder/2006/07/dynamic_properties.html feature. In that post, I explained how this feature could be used to automatically populate a list box or drop down list field with data from a data connection without having to write any script.

Today, I thought I would highlight one of the *main advantages* to using this feature: *localization* of your forms!

By using the Dynamic Properties feature to bind the caption of form fields to data nodes in a data connection, you can easily localize your forms *without having to write any script*!

To illustrate how this would work, I’ve designed a simple little form which has an address block on it (taken from the “Address Block” custom object that ships with Designer, found under the Custom tab in the Library palette). Each field in the address block (which excludes the “Locale” field at the top that’s just there for informational purposes) has its Caption property bound to a specific data node in the data connection I’ve defined, based on some different localized XML Data files. To localize the form at run-time (e.g. in Acrobat), just open the form and then load the XML Data file pertaining to the locale you want to use.

“Download Sample [zip]“:http://blogs.adobe.com/formbuilder/samples/DataBinding/AutoLocalizedForm.zip

*Minimum Requirements:* Designer 7.1, Acrobat Pro 7.0.5.

*Note:* If you open the form in Acrobat, don’t forget to load a data file into it by using the options under the “File | Form Data” menu.

Continue reading…

Dynamic Properties

Did you know that as of Designer *7.1*, there’s way to automatically populate certain field properties with data _without having to write any script_? This is what the new *Dynamic Properties* feature is designed to do.

First, you have to enable it because it’s disabled by default. You can do this by going to the Data Binding panel in the “Tools | Options” dialog. There, you’ll find a check box labeled, “Show Dynamic Properties”. Check the box and press OK. After doing so, put a list box (for example) on the form and take note of the changes in the Object palette’s Field, Value and Binding tabs.

You’ll notice that some property labels have now changed color (default is green) and are underlined. You can now click these property labels to make the properties they pertain to dynamic (i.e. to automatically push values into them when data is loaded into the form via a certain data connection that you specify). For instance, the Field tab now has dynamic _Caption_ and _List Items_ properties.

If you click on the List Items label, you’ll get the following dialog (this screen shot shows the properties already configured for this sample):

== ==

Using the Dynamic Property dialog (above), you can then specify the data connection from which the data will be loaded and also the data node(s) that will contain the data (in this case, for a list field, you can bind data nodes to the text and value items of the list).

“Download Sample [zip]“:http://blogs.adobe.com/formbuilder/samples/DataBinding/DynamicProperties.zip

*Minimum Requirements:* Designer 7.1, Acrobat Pro 7.0.5

*Note:* If you open the form in Acrobat, don’t forget to import the data into it using the “File | Form Data” menu.

Continue reading…

Demystifying IM.AddInstance

The definition for the Instance Manager’s addInstance method is as follows:

bc. addInstance( [BOOLEAN param] )

Personally, I find the word _param_ a little vague. I think it should be called _merge_ instead because that would give a clearer indication as to what it stands for: Essentially, if the data you’ve merged into your form has a repeating section that you’ve bound to a repeating (dynamic) subform and not all instances of this repeating data section have been merged into the form’s layout, you can control whether the new instance of the dynamic subform pertaining to that repeating data section will get merged with the next section or not by specifying _true_ (merge — the default) or _false_ (don’t merge — show empty instance) as the parameter value.

Usually, this doesn’t make a difference because you typically merge all instances of a repeating data section into your form and once there are no more data instances to merge, addInstance(true) will yield the same results as addInstance(false): an new empty (no data merged-in) instance.

Consider, however, the case where your form is a report and you’d like to show only a glimpse of the data instead of loading all 2000 instances of a repeating section. If your data was sorted from the most important to the least important, you could significantly *improve the performance* of your report (with respect to load time) by limiting the number of instances of that repeating data section that are initially merged into your form. Once your form is loaded, it could provide ways for the reader to get more instances if they wish to do so.

This can be achieved by using the Max property on the dynamic subform’s Binding tab in the Object palette along with addInstance([*true*]).

Here’s a sample which has a data connection to an XML Data File that lists movies. There are 16 movies in total but the form limits the number of movies initially displayed to 10 and provides a _Show More_ button. When this button is pressed, the movie dynamic subform’s Max count property, initially set to 10, is incremented by 1 and a new movie instance is added using _true_ as the parameter.

“Download Sample [zip]“:http://blogs.adobe.com/formbuilder/samples/im/AddInstanceTrueFalse.zip

*Minimum Requirements:* Designer 7.0, Acrobat 7.0.

*Note:* If you open the form in Acrobat, don’t forget to import the data into it using the “File | Form Data” menu.

Sorting Lists at Runtime

Have you ever needed to sort the content of a list box or drop down list at runtime (e.g. in a form loaded in PDF with Acrobat or HTML with a browser)?

Unfortunately, neither the XFA nor the AcroForm Object Models give you either properties or methods to achieve this functionality. The only thing available are Sort Ascending and Sort Descending buttons on the list of items you define in the Object palette’s Field tab in Designer — not very useful at runtime! Say you were loading data from an XML Data File into your form and this was populating a list with values that needed to be sorted: There wouldn’t be a built-in way for you to do that.

The only solution I’m aware of at this time is to flex your scripting muscles and write some functions that’ll get you sorting lists (from either list boxes or drop down lists) and that’s exactly what I did today while replying to a post on Adobe’s Designer Forums:

Download Sample [pdf]

Minimum Requirements: Designer 7.0, Acrobat 7.0.

Update: It looks like Acrobat 8.0 broke something that prevents my sample form from working correctly. It has to do with the call to

resolveNodes(“#items[*]“)

Fortunately, the bug will be fixed in Acrobat’s next release.

As a workaround, I would encourage you to have a look at the new list object properties and methods now available in Acrobat 8.0. You should be able to use a combination of those new properties/methods along with some of the original script in this sample in order to come-up with an update solution that works.

All the code is located in the script object appropriately named, “ScriptObject”.

The idea was to make use of the JavaScript Array object’s built-in sorting function, sort, by giving it a custom sorting function that was able to sort pairs of text and value items. Remember that for XFA choiceList fields, there’s always one <items save=”1”> node but there may be a second <items> node if text and value items are defined.

From Designer’s UI, you define value items by default by entering items in the list on the Object palette’s Field tab. This defines an <items save=”1”> node. If you then go to the Bindings tab and specify values, the items you specified on the Field tab become the “text” items, defined in the second <items> node, and the values are set in the <items save=”1”> node.

When sorting the list, it’s important to maintain the association between text and value item pairs and that’s why the script is a little complex — not to mention the fact that getting items out of an XFA choiceList field (list box or drop down list) isn’t as easy as 1-2-3 either!

So the script attempts to find text and/or value items, create ListItem objects for each pair, sort them using the custom sort function __SortFunction and then replaces the current items in the list with the ones in the sorted order.


Updated: April 11, 2007

Process All Fields

A common requirement on the “Adobe Designer Forums”:http://www.adobeforums.com/cgi-bin/webx/.3bb7d189/ is to find all fields on a form and do something specific with them.

For instance, you may want all mandatory fields to be automatically highlighted when a user attempts to submit a form electronically before having filled all mandatory fields. While Acrobat provides a button to toggle mandatory field highlighting on/off (via the _Highlight required fields_ check box in the yellow Form Field toolbar), Acrobat’s Scripting Object Model doesn’t provide a function to do the same. Therefore, you’re left having to write some script to achieve the same functionality.

Since this is requested so often, I thought I would try to put together some canned script that you can copy and paste into your form in order to instantly have the ability to make changes on everything that’s considered a field on your form.

“Download Script [js]“:http://blogs.adobe.com/formbuilder/samples/ProcessAllFields.js
“Download Sample [zip]“:http://blogs.adobe.com/formbuilder/samples/ProcessAllFields.zip

*Minimum Requirements:* Designer 7.0, Acrobat 7.0.

Continue reading…

Invalid Flashing Fields

So what’s the use of learning about new toys like “AcroForm Objects”:http://blogs.adobe.com/formbuilder/2006/06/acroform_objects.html and “AcroForm Field Name Generators”:http://blogs.adobe.com/formbuilder/2006/06/acroform_field_name_generator.html if you don’t take the time to play with them? Today felt like the right day to do just that and I came-up with a sample form where invalid fields flash red until the user has entered valid values into them. Only once all fields are valid can the form be submitted.

%{color:red} *Update:* Check-out the newer version on the new “Invalid Flashing Fields 2.0″:http://blogs.adobe.com/formbuilder/2006/08/invalid_flashing_fields_2.html post. %

“Download Sample [pdf]“:http://blogs.adobe.com/formbuilder/samples/AcroFormObjects/InvalidFlashingFields.pdf

*Minimum Requirements:* Designer 7.1, Acrobat 7.0.5.

*Note:* A basic understanding of “AcroForm Objects”:http://blogs.adobe.com/formbuilder/2006/06/acroform_objects.html is required for this sample.

Continue reading…