Setting Acrobat form field properties

Javascript provides a large number of properties and methods for determining the appearance and associated actions of form fields. In this section you will learn what properties and methods are available, and how to write scripts that control the appearance and behavior of form fields.

The list of topics in this section is:

 

Field properties

A form field has certain properties that determines its appearance, printability, orientation, and the actions performed when the user interacts with it. Some properties are common to all form fields, while others are particular to certain types of fields. The properties of a field can be set not only through the UI, but also programmatically with JavaScript.

The most basic property of every form field is its name, which provides the reference necessary for subsequent access and modification. The key to setting the properties of a field is to first acquire the Field object of that field using its name; this is done using the getField method of the Doc object:

   var f = this.getField("myField");

The getField method takes as its argument the field name of the target field. The Field object can be obtained using other methods as well, for example, the addField method returns the Field object of the field it just created.

General properties that apply to all form fields include the display rectangle, border style, border line thickness, stroke color, orientation, background color, and tooltip. In addition, you can choose whether it should be read only, have the ability to scroll, and be visible on screen or in print.

There are also specific settings you can apply to text characteristics, button and icon size and position relationships, button appearance when pushed, check box and radio button glyph appearance, and the number and selection options for combo box and list box items.

All formatting options are listed and described in the following table.

Field properties

Property

Description

Field properties

display rectangle

Position and size of field on page.

rect

border style

Rectangle border appearance.

borderStyle

stroke color

Color of bounding rectangle.

strokeColor

border thickness

Width of the edge of the surrounding rectangle.

lineWidth

orientation

Rotation of field in 90-degree increments.

rotation

background color

Background color of field (gray, transparent, RGB, or CMYK).

fillColor

tooltip

Short description of field that appears on mouse-over.

userName

read only

Whether the user may change the field contents.

readonly

scrolling

Whether text fields may scroll.

doNotScroll

display

Whether visible or hidden on screen or in print.

display

text

Font, color, size, rich text, comb format, multiline, limit to number of characters, file selection format, or password format.

textFont, textColor, textSize, richText,
richValue, comb, multiline,
charLimit, fileSelect, password

text alignment

Text layout in text fields.

alignment

button alignment

Alignment of icon on button face.

buttonAlignX, buttonAlignY

button icon scaling

Relative scaling of an icon to fit inside a button face.

buttonFitBounds, buttonScaleHow, buttonScaleWhen

highlight mode

Appearance of a button when pushed.

highlight

glyph style

Glyph style for checkbox and radio buttons.

style

number of items

Number of items in a combo box or list box.

numItems

editable

Whether the user can type in a combo box.

editable

multiple selection

Whether multiple list box items may be selected.

multipleSelection

Button fields

We will begin by creating a button named myButton:

   var f = this.addField("myButton", "button", 0, [200, 250, 250, 400]);

In most cases, however, a form field, such as this button, is created through the UI.

If the field already exists, get the Field object as follows:

   var f = this.getField("myButton");

To create a blue border along the edges of its surrounding rectangle, we will set its strokeColor property:

   f.strokeColor = color.blue;

In addition, you can select from one of the following choices to specify its border style: solid (border.s), beveled (border.b), dashed (border.d), inset (border.i), or underline (border.u). In this case we will make the border appear beveled by setting its borderStyle property:

   f.borderStyle = border.b;

To set the line thickness (in points) of the border, set its lineWidth property:

   f.lineWidth = 1;

To set its background color to yellow, we will set its fillColor property:

   f.fillColor = color.yellow;

To specify the text that appears on the button, invoke its buttonSetCaption method:

   f.buttonSetCaption("Click Here");

You can set the text size, color, and font:

   f.textSize = 16;

   f.textColor = color.red;

   f.textFont = font.Times;

To create a tooltip that appears when the mouse hovers over the button, set its userName property:

   f.userName = "This is a button tooltip for myButton.";

In addition to the text, it is also possible to specify the relative positioning of the icon and text on the button’s face. In this case, we will set the layout so that the icon appears to the left of the text:

   f.buttonPosition = position.iconTextH;

To specify whether the button should be visible either on screen or when printing, set its display property:

   f.display = display.visible;

To set the button’s appearance in response to user interaction, set its highlight property to one of the following values: none (highlight.n), invert (highlight.i), push (highlight.p), or outline (highlight.o). In this example, we will specify that the button appears to be pushed:

   f.highlight = highlight.p;

It is possible to specify the scaling characteristics of the icon within the button face. You can determine when scaling takes place by setting the button’s buttonScaleWhen property to one of the following values: always (scaleWhen.always), never (scaleWhen.never), if the icon is too big (scaleWhen.tooBig), or if the icon is too small (scaleWhen.tooSmall). In this case, we will specify that the button always scales:

   f.buttonScaleWhen = scaleWhen.always;

You can also determine whether the scaling will be proportional by setting the buttonScaleHow property to one of the following values: buttonScaleHow.proportional or buttonScaleHow.anamorphic. In this case, we will specify that the button scales proportionally:

   f.buttonScaleHow = buttonScaleHow.proportional;

To guarantee that the icon scales within the bounds of the rectangular region for the button, set the buttonFitBounds property:

   f.buttonFitBounds = true;

You can specify the alignment characteristics of the icon by setting its buttonAlignX and buttonAlignY properties. This is done by specifying the percentage of the unused horizontal space from the left or the vertical space from the bottom that is distributed. A value of 50 would mean that 50 percent of the unused space would be distributed to the left or bottom of the icon (centered). We will center our icon in both dimensions:

   f.buttonAlignX = 50;

   f.buttonAlignY = 50;

Now that you have prepared the space within the button for the icon, you can import an icon into the document and place it within the button’s area. There are two methods for importing an icon for a button face and associating it with a button

      var retn = f.buttonImportIcon("/C/temp/myIcon.pdf");

      if ( retn != 0 ) app.alert("Icon not imported");

If the argument of buttonImportIcon is empty, the user is prompted to choose an icon. This approach works for Acrobat Reader.

      this.importIcon({

         cName: "myIconName", cDIPath: "/C/temp/myIcon.pdf", nPage: 0});

      var myIcon = this.getIcon("myIconName");

      f.buttonSetIcon(myIcon);

If the cDIPath parameter is specified, which is the case in this example, the importIcon method can only be executed in batch and console events; however, this restrictions can be bypassed using the techniques discussed in Executing privileged methods in a non-privileged context. When cDIPath is not specified, the script works for Acrobat Reader.

To rotate the button counterclockwise, set its rotation property:

   f.rotation = 90;

Finally, you will undoubtedly wish to associate an action to be executed when the button is clicked. You can do this by invoking the setAction method of the Field object, which requires a trigger (an indication of the type of mouse event) and an associated script. The possible triggers are MouseUp, MouseDown, MouseEnter, MouseExit, OnFocus, and OnBlur. The following code displays a greeting when the button is clicked:

   f.setAction("MouseUp", "app.alert('Hello');" );

Check box fields

The check box field supports many of the same properties as the button, and actions are handled in the same manner. The properties common to both form fields are:

In the case of textFont, however, the font is always set to Adobe Pi.

The style property of the Field object is used to set the appearance of the check symbol that appears when the user clicks in the check box. Permissible values of the style property are check (style.ch), cross (style.cr), diamond (style.di), circle (style.ci), star (style.st), and square (style.sq). For example, the following code causes a check to appear when the user clicks in the check box:

   f.style = style.ch;

The export value of the check box can be set using the exportValues property of the Field object. For example, the code below associates the export value "buy" with the check box:

   var f = this.getField("myCheckBox");

   f.exportValues=["buy"];

If there are several check box fields, you can indicate that one particular form field is always checked by default. To do this, you must do two things:

This process is shown in the following code:

   var f = this.getField("myCheckBox");

   f.defaultIsChecked(0); // 0 means that check box #0 is checked

   this.resetForm([f.name]);

Other useful Field methods are

Combo box fields

The combo box has the same properties as the button and check box fields. Its primary differences lie in its nature. Since the combo box maintains an item list in which the user may be allowed to enter custom text, it offers several properties that support its formatting options.

If you would like the user to be permitted to enter custom text, set the editable property of the Field object, as shown in the following code:

   var f = this.getField("myComboBox");

   f.editable = true;

You can specify whether the user’s custom text will be checked for spelling by setting its doNotSpellCheck property. The following code indicates that the spelling is not checked:

   f.doNotSpellCheck = true;

A combo box can interact with the user in one of two ways: either a selection automatically results in a response, or the user first makes their selection and then takes a subsequent action, such as clicking a Submit button.

In the first case, as soon as the user clicks on an item in the combo box, an action can automatically be triggered. If you would like to design your combo box this way, then set its commitOnSelChange property to true. Otherwise, set the value to false. The following code commits the selected value immediately:

   f.commitOnSelChange = true;

To set the export values for the combo box items, invoke its setItems method, which can be used to set both the face and export values. In this case, the face (or appearance) value (the value that appears in the combo box) is the first value in every pair, and the export value is the second. The following code results in the full state names appearing in the combo box (as the face or appearance values), and abbreviated state names as their corresponding export values:

   f.setItems( ["Ohio", "OH"], ["Oregon", "OR"], ["Arizona", "AZ"] );

In many cases, it is desirable to maintain a sorted collection of values in a combo box. In order to do this, you will need to write your own sorting script. Recall that the JavaScript Array object has a sort method that takes an optional argument which may be a comparison function.

This means that you must first define a compare function that accepts two parameters. The function must return a negative value when the first parameter is less than the second, 0 if the two parameters are equivalent, and a positive value if the first parameter is greater.

In the following example, we define a compare function that accepts two parameters, both of which are user/export value pairs, and compares their user values. For example, if the first parameter is ["Ohio", "OH"] and the second parameter is ["Arizona", "AZ"], the compare function returns 1, since "Ohio" is greater than "Arizona":

   function compare (a,b)

   {

      if (a[0] < b[0]) return -1; // index 0 means user value

      if (a[0] > b[0]) return 1;

      return 0;

   }

Create a temporary array of values and populate it with the user/export value pairs in your combo box field. The following code creates the array, iterates through the combo box items, and copies them into the array:

   var arr = new Array();

   var f = this.getField("myCombobox");

   for (var i = 0; i < f.numItems; i++)

      arr[i] = [f.getItemAt(i,false), f.getItemAt(i)];

At this point you can invoke the sort method of the Array object and replace the items in the combo box field:

   arr.sort(compare); // Sort the array using your compare method

   f.setItems(arr);

Responding to combo box changes

The Format tab of the Combo Box properties lists categories of formats available to combo box text. They are None, Number, Percentage, Date, Time, Special and Custom. For all formatting categories, except None and Custom, the JavaScript interpreter uses special formatting functions to properly process the text of a combo box; these functions are undocumented now, so comments here are focused on the None and Custom category.

If the formatting category is set to None, then processing the combo box is easy. Whereas the combo box does not process its own change in value, another form element can easily read the current setting of the combo box. For example, if the name of the combo box is myComboBox, then the following code gets the current value:

var f = this.getField("myComboBox");

var valueCombo = f.value;

The variable valueCombo contains the export value of the combo box. You cannot, by the way, get the face value, if the export value is different from the face value.

When the formatting category is set to Custom,    there are two types of formatting scripts, Custom Keystroke Script and Custom Format Script.

The Custom Keystroke Script has the following general form:

   if (event.willCommit) {

      // Script that is executed when the choice is committed

   } else {

      // Script that is executed when the choice changes, or, if the

      // combox box is editable, when text is typed in.

   }

With regard to the Custom Keystroke Script, there are three event properties that can be read: value, change and changeEx. To illustrate these event properties, let’s use the state combo box, defined above. Here is the Custom Keystroke Script:

   if (event.willCommit) {

      console.println("Keystroke: willCommit")

          console.println("event.value = " + event.value);

          console.println("event.change = " + event.change);

          console.println("event.changeEx = " + event.changeEx);

   } else {

          console.println("Keystroke: not Committed")

          console.println("event.value = " + event.value);

          console.println("event.change = " + event.change);

          console.println("event.changeEx = " + event.changeEx);

   }

The results of this script are listed below. Assume the combo box is set on a face value of "Arizona" and you change the combo box to read "Ohio". Additional comments are inserted.

// Select Ohio, but not committed. Note that the value of event.value is still

// set to "Arizona", but event.change is now set to the face value of the new

// choice, and event.changeEx is set to the export value of the new selection.

Keystroke: not Committed

event.value = Arizona

event.change = Ohio

event.changeEx = OH

 

// The choice is committed. Note that the value of event.value is now "Ohio"

// and that event.change and event.changeEx are empty.

Keystroke: willCommit

event.value = Ohio

event.change =

event.changeEx =

The only difference between the above sequence of events when f.commitOnSelChange=false versus f.commitOnSelChange=true is that in the first case, after the user makes a (new) choice from the combo box (and the “not committed” script is executed), the user must press the Enter key or click on a white area outside the field to commit the change, at this point, the "willCommit" script will execute. When f.commitOnSelChange=true, these two blocks of code will execute one after the other, with the “not committed” code executing first.

A combo box can also be editable. An editable combo box is one where the user is allowed to type in, or paste in, a selection. A combo box can be made editable by checking Allow User to Enter Custom Text in the Options tab of the Combo Box Properties dialog box. For JavaScript, the editable field property is used, as in the following example.

   var f = this.getField("myComboBox");

   f.editable = true;

The above output was captured in the console from a combo box that was not editable. The output is the same when the user selects one of the items in the combo box; when the user types in a selection, the output looks like this, assuming the user has already typed in the string "Te"and is now typing in "x":

/*

   Note that when the selection is not committed, event.changeEx is empty. You

   can test whether the user is typing in by using the conditional test

   if ( event.changeEx == "" ) {<type/paste in>} else {<select from list>}

   Note also that the value of event.value is "Te" and the value of

   event.change is "x"; the previous keystrokes and the current keystroke,

   respectively. When the user pastes text into the combo box, the length of

   event.change will be larger than one,

   if(event.change.length > 1 ) {<pasted text>} else {<typed text>}

*/

Keystroke: not Committed

event.value = Te

event.change = x

event.changeEx =

// ...Additional keystrokes to spell "Texas"

// Once committed, this output is the same as when the combo box is not

// editable.

Keystroke: willCommit

event.value = Texas

event.change =

event.changeEx =

Suppose now you want to make the combo box editable, and ask to user to pick a state from the pop-up combo box, or to type in a state. You want to format the state entered by the user so that the first letter is capitalized, and the rest are lower case.

The following script is used for the Custom Keystroke Script of the combo box:

   if (event.willCommit) {

      // Test to be sure there something more than white spaces.

      if ( event.rc = !( event.value.replace(/\s/g,"") == "" )) {

         // On commit, split event.value into an array, convert to lower case

         // and upper case for the first letter.

         var aStr = event.value.split(" ");

         for ( var i=0; i<aStr.length; i++){

            aStr[i] = aStr[i].charAt(0).toUpperCase()

               +aStr[i].substring(1,aStr[i].length).toLowerCase();

         }

         // Join the separate words together, and return as the new value.

         event.value = aStr.join(" ");

      }

      

   } else {

      // User is typing in something, make sure it is a letter or space

      var ch = event.change;

      if ( ch.length==1 )

      event.rc = (ch==" ") || (ch>="a" &&  ch<="z") || (ch>="A" && ch<="Z");

   }

Format the combo box so that is reads "State of Ohio", for example.

Custom format script:

   event.value =  "State of " + event.value;

If the user has pasted into the editable combo box, you can catch any non-letters or spaces with the validation script. A regular expression is used to see if there is something different from a letter or space.

Custom validation script:

   event.rc = !/[^a-zA-Z ]+/.test(event.value);

These various events, Keystroke, Format and Validate, define the rc property of the event object. In the above code, the event.rc is used to signal that the input is acceptable (true) or not acceptable (false). In this way, the input can be checked, validated, and formatted, or, at some stage, can be canceled by setting event.rc = false.

Full documentation of the objects used in the above sample script can be found in the JavaScript for Acrobat API Reference.

List box fields

A list box has many of the same properties as buttons and combo boxes, except for the fact that the user cannot enter custom text and, consequently, that spellchecking is not available.

However, the user can select multiple entries. To enable this feature, set its multipleSelection property to true, as shown in the code below:

   var f = this.getField("myListBox");         

   f.multipleSelection = true;

The List Box Properties dialog box has a Selection Change tab, this corresponds to the "Keystroke" trigger of the combo box or text field. To enter script to process a change in the status of the list box, you can either use the UI, or you can install your script, like so,

   f.setAction( "Keystroke", "myListboxJavascript();" );

In the above, the action is to simply call a JavaScript function, defined, perhaps, as document JavaScript.

The manner in which you process a selection change is the same as the combo box, with one exception.

// Note that unlike the combo box, the value of event.value is the export value

// of the field, not the face value as it is with the combo box.

Keystroke: not committed

event.value = FL

event.change = Arizona

event.changeEx = AZ

// When we commit, the value of event.value is the face value, not the export

// value.

Keystroke: willCommit

event.value = Arizona

event.change =

event.changeEx =

You can allow the user to make multiple selections from a list box by checking the Multiple Selection check box    in the Options tab of the List Box Properties dialog box, or you can make this selection using JavaScript:

   var f = this.getField("myListBox");

   f.multipleSelection=true;

It is not possible to detect multiple selection using a Selection Change script; however, multiple selection can be detected from another form field, such as a button. To get and set multiple values of the list box, use the currentValueIndices property of the Field object. The following example illustrates the techniques.

This example accesses the list box which allows multiple selections. It simply reads the current value and reports to the console. When the current value of the list box is a single selection, currentValueIndices returns a number type (the index of the item selected); when there are multiple selections, currentValueIndices returns an array of indices.

   var f = this.getField("myListBox");

   var a = f.currentValueIndices;

   if (typeof a == "number") // A single selection

      console.println("Selection: " + f.getItemAt(a, false));

   else {// Multiple selections

      console.println("Selection:");

      for (var i = 0; i < a.length; i ++)

         console.println(" " + f.getItemAt(a[i], false));

   }

The field method getItemAt is used to get the face values of the list, using the index value returned by currentValueIndices.

Other relevant field properties and methods not mentioned in this section are numItems, insertItemAt, deleteItemAt and setItems. The JavaScript for Acrobat API Reference documents all these methods and supplies many informative examples.

Radio button fields

The unique nature of radio buttons is that they are always created in sets, and represent a collection of mutually exclusive choices. This means that when you create a set of radio buttons, you must give all of them identical names with possibly different export values.

The behavior of the radio buttons depends on several factors, whether or not there are two or more members of the same radio set that have the same export value, and whether or not the item Buttons With the Same Name and Value are Selected in Unison is checked in the Options tab of the Radio Button Properties dialog box. (The latter can be set by JavaScript using the radiosInUnison field property.) The differences are illustrated in the discussion below.

You have four radio buttons all in the same group (all having the same name of "myRadio"):

   var f = this.getField("myRadio");

Suppose the export values are export0, export1, export2, and export3. This is the simplest case, all choices are mutually exclusive; the behavior does not depend on whether Buttons With the Same Name and Value are Selected in Unison is checked.

Now suppose the export values of the four radio buttons are export0, export1, export2, and export2. If f.radiosInUnison=false, the four buttons behave as in the simplest case above. If f.radiosInUnison=true, then there are only three mutually exclusive buttons; clicking either of the two radios with export value export2 will select both of them, while clicking the radio button with export value of export0 will select only that button.

This example illustrates how you can programmatically access the individual radio buttons in the same radio group (all having the same name). Assume the command name is myRadio and there are four widgets in the field.

   var f = this.getField("myRadio");

   // Get the second widget, change its appearance and add an action

   var g = this.getField(f.name+".1");

   g.strokeColor = color.red;

   g.setAction("MouseUp",

      "app.alert('Export value is ' + this.getField('myRadio').value)");

Some properties of the Field object, such as value, apply to all widgets that are children of that field. Other properties, such as strokeColor and setAction, are specific to individual widgets. See the section on the Field object in the JavaScript for Acrobat API Reference for a complete list of Field properties accessible at the widget level.

Sometimes the number of widgets in a radio button field is unknown. The code below counts the number of widgets.

   var f = this.getField("myRadio")

   var nWidgets=0;

   while(true) {

      if ( this.getField(f.name + "." + nWidgets) == null ) break;

          nWidgets++;

   }

   console.println("There are " + nWidgets + " widgets in this radio field");

Signature fields

Signature fields have the usual properties, as listed under the General and Appearance tabs of the Digital Signature Properties dialog box. These can be set in the standard way, by the UI or through JavaScript, as in this example:

   var f = this.getField("Signature1”);

   f.strokeColor = color.black;

When the signature field is signed, you may want to execute some script in response to this event. The script can be entered through the Signed tab of the Digital Signature Properties dialog box, or through the setAction method of the Field object.

You can set the action of a signature field by invoking its setAction method and passing in the Format trigger name as the first parameter. When the user signs the form, you can reformat other form fields with the script you pass in to the setAction method.

Once a document is signed, you may wish to lock certain form fields within the document. You can do so by creating a script containing a call to the signature field’s setLock method and passing that script as the second parameter to the signature field’s setAction method.

The setLock method requires a Lock object, which you will obtain by invoking the form field’s getLock method. Once you obtain the Lock object, set its action and fields properties. The action property can be set to one of 3 values: "All" (lock all fields), "Exclude" (lock all fields except for these), or "Include" (lock only these fields). The fields property is an array of fields.

For example, suppose you created a signature and would like to lock the form field whose name is myField after the user signs the document. The following code would lock myField:

   var f = this.getField("Signature1");

   var oLock = f.getLock();

   oLock.action = "Include";

   oLock.fields = new Array("myField");

   f.setLock(oLock);

To actually sign a document, you must do two things: choose a security handler, and then invoke the signature field’s signatureSign method. The following code is an example of how to choose a handler and actually sign the document:

   var f = this.getField("Signature1");   

   var ppklite = security.getHandler("Adobe.PPKLite");

   var oParams = {

      cPassword: "myPassword",

      cDIPath: "/C/signatures/myName.pfx" // Digital signature profile

   };

   ppklite.login(oParams);

   f.signatureSign(ppklite,

      {

         password: "myPassword",

         location: "San Jose, CA",

         reason: "I am approving this document",

         contactInfo: "userName@example.com",

         appearance: "Fancy"

      }

   ); //End of signature

   ppklite.logout()

Text fields

The text field has many of the same properties as buttons and combo boxes. In addition, it offers the following specialized properties shown in the following table. (The table assumes that f is the field object of a text field.)

Text field properties

Property

Description

Example

alignment

Justify text

f.alignment = "center";

charLimit

Limit on number of characters in area

f.charLimit = 40;

comb

Comb of characters subject to limitation set by charLimit 

f.comb = true;

defaultValue

Set a default text string

f.defaultValue = "Name: ";

doNotScroll

Permit scrolling of long text

f.doNotScroll = true;

doNotSpellCheck

Set spell checking

f.doNotSpellCheck = true;

fileSelect

Format field as a file path

f.fileSelect = true;

multiline

Allow multiple lines in the area

f.multiline = true;

password

Use special formatting to protect the user’s password

f.password = true;

richText

Set rich text formatting

f.richText = true;

When the user enters data into a text field, the usual event object can be queried to process the keystrokes, the behavior is similar to the combo box. In the output below, assume the user has already typed in the "Te" and types in the letter "x":

// The value of event.value is the current text in text field, event.change has

// the current keystroke. Note that event.changeEx is always empty, and is not

// relevant to the text field.

Keystroke: not Committed

event.value = Te

event.change = x

event.changeEx =

 

Keystroke: willCommit

event.value = Texas

event.change =

event.changeEx =

Use the Custom Keystroke Script to intercept user keystrokes and process them. For example, the following script changes all input to upper case:

Custom Keystroke Script:

if (!event.willCommit) event.change = event.change.toUpperCase();

Validation scripts

You can enforce valid ranges, values, or characters entered in form fields. The main reason to use validation is to ensure that users are only permitted to enter valid data into a form field. Validation is used whenever the user enters text into a form field, for text fields and for editable combo boxes.

Enter the validation script through the Validation tab of the Text Field Properties dialog box, or through the setAction method of the Field object. In the latter case, pass Validate as the first parameter, as follows:

   var f = this.getField("myText");

   f.setAction("Validate", "myValidateRange(true, -1, true, 5)");

Normally, however, such a script is entered through the UI.

This is a simple example of a Custom Keystroke Script for inputting a number, and a simple validation script for checking the range of the number.

Custom Keyboard Script:

   if ( event.willCommit ) {

      var value = ""+event.value.replace(/\s*/g,"");

      if ( value != "" ) {

         if (!isFinite(value)) {

            app.beep(0);

                event.rc = false;

         }

      }

   } else

      if ( event.change == " " ) event.change = "";

A representative Custom Validation Script is

      myValidateRange(true, -1, true, 5);

which checks whether the value entered is strictly between -1 and 5. The validation script calls the following document JavaScript:

   function myRangeCheck(bGreater, nGreater, bLess, nLess)

   {

          value = event.value;

          if ( bGreater && ( value <= nGreater ) ) {

         app.alert("Value must be greater than " + nGreater);

                 app.beep();

                 event.rc = false;

                 return;

      }

      if ( bLess && ( value >= nLess ) ) {

         app.alert("Value must be less than " + nLess);

                 app.beep();

                 event.rc = false;

                 return;       

          }

   }

Calculation script

Calculation options make it possible to automate mathematical calculations associated with form fields. To apply a calculation to a form field action, enter the script through the Calculate tab of the Text Field Properties dialog box. On this tab there are three options:

1.The value is the sum(+)/product(x), average/minimum/maximum of a specified collection of fields.

2.The value is the result of simplified field notation.

3.The value is the result of a Custom Calculation Script.

Options (1) and (2) are entered through the UI, option (3) is entered through the UI or through the setAction method of the Field object. If you use the setAction method, pass "Calculate" as the first parameter, and pass a script containing a call to a calculation script as the second parameter.

The calculation script makes all necessary calculations, perhaps drawing values from other text fields, then reports the calculated value to the field by setting event.value.

The script presented here calculates the average of several text fields. If one of the fields has no value, it is not figured into the average. The example assumes all fields require a number for their value.

The following script is entered as a custom calculation script:

   var aNumFields = new Array("Text1.0", "Text1.1", "Text1.2","Text1.3",
      "Text1.4");

   myAverageFunction(aNumFields);

The script above simply calls the myAverageFunction, it is this function that calculates the average of the array of fields passed as its argument, and sets event.value. The function is placed in the document as document JavaScript.

   function myAverageFunction(aNumFields)

   {

      // n = number of fields that have a numerical value

      var n=0, sum = 0;

          for ( var i=0; i<aNumFields.length; i++) {

         var v = this.getField(aNumFields[i]).value;

                    if ( v != "" ) {

                           n++;

                           sum += v;

                    }

          }

      if ( n == 0 ) event.value = "";

          else event.value = sum/n;    

   }