Posts in Category "Scripting"

Expanding to Fit the Entire Value

A while ago, I posted an article detailing a trick to make the value of a field be displayed entirely within the field’s content area. Essentially, by setting the value font size to zero, this tells Acrobat to shrink the field’s content area (value) font at will to make the entire value entered fit horizontally. This can certainly be useful but there’s one significant drawback: the value font may shrink such that it becomes too small for anyone to read depending on how much data the user enters into the field.

Fortunately, there’s an alternative method to making a value fit within a field’s content area when you don’t know how long the value will be: Making the field’s width and/or height expandable!

The advantage of this solution is that the value font’s size remains constant (the same as which you specified it to be when you designed the form). When a field is make expandable, its "w" (width) and/or "h" (height) attributes are replaced by "minW" (minimum width) and/or "minH" (minimum height) attributes, respectively. These attributes define the initial and minimum size of the entire field (that is, its caption and content areas combined). When the width is extended, however, only the field’s content area is increased in width. Its caption area remains the same width. On the other hand, causing the height of a field’s content area to be extended will also cause the caption area’s height to be extended.

Making a Field Expandable

Specifying that a field’s width and/or height is to expand to fit its content is quite simple: You just need to check the "Expand to fit" check box that pertains to the width and/or height property on the Layout palette.

Getting a Tight Fit

So far, you’ve learned how to make a field’s width and/or height expandable, essentially by specify a minimum width and/or height instead of a set width and/or height. Now what if you wanted to ensure that the field’s width and/or height was always just wide enough to contain whatever value was entered? For example, you don’t want a whole bunch of empty space if you set a minimum width of 2 inches to have a nice initial size to enter a value into the field but the user only entered a value that required 1 inch to be entirely displayed.

In that case, you could simply set the minimum width to zero when the user leaves the field, if they’ve entered a value. This is done by scripting the field’s Exit event (shown here in FormCalc):

$.minW = "0"

Look-out for Long Values!

One thing you have to look-out for is extra long values — especially if you haven’t specified a maximum length for the field. If the user enters too much data, the field might simply run off the page.

If you don’t want to set a maximum data length for the field but you don’t want it to expand beyond a certain width, you can set a maximum width and/or height. Since Designer’s UI doesn’t let you set this property directly, you can use the field’s Initialize script to set it (shown here in JavaScript):

this.maxW = "4.5in"; // max width of 4.5 inches

Note, however, that if the user enters more data than can fit within the specified maximum dimensions, the value will be cut-off and won’t print so you may consider setting a maximum data length or resorting to the previous solution (setting the font size to zero).

Sample

This sample form implements the solution I’ve described in this post.

Download Sample [pdf]

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

Scripting Table Columns

A few days ago, Sergio, one of my regular commenters, posted a question about programmatically adding new columns to a table. My reply to his comment quickly turned into something that I thought should be promoted to a blog post so here it is.

This question required some investigation because it led me to the discovery of a bug related to adding/removing instances of a table column in a form viewed in a version of Acrobat prior to 8.0. More on that later in this post.

The short answer to Sergio’s question is that yes, in fact, you can modify the set of columns in a table programmatically at runtime. You can do this by either using the presence attribute — although this isn’t recommended because it can lead to data merging problems — or you can use Instance Managers to do it, which is the recommended method to use.

Here’s a sample form that contains a table with a “repeatable column”. Using the add and remove buttons that are provided, you can add and remove instances of the 3rd column.

Download Sample [pdf]

Minimum Requirements: Designer 7.1, Acrobat 7.0.5.

Continue reading…

Using URL Requests in PDF Forms

Here’s a sample in response to “Ernest’s question”:http://blogs.adobe.com/formbuilder/2006/09/selecting_specific_database_records.html#comment-49371 on passing values to PDF forms via URL. His intent is to use it to provide a key to a PDF form such that it can be used to filter records from an “ODBC Data Connection”:http://blogs.adobe.com/formbuilder/2006/09/selecting_specific_database_records.html in order to pre-populate the form with data.

I love these kinds of questions because they challenge me to find answers!

Of course, this is quite specific but there are many other uses for this. In fact, you could have a whole lot of fun with it too! You could even use this to alter the appearance of your form: Say you had one form that you were using for multiple departments in your company and every department had its own header. You could place each header in a subform, make them all hidden and then, based on the URL request which would include a department code, decide which one to show — no XML Data file, database connection or web service needed!

Beware, however, that URL request strings are *not secure* because they get posted in plain text for anyone to read so be careful of the information you pass-in to your form this way.

This sample form looks for a “message” and a “color” key in the URL request in order to show a message in a text field and change the text field content area’s color (an RGB value). For example:

* == //URLRequests.pdf?message=Isn’t%20this%20cool%3F == — Shows the message “Isn’t this cool?” in the text field.
* “//URLRequests.pdf?message=Think%20of%20the%20possibilities…&color=0%2C255%2C0″:http://blogs.adobe.com/formbuilder/samples/URLRequests.pdf?message=Think%20of%20the%20possibilities…&color=0%2C255%2C0 — Shows the message “Think of the possibilities…” in the text field and makes the text field green.

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

*Minimum Requirements:* Designer 7.0, Acrobat 7.0.

Continue reading…

Displaying All Records from an ODBC Data Connection

So far, I’ve covered two ways of connecting forms to ODBC data sources:

# “Connecting a Form to a Database”:http://blogs.adobe.com/formbuilder/2006/09/connecting_a_form_to_a_database.html — explains how to design a form which lets the user iterate through each record one at a time; and
# “Selecting Specific Database Records”:http://blogs.adobe.com/formbuilder/2006/09/selecting_specific_database_records.html — takes the first tutorial one step further by providing a means to specify which record(s) to view.

This time, in response to “Y. Gautham’s recent comments”:http://blogs.adobe.com/formbuilder/2006/08/importing_data_in_acrobat.html#comment-39853, I’ve decided to post a little tutorial on *displaying all records* from an ODBC data connection for reporting purposes (as opposed to editing).

Continue reading…

FormCalc Expressions (Foreach)

A couple of weeks ago, I started a series of posts on FormCalc Expressions. The first ones I convered were the “If and For expressions”:http://blogs.adobe.com/formbuilder/2006/09/formcalc_expressions_if_and_for.html. This time, I thought I would explain the Foreach expression.

Continue reading…

Selecting Specific Database Records

Every now and then, someone posts a comment with a question on how to do something and the answer requires more than just a quick response. In this case, it was “Ricardo’s question”:http://blogs.adobe.com/formbuilder/2006/09/connecting_a_form_to_a_database.html#comment-34179 on how to select a specific record from a data connection to a database for editing in a form.

If you read my previous post on “Connecting a Form to a Database”:http://blogs.adobe.com/formbuilder/2006/09/connecting_a_form_to_a_database.html, you might’ve realized that the result was a single live data connection to the entire set of records in a database. This is great if you want to iterate through all records one at a time and update them on an individual basis. You might’ve also realized that you could narrow the scope of the data connection by specifying a more specific SQL statement (with a _WHERE_ clause, for example). But what if you wanted the form to filter, on the spot, the data loaded from the data connection? For example, you might want to let the user pick from the different movie categories (action, comedy or drama) and then let them iterate through only that subset of the Movie Database.

If you’ve been scratching your elbow, pinching your nose and blinking your eyes in hopes that this might “just work”, well, it’s actually scratch your nose, pinch your elbow and roll your eyes — ok, just kidding…

Continue reading…

Getting a List’s New Selection

Have you ever struggled to figure-out what item from a list (list box or drop down list) a user had just selected in the list’s Change event? If so, it’s possible you were trying to use the

bc. rawValue

property in order to get at this information.

Unlike other objects such as exclusion groups, the _rawValue_ property of a list object doesn’t reflect the new selection until the selected value is committed to it (by the user tabbing or clicking away from the list). That means that if you’re trying to, say, make a certain field visible at the moment when a particular item in the list is selected, you can’t use the _rawValue_ property because it still contains the _old_ (previous selection) value.

Instead, you must use the

bc. xfa.event.newText

object/property of the Change event itself and possibly the list object’s

bc. boundItem

function in order to determine the _value_ associated with the new selection.

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…

Complex Validations

A couple of days ago, Michael Ramirez “asked me”:http://blogs.adobe.com/formbuilder/2006/08/invalid_flashing_fields_2.html#comments how to do complex validations on forms. He asked how one could have a validation as follows: Given 3 text fields A, B and C and a check box E, A is mandatory only if B and C are filled or if E is checked. I thought this would make a great little sample of both complex validation scripts and what I like to call the “Two Button Submit” technique.

“Download Sample [pdf]”:http://blogs.adobe.com/formbuilder/samples/ComplexValidations.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.