Lotus Forms Viewer - 4.0

First Edition

Published December 2010

About this edition

Printing

When you print this document some of the style elements are removed to create a better print output. Here are a few tips about printing:
  • The document length may exceed the browser's print capability. Microsoft Internet Explorer has demonstrated the ability to print large files successfully.
  • This document is long. Use print preview to determine the printed page length.
  • You can highlight section of the document and then choose to only print the selected content

Working offline

You can save a local copy of this document from your browser. Each browser has different menus and menu options. Consult the browser help if you need assistance saving the document locally.

Submitting feedback

If you would like to provide feedback about this document, see the Lotus Documentation Feedback Web site.

IBM Lotus Forms Viewer overview

The IBM® Lotus® Forms Viewer provides a single interface for users to open, fill out, and save forms.

The Viewer can display forms within its own window (standalone) or within your Web browser. In either case, all Viewer functionality is available.

What's new in the IBM Lotus Forms Viewer

The new features for the Viewer 4.0 are listed below.

New features for the Viewer include:
  • XFDL 8.0 - Forms using XFDL 8.0 are supported.
  • Button and Text Label gradients - Gradients in buttons and text labels are displayed.
  • Interactive state appearance - Button color luminance is adjusted based on the button's state, such as when it has focus, when it has been pressed, or when the mouse hovers over it.
  • Modal dialogs - The Viewer allows you to open an external HTML page within a form, and stores the results of any interactions in the external HTML page in the form.
  • Rich Text - Rich text items are now supported

Viewer accessibility

This section describes the available accessibility features for the IBM Lotus Forms Viewer.

Using a screen reader

The Viewer supports screen readers through the MSAA (Microsoft® Active Accessibility) standard. Through this standard, the Viewer works with the JAWS screen reader from Freedom Scientific, as well as other MSAA-compliant readers, such as Window-Eyes from GW Micro and Microsoft Narrator.

Each item in a form can have an accessibility-specific message associated with it. When a screen reader is active, the Viewer checks items for these messages as each item receives the focus. The Viewer then passes the message to the screen reader, which reads the message aloud for the user, along with some general information about the item.

If a form does not have any accessibility-specific messages, the screen reader still reads general information about each item, but this information may not be clear to the user.

The Viewer automatically activates screen reader support when an MSAA-compliant screen reader is running.

Note: If you are using a release of JAWS 5.0 prior to build 813, JAWS will not work properly when the Viewer is embedded in a browser. To correct this problem, we recommend upgrading to a later version of JAWS.

Using the enhanced focus indicator

The enhanced focus indicator makes it easier to see which item has the focus by drawing a small, black square near the top-left corner of the item. This enhancement appears in addition to the regular focus indicator, which normally outlines an item or places the cursor inside an item.

To enable the enhanced focus indicator:

  1. Open a form in the Viewer.
  2. Click Preferences The Preferences icon is shown as a small square containing a blue dot above a red dot. The Preferences form opens to the Basic Preferences.
  3. Beside Accessibility Configuration, select Use Enhanced Focus Indicator.
  4. Click Save to close the Preferences form and save your changes.

Using the operating system colors

You can set the Viewer to use the operating system colors rather than the colors defined by the form itself. This is useful if you have set your operating system colors to provide a higher contrast than normal.

To make the Viewer use the operating system colors:
  1. Open a form in the Viewer.
  2. Click Preferences The Preferences icon is shown as a small square containing a blue dot above a red dot..
    • The Preferences form opens to the Basic Preferences.
  3. Beside Accessibility Configuration, select Use Operating System Colors.
  4. Click Save.

Before this setting will take effect, you must first close and then reopen the Viewer.

Viewer release notes

The release notes provide a summary of new features and improvements, and descriptions of known limitations, problems, and workarounds.

About this release New features and improvements What's new in the IBM Lotus Forms Viewer
Migration, upgrade, and configuration information System requirements, backward compatibility information Viewer system requirements
Known limitations, problems, and workaround Troubleshooting Troubleshooting and support
Limitations, problems, and workarounds Viewer technotes and flashes
Contacting customer support Customer support Lotus Forms Support web page

Using the Viewer

This section contains two reference cards which provide information on keyboard shortcuts and accessibility options.

IBM Lotus Forms Viewer keyboard commands

This reference card provides a list of Viewer keyboard commands used to navigate a form without the use of a mouse.

Table 1. Filling out a form
Tab Moves focus forward from item to item in the form.
Shift + Tab Moves focus backward from item to item in the form.
Enter Activates a button or field in the form.
Space Selects a check box or radio button, or displays the contents of a dropdown list. In an open dropdown list, pressing SPACE selects the highlighted choice and closes the list.
Arrow keys Pressing the LEFT or RIGHT arrow keys moves the cursor between letters in a field. In a dropdown list, pressing the DOWN arrow key displays the contents of the list. Use the DOWN and UP arrows to move through the list of choices.
Table 2. Controlling the Viewer
Alt + F1 Opens Viewer Help.
Alt + F7 Spell checks the selected item.
Alt + F12 Opens the Preferences window.
Alt + Space Opens the context menu, which allows resizing or closing of the Viewer's window.
 
Ctrl +A Selects all from a text field.
Ctrl + B Turns bold typeface in a rich text field on or off.
Ctrl + C Copies from a text field.
Ctrl + F Opens the font dialog in a rich text field.
Ctrl + G Opens the paragraph dialog in a rich text field.
Ctrl + H Toggles the Viewer 's help mode which displays any context-sensitive help messages in the form.
Ctrl + I Turns italic typeface in a rich text field on or off.
Ctrl + M E-mails the form.
Ctrl + O Opens a form.
Ctrl + P Prints the form.
Ctrl + S Saves the form.
Ctrl + U Turns underline typeface in a rich text field on or off.
Ctrl + V Pastes into a text field.
 
Ctrl + Shift + S Save as.
Ctrl + Shift + Plus (+) Increases zoom.
Ctrl + Shift + Minus (-) Decreases zoom.

IBM Lotus Forms Viewer preferences

This reference card provides descriptions of the Viewer preferences available for modification.

Table 3. Basic settings
WWW Browser Configuration  
Online The computer is connected to a network and will submit forms when "Submit" is clicked.
Online with Backup The computer is connected to a network and will save a backup copy of the last form submitted.
Offline The computer is not connected to a network. A save prompt appears when the "Submit" is clicked.
Accessibility Configuration  
Use Enhanced Focus Indicator A small, black square is drawn near the top-left corner of the item that currently has focus. This square appears in addition to the normal focus indicators, making it easier to see which item has focus.
Use Operating System Colors The Viewer uses the operating system colors, such as high contrast, when drawing a form rather than the colors specified in the form itself.
Table 4. Input options
Type Checking Options  
Do Predictive Input Checking The Viewer checks for errors, and underlines them as words are typed.
Date Format This setting determines how the Viewer interprets numeric dates. For example, 02/03/2009 may be interpreted as either February 3, 2009 or March 2, 2009. Setting the Date Format ensures the Viewer correctly identifies potentially confusing dates.
Tabbing Options – Pressing the Tab key twice moves the focus from an item with invalid information, or missing mandatory information. Regardless of selected Tab options, focus can be moved by using the mouse.  
Stop Tab from Invalid Input Items When enabled, the Tab key does not move focus away from invalid input items.
Stop Tab from Empty Mandatory Items When enabled, the Tab key does not move focus away from empty mandatory items.
Smartfill – Smartfill records frequently used information, then automatically inserts the information in Smartfill-enabled forms.  
Enable Smartfill When enabled, Smartfill prompts users to save applicable data. In a Smartfill-enabled form, the user is asked whether or not the saved data should be used to fill in the form.
Table 5. Print options
Conversion Options  
Print Radio Buttons as Check Boxes Prints radio buttons as check boxes. This creates visual consistency in the printed form, with all choices appearing uniformly as check boxes.
Print Radio Buttons without Values Prints all radio buttons in a group as blank choices.
Print Scroll Bars on Fields Prints the scroll bars as they appear beside text fields.
Print Single Line Fields as Lines Prints a blank line instead of printing a single line field as an empty rectangle.
Print Border Around Form Page Visually frames the form by printing a border around the form.
Page Layout Defaults  
Fit to One Page (expand or shrink) Prints the form page on a single piece of paper. This option scales the form up or down so it fits on a single page, covering as much of the page as possible.
Shrink to One Page Prints the form page on a single piece of paper. This option scales the form down so that it will fit on a single page. If the form already fits on a single page, it is not scaled.
Tile in One Direction Prints the form on multiple pages in the longer dimension (either horizontal or vertical). This option scales the form so that the smaller dimension fits on a single page if necessary.
Tile in Two Directions Prints the form on multiple pages in both dimensions. This option prints the form in its true size.
Miscellaneous Options  
Print each page as separate print job Prints each form page as a separate print job rather than grouping all the pages of a form into a single print job. Only select this option if the printer does not have enough memory to print a large form.
Print black and white (excluding images) Prints the form in black and white only. Select this option if the printer has difficulty representing the form's colors in color. Typical symptoms include: getting black boxes where the text should be; text not showing up; or whiteness appearing around the text of transparent labels.
Table 6. Advanced settings
Form Appearance Options  
Show Boundary on All Form Items Draws a boundary line around the edges of all visible form items. This option should be turned off except when designing the layout of a form.
Use "X" Style Check Boxes By default, check boxes are drawn as a three-dimensional box with a red check mark when selected. Using "X" style check boxes draws a two-dimensional box with a black "X" when selected.
Scroll Fields on Zoom Provides access to complete text by adding scroll bars to zoomed fields. This does not change the amount of text that can be entered into the field. Note that this setting may be overridden by individual forms.
Viewer Language  
Locale Determines what language used by the Viewer. This feature does not translate forms, but ensures that all elements of the Viewer are displayed in the chosen language.
Security Options  
Digital Certificate Identity Filter Filters the list of available digital certificates. The value can be any part of a valid signing identity, such as an email address or first name. All certificates that match the entered value will be available. For example, if you entered, "Bob", all certificates with the name Bob in the signing identity are made available. Select this option only if there are digital certificates installed on the computer that should remain inaccessible.
Check CRL Distribution Points Certificate Revocation Lists (CRLs) contain the names of digital certificates that are no longer valid. When a form is signed, the Viewer checks its locally stored CRLs to verify the certificate is valid. Select this check box to have the Viewer verify online CRLs. Only check this box if the Viewer can connect to the required URLs. If this check box is selected and the computer is unable to connect to the required URL, there may be a delay of up to three minutes during which the Viewer will not respond to any requests.

Displaying forms in an HTML page

When you embed an XFDL form in an HTML page, you are essentially declaring that a portion of the web page is controlled by a program other than the browser, such as the Viewer. As a result, this portion of the page operates differently than the HTML page in which it resides.

For example, if a user is filling out a form on a Web page but needs more information to complete it, he or she might click a link on the HTML page and go to a new page. Normally when users perform this action, any data that they have entered into the form is lost. However, with an XFDL form, the form can be detached from the first Web page and provided for viewing in a second Web page.

When a form is detached from one Web page and reattached to another, it maintains all of the user's data. Unlike the first Web page, any successive Web pages that need to display the same form do not need to explicitly embed the form. If you want them to display the same form and retain user data, they must contain objects that share the same detach_id.

Successive pages do not have to display the same form. A second Web page can display a different form if it contains a different object. You can even redirect users to a different Web page if they are taking too long to complete a form and the detached form has timed out. Objects that contain a refresh_URL ensure that users can be directed to another Web page if they need help or to a new form if they abandon completion of the old one.

Once the Viewer is embedded in an HTML Web page, you can treat it like any other HTML object. For example, you can use JavaScript™, other portlets, or servlets to generate dynamic content within the object or form. You can also generate new XML instances for your form.

Embedding a form

Embedding the Viewer in an HTML page allows you to display forms in a portal environment or as part of a series of web pages. This permits forms to be updated dynamically in response to user selections on the HTML page.

To embed the Viewer, you must use two HTML elements:

  • objects — An object allows you to embed the Viewer in the browser. It also allows you to define the size and borders of the Viewer.
  • scripts — The script contains and loads the form. You can also use other scripts to contain data that is used to modify the form, such as XML instances.

The HTML object is a placeholder. In your HTML file, it specifies the location where the object will be displayed in relation to the other elements on the web page. For example, you could place an object inside an HTML table cell:

   <tr>
      <td>
         <object>...</object>
      </td>
   </tr>

The script element is not displayed as part of the Web page, so it can be placed anywhere in your HTML code. You may prefer to place scripts directly after the object that they are associated with, or at the beginning or end of the page. In the following example, the script that contains the form is placed immediately after the table with the form's object:

   </table>
      <script> 
         ... XFDL form ...
      </script>

To embed a form inside an HTML page, you must:

  • Determine which browsers you want to support.
  • Create an object inside the web page.
  • Define the object parameters.
  • Define the script parameters of the embedded form.
  • Insert the XFDL form you want to embed.
  • Add XML instances to the web page. (optional)

Selecting which browsers to support

You can embed a form into any HTML page. However, every browser interprets HTML code differently. If you know that all your users are only using one type of browser, you can focus your HTML code to support it specifically. On the other hand, if your users are using multiple browser types, you will need to create additional code to ensure that all of the browsers recognize and display the embedded form.

If you are only supporting one kind of browser, you can create a single object. If you are supporting multiple browsers, you need to dynamically create the object with JavaScript, as shown in Supporting multiple browsers.

Creating an object

The object element in HTML allows Web page designers to specify data to be rendered by a browser plugin. IBM has taken advantage of this element to allow XFDL forms to be embedded in a web page. Using the object element allows you to specify how the object is implemented and the location of the object's data. This is done using the following attributes:

Table 7.
Attribute Browser Support Description
id All Assigns a name to the object, identifying it for manipulation by associated applications. It must be unique within the HTML page. For example,
   <OBJECT id="unique_name">
classid IE only Specifies the browser plugin used to display the object. In this case, it identifies the Active X control that activates the Viewer This value must always be:
   CLSID:354913B2-7190-49C0-944B-1507C9125367

For example:

   <OBJECT  classid="CLSID:354913B2-7190-49C0
     -944B-1507C9125367">

Note that the classid attribute essentially fulfills the same function for the Internet Explorer browser as the type attribute does for the Mozilla Firefox browser.

type Mozilla Firefox The type attribute has one parameter:
  • mime type – This value must always be application/vnd.xfdl.

For example:

   <OBJECT type="application/vnd.xfdl">

Note that the type attribute fulfills the same function for the Mozilla Firefox browser as the classid attribute does for the Internet Explorer browser.

height All Indicates the height of the object in pixels. For example:
   <OBJECT height="400">
width All Indicates the width of the object in pixels. For example:
   <OBJECT width="800">
style All Allows you to specify font color, styles, and sizes, as well as background colors and object positioning. For example:
   <OBJECT STYLE="position:absolute;
      left:10px;top:10px;height:600px;
      width:800px;background-color:aqua;
      font-family:Helvetica">

You can also modify the display area of the form with the following optional attributes:

Table 8.
Attribute Browser Support Description
align All Sets the position of the object within its allowed display area. The valid settings are: left, right, and center. For example:
   <OBJECT align="center">
border All Sets the width of the object's border in pixels. This value must always be an integer. For example:
   <OBJECT border="2">
hspace All Sets the amount of white space (in pixels) to be inserted to the left and right of an object. If the object has a border, this additional white space is outside of the border. This number is always an integer. For example:
   <OBJECT hspace="2">
vspace All Sets the amount of white space (in pixels) to be inserted above and below an object. If the object has a border, this additional white space is outside of the border. This number is always an integer. For example:
   <OBJECT hspace="2">

Example

In the following example, the object is assigned a unique name, pointed at the Viewer Active X control, and given a size.

   <OBJECT id="unique_name" height="400" width="800"
      classid="CLSID:354913B2-7190-49C0-944B-1507C9125367"> 
      ... object parameters... 
   </OBJECT>
Note: For more information about the HTML object element, refer to the W3C Web site at: http://www.w3.org/TR/REC-html40/struct/objects.html.

Defining the object parameters

Object attributes identify and set the size of the object, but to specify run-time values you must use the param element. The param element consists of name and value pairs. For example:

   <PARAM NAME="XFDLID" VALUE="XFDLData">

The param elements determine the behavior of the Viewer and how it handles the embedded form. There are six param elements:

XFDLID
The ID of the script element that contains the form. This value can be anything, as long as the XFDLID and the script ID match. For example:
   <PARAM NAME="XFDLID" VALUE="XFDLData">
detach_id
The unique ID of the form instance. This attribute allows an XFDL form to "detach" from one web page and "attach" itself to another while retaining its data. The detach_id value can be any unique string. For example:
   <PARAM NAME="detach_id" VALUE="1234567890ABCD">

Successive objects containing the same form must all have the same detach_id if you want to maintain user data between web pages. For example, if form A appears in HTML pages 1- 4, and the form object in page 1 has a detach_id of 10236B, then the form objects in pages 2 - 4 must also have a detach_id of 10236B.

If you specify a detach_id, you must also give the object a TTL (Time To Live).

refresh_URL
The URL called to refresh the HTML page if the detach_id of the object has expired, and the page does not have an embedded XFDL form. This URL can point to any web page, regardless of whether it contains an object or a form. refresh_URL does not maintain user data. For example:
   <PARAM NAME="refresh_URL" 
      VALUE="http://www.serv1/IRS/Sched22.htm">
TTL
The length of time, called the Time To Live, that the detached form will live before being destroyed. The default TTL is 0. This value is given in seconds. For example:
   <PARAM NAME="TTL" VALUE="15">

If you specify a TTL, you must also specify a detach_id.

retain_viewer
Determines whether the Viewer remains available after completing
instance_1... instance_n
Identifies XML instances inside an HTML page. The instances can be used to modify specified XML instances inside the XFDL form. This information includes:
  • The ID of the new instance.
  • The ID of the form instance you want to modify or replace.
Note: Multiple instance parameters must have sequentially numbered names, starting with 1. For example, instance_1, instance_2, and so on.

If you are using data instances, several additional values may be included:

  • xforms; – Indicates that the instance data is XForms.
  • Positioning information – Indicates whether the new instance data replaces or is added to the existing instance. This value is optional, but one of replace, append, or insertbefore must be used.
    • replace – Indicates that the new instance data replaces the original instance data.
    • append – Indicates that the new instance data is added to the end of the existing instance data.
    • insertbefore – Indicates that the new instance data is added to the beginning of the existing instance data.
  • A reference – Indicates the instance or instance element where the new data should be placed. This could be a non-default instance, or a particular element in an instance. Note that any namespaces listed in this value resolve relative to the document root. This value is optional if only one data instance exists. If multiple instances exist, this reference is mandatory.
    Note: If using an XForms data model, the reference must be an XPath reference, and must always be written as position=XPath, where position is one of replace, append, or insertbefore. For example, replace=&quot;instance('FormData')/POLines/Line[last()]&quot;.

The following code sample shows how to define the object parameters if you want to add new XML data to the end of an existing XML data model instance:

   <PARAM NAME="instance_1" 
      VALUE="new_Inst old_Inst append '[custom:rec][custom:name]'">

The following code sample shows how to define the object parameters if you want to replace the existing XForms data instance with a new one:

   <PARAM NAME="instance_1" 
      VALUE="new_Inst old_Inst xforms; replace=&quot;.&quot;">

Examples

The following example displays an object with a complete set of param attributes for replacing an XML data model instance:

   <OBJECT...object attributes...>
      <PARAM NAME="XFDLID" VALUE="theForm">
      <PARAM NAME="TTL" VALUE="15">
      <PARAM NAME="detach_id" VALUE="12354678901234567890">
      <PARAM NAME="refresh_URL" VALUE="http://www.serv1/IRS/Sched22.htm">
      <PARAM NAME="retain_Viewer" VALUE="on">
      <PARAM NAME="instance_1" VALUE="newIns oldIns replace [0][0]"> 
   </OBJECT>

The following example displays an object with a complete set of param attributes for replacing an XForms instance:

   <OBJECT...object attributes...>
      <PARAM NAME="XFDLID" VALUE="theForm">
      <PARAM NAME="TTL" VALUE="15">
      <PARAM NAME="detach_id" VALUE="12354678901234567890">
      <PARAM NAME="refresh_URL" VALUE="http://www.serv1/IRS/Sched22.htm">
      <PARAM NAME="retain_Viewer" VALUE="on">
      <PARAM NAME="instance_1" 
             VALUE="new_Inst old_Inst xforms; replace=&quot;.&quot;"> 
   </OBJECT>
Note: The param element requires a start tag only. It does not require an end tag. For more information about the HTML parameter element, refer to the W3C Web site at: http://www.w3.org/TR/REC-html40/struct/objects.html#h-13.3.2.

Usage Notes

  1. The contents of the value attribute must be space separated. The only exception to this requirement is the XForms XPath reference.
  2. XPath references must be surrounded by the &quot; entity instead of quotation marks.
  3. The XForms XPath reference must always be written as position=XPath, where position is one of replace, append, or insertbefore. For example, replace=&quot;instance('FormData')/POLines/Line[last()]&quot;

Order of precedence for object parameters

Objects frequently include multiple parameters. As a result, the Viewer must follow an order of precedence so that the object parameters are always processed in a consistent manner. When a new Web page containing a form object is opened, the following precedence is used to determine what is displayed:

  1. detach_id - If a detach_id exists and its TTL has not expired, the object displays the form referenced by the detach_id.
  2. XFDLID - If there is no detach_id or it has expired, the object displays the embedded form identified by the XFDLID.
  3. refresh_URL - If there is no detach_id or XFDLID, then the entire page is reloaded to display the page specified by the refresh_URL.

Supporting multiple browsers

Internet Explorer and Mozilla Firefox have different and incompatible ways of embedding objects. The best way to support both browsers is to use JavaScript to dynamically create the object specific to the browser which is being used.

The JavaScript technique is shown in the example below. The code is in two parts. The first part is a function declaration that you place in the HTML head section of your Web page. In the example, the function is named addViewer, but you can give it any name you want. You can copy this part of the code without any changes.

The second part is a call to the addViewer function. The call is placed inside an HTML div element in the body of the Web page. You can copy this part of the code, but you must customize the parameters for your particular application. The parameters are as follows:
  • The id attribute of the HTML div element that will contain the HTML object element that embeds the Viewer. In the example, this parameter is viewer.
  • The id attribute of the HTML object element that embeds the Viewer. In the example, this parameter is CPClient.
  • The width of the Viewer. In the example, this parameter is 800.
  • The height of the Viewer. In the example, this parameter is 400.
  • Name/value pairs that will become the param elements of the HTML object element. For a description of the available param elements, see Defining the object parameters.

When modifying the parameters, make sure that you have a comma after each one. You do not need a comma after the last parameter.

Note: The method of supporting multiple browsers is slightly different if you want to use the IBM Lotus Forms JavaScript API. For more information on the JavaScript API, see Lotus Forms Server API – JavaScript API User's Manual.

Example

<html>
<head>
<title>Embedded Form</title>
 <script type="text/javascript">
  	
function addViewer(containerDiv, tagID, _width, _height)
{
	var parentDiv = document.getElementById(containerDiv);
	var element = document.createElement('object');

	for (var i = 4; i < arguments.length; i+=2)
	{
		var param = document.createElement('param');
		param.setAttribute('name', arguments[i]);
		param.setAttribute('value',arguments[i+1]);
		element.appendChild(param);
	}

	element.setAttribute('id',tagID);
	element.setAttribute('height',_height);
	element.setAttribute('width',_width);
	
	if (navigator.appName == 'Microsoft Internet Explorer')
	{
		parentDiv.appendChild(element);
		element.setAttribute('classid', 'clsid:354913B2-7190-49C0-944B-1507C9125367');
	}
	else
	{
		element.setAttribute('type', 'application/vnd.xfdl');
		parentDiv.appendChild(element);
	}
}  </script>

  <script language="XFDL" id="XFDLData" type="application/vnd.xfdl; 
   wrapped=comment;">
   <!--
     form data goes here
    -->
  </script>

</head>
<body>
 <div id="viewer">
   <script type="text/javascript">
    addViewer (
      "viewer",                       // id of the HTML div element
      "CPClient",                     // id to assign to the object element
      800, 400,                       // width and height of the Viewer
      "XFDLID", "XFDLData",           // name/value pair for XFDL param
      "detach_id", value="2507088000" // name/value pair for detach_id param
      /* other params as required. */
    );
   </script>
 </div>
 web page content goes here
</body>
</html>

Defining the script parameters

In HTML, the script element places a script inside the HTML page. In the case of XFDL forms, the script includes the form itself. There are a number of attributes that modify the script element. These attributes help the Viewer to recognize the embedded form as valid XFDL. They include:

language
This value must always be XFDL. For example:
   <SCRIPT language="XFDL">
id
Identifies the object referred to by the script. This id must match the object's XFDLID value. For example, if your XFDLID value is:
   <PARAM NAME="XFDLID" VALUE="XFDLData">

then your script id must be:

   <SCRIPT id="XFDLData">
type
The type attribute has five parameters:
  • mime type — This value must always be application/vnd.xfdl.
  • wrapped — Identifies the type of container that encloses the form. This value must always be comment.
  • next-chunk — Indicates the next portion of the form. If used, this value must be the script id of the next portion of the form.
  • encoding — The encoding of the form embedded in the script element. For example, if the form is base64 encoded, then the value is base64.
  • content-encoding — The encoding of the character set of the form. The default is UTF-16.

For example:

   <SCRIPT type="application/vnd.xfdl; wrapped=comment;
      encoding=base64; next-chunk=Part2; content-encoding=utf-16">

These parameters must be separated with a semi-colon followed by a space.

Example

The following example displays a script starting tag, complete with all of the required attributes:

   <SCRIPT language="XFDL" id="XFDLData" 
      type="application/vnd.xfdl; wrapped=comment;">
         ...enclosed form...
   </SCRIPT>  
Note: For more information about the HTML script element, see http://www.w3.org/TR/REC-html40/interact/scripts.html.

Adding the form to the script

Once you have defined the script parameters, you can insert your XFDL form.

To insert the form:

  1. Place a comment wrapper between the script tags. For example:
       <SCRIPT ...script attributes...>
          <!-- 
          -->
       </SCRIPT>
  2. Paste the entire XFDL form inside the comment wrapper.

Example

The following example shows a small XFDL form enclosed in a comment wrapper:

   <SCRIPT ...script attributes...>
      <!--
         <?xml version="1.0"?>
         <XFDL xmlns="http://www.ibm.com/xmlns/prod/XFDL/7.0" 
            xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom">
            <globalpage sid="global">
                <global sid="global">
                   <vfd_date>9/7/2004</vfd_date>
               </global>
            </globalpage>
            <page sid="PAGE1">
               <global sid="global">
                  <label>PAGE1</label>
               </global>
               <label sid="LABEL1">
                  <value>This is a short sample form.</value>
               </label>
            </page>
         </XFDL>
      -->
   </SCRIPT>

Adding XML instances to the HTML page

You can include XML instances (XForms or XML Data Model) in your Web page that contain XML data that you can move into your form. This XML data can replace or add to existing XML data inside your form – particularly useful for dynamically populating forms with information selected by the user from an HTML page.

For example, consider a purchase order form embedded in an HTML page. The XFDL form is a generic purchase order form, possibly personalized with user information via a data fragment. This form is displayed in an HTML page (or a series of HTML pages) that allow users to select the products they want to purchase. When users select the desired product, they trigger the application server to create a custom XML instance to replace the generic XML instance currently in the XFDL form. To the eyes of the users, the form appears to automatically populate with the correct purchase information, including order number, product type, and pricing.

Regardless of whether the XML instance is hardcoded into the HTML page or generated by an application server, it must be wrapped in a script container. Like a script element containing an XFDL form, you must define the following attributes:

language
This value must always be XFDL. For example:
   <SCRIPT language="XFDL">
id
Identifies the instance. This id must match the instance value in the parameter of the object element that contains the form. For example, if the instance value of instance_1 is as below:
<OBJECT ... object attributes ...>
  <PARAM NAME="instance_1" 
         VALUE="new_Instance old_Instance
                append[custom:record][custom:name]">
... other params ...
</OBJECT>

then your script id must be:

<SCRIPT id="new_Instance">
type
The type attribute has two parameters:
  • mime type — This value must always be application/vnd.xfdl.
  • wrapped — Identifies the type of container that encloses the instance. This value must always be comment.
  • encoding — The encoding of the instance embedded in the script element. For example, if the instance is base64 encoded, then the value is base64.

For example:

   <SCRIPT type="application/vnd.xfdl; wrapped=comment">

The type and wrapped parameters must be separated with a semi-colon.

Important: To identify XForms instances, you must add an xforms; parameter to the form object. For more information, see Defining the object parameters.

To embed an instance:

  1. Create a new script element. For example:
       <SCRIPT id=new_Instance type="application/vnd.xfdl; wrapped=comment">
       </SCRIPT>
  2. Place a comment wrapper between the script tags.
  3. Paste the XML instance between the comment tags.

Example

The following example depicts a script element that contains an XML instance enclosed in a comment wrapper:

   <SCRIPT id="new_Instance" type="application/vnd.xfdl; wrapped=comment">
      <!--
         <name xmlns="http://www.ibm.com/xmlns/prod/XFDL/Custom">
            Arnold Jevaston</name>
      -->
   </SCRIPT>

Order of precedence

Forms often include multiple XML instances. They may even refer to data fragments, frequently used scraps of XML data that are stored on users’ computers. If your HTML contains replacement instances, or if replacement instances are generated by an application server, the Viewer must follow an order of precedence to ensure the instances are always loaded in a consistent manner.

When a new Web page containing XML instances is opened, the following precedence is used to determine what is displayed:

  • Data Fragments — If Smartfill is on and an appropriate data fragment is stored on a user's computer, data fragments are loaded first. If there is a replacement instance targeted at the fields populated by the Smartfill data, the data contained in the replacement instance is ignored. To avoid this sort of complication, ensure that your data fragments and instances have unique names or different naming styles for each. For example, if your organization uses a data fragment called PersonalInfo, but you want to use a different instance containing personal data in a form, make sure the form's instance has a different name or naming convention. For example, personal_data.
  • instance_1...instance_n — If your form is embedded in an HTML page that contains multiple XML instances, the Viewer will process them sequentially, in accordance to the number sequence in their script id. Thus instance_1 will load first, instance_2 will load second, and so on.

Sample embedded form

The following example shows all the code required to fully embed a form in Internet Explorer or Firefox.

This includes an object element, the object parameters, the script element, and a sample XFDL form wrapped in a comment structure.

   <OBJECT id="Object1" height="200" width="200" border="5" 
      classid="CLSID:354913B2-7190-49C0-944B-1507C9125367">
      <PARAM NAME="XFDLID" VALUE="XFDLData">
      <PARAM NAME="detach_id" VALUE="2507088000">
      <PARAM NAME="refresh_url" VALUE="envAware.html">
      <PARAM NAME="TTL" VALUE="17">
      <PARAM NAME="retain_Viewer" VALUE="on">
   </OBJECT>
	<!--[if !IE]>
	Mozilla 1.x, Firefox 1.x, Netscape 7+ and others will use the inner object, the nested object
	-->
	  <OBJECT ID="forMozillabrowser" height="300" width="800" border="5"
			type="application/vnd.xfdl">
			<PARAM NAME="XFDLID" VALUE="theForm2">
			<PARAM NAME="detach_id" VALUE="2507088000">
			<PARAM NAME="refresh_url" VALUE="envAware.html">

			<PARAM NAME="TTL" VALUE="17">
			<PARAM NAME="retain_Viewer" VALUE="on">
			<PARAM NAME="instance_1" VALUE="newInst xforms; replace=&quot;.&quot;">
	  </OBJECT>
<!--<![endif]-->
</OBJECT>   

<SCRIPT language="XFDL" id="XFDLData"
      type="application/vnd.xfdl; wrapped=comment">
      <!-- 
         <?xml version="1.0"?>
            <XFDL xmlns="http://www.ibm.com/xmlns/prod/XFDL/7.0" 
               xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom">
               <globalpage sid="global">
                  <global sid="global">
                     <vfd_date>9/7/2004</vfd_date>
                  </global>
               </globalpage>
               <page sid="PAGE1">
                  <global sid="global">
                     <label>PAGE1</label>
                  </global>
                  <label sid="LABEL1">
                     <value>This is a short sample form.</value>
                  </label>
               </page>
            </XFDL>
       -->
   </SCRIPT>

Sample embedded XForms form

The following example shows all the code required to fully embed an XForms form and support both Internet Explorer and Firefox browsers. It also demonstrates how to use chunking.

<html>
<head>
<title>Embed Form</title>
 <script type="text/javascript">
  	
 function addViewer(containerDiv, tagID, _width, _height)
{
	var parentDiv = document.getElementById(containerDiv);
	var element = document.createElement('object');

	for (var i = 4; i < arguments.length; i+=2)
	{
		var param = document.createElement('param');
		param.setAttribute('name', arguments[i]);
		param.setAttribute('value',arguments[i+1]);
		element.appendChild(param);
	}

	element.setAttribute('id',tagID);
	element.setAttribute('height',_height);
	element.setAttribute('width',_width);
	
	if (navigator.appName == 'Microsoft Internet Explorer')
	{
		parentDiv.appendChild(element);
		element.setAttribute('classid', 'clsid:354913B2-7190-49C0-944B-1507C9125367');
	}
	else
	{
		element.setAttribute('type', 'application/vnd.xfdl');
		parentDiv.appendChild(element);
	}
} 
  </script>

  <script language="XFDL" id="XFDLData" type="application/vnd.xfdl; 
   wrapped=comment; next-chunk=chunk2">
   <!--
   <?xml version="1.0" encoding="UTF-8"?>
   <XFDL xmlns="http://www.ibm.com/xmlns/prod/XFDL/7.1"
      xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom" 
      xmlns:ev="http://www.w3.org/2001/xml-events" 
      xmlns:xforms="http://www.w3.org/2002/xforms">
      <globalpage sid="global">
         <global sid="global">
            <xformsmodels>
               <xforms:model>
                  <xforms:instance id="instance1" xmlns="">
                     <root>
                        <field_1></field_1>
                        <field_2></field_2>
                        <field_3></field_3>
                     </root>
                  </xforms:instance>
               </xforms:model>
            </xformsmodels>
         </global>
      </globalpage>
    -->
  </script>
  <script language="XFDL" id="chunk2" type="application/vnd.xfdl; 
   wrapped=comment; next-chunk=chunk3">
    <!--
    <page sid="PAGE1">
       <global sid="global">
          <label>PAGE1</label>
       </global>
       <field sid="field1">
          <xforms:input ref="field_1">
             <xforms:label>Field with xforms:input</xforms:label>
          </xforms:input>
       </field>
       <field sid="field2">
          <xforms:textarea ref="field_2">
             <xforms:label>Field with xforms:textarea</xforms:label>
          </xforms:textarea>
         <size>
            <width>30</width>
            <height>2</height>
         </size>
      </field>
    -->
  </script>
  <script language="XFDL" id="chunk3" type="application/vnd.xfdl; 
   wrapped=comment">
   <!--  
    <field sid="field3">
       <xforms:secret ref="field_3">
          <xforms:label>Field with xforms:secret</xforms:label>
       </xforms:secret>
    </field>
    <spacer sid="vfd_spacer">
       <itemlocation>
          <x>250</x>
          <y>250</y>
          <width>1</width>
          <height>1</height>
       </itemlocation>
    </spacer>
   </page>
  </XFDL>
  -->
  </script>

</head>
<body>
 <div id="viewer">
  <script type="text/javascript">
    addViewer (
      "viewer",                       // id of the HTML div element
      "CPClient",                     // id to assign to the object element
      800, 400,                       // width and height of the Viewer
      "XFDLID", "XFDLData",           // name/value pair for XFDL param
      "detach_id", value="2507088000" // name/value pair for detach_id param
      /* other params as required. */
    );
   </script>
 </div>

</body>
</html>   

Using object parameters in computes

The Viewer functions enable you to trigger actions in the Viewer. The param Viewer function allows you to call specific object parameters in computes that return the parameter's value. For example, if the param function called the object's XFDLID parameter, then it would return the object’s XFDL ID. For more information, see the XFDL Specification

Embedding signed forms

If you want to embed a signed form into a Web page, the form must be base64-gzip encoded. When Internet Explorer parses a signed embedded form, it may add extra carriage returns to the form. This prevents the form from matching the signature hash value, which causes the Viewer to declare that the form’s signature is invalid. Encoding signed forms in base64-gzip ensures that this does not occur.

The easiest way to encode an XFDL form is to open it and encode it in the Designer.

To base64-gzip encode a form:

  1. Open the Designer.
  2. Open the form you want to base64-gzip encode.
  3. In the Outline view, select Form Global.
    • Form Global data appears in the Properties view.
  4. Click the popup in the field next to saveformat and select application/vnd.xfdl;content-encoding="base64-gzip".

Embedding internationalized forms

If your form contains characters outside of the ASCII (0-7F) range, the character encoding in your XFDL form must match the BSTR encoding passed by the browser to the object containing the Viewer. The easiest way to ensure that they match is to specify character encoding only in the HTML form. You can place it in a meta tag inside the HTML head tag. For example:

   <META http-equiv="Content-Type" content="text/html;
    charset=utf-8">

Furthermore, you must also remove the character encoding already in your form. As the Designer automatically adds character encoding, you must open the form in another text editor, such as UltraEdit, Notepad, or TextPad, and delete the encoding.

To strip character encoding from an XFDL form:

  1. Open the file in a text editor. Do not open it in the Designer.
  2. Search for the encoding attribute on the XML version tag and delete the attribute and its setting.
  3. Save the form.

However, under some circumstances you may find that you must include character encoding in your XFDL form. If so, you must still ensure that the form encoding matches the BSTR encoding. Therefore, if you include character encoding in your form, it must always be:

  • UTF-16LE

You cannot change the character encoding of the form in the Designer. You must edit it in another text editor, such as UltraEdit or Notepad.

To change your form's character encoding:

  1. Open the file in a text editor.
    • Do not open it in the Designer.
  2. Search for the encoding attribute on the XML version tag.
  3. Change the encoding setting to UTF-16LE.
  4. Save the form.

Using HTML in forms

You can use Lotus Forms JavaScript API to communicate between a form and a web page. The web page can be in an XFDL pane item, or it can be inside a modal dialog box.

The tutorials describe how to use Dojo widgets inside a web page on an XFDL form, and how to use the JavaScript API to transfer data between the form and the web page. Although the use of Dojo Toolkit is described, you can modify the technique to use other toolkits.

Except for minor differences in file paths, the forms and web pages in the Webform Server and Viewer versions of the tutorials are identical. The differences in the file paths are due to the way that the sample servlet that comes with Webform Server handles relative URLs. It is possible to design a servlet so that the file paths can be identical. However, because the tutorial relies on the sample servlet, some adjustments to the file paths are required.

If your forms are served by Webform Server but viewed inside Viewer embedded in an HTML page, follow the tutorial for Webform Server.

Tutorial: Embedding HTML in an XFDL pane (Viewer)

In this tutorial, you will learn how to embed a web page in a form. The web page contains a Dojo slider widget. When the value of the slider widget changes, the new value is inserted into a label on the form.

The project that you build in this tutorial consists of two files. One file is a simple XFDL form that contains data, a pane, and a label. The other file is a web page that implements a Dojo slider control and is displayed inside the pane. The web page uses the Lotus Forms JavaScript API to transfer data between the slider control and the form.

The web page is loaded when you open the form. A script on the web page copies the slider value from the XForms model into the slider control. When you change the value of the slider, the script copies the new value into the XForms model, which updates the label.

The first task is to verify that you have the appropriate files installed on your computer. Next, you create the XFDL form that contains the web page. After you create the form, you create the web page that is displayed in the form. Finally, you deploy and use the form.

Set up the environment for HTML in pane (Viewer)

To avoid problems during the tutorial, make sure that you have Dojo Toolkit in the correct location and that you have the appropriate supporting files in place.

The folder structure that you create in this tutorial is only one of several valid structures. You can use a different structure if you want, but you must adjust filepaths in your XFDL form and HTML pages to suit the structure.

You can download Dojo Toolkit from the Dojo website, or use the version that is included with Webform Server. If you have Webform Server, look for dojo.ibm.standard-1.4.3-20100331.zip in C:\Program Files\IBM\Lotus Forms\WebformServer\redist.

  1. Install Lotus Forms Viewer 4.
  2. In a convenient location on your hard disk, create the folder structure for this project.
    1. Create a new folder, and give it the name HTMLPane.
    2. In the HTMLPane folder, create two new folders: JavaScript and dojo.
  3. Copy the supporting files into the folders that you created.
    1. Locate LF_FormNodeP.js and LF_XFDL.js. Copy them into the JavaScript folder that you created.

      The default source location of the two files is C:\Program Files\IBM\Lotus Forms\Viewer\4.0\JavaScript but it might be different on your computer, depending on where you installed Viewer.

    2. Locate LF_ViewerFormEmbeddedHTMLFrame.htm and copy it into the HTMLPane folder.

      Although the source location of this file is the same as LF_ViewerScript.js and LF_XFDL.js, the destination is different. Make sure that you copy it into the HTMLPane folder, not the HTMLPane\JavaScript folder.

    3. Copy the folder structure from the Dojo toolkit into the HTMLPane folder.
At the end of the procedure, your folder structure should be as follows:
HTMLPane\dojo\dijit
HTMLPane\dojo\dojo
HTMLPane\dojo\dojox
HTMLPane\JavaScript

Create the XFDL form (Viewer)

The form contains a label and a pane. The form also contains an XForms model that supplies the value for the label and for the slider control.

In this stage of the tutorial, you create the XFDL form that contains a pane. The pane will display the web page that you create in a later stage.

  1. Create a new XFDL file, give it the name TutorialHTMLPane.xfdl, and open it in a text editor.
  2. Create a skeleton XFDL form that contains the namespaces that are needed, the globalpage, and the first page.
    <?xml version="1.0" encoding="UTF-8"?>
    <XFDL xmlns="http://www.ibm.com/xmlns/prod/XFDL/8.0" 
          xmlns:xfdl="http://www.ibm.com/xmlns/prod/XFDL/8.0" 
          xmlns:xforms="http://www.w3.org/2002/xforms">
       <globalpage sid="global">
         <global sid="global">
    
           <!-- add XForms model here -->
    
         </global>
       </globalpage>
       <page sid="PAGE1">
         <global sid="global">
            <label>HTML pane</label>
          </global>
          <label sid="LABEL1">
            <value>HTML in pane Tutorial</value>
          </label>
    
         <!-- add the label and items here -->
    
       </page>
    </XFDL>
  3. Add the XForms model to the global page.

    The model contains the data that is updated by the slider control. The model also provides the initial value for the slider, which in this case is 4.

    <globalpage sid="global">
         <global sid="global">
           <xformsmodels>
             <xforms:model>
               <xforms:instance id="slider-value" xmlns="">
                 <data>
                   <slider>4</slider>
                 </data>
               </xforms:instance>
             </xforms:model>
           </xformsmodels> 
         </global>
       </globalpage>
  4. Add a label item to the PAGE1 page. This label displays the value of the <slider> element that is in the XForms model.
    <page sid="PAGE1">
      <global sid="global">
         <label>Modal Dialog</label>
       </global>
       <label sid="LABEL1">
         <value>HTML in pane Tutorial</value>
       </label>
       <label sid="LABEL2">
          <xforms:output ref="instance('slider-value')/slider">
            <xforms:label>Value of slider: </xforms:label>
          </xforms:output>
          <itemlocation>
            <below>LABEL1</below>
          </itemlocation>
        </label> 
      .
      .
      .
  5. Add the pane item after the label item.

    The pane item has three purposes; to provide the URL of the embedded web page, to provide the width and height of embedded content, and to provide content for the printed version of the form. Everything within the xforms:group element is visible only when the form is printed.

      .
      .
      .
        </label>
    
        <pane sid="PANE1">
           <xforms:group ref="instance('slider-value')/slider">
              <label sid="PANE1_LABEL1">
                <value>This is printed.</value>
              </label>
              <spacer sid="vfd_spacer">
                <itemlocation>
                  <x>300</x>
                  <y>40</y>
                </itemlocation>
             </spacer>
            </xforms:group>         
            <!-- The file must be in the same folder as the XFDL form -->
            <url>TutorialHTMLPane.html</url>
         </pane>
      </page>
    </XFDL>      
  6. Save the file.

Here is the complete file:

<?xml version="1.0" encoding="UTF-8"?>
<XFDL xmlns="http://www.ibm.com/xmlns/prod/XFDL/8.0" 
      xmlns:xfdl="http://www.ibm.com/xmlns/prod/XFDL/8.0" 
      xmlns:xforms="http://www.w3.org/2002/xforms">
   <globalpage sid="global">
     <global sid="global">
       <xformsmodels>
         <xforms:model>
           <xforms:instance xmlns="" id="slider-value">
             <data>
               <slider>4</slider>
             </data>
           </xforms:instance>
         </xforms:model>
       </xformsmodels> 
     </global>
   </globalpage>
   <page sid="PAGE1">
   
      <global sid="global">
        <label>HTML in pane</label>
      </global>

      <label sid="LABEL1">
         <value>Viewer HTML in pane Tutorial</value>      
      </label>
      
      <label sid="LABEL2">
        <xforms:output ref="instance('slider-value')/slider">
          <xforms:label>Value of slider: </xforms:label>
        </xforms:output>
        <itemlocation>
          <below>LABEL1</below>
        </itemlocation>
      </label>
      
      <pane sid="PANE1">
         <xforms:group ref="instance('slider-value')/slider">
            <label sid="PANE1_LABEL1">
              <value>This is printed.</value>
            </label>
            <spacer sid="vfd_spacer">
              <itemlocation>
                <x>300</x>
                <y>40</y>
              </itemlocation>
            </spacer>
        </xforms:group>
        <!-- The file must be in the same folder as the XFDL form -->
        <url>TutorialHTMLPane.html</url>       
     </pane>

   </page>
</XFDL>
The next step is to create the TutorialHTMLPane.html web page that the form will display.

Create the web page (Viewer)

In this stage of the tutorial, you create the web page for the form.

The web page contains a short piece of JavaScript that uses the Lotus Forms JavaScript API to obtain the value of the <slider> element from the XForms model. The value becomes the initial value for the slider control. When you change the slider, the script updates the <slider> element in the XForms model.

  1. Create a new HTML file, give it the name TutorialHTMLPane.html, and open it in a text editor.
  2. Create a skeleton HTML file that contains references to the Dojo library and Lotus Forms JavaScript API files.
    <html>
      <head>
        <link href="dojo/dijit/themes/nihilo/nihilo.css" rel="stylesheet" type="text/css">
        <link href="dojo/dojo/resources/dojo.css" rel="stylesheet" type="text/css">
    
        <script type="text/javascript" src="dojo/dojo/dojo.js" djConfig="parseOnLoad: true"></script>
        <script type="text/javascript" src="JavaScript/LF_FormNodeP.js"></script>
        <script type="text/javascript" src="JavaScript/LF_XFDL.js"></script>
    
        <!-- Add custom JavaScript here -->
    
      </head>
    
      <body class="nihilo">
    
      <!-- Add slider control here -->
    
      </body>
    
    </html>
  3. Add the JavaScript functions that load the Dojo slider control and initialize it when the form opens.
        .
        .
        .
    
        <script type="text/javascript">
          dojo.require("dijit.form.Slider");
    
          dojo.addOnLoad(function() {
          
            /* get the value of the field in the form and assign it to the variable
               initvalue. The extractXFormsInstance method from the Lotus Forms 
               JavaScript API returns a string in this format: "<slider>n</slider>" 
               where n is a number */
            var initvalue = XFDL.getCurrentForm().extractXFormsInstance(null,
              "instance('slider-value')/slider", true, true, null);        
            
            // use a regular expression to extract the number from initvalue
            initvalue = initvalue.match(/\d+/);
    
            // set up the Dojo slider
            var sliderRules = new dijit.form.HorizontalRule({
              count: 10,
              style: "height:5px;"
            },
            "sliderrules");
    
            var slider = new dijit.form.HorizontalSlider({
              name: "slider",
              value: initvalue,
              minimum: 1,
              maximum: 10,
              discreteValues: 10,
              style: "width:300px;",
              onChange: function(value) {
                // update the XForms model when the slider value changes
                XFDL.getCurrentForm().updateXFormsInstance(null, 
                "instance('slider-value')/slider", 
                null, value.toString(), 
                XFDL.UFL_XFORMS_UPDATE_REPLACE_TEXT);
              }
            },
            "slider");
          });
          </script>    
        </head>
        .
        .
        .
  4. Add the slider control to the body of the web page.
      .
      .
      .
      <body class="nihilo">
        <div id="slider">
           <div id="sliderrules"></div>
           <ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" 
               style="height:1.5em;font-size:75%;color:gray;">
              <li>1</li>
              <li>2</li>
              <li>3</li>
              <li>4</li>
              <li>5</li>
              <li>6</li>
              <li>7</li>
              <li>8</li>
              <li>9</li>
              <li>10</li>
            </ol>
          </div>
      </body>

Here is the complete file:

<html>
  <head>
    <link href="dojo/dijit/themes/nihilo/nihilo.css" rel="stylesheet" type="text/css">
    <link href="dojo/dojo/resources/dojo.css" rel="stylesheet" type="text/css">

    <script type="text/javascript" src="dojo/dojo/dojo.js" djConfig="parseOnLoad: true"></script>
    <script type="text/javascript" src="JavaScript/LF_FormNodeP.js"></script>
    <script type="text/javascript" src="JavaScript/LF_XFDL.js"></script>
    <script type="text/javascript">
      dojo.require("dijit.form.Slider");

      dojo.addOnLoad(function() {
      
        /* get the value of the field in the form and assign it to the variable
           initvalue. The extractXFormsInstance method from the Lotus Forms 
           JavaScript API returns a string in this format: "<slider>n</slider>" 
           where n is a number */
        var initvalue = XFDL.getCurrentForm().extractXFormsInstance(null,
          "instance('slider-value')/slider", true, true, null);
        
        // use a regular expression to extract the number from initvalue
        initvalue = initvalue.match(/\d+/);
        
        // set up the Dojo slider
        var sliderRules = new dijit.form.HorizontalRule({
          count: 10,
          style: "height:5px;"
        },
        "sliderrules");

        var slider = new dijit.form.HorizontalSlider({
          name: "slider",
          value: initvalue,
          minimum: 1,
          maximum: 10,
          discreteValues: 10,
          style: "width:300px;",
          onChange: function(value) {
            // update the XForms model when the slider value changes
            XFDL.getCurrentForm().updateXFormsInstance(null, 
            "instance('slider-value')/slider", 
            null, value.toString(), 
            XFDL.UFL_XFORMS_UPDATE_REPLACE_TEXT);
          }
        },
        "slider");
      });
    </script>
  </head>

  <body class="nihilo">
      <div id="slider">
        <div id="sliderrules"></div>
        <ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" 
            style="height:1.5em;font-size:75%;color:gray;">
          <li>1</li>
          <li>2</li>
          <li>3</li>
          <li>4</li>
          <li>5</li>
          <li>6</li>
          <li>7</li>
          <li>8</li>
          <li>9</li>
          <li>10</li>
        </ol>
      </div>
  </body>

</html>

Using the HTML in pane project (Viewer)

After creating the form and the web page, open the form in Viewer.

To use the HTML in pane project:

  1. In Windows® Explorer, double-click TutorialHTMLPane.xfdl. The form that you created opens in Viewer.
  2. Use the slider control to change the value.
  3. Print the form. On the printed page, the slider control is replaced with the text This is printed.

Troubleshooting and support

If you are experiencing a problem with the Viewer:
  1. Refer to the documentation for the task you are performing or the product component you are working with. These topics may contain troubleshooting information for common problems.
  2. Refer to the Viewer technotes and flashes. These topics contain troubleshooting information for specific problems.
  3. Refer to the Lotus Forms Support web page for documents, fixes, and other resources that may help you resolve the problem.
  4. Refer to the Directory of worldwide contacts Web page and contact IBM Software Support for your region.

JavaScript API

About the JavaScript API

The IBM Lotus Forms Server – JavaScript API is a collection of tools that allow you to programmatically interact with XFDL forms on web pages.

The API gives you direct access to an entire form and all of its nodes. The API has functions that allow you to manipulate the properties of fields, labels, lists, and other controls. You can retrieve information from a form that is embedded in a Web page, manipulate it with your own JavaScript code, and then insert it back into the same form or into another form on the same Web page. Furthermore, you can get information about the digital signatures on the form (if any), and verify that the signatures are valid.

The forms can be displayed by IBM Lotus Forms Viewer or by IBM Lotus Forms Server – Webform Server. For the most part, whether your form is hosted by the Viewer or by Webform Server, the use of the API is identical.

Exceptions and error handling

There are two sources of exceptions that can occur. One source is the JavaScript code, and the other is the underlying form processing code in the Viewer or on the Webform Server server.

JavaScript errors are handled in the normal fashion. That is, you can keep the default browser behavior, or you can use JavaScript try-catch blocks to intercept these errors.

Exceptions thrown by the underlying processing code are intercepted by the error handling mechanism of the JavaScript API. These exceptions are either displayed as an error in a JavaScript alert box, or passed to a custom exception handler that you write to handle the exception. You register the custom function using the API method XFDL.registerAPIExceptionHandler. Note that because these types of exceptions are intercepted, you cannot catch them inside a normal JavaScript try-catch block.

Differences between the Viewer and Webform Server implementations

Both the Viewer and Webform Server implement the JavaScript API, but you might need to adjust your application design if you are using Webform Server.

When the form is rendered in the Viewer, the Viewer handles calls made into the JavaScript API. When the form is rendered by Webform Server as HTML, the JavaScript API calls are sent over the Internet and executed on the server. This arrangement imposes design limitations on applications that access the JavaScript API.

Note: Note: These limitations apply only to XFDL forms rendered by Webform Server as HTML. The limitations do not apply to XFDL forms that are delivered by Webform Server and rendered in the Viewer.
The limitations are:
  • Web page loading: Your JavaScript code must not use the API until the form is completely loaded into the browser and registered by Webform Server. However, you cannot depend on the Web browser to load the various sections of a page in the correct order. This means that you cannot be sure that the form is properly loaded and registered before your JavaScript application tries to access it.

    If you are using portlets, you can solve the problem by creating two portlets. One portlet contains a button that the user must click to initialize the JavaScript application. The other portlet contains the form. The technique is described in Portlet scenario.

    If you are using a servlet, you can solve the problem by separating your web page into frames, as described in Servlet scenario. Use the onload event of the frameset element to initialize the API; the onload event of the frameset does not fire until all frames are completely loaded.

  • Web page reloading: Although Webform Server makes extensive use of AJAX, it must still reload the entire page from time to time. When a page is reloaded, the JavaScript state information is lost; variables are reset and any data in memory is destroyed.

    You can prevent page reloads by avoiding changes to the XFDL form options that are updated by automatic refresh. These options are listed in Supported XFDL options. A compute on a form that changes one or more of these options will also trigger a page reload.

    If you are using portlets, then you must either avoid changing the values of the listed options, or take steps to preserve the state of your JavaScript application across page reloads.

    If you are using servlets, you can separate your web page into HTML frames. One frame contains the JavaScript application and another frame contains the form supplied as HTML by Webform Server. In this case, Webform Server can reload the frame without resetting your JavaScript application. The technique is described in Servlet scenario.

About parameters in the method descriptions

Although typed parameters are not used in JavaScript, they are included in the method descriptions to indicate the types that are expected by each method. You declare variables for these parameters using the normal JavaScript var statement.

Getting started with the JavaScript API

This section contains a tutorial to help you understand how to use the JavaScript API. By working through the tutorial, you will perform all of the steps involved in creating an application that uses the API.

About the sample application

The sample application is for demonstration purposes only and is not to be used in production. It is intended as a guide to help you use the JavaScript API. It is not intended to demonstrate best practices for form deployment.

About the form used in the sample applications

The form that is used in the sample applications is the Calculate Age form, which was originally intended as a simple example for basic server-side processing of forms in C and Java™. It accepts data but does not process it. Using this form as a base, you will create an interactive application that displays a person's age given a birth date and the current date. You will do that without modifying the form itself; everything will be done via the JavaScript API.

Note: You can find the Calculate Age form in the samples folder of IBM Lotus Forms Server – API, with the filename calculateAge.xfd. It is also presented inThe complete application.

A single HTML file scenario

Use a Web server to deliver a form for display in the Viewer.

The sample application in this tutorial uses an embedded Viewer to display the Calculate Age form, and JavaScript to interact with the form. During the course of this tutorial, you will create an HTML file that contains a form, the Viewer embedding code, and the JavaScript code that manipulates the form displayed by the Viewer.

Embed the form

First, you must create the HTML file that will contain both the form and the JavaScript code that manipulates the form. Initially, you will only embed the form so that you can test to make sure that it opens properly in the Viewer.

To embed the form:

  1. Create a new HTML file and give it a meaningful name, such as tutorial.html.
  2. In the head section, include the necessary JavaScript files:
    <html>
    <head>
    <script src="LF_XFDL.js"></script>
    <script src="LF_FormNodeP.js"></script>
    <script src="LF_ViewerScript.js"></script>
    Note that the order is important. First LF_XFDL.js, then LF_FormNodeP.js, and finally LF_ViewerScript.js. You can find these files in the JavaScript folder of IBM Lotus Forms Viewer.
  3. Next, embed the form. This is done within HTML script tags:
    <script language="XFDL" id="XFDLData" type="application/vnd.xfdl; wrapped=comment">
    <!--
    
    <?xml version="1.0" encoding="UTF-8"?>
    <XFDL xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom"
     xmlns:designer="http://www.ibm.com/xmlns/prod/workplace/forms/designer/2.6"
     xmlns:xfdl="http://www.ibm.com/xmlns/prod/XFDL/7.0"
     xmlns="http://www.ibm.com/xmlns/prod/XFDL/7.0">
       <globalpage sid="global">
          
          <!-- rest of form not shown for brevity -->
    
    </XFDL>
    
    -->
    </script>
    Note: The entire form is presented later, in The complete application.
  4. Create the HTML script element that will hold the initialization code. For now, it will have only one line of JavaScript code. Later you will add to this script, but leave it like this so that you can test the Viewer embedding code:
    <script type="text/javascript">
    
      var objectID = "Main";
    
    </script>
    </head>
  5. Create the body element of the page. For now, the body will have only the div that contains the Viewer and the script that embeds the Viewer. You will add additional elements later.
    <body>
      
      <div id="viewer">
    
        <script type="text/javascript">
          addViewer (
            "viewer",                  // id of the HTML div element
            objectID,                  // id to assign to the object element
            500, 400,                  // width and height of the Viewer
            "XFDLID", "XFDLData",      // name-value pair for XFDL param
            "detach_id", "2507088000"  // name-value pair for detach_id param
          );
        </script>
    
      </div>
    </body>
    <html>
  6. Save the file, then open it in either Firefox or Internet Explorer.

    You should see something like this:

    Calculate Age form

When you have the form displayed in your browser, change one or more of the fields. When you change a value, the Age field is not updated, but this is the expected behavior for this form. As mentioned previously, it was originally intended for demonstrating server-side processing of completed forms. Normally, this form would be processed on the server using either the C or Java API. In this case though, you want to make the form interactive without redesigning it.

The next step is to register the form with the API.

Register the form

Now that the form is embedded in the Web page, you must register it with the JavaScript API. This is done by first creating a new FormNodeP object to represent the form (called theForm), then passing it as the first parameter to the XFDL.registerForm method.
Add the OnLoadForm function to the script element:
<script type="text/javascript">

  var objectID = "Main";

 // this must be "OnLoadForm" or IE will have error on page
  function OnLoadForm () {
    try {
      var theForm = new FormNodeP(objectID);
      XFDL.registerForm(theForm, objectID);
    } catch (error) {
      alert("Could not register the form\n" + error);
      return;
    }
  } 
</script>
After the form is registered, you can access it in the ibmForms array. For example, the form that is registered by the code above can be assigned to a variable as shown in this code fragment:
var formMain = ibmForms[objectID];
Note: Be careful when assigning members of the ibmForms array to variables. Changes to the array might not be reflected in the variable due to Web browser caching.

Now you are ready to add the JavaScript.

Add the JavaScript code

In this section, you add the JavaScript code that interacts with the form. In the final step, you add a heading, a button, and an empty paragraph in the HTML body.

To add the JavaScript code:

  1. Insert additional initialization code into the OnLoadForm function, as shown in bold:

    The new code uses the JavaScript API to insert a string into a hidden field on the form. If you examine the Calculate Age source XFDL in calculateAge.xfd, you will see that a compute is activated when the field HIDDENYEAR has a value. The compute calculates the difference between the current date as shown on the form, and the birth date of the person. Any value will activate the compute; in this case it is "activate compute".

    function OnLoadForm() {
      try {
        var theForm = new FormNodeP(objectID);
        XFDL.registerForm(theForm, objectID);
      } catch (error) {
        alert("Could not register the form\n" + error);
        return;
      }
    
      try {
        // put any value in the HIDDENYEAR field, which activates the compute
        ibmForms[objectID].setLiteralByRefEx(null, "PAGE1.HIDDENYEAR.value", 0, 
                                             null, "activate compute");
        
        // set up a couple of OnChange events
        var age = ibmForms[objectID].dereferenceEx(null, "PAGE1.SHOWAGE", 0,
                  FormNodeP.UFL_ITEM_REFERENCE, null);
        age.addOnChange(showMessage);
        var name = ibmForms[objectID].dereferenceEx(null, "PAGE1.NAMEFIELD", 0,
                 FormNodeP.UFL_ITEM_REFERENCE, null);
        name.addOnChange(showMessage);
        
        // change the form labels
        changeForm();
        
        // update the result message
        showMessage();
    
      } catch (error) {
        alert("Could not set up custom form\n\n" + error);
      }
    }

    The new code also adds an onChange event to the SHOWAGE and NAMEFIELD fields. A call to dereferenceEx retrieves the FormNodeP object that represents each field, then an onChange event handler is added with the FormNodeP method addOnChange. In this case, the onChange event of both fields is handled by the function showMessage, which you will add in a later step.

    It also contains a call to the changeForm function which rewrites the labels within the form. You will add the changeForm function in a later step.

    Finally, it has a call to showMessage, which you will add next.

  2. Add the function showMessage. The JavaScript API passes an XFDL event object as the only parameter to this function, but showMessage ignores it. Instead, you will use the JavaScript API method getLiteralByRefEx to retrieve the person's name and age from the form. With that data, showMessage builds a string then inserts it into the paragraph that has the HTML id "message".
    function showMessage(xfdlEvent) {
    
      var theForm = ibmForms[objectID];
      var s;
      
      try {
        s = theForm.getLiteralByRefEx(null, "PAGE1.NAMEFIELD.value", 0, null);
        s += " is " + theForm.getLiteralByRefEx(null, "PAGE1.SHOWAGE.value",
                              0, null) + " years old."
        document.getElementById("message").innerHTML = s;
      } catch (error) {
        alert("Can't show the name and age information\n" + error);
      }
    
    }
  3. Add the function changeForm. This uses the JavaScript API function setLiteralByRefEx to change both the title of the form and the text that describes what the form does.
    function changeForm() {
      
      var theForm = ibmForms[objectID];
      var s;
      
      try {
        s = "Calculate a Person's Age";
        theForm.setLiteralByRefEx(null, "PAGE1.TITLE.value", 0, null, s);
        
        s = "This is a simple form that calculates a person's age.\n";
        s += "The age is updated whenever one of the values is changed.\n\n"
        s += "Click on the 'Insert Today's Date' button to insert today's date.";
        theForm.setLiteralByRefEx(null, "PAGE1.LABEL1.value", 0, null, s);
        
      } catch (error) {
        alert("Could not change one or more labels on the form\n" + error);
      }
    
    }
  4. Add the insertToday function. It inserts the current date into the form, and is called when the 'Insert Today's Date' button is clicked. Also add the closing tags for the script and head elements.
    function insertToday() {
    
      var theForm = ibmForms[objectID];
      var today = new Date();
    	
      try {
        theForm.setLiteralByRefEx(null, "PAGE1.CURRENTYEAR.value", 0, null,
                today.getFullYear().toString());
        theForm.setLiteralByRefEx(null, "PAGE1.CURRENTMONTH.value", 0, null,
                (today.getMonth()+1).toString());
        theForm.setLiteralByRefEx(null, "PAGE1.CURRENTDAY.value", 0, null,
                today.getDate().toString());
    	  
      } catch (ex) {
        alert("Failed to set today's date.\n" + ex);
      }
    
    }
    
    </script>
    </head>
  5. Add a heading, a button, and the message container paragraph to the HTML body, as shown in bold:
    <body>
    
      <h3>JavaScript API Sample</h3>
    
      <div id="viewer">
    
        <script type="text/javascript">
          addViewer (
            "viewer",                  // id of the HTML div element
            objectID,                  // id to assign to the object element
            500, 400,                  // width and height of the Viewer
            "XFDLID", "XFDLData",      // name-value pair for XFDL param
            "detach_id", "2507088000"  // name-value pair for detach_id param
          );
        </script>
    
      </div>
    
      <input type="button" value="Insert Today's Date" onClick="insertToday();"/>
    
      <div style="width:200px;margin-top:10px;padding:5px;border:solid blue thin">
        <p id="message"></p>
      </div>
    
    </body>
    </html>
  6. Save the file and open it in your browser.

When you open the file, notice the changes to the form. Click the "Insert Today's Date" button and change the values of one or more fields. You have turned an old, static form into a simple interactive application.

The entire file, including the Calculate Age XFDL form, is shown in The complete application.

The complete application

The complete tutorial application is shown here, including the embedded Calculate Age form. To run the application, paste the HTML below into a new file then open it in your Web browser.
<html>
<head>
<script type="text/javascript" src="LF_XFDL.js"></script>
<script type="text/javascript" src="LF_FormNodeP.js"></script>
<script type="text/javascript" src="LF_ViewerScript.js"></script>
<script language="XFDL" id="XFDLData" type="application/vnd.xfdl; wrapped=comment">
<!--
<?xml version="1.0" encoding="UTF-8"?>
<XFDL xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom" 
 xmlns:designer="http://www.ibm.com/xmlns/prod/workplace/forms/designer/2.6"
 xmlns:xfdl="http://www.ibm.com/xmlns/prod/XFDL/7.0"
 xmlns="http://www.ibm.com/xmlns/prod/XFDL/7.0">
   <globalpage sid="global">
      <global sid="global">
         <label>Calculate Age Input</label>
         <transmitformat>application/vnd.xfdl</transmitformat>
         <saveformat>application/vnd.xfdl</saveformat>
         
         <designer:date>12/3/98</designer:date>
         <printsettings>
            <dialog>
               <copies>1</copies>
            </dialog>
         </printsettings>
         <formid>
            <version>1.5.3</version>
         </formid>
      </global>
   </globalpage>
   <page sid="PAGE1">
      <global sid="global">
         <designer:pagesize>960;1260</designer:pagesize>
         
         
      </global>
      <label sid="TITLE">
         <value>Calculate Age &#xD;
Input Form</value>
         <fontinfo>
            <fontname>Helvetica</fontname>
            <size>14</size>
            <effect>bold</effect>
         </fontinfo>
         <itemlocation>
            <x>17</x>
            <y>12</y>
         </itemlocation>
         <fontcolor>0,0,0</fontcolor>
         <justify>left</justify>
      </label>
      <label sid="NAMELABEL">
         <value>Name:</value>
         <itemlocation>
            <x>19</x>
            <y>178</y>
         </itemlocation>
      </label>
      <field sid="NAMEFIELD">
         <value>Jane E. Smith</value>
         <itemlocation>
            <x>74</x>
            <y>178</y>
            <width>166</width>
            <height>22</height>
         </itemlocation>
      </field>
      <label sid="BIRTHLABEL">
         <value>Date of Birth:</value>
         <itemlocation>
            <x>19</x>
            <y>227</y>
         </itemlocation>
      </label>
      <field sid="BIRTHYEAR">
         <label>Year</label>
         <value>1972</value>
         <format>
            <datatype>integer</datatype>
            <presentation>
              <groupingseparator>none</groupingseparator>
            </presentation>               
         </format>
         <size>
            <width>6</width>
            <height>1</height>
         </size>
         <itemlocation>
            <x>141</x>
            <y>206</y>
         </itemlocation>
      </field>
      <field sid="BIRTHMONTH">
         <label>Month</label>
         <value>9</value>
         <format>
            <datatype>month</datatype>
            <constraints>
            </constraints>
            <presentation>
                <style>short</style>
            </presentation>
         </format>
         <size>
            <width>4</width>
            <height>1</height>
         </size>
         <itemlocation>
            <x>210</x>
            <y>206</y>
         </itemlocation>
      </field>
      <field sid="BIRTHDAY">
         <label>Day</label>
         <value>14</value>
         <format>
            <datatype>day_of_month</datatype>
         </format>
         <size>
            <width>4</width>
            <height>1</height>
         </size>
         <itemlocation>
            <x>268</x>
            <y>206</y>
         </itemlocation>
      </field>
      <label sid="SHOWAGE">
         <itemlocation>
            <x>73</x>
            <y>328</y>
         </itemlocation>
         <value compute="
            PAGE1.HIDDENYEAR.value == '' ? 'run calculateAge and see output.xfd' &#xA;
            : ((PAGE1.CURRENTMONTH.value > PAGE1.BIRTHMONTH.value) or  &#xA;
            ! ( ! (PAGE1.CURRENTMONTH.value == PAGE1.BIRTHMONTH.value) or  &#xA;
            ! (PAGE1.CURRENTDAY.value > PAGE1.BIRTHDAY.value)) &#xA;
            ? PAGE1.CURRENTYEAR.value - PAGE1.BIRTHYEAR.value &#xA;
            : PAGE1.CURRENTYEAR.value - PAGE1.BIRTHYEAR.value - '1')&#xA;
            ">run calculateAge and see output.xfd
         </value>
      </label>
      <label sid="DATELABEL">
         <value>Today's date:</value>
         <fontcolor>0,0,0</fontcolor>
         <itemlocation>
            <x>19</x>
            <y>282</y>
            <width>83</width>
            <height>23</height>
         </itemlocation>
      </label>
      <field sid="CURRENTYEAR">
         <label>Year</label>
         <value>2001</value>
         <format>
            <datatype>integer</datatype>
            <presentation>
              <groupingseparator>none</groupingseparator>
            </presentation>               
         </format>
         <size>
            <width>6</width>
            <height>1</height>
         </size>
         <itemlocation>
            <x>141</x>
            <y>262</y>
         </itemlocation>
      </field>
      <field sid="CURRENTMONTH">
         <label>Month</label>
         <value>9</value>
         <format>
            <datatype>month</datatype>
            <constraints>
            </constraints>
            <presentation>
                <style>short</style>
            </presentation>
         </format>
         <size>
            <width>4</width>
            <height>1</height>
         </size>
         <itemlocation>
            <x>210</x>
            <y>262</y>
         </itemlocation>
      </field>
      <field sid="CURRENTDAY">
         <label>Day</label>
         <value>13</value>
         <format>
            <datatype>day_of_month</datatype>
         </format>
         <size>
            <width>4</width>
            <height>1</height>
         </size>
         <itemlocation>
            <x>268</x>
            <y>262</y>
         </itemlocation>
      </field>
      <label sid="LABEL1">
         <itemlocation>
            <x>15</x>
            <y>78</y>
         </itemlocation>
         <value>This is a demonstration of the Calculate Age application&#xD;
presented in the IBM(R) Lotus(R) Forms Server - API Installation &amp; Setup Guide.&#xD;
&#xD;
Fill out and save this input form. Run the Calculate Age application.&#xD;
View the results in the output form called "output.xfd".</value>
         <fontinfo>
            <fontname>Helvetica</fontname>
            <size>8</size>
            <effect>plain</effect>
         </fontinfo>
         <justify>left</justify>
      </label>
      <field sid="HIDDENYEAR">
         <itemlocation>
            <x>343</x>
            <y>181</y>
            <width>51</width>
            <height>22</height>
         </itemlocation>
         <value></value>
         <visible>off</visible>
      </field>
      <field sid="HIDDENMONTH">
         <itemlocation>
            <x>344</x>
            <y>216</y>
            <width>49</width>
            <height>22</height>
         </itemlocation>
         <value></value>
         <visible>off</visible>
      </field>
      <field sid="HIDDENDAY">
         <itemlocation>
            <x>344</x>
            <y>248</y>
            <width>50</width>
            <height>23</height>
         </itemlocation>
         <value></value>
         <visible>off</visible>
      </field>
      <label sid="AGELABEL">
         <itemlocation>
            <x>19</x>
            <y>327</y>
            <width>38</width>
            <height>24</height>
         </itemlocation>
         <value>Age:</value>
      </label>
      <spacer sid="vfd_spacer">
         <itemlocation>
            <x>420</x>
            <y>360</y>
            <width>1</width>
            <height>1</height>
         </itemlocation>
      </spacer>
   </page>
</XFDL>
-->
</script>
<script type="text/javascript">

  var objectID = "Main";
  window.onload = OnLoadForm;

  function OnLoadForm() {
    try {
      var theForm = new FormNodeP(objectID);
      XFDL.registerForm(theForm, objectID);
    } catch (error) {
      alert("Could not register the form\n" + error);
      return;
    }
  
    try {
      // put any value in the HIDDENYEAR field, which activates the compute
      ibmForms[objectID].setLiteralByRefEx(null, "PAGE1.HIDDENYEAR.value",
                         0, null, "trigger compute");
      
      // set up a couple of OnChange events
      var age = ibmForms[objectID].dereferenceEx(null, "PAGE1.SHOWAGE", 0,
                FormNodeP.UFL_ITEM_REFERENCE, null);
      age.addOnChange(showMessage);
      var name = ibmForms[objectID].dereferenceEx(null, "PAGE1.NAMEFIELD", 0,
                 FormNodeP.UFL_ITEM_REFERENCE, null);
      name.addOnChange(showMessage);
      
      // change the form labels
      changeForm();
      
      // update the result message
      showMessage();
      
    } catch (error) {
      alert("Could not set up custom form\n\n" + error);
    }
  }
  
  function showMessage(xfdlEvent) {
    
    var theForm = ibmForms[objectID];
    var s;
    
    try {      
      s = theForm.getLiteralByRefEx(null, "PAGE1.NAMEFIELD.value", 0, null);
      s += " is " + theForm.getLiteralByRefEx(null, "PAGE1.SHOWAGE.value", 0, null) + " years old."
      document.getElementById("message").innerHTML = s;
    } catch (error) {
      alert("Can't show message\n" + error);
    }
  }

  function changeForm() {
    
    var theForm = ibmForms[objectID];
    var s;
    
    try {      
      s = "Calculate a Person's Age";
      theForm.setLiteralByRefEx(null, "PAGE1.TITLE.value", 0, null, s);
      
      s = "This is a simple form that calculates a person's age.\n";
      s += "The age is updated whenever one of the values is changed.\n\n"
      s += "Click on the 'Insert Today's Date' button to insert today's date.";
      theForm.setLiteralByRefEx(null, "PAGE1.LABEL1.value", 0, null, s);
      
    } catch (error) {
      alert("Could not change one or more labels on the form\n" + error);
    }
  }
  
  function insertToday() {
    
    var theForm = ibmForms[objectID];
    var today = new Date();
  
    try {      
      theForm.setLiteralByRefEx(null, "PAGE1.CURRENTYEAR.value", 0, null,
              today.getFullYear().toString());
      theForm.setLiteralByRefEx(null, "PAGE1.CURRENTMONTH.value", 0, null,
              (today.getMonth()+1).toString());
      theForm.setLiteralByRefEx(null, "PAGE1.CURRENTDAY.value", 0, null,
              today.getDate().toString());
    
    } catch (ex) {
      alert("Failed to set today's date.\n" + ex);
    }
  }

</script>
</head>

<body>

<h3>JavaScript API Sample</h3>

<div id="viewer">
  <script type="text/javascript">

      addViewer (
        "viewer",                  // id of the HTML div element
        objectID,                  // id to assign to the object element
        500, 400,                  // width and height of the Viewer
        "XFDLID", "XFDLData",      // name-value pair for XFDL param
        "detach_id", "2507088000"  // name-value pair for detach_id param
      );

    </script>

</div>

<input type="button" value="Insert Today's Date" onClick="insertToday();"/>

<div style="width:200px;margin-top:10px;padding:5px;border:solid blue thin">
  <p id="message"></p>
</div>

</body>
</html>

Summary

By working through this tutorial, you have turned an existing static form into an interactive form. In the process, you learned how to set up a Web page that uses the JavaScript API to access an XFDL form inside an embedded Viewer. Of the over 50 methods in the API, you used the following handful to create an interactive application:
  • addViewer
  • registerForm
  • setLiteralByRefEx
  • getLiteralByRefEx
  • dereferenceEx

You also learned how to register a form and then access it through the global array ibmForms[].

FormNodeP object

Contains the methods that manipulate forms. This is the primary object that you use for adding, revising, deleting, and validating form content.

Each XFDL element in a form corresponds to a FormNodeP object. The API represents a form in memory as a DOM-like tree structure, with a FormNodeP object at each node, including the root node.

Any Web page that has JavaScript™ calls to the FormNodeP methods must include the script file LF_FormNodeP.js For example:
<script type="text/javascript" src="LF_FormNodeP.js"></script>
Note: Although typed parameters are not used in JavaScript, they are included in the method descriptions to indicate the types that are expected by each method. You declare variables for these parameters using the normal JavaScript var statement.

addNamespace method

Description

This method adds a namespace declaration to the node it is called on. Each namespace is defined in the form using the XML xmlns namespace declaration as shown in these two sample declarations:

   xmlns:xfdl="http://www.ibm.com/xmlns/prod/XFDL/7.7" 
   xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom"

Each namespace declaration defines a prefix and a URI for the namespace. In the samples shown, the prefix for the XFDL namespace is xfdl and the URI is http://www.ibm.com/xmlns/prod/XFDL/7.7. The prefix for the custom namespace is custom and the URI is http://www.ibm.com/xmlns/prod/XFDL/Custom.

Tags within the form are assigned specific namespaces by using the defined prefix. For example, to declare that an option is in the custom namespace, use the prefix custom as shown:

   <field sid="testField">
      <custom:custom_option>value</custom:custom_option>
   </field>

Method

void addNamespace(
   String uri,
   String prefix
);

Parameters

Table 9. Method parameters
Expression Type Description
uri String The namespace URI. For example:
http://www.ibm.com/xmlns/prod/XFDL/7.7
prefix String The prefix for the namespace. For example, xfdl.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample function adds a new namespace to the form that is passed in. It also adds a namespace with the prefix "myspace" to the PAGE1.FIELD1 node on the form.

function AddNamespace(theForm) {
  var s;
  var fieldNode;

  s = "--- Results of addNamespace test ---\n";
  theForm.addNamespace("http://www.example.com/xmlns/newspace", "news");
  s += " Namespace added to form.\n";

  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD1", 0, 
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(fieldNode == null) {
    s += " Could not locate FIELD1 node.\n";
  } else {
     fieldNode.addNamespace("http://www.example.com/xmlns/myspace", "myspace");
     s += " Namespace added to PAGE1.FIELD1.\n";
  }
  alert(s);
}
The message displayed in the alert box should be:
--- Results of addNamespace test ---
 Namespace added to form.
 Namespace added to PAGE1.FIELD1.

addOnBlur method

Description

This method registers an event handler for the onBlur event. The onBlur event occurs when an item loses focus. It is applicable to the following form items only:
  • button
  • check
  • combobox
  • field
  • list
  • popup
  • radio
  • slider
  • page global
The page global is on each page of your form. The onBlur event occurs when you go to a new page on the form.

Method

void addOnBlur (
   Function handler
);

Parameters

Table 10. Method parameters
Expression Type Description
handler Function The name of the function that will be called when the onBlur event occurs.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

The event handler that you register should take an event object as its input parameter. The event object has two properties:
  • type – a string representing the type of event. The possible values are "blur", "change", "click", and "focus"
  • source – the formNodeP on which the event occurred

Example

The sample code adds an onBlur event handler to BUTTON1. The event handler is given the name button1OnBlur, but you can use any name that you want. The event handler displays the type of event and the local name of the source node.

function registerButtonEvent(theForm) {
  var buttonNode;
  var s;
  
  s = "- Results of registerButtonEvent function call -\n";
  buttonNode = theForm.dereferenceEx(null, "PAGE1.BUTTON1", 0, 
               FormNodeP.UFL_ITEM_REFERENCE, null);
  if(buttonNode == null) {
    s += " Could not find BUTTON1 on the form.\n";
  } else {
    buttonNode.addOnBlur(button1OnBlur);
    s += " function button1OnBlur registered.\n";
  }
  alert(s);

}

function button1OnBlur(xfdlEvent) {
   alert(xfdlEvent.type);
   alert(xfdlEvent.source.getLocalName());
}

addOnChange method

Description

This method registers an event handler for the onChange event. The onChange event occurs when the value of an item changes. It is applicable to the following form items only:
  • button
  • check
  • checkgroup
  • combobox
  • field
  • label
  • list
  • popup
  • radio
  • radiogroup
  • slider

Method

void addOnChange (
   Function handler
);

Parameters

Table 11. Method parameters
Expression Type Description
handler Function The name of the function that will be called when the onChange event occurs.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

The event handler that you register should take an event object as its input parameter. The event object has two properties:
  • type – a string representing the type of event. The possible values are "blur", "change", "click", and "focus"
  • source – the formNodeP on which the event occurred

Example

The sample code adds an onChange event handler to BUTTON1. The event handler is given the name button1OnChange, but you can use any name that you want. The event handler displays the type of event and the local name of the source node.

function registerButtonEvent(theForm) {
  var buttonNode;
  var s;
  
  s = "--- Results of registerButtonEvent function call ---\n";
  buttonNode = theForm.dereferenceEx(null, "PAGE1.BUTTON1", 0, 
               FormNodeP.UFL_ITEM_REFERENCE, null);
  if(buttonNode == null) {
    s += " Could not find BUTTON1 on the form.\n";
  } else {
    buttonNode.addOnChange(button1OnChange);
    s += " Function button1OnChange registered.\n";
  }
  alert(s);
}

function button1OnChange(xfdlEvent) {
   alert(xfdlEvent.type);
   alert(xfdlEvent.source.getLocalName());
}   

addOnClick method

Description

This method registers an event handler for the onClick event. The onClick event occurs when an item is clicked with the mouse. It is applicable to the following form items only:
  • button
  • check
  • combobox
  • field
  • list
  • popup
  • radio
  • slider

Method

void addOnClick (
   Function handler
);

Parameters

Table 12. Method parameters
Expression Type Description
handler Function The name of the function that will be called when the onclick event occurs.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

The event handler that you register should take an event object as its input parameter. The event object has two properties:
  • type – a string representing the type of event. The possible values are "blur", "change", "click", and "focus"
  • source – the formNodeP on which the event occurred

Example

The sample code adds an onClick event handler to BUTTON1. The event handler is given the name button1OnClick, but you can use any name that you want. The event handler displays the type of event and the local name of the source node.

function registerButtonEvent(theForm) {
  var buttonNode;
  var s;
  
  s = "--- Results of registerButtonEvent function call ---\n";
  buttonNode = theForm.dereferenceEx(null, "PAGE1.BUTTON1", 0, 
               FormNodeP.UFL_ITEM_REFERENCE, null);
  if(buttonNode == null) {
    s += " Could not find BUTTON1 on the form.\n";
  } else {
    buttonNode.addOnClick(button1OnClick);
    s += " function button1OnClick registered.\n";
  }
  alert(s);
}

function button1OnClick(xfdlEvent) {
  alert(xfdlEvent.type);
  alert(xfdlEvent.source.getLocalName());
}

addOnFocus method

Description

This method registers an event handler for the onFocus event. The onFocus event occurs when an item gets focus. It is applicable to the following form items only:
  • button
  • check
  • combobox
  • field
  • list
  • popup
  • radio
  • slider
  • page global
The page global is on each page of your form. The onFocus event occurs when you go to a new page in the form.

Method

   void addOnFocus (
   Function handler
);   

Parameters

Table 13. Method parameters
Expression Type Description
handler Function The name of the function that will be called when the onFocus event occurs.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

The event handler that you register should take an event object as its input parameter. The event object has two properties:
  • type – a string representing the type of event. The possible values are "blur", "change", "click", and "focus"
  • source – the formNodeP on which the event occurred
The following code sample demonstrates a simple event handler for the onFocus event of BUTTON1:
function button1OnFocus(xfdlEvent) {
   alert(xfdlEvent.type);
   alert(xfdlEvent.source.getInfoEx(FormNodeP.IDENTIFIER));
}

Example

The sample code adds an onFocus event handler to BUTTON1. The event handler is given the name button1OnFocus, but you can use any name that you want. The event handler displays the type of event and the local name of the source node.

function registerButtonEvent(theForm) {
  var buttonNode;
  var s;
  
  s = "--- Results of registerButtonEvent function call ---\n";
  buttonNode = theForm.dereferenceEx(null, "PAGE1.BUTTON1", 0, 
               FormNodeP.UFL_ITEM_REFERENCE, null);
  if(buttonNode == null) {
    s += " Could not find BUTTON1 on the form.\n";
  } else {
    buttonNode.addOnFocus(button1OnFocus);
    s += " function button1OnFocus registered.\n";
  }
  alert(s);
}

function button1OnFocus(xfdlEvent) {
   alert(xfdlEvent.type);
   alert(xfdlEvent.source.getLocalName());
}

checkValidFormats method

Description

This method checks the format of either all items on the form or all items on a single page. It returns a list of items that have non valid formats.

Method

   FormNodeP[] checkValidFormats( );

Parameters

There are no parameters for this method.

Returns

The list of all nodes with non valid formats. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code takes the root node of the form as input, calls checkValidFormats, then displays the results in a JavaScript alert window.

function testCheckValidFormats(theForm) {
  var nodes = new Array();
  var s;
  
  s = "--- Results of checkValidFormats test ---\n";
  nodes = theForm.checkValidFormats();
  if(nodes == null || nodes.length == 0) {
    s += " All nodes have valid formats.\n";
  } else {
    s += " These nodes have non valid formats:\n"
    for(i = 0; i < nodes.length; i++) {
      s += "  Node: " + nodes[0].getReferenceEx(null, null, null, false) + "\n";
    }
  }
  alert(s);
}   
The message displayed in the alert box should look something like this, depending on which fields, if any, do not have valid formats on the form:
--- Results of checkValidFormats test ---
  These nodes have non valid formats:
   Node: PAGE1.FIELD1

createCell method

Description

Use this method to create a new cell item for a combobox, list, or popup. The createCell method adds one new cell to a group on a page in the form. Note that this method can only assign a name to the new cell; it cannot set the value of the cell. To set the value of a cell, you must use the setLiteralByRefEx method.

This method is called from a page level node, and creates the new cell in that page. Note that you cannot call this method from the global page node.

Method

FormNodeP createCell(
   String cellName,
   String groupName
);

Parameters

Table 14. Method parameters
Expression Type Description
cellName String The name of the new cell being created.
groupName String The name of the group option to which the new cell will be added.

Returns

A FormNodeP containing the new cell. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

This sample code makes two calls to createCell to add two new cells to the same group. Each call to createCell is followed by a call to setLiteralByRefEx to set the value for the new cell.

function testCreateCell(theForm) {
  var newCell;
  var pageNode;
  var s;
  
  s = "--- Results of createCell test ---\n";
  pageNode = theForm.dereferenceEx(null, "PAGE1", 0,
             FormNodeP.UFL_PAGE_REFERENCE, null);
  if(pageNode == null) {
    s += "Could not find PAGE1 on the form.";
  } else {
    newCell = pageNode.createCell("ORANGE_CELL", "POPUP1_GROUP");
    newCell.setLiteralByRefEx(null, "value", 0, null, "Orange");
  	
    newCell = pageNode.createCell("PURPLE_CELL", "POPUP1_GROUP");
    newCell.setLiteralByRefEx(null, "value", 0, null, "Purple");
  	
    s += " Cells added to the popup item.";
  }
  alert(s);
}  
The message displayed in the alert box should be:
--- Results of createCell test ---
 Cells added to the popup item.

deleteSignature method

Description

This method deletes the specified digital signature in the form. For security reasons, the form must meet certain criteria before this is allowed. None of the following should be locked by another signature: the signature, its descendants, the associated signature button, and its signer option. If these criteria are met, then the signature's locks are removed, the signature item is deleted, and the signer of the associated signature button is set to empty ("").

Method

void deleteSignature(
    FormNodeP signatureItem 
);  

Parameters

Table 15. Method parameters
Expression Type Description
signatureItem FormNodeP The signature node to delete. You can retrieve this node by calling dereferenceEx

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

If the signatureItem item contains a layoutinfo option, deleteSignature will not remove the entire signature from the form. Instead, the signature item and the layoutinfo option will remain. To completely delete the signature item, you must delete the remaining nodes manually by using destroy to delete the signature item.

Example

function testDeleteSignature(theForm) {
  var s;
  var node;
  
  s = "--- Results of deleteSignature test ---\n";
  node = theForm.dereferenceEx(null, "PAGE1.BUTTON1_SIGNATURE_405824760", 0,
         FormNodeP.UFL_ITEM_REFERENCE, null);
  if(node == null) {
    s += " Could not find PAGE1.BUTTON1_SIGNATURE_405824760 on the form.\n";
  } else {
    theForm.deleteSignature(node);
    s += " The signature has been deleted.\n";
  }
  alert(s);
}   
If the signature exists on the form, the message displayed in the alert box should be:
--- Results of deleteSignature test --
 The signature has been deleted.

dereferenceEx method

Description

Use this function to locate a particular FormNodeP, to locate a cell in a particular group, or to locate a data item in a particular datagroup.

Note: It is not necessary to call this method when you are working with an XForms data model. The updateXFormsInstance and extractXFormsInstance methods perform this task automatically.

Method

   FormNodeP dereferenceEx(
      String scheme,
      String reference,
      Number referenceCode,
      Number referenceType,
      FormNodeP NSNode
   );

Parameters

Table 16. Method parameters
Expression Type Description
scheme String Reserved. This must be null.
reference String The reference string.
referenceCode Number Reserved. This must be 0.
referenceType Number One of the following constants:

FormNodeP.UFL_PAGE_REFERENCE— Indicates page level nodes. For example, PAGE1.

FormNodeP.UFL_ITEM_REFERENCE — Indicates item level nodes. For example, PAGE1.FIELD1.

FormNodeP.UFL_OPTION_REFERENCE — Indicates option level nodes. For example, PAGE1.FIELD1.itemlocation.

FormNodeP.UFL_ARRAY_REFERENCE — Indicates argument level nodes. For example, PAGE1.FIELD1.itemlocation[2].

FormNodeP.UFL_GROUP_REFERENCE — Indicates grouped nodes, such as radio button or checkbox groups. For example, PAGE1.group1.

FormNodeP.UFL_DATAGROUP_REFERENCE — Indicates a datagroup node, such as an attachment. For example, PAGE1.datagroup1.

If it is an option or argument reference, you can use bitwise OR ( | ) with one of:

FormNodeP.UFL_SEARCH — Searches for the requested node or returns null if the node is not found.

FormNodeP.UFL_SEARCH_AND_CREATE — Searches for the requested node or creates one if the node is not found.

If it is a group or datagroup reference, you can use bitwise OR ( | ) with one of:

FormNodeP.UFL_FIRST — Finds the first cell or data item in the group or datagroup.

FormNodeP.UFL_NEXT — Finds the next cell or data item in the group or datagroup.

NSNode FormNodeP A node that is used to resolve the namespaces in the reference parameter (see the note about namespace below). Use null if the node that this method is operating on has inherited the necessary namespaces.

Returns

The FormNodeP defined by the reference string or null if the referenced node does not exist and FormNodeP.UFL_SEARCH_AND_CREATE is not specified. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

FormNodeP

Before you decide which FormNodeP to use this method on, be sure you understand the following:

  1. The FormNodeP supplied can never be more than one level in the hierarchy above the starting point of the reference string. For example, if the reference string begins with an option, then the FormNodeP can be no higher in the hierarchy than an item.
  2. If the FormNodeP is at the same level or lower in the hierarchy than the starting point of the reference string, the method will attempt to locate a common ancestor. The method will locate the ancestor of the FormNodeP that is one level in the hierarchy above the starting point of the reference string. The method will then attempt to follow the reference string back down through the hierarchy. If the reference string cannot be followed from the located ancestor (for example, if the ancestor is not common to both the FormNodeP and the reference string), the function will fail. For example, given a FormNodeP that represents field_1 and a reference of field_2, the function will access the page node above field_1, and will then try to locate field_2 below that node. If the two fields are not on the same page, the function fails.
  3. dereferenceEx does not support the XForms scheme.

Creating a reference string

For general information about creating a reference string, see About references .

Reference strings for groups or datagroups follow this format:

   page.group. or page.datagroup

In both cases, the page component is optional. It is only required if you want to search a different page than the one containing your reference node.

For example, to refer to the "State" group of cells on PAGE1 of the form, use:

   PAGE1.State

Locating cells or data items

If you want to locate a cell or a data item, you must perform a bitwise OR with UFL_FIRST or UFL_NEXT. UFL_FIRST will locate the first cell or data item in the page. UFL_NEXT will locate the next cell or data item. This allows you to loop through all the cells or data item on a page until you have found the one you want.

Note that groups and datagroups are limited to a single page, and that your search will likewise be limited to a single page.

Creating a node

For an option or argument reference, you can have the library create a node that does not exist. To do so, perform a bitwise OR of UFL_SEARCH_AND_CREATE to the referenceType parameter; otherwise, perform a bitwise OR of UFL_SEARCH to the referenceType variable and the function will return null if the node does not exist.

Determining namespace

In some cases, you may want to use the dereferenceEx method to locate a node that does not have a globally defined namespace. For example, consider the following form:

   <label sid="Label1">
      <value>Field1.processing:myValue</value>
   </label>
   <field sid="Field1" xmlns:processing="URI">
      <value></value>
      <processing:myValue>10<processing:myValue>
   </field>

In this form, the processing namespace is declared in the Field1 node. Any elements within Field1 will understand that namespace; however, elements outside of the scope of Field1 will not.

In cases like this, you will often start your search at a node that does not understand the namespace of the node you are trying to locate. For example, you might want to locate the node referenced in the value of Label1. In this case, you would first locate the Label1 value node and get its literal. Then, from the Label1 value node, you would attempt to locate the processing:myValue node as shown:

   Label1Node.dereferenceEx(null, "Field1.processing:myValue", 0,
      FormNodeP.UFL_OPTION_REFERENCE, null)

In this example, the dereferenceEx method would fail. The method cannot properly resolve the processing namespace because this namespace is not defined for the Label1 value node. To correct this, you must also provide a node that understands the processing namespace (in this case, any node in the scope of Field1) as the last parameter in the method:

   Label1Node.dereferenceEx(null, "Field1.processing:myValue", 0,
      FormNodeP.UFL_OPTION_REFERENCE, Field1Node)

Example

The sample code makes a variety of calls to dereferenceEx and displays the results in a JavaScript alert() message.

function testDereferenceEx(theForm) {
  
  var s;
  var tempNode;
  
  s = "--- results of dereferenceEx test ---\n";
  /* find PAGE2 */
  s += "1. ";
  tempNode = theForm.dereferenceEx(null, "PAGE2", 0, 
             FormNodeP.UFL_PAGE_REFERENCE, null);
  if(tempNode == null) {
    s += "Could not find PAGE2 on the form.\n";
  } else {
    s += "PAGE2 found.\n";
  }
  
  /* find PAGE1.FIELD3 */
  s += "2. ";
  tempNode = theForm.dereferenceEx(null, "PAGE1.FIELD3", 0, 
             FormNodeP.UFL_ITEM_REFERENCE, null);
  if(tempNode == null) {
    s += "Could not find PAGE1.FIELD3 on the form.\n";
  } else {
    s += "PAGE1.FIELD3 found.\n";
  }
  
  /* find fontinfo of FIELD3, create if not found*/
  s += "3. ";
  tempNode = theForm.dereferenceEx(null, "PAGE1.FIELD3.fontinfo[fontname]", 0, 
             FormNodeP.UFL_ARRAY_REFERENCE | FormNodeP.UFL_SEARCH_AND_CREATE, null);
  if(tempNode == null) {
    s += "Could not create PAGE1.FIELD3.fontinfo[fontname].\n";
  } else {
    s += "PAGE1.FIELD3.fontinfo[fontname] created.\n";
  }
  
  /* find the first node in the COMBOBOX1_GROUP group */
  s += "4. ";
  tempNode = theForm.dereferenceEx(null, "PAGE1.COMBOBOX1_GROUP", 0, 
             FormNodeP.UFL_GROUP_REFERENCE | FormNodeP.UFL_FIRST, null);
  if(tempNode == null) {
    s += "Could not find PAGE1.COMBOBOX1_GROUP.\n";
  } else {
    s += "The first COMBOBOX1_GROUP on PAGE1 is: ";
    s += tempNode.getAttribute("http://www.ibm.com/xmlns/prod/XFDL/7.5", "sid");
  }
  alert(s);
}
A typical message displayed in the alert box might look like this:
--- Results of dereferenceEx test ---
 1. Could not find PAGE2 on the form.
 2. PAGE1.FIELD3 found.
 3. PAGE1.FIELD3.fontinfo[fontname] created.
 4. The first PAGE1.COMBOBOX1_GROUP is: ORANGE_CELL.

destroy method

Description

This method destroys the indicated FormNodeP and all of its child nodes.

Method

void destroy( );

Parameters

There are no parameters for this method.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

Attempting to destroy a form or a digitally signed item causes an error.

Example

The sample code destroys PAGE1.FIELD2.

function testDestroy(theForm) {
  var s;
  var node;
  
  s = "--- Results of destroy test ---\n";
  node = theForm.dereferenceEx(null, "PAGE1.FIELD2", 0,
         FormNodeP.UFL_ITEM_REFERENCE, null);
  if(node == null) {
    s += " Could not find PAGE1.FIELD2 on the form.\n";
  } else {
    node.destroy();
    s += " PAGE1.FIELD2 has been destroyed.\n";
  }
  alert(s);
} 
The message displayed in the alert box should be:
--- Results of destroy test ---
 PAGE1.FIELD2 has been destroyed.

duplicate method

Description

This method makes a copy of a node. The duplicated node can be attached to any other node as either a sibling or a child, or can be stored as a separate node structure. The new node can also be assigned a new identifier with the identifier parameter. All of the properties of the original node are duplicated, including any children and any namespace settings.

Note: If you duplicate a node that is not in the XFDL namespace, the namespace is copied as part of the duplicated node, but is not set globally.

Method

   FormNodeP duplicate(
      FormNodeP baseNode,
      Number where,
      String identifier
   );   

Parameters

Table 17. Method parameters
Expression Type Description
baseNode FormNodeP The formNodeP to attach the new copy to. If null, then the node on which it is called is used as the baseNode.
where Number A constant that describes the location in relation to the supplied baseNode in which the new node should be placed. Can be one of:


UFL_APPEND_CHILD — adds the new node as the last child of the baseNode.


UFL_AFTER_SIBLING — adds the new node as a sibling of the baseNode, placing it immediately after that node in the form structure.


UFL_BEFORE_SIBLING — adds the new node as a sibling of the baseNode, placing it immediately before that node in the form structure.


UFL_ORPHAN — copies the node but does not insert it into the form structure.

identifier String The new id attribute for this node. If null, the id attribute of the original node is used.

Returns

The new node. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code makes a duplicate of PAGE1.FIELD1 and gives it the sid FIELD5. Because the new node is an exact copy of PAGE1.FIELD1, it will also have the same value and location as PAGE1.FIELD1. For this reason, the sample code uses setLiteralByRefEx to give FIELD5 a new value and location.

function testDuplicate(theForm) {
  var tempNode, newNode;
  var s;
  
  s = "--- Results of duplicate test ---\n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD1", 0, 
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(fieldNode == null) {
     s += " Could not locate FIELD1 node.";
  } else {
    newNode = fieldNode.duplicate(null, XFDL.UFL_AFTER_SIBLING, "FIELD5");
    if(newNode == null) {
      s += " Could not duplicate FIELD1 node.\n";
    } else {
      /* give the new node a new value and location */
      newNode.setLiteralByRefEx(null, "value", 0, 
              null, "this field is a duplicate of FIELD1");
      newNode.setLiteralByRefEx(null, "itemlocation[y]", 0, 
              null, "300");
      s += " FIELD1 duplicated and new field relocated.\n";
    }
  }
  alert(s);
}  
The message displayed in the alert box should look be:
--- Results of duplicate test ---
 FIELD1 duplicated and new field relocated.

encloseFile method

Description

This method encloses file data in a form. The formNodeP object can be either a page node or an item node. If the formNodeP is a page node, the method creates a data item in that page to contain the enclosure. If the formNodeP is an item node, it must be a data item, and the method encloses the file in that node.

Method

FormNodeP encloseFile(
   String data,
   String dataEncoding,
   String mimeType,
   String dataGroup,
   String identifier
 );   

Parameters

Table 18. Method parameters
Expression Type Description
data String The data to enclose.
dataEncoding String A string that represents the encoding of the data. Valid values are "xml", "base64", and "base64-gzip".
mimeType String The MIME type of the file. If null, the library will attempt to find a suitable MIME type for the file.
dataGroup String The data group to which this file should belong. If the object is a page node, you must provide this parameter. If the object is an item node, use null to keep the current datagroup option, or provide a different value to overwrite the option.
identifier String The identifier to assign to the new data item if one is created. If null, either the current name is used or a unique name is automatically generated for the new data item.

Returns

The item formNodeP that contains the enclosure on success or null on failure.On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code encloses a short string in the form and displays the result in a JavaScript alert() message.

function testEncloseFile(theForm) {
  var pageNode, newNode;
  var s, sData;
  
  s = "--- Results of encloseFile test ---\n";
  
  pageNode = theForm.dereferenceEx(null, "PAGE1", 0,
             FormNodeP.UFL_PAGE_REFERENCE, null);
  if(pageNode == null) {
    s += " Could not find PAGE1 on the form.";
  } else {
    s += " XML encoding test:\n";
    sData = "data to enclose as xml encoding";
    newNode = pageNode.encloseFile(sData, "xml", null, "dGroup", "xmldata");
    if(newNode == null) {
      s += "  Fail. The data was not enclosed.\n";
    } else {
      s += " Success. The data was enclosed.\n";
    }
  }
  alert(s);
}
   
The message displayed in the alert box should be:
--- Results of encloseFile test ---  
 XML encoding test:
 Success. The data was enclosed.

encloseInstance method

Description

This method modifies one instance in the data model, either updating information or appending information. Note that the form must have an existing data model.

Note: Use caution when calling this method. It can be used to overwrite signed instance data.

Method

   void encloseInstance(
      String instanceID,
      String  data,
      Number flags,
      String scheme,
      String rootReference,
      FormNodeP NSNode,
      boolean replaceNode
   );   

Parameters

Table 19. Method parameters
Expression Type Description
instanceID String The ID of the instance node to create or replace. This is defined by the id attribute of that node, and is case sensitive.

To replace the root node of the form, set this parameter to null.

data String A valid XML document.
flags Number Reserved. Must be 0.
scheme String Reserved. Must be null.
rootReference String A reference to the node you want to replace or append children to. This reference is relative to the instance node.

Use null to default to the instance node.

NSNode FormNodeP A node that inherits the namespaces used in the reference. This node defines the namespaces for the method. Use null if the node that this method is operating on has inherited the necessary namespaces.
replaceNode boolean If true, the node specified by rootReference is replaced with data. If false, the data is appended as the last child of the rootReference node.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code encloses some XML data in the form, then uses extractInstance for display in a JavaScript alert box. Note that in the sample, the instance "instance1" must exist in the XML data model.

function testEncloseInstance(theForm) {
  var s, xmlData;
  
  s = "--- Results of encloseInstance test ---\n";
  xmlData = "<data><flower>Rose</flower></data>";
  theForm.encloseInstance("instance1", xmlData, 0, null, null, null, true);
  s += " New contents of instance1:\n  ";
  s += theForm.extractInstance("instance1",null, "", 0, null, null, null) + "\n";
  
  alert(s);
}   
The message in the JavaScript alert box should be similar to this:
--- Results of encloseInstance test ---
 New contents of instance1:
  <data xmlns="" xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom"
 xmlns:designer="http://www.ibm.com/xmlns/prod/workplace/forms/designer/2.6"
 xmlns:test="http://www.ibm.com/xmlns/prod/XFDL/Custom"
 xmlns:xfdl="http://www.ibm.com/xmlns/prod/XFDL/7.5"
 xmlns:xforms="http://www.w3.org/2003/xforms">
    <flower>Rose</flower>
 </data>

extractFile method

Description

This method will extract an enclosure contained in a node and return it as a string. Note that this method does not remove the enclosure from the form.

Method

String extractFile(
   String dataEncoding
);   

Parameters

Table 20. Method parameters
Expression Type Description
dataEncoding String A string that represents the encoding of the returned data. Valid values are: "xml", "base64", and "base64-gzip".

Returns

The data is returned as a string in the encoding specified by the dataEncoding parameter. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code extracts the data in each of the possible encoding formats and displays the results in a JavaScript alert box. The XFDL fragment below shows the data that the sample operates on.
<data sid="data">
   <mimetype>text/base64-gzip</mimetype>
   <filename>base64-gzip.txt</filename>
   <mimedata encoding="base64-gzip">H4sIAAAAAAAAAEtJLElUKMlXSM1LzskvT
       lVILFZISixONTMBieSnZOalAwBjuqgyIgAAAA==</mimedata>
</data>
Note that the mimedata content has been artificially split to fit the width of this page.

In the above fragment, the plain-text version of the mimedata is: "data to enclose as base64 encoding".

function testExtractFile(theForm) {
  var fieldNode;
  var s, sData;
  
  s = "--- Results of extractFile test ---\n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.data", 0,
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(fieldNode == null) {
    s += " Could not find PAGE1.data on the form.";
  } else {
    s += " XML encoding test:\n";
    sData = fieldNode.extractFile("xml");
    if(sData == "") {
      s += "  Failed XML extract test.\n";
    } else {
      s += " The data with no encoding is:\n  '";
      s += sData + "'\n";
    }
    sData = fieldNode.extractFile("base64");
    if(sData == "") {
      s += "  Failed BASE64 extract test.\n";
    } else {
      s += " The data with base64 encoding is:\n  '";
      s += sData + "'\n";
    }
    sData = fieldNode.extractFile("base64-gzip");
    if(sData == "") {
      s += "  Failed BASE64-GZIP extract test.\n";
    } else {
      s += " The data with base64-gzip encoding is:\n  '";
      s += sData + "'";
    }
  }
  alert(s);
}
The message displayed in the alert box should look something like this:
--- Results of extractFile test ---
 XML encoding test:
  The data with no encoding is:
   'data to enclose as base64 encoding'
  The data with base64 encoding is:
   'ZGF0YSB0byBlbmNsb3NlIGFzIGJhc2U2NCBlbmNvZGluZw==' 
  The data with base64-gzip encoding is: 
   'H4sIAAAAAAAAC0tJLElUKMlXSM1LzskvTlVILFZISixONTMBieSnZOalAwBjuqgyIgAAAA=='

extractInstance method

Description

This method returns the XML instance data as a string. It does not remove the instance from the form.

Call this method on the root node of the form or an XML instance node.

Method

String extractInstance (
   String instanceID,
   FormNodeP triggerItem,
   String includeNamespacePrefixes,
   Number flags,
   String scheme,
   String rootReference,
   FormNodeP NSNode
);
  

Parameters

Table 21. Method parameters
Expression Type Description
instanceID String The ID of the instance node to extract. This is defined by the id attribute of that node.

To extract the root node of the form, set this parameter to null.

triggerItem FormNodeP

An item in the form, such as a button or cell, that defines the filtering for the instance. Filtering of elements is controlled by the transmit filters in the item. If all of an element's bound options are filtered out, then the element is also filtered out. Use null.for no filtering.

includeNamespacePrefixes String

To filter the namespaces, list the prefixes for those namespaces you want to include in the instance, separated by spaces.

For example, to include only the xfdl and custom namespaces, you would set this parameter to:

   xfdl custom

Use #default to indicate the default namespace for the instance.

Use an empty string ("") to include only those namespaces that are used by the instance.

Namespaces that are used in the instance are always included, regardless of this setting.

flags Number Reserved. This must be 0.
scheme String Reserved. Must be null.
rootReference String

A reference to the node you want to extract. This reference is relative to the instance node.

Use null to default to the instance node.

NSNode FormNodeP

A node that inherits the namespaces used in the reference. It defines the namespaces for the method. Use null if the node that this method is operating on has inherited the necessary namespaces.

Returns

The instance as a string. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code encloses some XML data in the form then uses extractInstance for display in a JavaScript alert box. Note that in the sample, the instance "instance1" must exist in the XML data model.

function testExtractInstance(theForm) {
  var s, xmlData;

  s = "--- Results of extractInstance test ---\n";
  xmlData = "<data><flower>Rose</flower></data>";
  theForm.encloseInstance("instance1", xmlData, 0, null, null, null, false);
  s += " New contents of instance1:\n  ";
  s += theForm.extractInstance("instance1",null, "", 0, null, null,null) + "\n";
  
  alert(s);
}   
The message in the JavaScript alert box should be similar to this:
--- Results of extractInstance test ---
 New contents of instance1:
  <data xmlns="" xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom"
 xmlns:designer="http://www.ibm.com/xmlns/prod/workplace/forms/designer/2.6"
 xmlns:test="http://www.ibm.com/xmlns/prod/XFDL/Custom"
 xmlns:xfdl="http://www.ibm.com/xmlns/prod/XFDL/7.5"
 xmlns:xforms="http://www.w3.org/2003/xforms">
     <flower>Rose</flower>
 </data>

extractXFormsInstance method

Description

This method returns the XForms instance data as a string. It does not remove the instance from the form.

Call this method on the root node of the form or an instance node.

Method

   String extractXFormsInstance(
      String modelID,
      String instanceXPath,
      boolean respectRelevantMIP,
      boolean ignoreFailures,
      FormNodeP NSNode,
   );  

Parameters

Table 22. Method parameters
Expression Type Description
modelID String The ID of the model to extract. Use null to extract the default model.
instanceXPath String An XPath reference to a node in the instance. This node and all of its children are copied. Leave blank to extract the entire instance.
respectRelevantMIP boolean

If true, returns only relevant instance data, else use false.

ignoreFailures boolean

If true, ignores constraint or validation failures, else use false.

NSNode FormNodeP

A node that inherits the namespaces used in the reference. This node defines the namespaces for the method. Use null if the node that this method is operating on has inherited the necessary namespaces.

Returns

XForms instance data as a string. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

XForms data model

The updateXFormsInstance and the extractXFormsInstance methods are the only methods that are intended to modify the XForms data model.

Example

The sample code extracts various portions of an instance and places the results in a string. It then displays the string in a JavaScript alert window.

Instance data:
<xformsmodels>
   <xforms:model>
      <xforms:instance id="instance1" xmlns="">
         <document>
            <cities>
               <city>Paris</city>
               <city>Beijing</city>
            </cities>
         </document>
      </xforms:instance>
   </xforms:model>
</xformsmodels>

Sample code:

function testExtractXFormsInstance(theForm) {
  var s, sData;

  s = "--- Results of extractXFormsInstance test ---\n\n";
  
  s += "Entire instance:\n"
  sData = theForm.extractXFormsInstance(null,
                  "",
                  true, true, null);
  s += sData + "\n\n";
  
  s += "Cities data only:\n"
  sData = theForm.extractXFormsInstance(null,
                  "instance('instance1')/cities",
                  true, true, null);
  s += sData + "\n\n";
  
  s += "The first city element:\n"
  sData = theForm.extractXFormsInstance(null,
                  "instance('instance1')/cities/city[1]",
                  true, true, null);
  s += sData + "\n\n";
  
  alert(s);
}   
The message displayed in the JavaScript alert window should be:
--- Results of extractXFormsInstance test ---

Entire instance:
<document>
   <cities>
      <city>Paris</city>
      <city>Beijing</city>
   </cities>
</document>

Cities data only:
<cities>
   <city>Paris</city>
   <city>Beijing</city>
</cities>

The first city element:
<city>Paris</city>

getAttribute method

Description

This method returns the value of an attribute in a node. For example, in the XFDL fragment shown, the mimedata node has an attribute called encoding with the value base64.

   <mimedata encoding="base64"></mimedata>

Method

String getAttribute(
   String namespaceURI,
   String localName
);
   

Parameters

Table 23. Method parameters
Expression Type Description
namespaceURI String The namespace URI for the attribute. For example:
http://www.ibm.com/xmlns/prod/XFDL/7.7
localName String The local name of the attribute. For example, encoding.

Returns

The value of the attribute. If the attribute is empty or does not exist, the method returns an empty string. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

Namespaces

If you refer to an attribute with a namespace prefix, getAttribute first looks for a complete match, including both prefix and attribute name. If it does not find a match, it will look for a matching attribute name that has no prefix but whose containing element has the same namespace.

For example, assume that the custom namespace and the test namespace both resolve to the same URI. In the following case, looking for the id attribute would locate the second attribute (test:id), since it has an explicit namespace declaration:

   <a xmlns:custom="ABC" xmlns:test="ABC">
      <custom:myElement id="1" test:id="2">
   </a>

However, in the next case, the id attribute does not have an explicit namespace declaration. Instead, it inherits the custom namespace. However, since the inherited namespace resolves to the same URI, the id attribute is still located:

   <custom:myElement id="1">

Special attributes

Forms generally use three special attributes that are not in an explicitly defined namespace and which require special commands to retrieve.

The first is the default namespace attribute, which looks like this:

   xmlns="http://www.ibm.com/xmlns/prod/XFDL/7.7"

To retrieve this attribute, you must use a namespace URI of null and the attribute name xmlns.

The second special attribute is a namespace declaration, which looks like this:

   xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom"

To retrieve this sort of attribute, you must use the namespace URI http://www.w3.org/2000/xmlns and the appropriate attribute name, such as custom.

Finally, there is the language attribute, which looks like this:

   xml:lang="en-GB"

To retrieve this sort of attribute, you must use the namespace URI http://www.w3.org/XML/1998/namespace and the attribute name lang.

Example

The following example shows a method that gets the value of the encoding attribute for a node. The node is passed to the method which calls getAttribute to get the value of encoding attribute. This sample method assumes that the attribute is always in the XFDL namespace.

The sample code uses getAttribute to retrieve the sid of the first child node on PAGE1 of the form that is passed in, and to retrieve the lang attribute of the form.

function testGetAttribute(theForm) {
  var pageNode, childNode;
  var s;
  
  s = "--- Results of getAttribute test ---\n";
  pageNode = theForm.dereferenceEx(null, "PAGE1", 0,
             FormNodeP.UFL_PAGE_REFERENCE, null);
  if(pageNode == null) {
     s += " FAILED: Could not find PAGE1 on the form.\n";
  } else {
      childNode = pageNode.getChildren();
  }
  if(childNode == null) {
     s += " FAILED: Could not find first child of PAGE1.\n";
  } else {
     s += " The sid of the first child node of PAGE1: '";
     s += childNode.getAttribute("http://www.ibm.com/xmlns/prod/XFDL/7.7", "sid");
     s += "'\n";
  }

  s += " The language of the form is: '"; 
  s += theForm.getAttribute("http://www.w3.org/XML/1998/namespace", "lang");
  s += "'\n";
  alert(s);
}   
The message displayed in the alert box should be:
--- Results of getAttribute test ---
 The sid of the first child node of PAGE1: 'global'
 The language of the form is: 'en-US'

getAttributeList

Description

This method returns a list of either the namespace URIs of all attributes of the node on which it is called, or the local names of all attributes of the node on which it is called. The returned list depends on the value of the namespaces parameter. If the parameter is FormNodeP.NAMESPACE, a list of the namespace URIs is returned. If the parameter is FormNodeP.LOCALNAME, a list of the local names of all attributes is returned. The lists are ordered such that element 1 of one list corresponds to element 1 of the other list.

Method

String[] getAttributeList(
   Number namespaces
);

Parameters

Expression Type Description
namespaces Number

One of the two following constants:

FormNodeP.NAMESPACE — a list of namespaces for the attributes of the node.

FormNodeP.LOCALNAME — a list of local names for the attributes of the node.

Returns

The requested list. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code retrieves the list of namespace URIs and local names from a field on PAGE1 with the following definition:
 <field sid="FIELD3" custom:id="2">
   <value>This is the value for FIELD3</value>
 </field>
function testGetAttributeList(theForm) {
  var namespaceURIList, localNameList;
  var fieldNode;
  var s;
  
  s = "--- Results of getAttributeList test ---\n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD3", 0,
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(fieldNode == null) {
    s += " Could not find PAGE1.FIELD3 on the form.\n";
  } else {
    namespaceURI = fieldNode.getAttributeList(FormNodeP.NAMESPACE);
    localName = fieldNode.getAttributeList(FormNodeP.LOCALNAME);
    for(i=0, j=1; i < namespaceURI.length; i++,j++) {
      s += "  Attribute " + j + ": '";
      s += namespaceURIList[i] + "', '";
      s += localNameList[i] + "'\n";
    }
  }
  alert(s);
}   
The message displayed by the alert box should be:
--- Results of getAttributeList test --
  Attribute 1: 'http://www.ibm.com/xmlns/prod/XFDL/Custom', 'id'.
  Attribute 2: 'null', 'sid'.

getChildren method

Description

This method, along with getParent, is used to traverse vertically along the form hierarchy. getChildren returns the first child of the indicated node. If the node has no children, null is returned. All child nodes of a FormNodeP can be traversed using a while loop in combination with getNext.

Method

FormNodeP getChildren( );   

Parameters

There are no parameters for this method.

Returns

The FormNodeP that represents the first child or null if no child nodes exist. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code returns the first child node of PAGE1.FIELD1 and displays the result in a JavaScript alert() message.

function testGetChildren(theForm) {
  var parentNode, tempNode;
  var s;
	
  s = "--- Results of getChildren test ---\n";
  parentNode = theForm.dereferenceEx(null, "PAGE1.FIELD3", 0, 
               FormNodeP.UFL_ITEM_REFERENCE, null);
  if(parentNode == null) {
    s = " Cannot find PAGE1.FIELD3";
  } else {
    tempNode = parentNode.getChildren();
    s += " The first child node of PAGE1.FIELD3 is: "
      + tempNode.getLocalName() + "\n";
  }
  alert(s);
}
The message displayed in the alert box should be:
--- Results of getChildren test ---
 The first child node of PAGE1.FIELD3 is: itemlocation.

getDialog

Returns a reference to the Modal Dialog object.

Description

After you obtain a reference to the Modal Dialog box, you can change its title, size, and whether it displays a header or footer section. You can also close the dialog.

The available methods are:

Table 24. Methods of the Modal Dialog object
Method Parameters Description
setTitle string The new title of the dialog.
setSize integer, integer The new width and height in pixels.
showHeader boolean To display a header, set to true.
showFooter boolean To display a footer, set to true.
close   Closes the dialog box. The close method has no parameters.
     

Method

getDialog ();

Parameters

This method has no parameters.

Returns

A reference to the Modal Dialog object. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample shows a JavaScript method that runs when the Modal Dialog box opens. The script modifies the title, the size, and the header sections of the Modal Dialog box.

<html>
<head>

<script src="LF_XFDL.js"> </script>
<script src="LF_FormNodeP.js"> </script>

<script>
    function setupDialog () {
      
      // get a reference to the Modal Dialog object
      var dialog = ibmForms[""].getDialog();

      // set a new title 
      dialog.setTitle("Modal Dialog");

      // change the size to 600 pixels wide by 400 pixels high
      dialog.setSize(600, 400);

      // show the header section
       dialog.showHeader(true);

      // do not show the footer section
       dialog.showFooter(false);
    }
    window.onload = setupDialog;
</script>
</head>
<body>
 <p>This is the content of the Modal Dialog</p>
</body>
</html>

getFormVersion method

Description

This method determines the XFDL version of a form.

Method

   Number getFormVersion( );   

Parameters

There are no parameters for this method.

Returns

A decimal number that when converted to base 16, is in the form of MMmm300. The example below shows how to convert the return value to base 16.

Example

The sample code retrieves the version of the form and converts it to a string for display in a JavaScript alert() window.

function testGetFormVersion(theForm)
{
  var version;
  var s;
  
  s = "--- Results of getFormVersion test ---\n";
  version = theForm.getFormVersion().toString(16);
  s += " Form Version: " + version;
  alert(s);
}
The message displayed in the alert box should look similar to this, depending on the version of your form:
--- Results of getFormVersion test ---
 Form Version: 7050300

getInfoEx method

Description

This method retrieves information about a particular node. If you do not want information about a particular property, set it to null.

Method

String getInfoEx(
  Number property
);   

Parameters

Expression Type Description
property Number

One of these four constants:

FormNodeP.TYPE — to return the type of the node.

FormNodeP.LITERAL — to return the literal of the node.

FormNodeP.COMPUTE — to return the compute for the node.

FormNodeP.IDENTIFIER — to return the identifer of the node.

Returns

The value that corresponds to the parameter that is passed in, or null if the requested value does not exist. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

If you are getting information about a node that is not in the XFDL namespace, getInfoEx may return values that include namespace prefixes as follows:

  • Any item node in a non-XFDL namespace will return a Type that includes a namespace prefix. For example, myNamespace:Field1.
  • Any option node in a non-XFDL namespace will return an Identifier that includes a namespace prefix. For example, myNamespace:value.

Example

The sample code makes four calls to getInfoEx to retrieve the type, literal, compute, and identifer properties of the node PAGE1.FIELD1.value, and displays the results in a JavaScript alert() message.

function testGetInfoEx(theForm) {
  var fieldNode;
  var s, sType, sLiteral, sCompute, sIdentifier;
  
  s = "--- Results of getInfoEx test ---\n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD1.value", 0,
              FormNodeP.UFL_OPTION_REFERENCE, null);
  if(fieldNode == null) {
    s += "Cannot find PAGE1.FIELD1.value";
  } else {
    sType = fieldNode.getInfoEx(FormNodeP.TYPE);
    sLiteral = fieldNode.getInfoEx(FormNodeP.LITERAL);
    sCompute = fieldNode.getInfoEx(FormNodeP.COMPUTE);
    sIdentifier = fieldNode.getInfoEx(FormNodeP.IDENTIFIER);
    
    s += " Type: " + sType + "\n";
    s += " Literal: " + sLiteral + "\n";
    s += " Formula: " + sCompute + "\n";
    s += " Identifier: " + sIdentifier + "\n";
  }
  alert(s); 
}
A typical message displayed in the alert box by the sample code might be:
--- Results of getInfoEx test --- 
 Type: undefined
 Literal: This is the value for FIELD3
 Formula: PAGE1.FIELD3.value
 Identifier: value

getLiteralByRefEx method

Description

This method finds a particular FormNodeP on the basis of a reference string. Once the FormNodeP is found, its literal is retrieved.

Note: It is not necessary to call this method when you are using XForms. The updateXFormsInstance and extractXFormsInstance methods perform this task automatically.

Method

String getLiteralByRefEx(
   String scheme,
   String reference,
   Number referenceCode,
   FormNodeP NSNode
);   

Parameters

Table 25. Method parameters
Expression Type Description
scheme String Reserved. This must be null.
reference String The reference string.
referenceCode Number Reserved. This must be 0.
NSNode FormNodeP A node that is used to resolve the namespaces in theReference reference parameter (see the note about namespace below). Use null if the node that this method is operating on has inherited the necessary namespaces.

Returns

The literal string. If the literal is empty or does not exist, the method returns null. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

This method is a shortcut method and is equivalent to performing the following on a FormNodeP object:
   aNode.dereferenceEx(scheme, reference, referenceCode,
      UFL_OPTION_REFERENCE | UFL_SEARCH_AND_CREATE,
      theNamespaceNode).getLiteralEx();

FormNodeP

Before you decide which FormNodeP to call the method on, be sure you understand the following:

  1. The FormNodeP supplied can never be more than one level in the hierarchy above the starting point of the reference string. For example, if the reference string begins with an option, then the FormNodeP can be no higher in the hierarchy than an item.
  2. If the FormNodeP is at the same level or lower in the hierarchy than the starting point of the reference string, the method will attempt to locate a common ancestor. The method will locate the ancestor of the FormNodeP that is one level in the hierarchy above the starting point of the reference string. The method will then attempt to follow the reference string back down through the hierarchy. If the reference string cannot be followed from the located ancestor (for example, if the ancestor is not common to both the FormNodeP and the reference string), the method will fail.

    For example, given a FormNodeP that represents "field_1" and a reference of "field_2", the method will access the "page" node above "field_1", and will then try to locate "field_2" below that node. If the two fields are not on the same page, the method will fail.

  3. If the FormNodeP is at the argument level, the search will not start from that point. Instead, the nearest ancestor that is at the option level will be used as the starting point for the search.
Creating a reference string:

For more information about creating a reference, see About references .

Determining namespace:

In some cases, you may want to use the to get the literal of a node that does not have a globally defined namespace. For example, consider the following form:

   <label sid="LABEL1">
      <value>FIELD1.processing:myValue</value>
   </label>
   <field sid="FIELD1" xmlns:processing="URI">
      <value>This is Field 1</value>
      <processing:myValue>10</processing:myValue>
   </field>

In this form, the processing namespace is declared in the FIELD1 node. Any elements within FIELD1 will understand that namespace; however, elements outside of the scope of FIELD1 will not.

In cases like this, you will often start your search at a node that does not understand the namespace of the node you are trying to locate. For example, you might want to locate the node referenced in the value of LABEL1. In this case, you would first locate the LABEL1 value node and get its literal. Then, from the LABEL1 value node, you would attempt to locate the processing:myValue node as shown:

   Label1Node.getLiteralByRefEx(null, "FIELD1.processing:myValue", 0, null)

In this example, the getLiteralByRefEx method fails. The method cannot properly resolve the processing namespace because this namespace is not defined for the LABEL1 value node. To correct this, you must also provide a node that understands the processing namespace (in this case, any node in the scope of LABEL1) as a parameter in the method:

   Label1Node.getLiteralByRefEx(null, "FIELD1.processing:myValue", 0, Field1Node)

Example

Using the form fragment described above, the sample code retrieves the literal of PAGE1.FIELD1.value, which is "This is Field 1". The code then attempts to retrieve the literal of PAGE1.FIELD1.processing:myValue, which is in the processing namespace. The first attempt returns "null" because the namespace is not understood. The second attempt returns the correct value of "10" because the node representing FIELD1.PAGE1 is passed in as the NSNode parameter. The results are displayed in a JavaScript alert window.

function testGetLiteralByRefEx(theForm) {
  var fieldNode, labelNode;
  var s, sLiteral;
  
  s = "--- testGetLiteralByRefEx results ---\n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD1", 0,
              FormNodeP.UFL_ITEM_REFERENCE, null);
  labelNode = theForm.dereferenceEx(null, "PAGE1.LABEL1", 0,
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(fieldNode == null) {
    s += "Cannot find PAGE1.FIELD1";
  } else {
    sLiteral = labelNode.getLiteralByRefEx(null,
               "PAGE1.FIELD1.value", 0, null);
    s += " First test: " + sLiteral + "\n";
    sLiteral = labelNode.getLiteralByRefEx(null,
               "PAGE1.FIELD1.processing:myValue", 0, null);
    s += " Second test: " + sLiteral + "\n";
    sLiteral = labelNode.getLiteralByRefEx(null,
               "PAGE1.FIELD1.processing:myValue", 0, fieldNode);
    s += " Third test: " + sLiteral + "\n";
  }
  alert(s);
}   
The message displayed in the alert box should be:
--- getLiteralByRefEx results ---
 First test: This is Field 1
 Second test: null
 Third test: 10

getLiteralEx method

Description

This method retrieves the literal of a node. The literal is returned in the specified character set.

Note: It is not necessary to call this method when you are using XForms. Use the extractXFormsInstance method instead.

Method

String getLiteralEx( );  

Parameters

There are no parameters for this method.

Returns

A string containing the literal of the node, or null if the literal is empty or does not exist. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The following example uses dereferenceEx to locate a specific node. getLiteralEx is then used to get the literal value for that node.

function testGetLiteralEx(theForm) {
  var valueNode;
  var s, value;

  s = "--- Results of getLiteralEx test ---\n";
  valueNode = theForm.dereferenceEx(null, "PAGE1.FIELD4.value", 0, 
              FormNodeP.UFL_OPTION_REFERENCE, null);
  if(valueNode == null) {
    s += "Cannot find PAGE1.FIELD4.value";
  } else {
    value = valueNode.getLiteralEx();
    s += " The value is: " + value + "\n";
  }
  alert(s);
}
A typical message displayed in the alert box by the sample code might be:
--- Results of getLiteralEx test ---
 The value is: This is FIELD4

getLocalName method

Description

This method returns the local name of a given node. The local name is determined by the XML tag that represents that node. For example, examine the following XML fragment:

   <page sid="PAGE1">
      <global sid="global"></global>
      <field sid="testField">
         <value>Hello</value>
         <bgcolor>120, 120, 120</bgcolor>
      </field>
   </page>

In this sample, the name of the page node is "page", the name of the field node is "field", the name of the value node is "value", and the name of the bgcolor node is "bgcolor".

Note that the local name does not include any namespace prefix that might exist. For example, you might have a custom option in a different namespace as shown:

   <field sid="testField">
      <custom:my_option>value</custom:my_option>
   </field>

In this case, the local name of the custom option is returned without the prefix, resulting in "my_option".

Method

String getLocalName ( );   

Parameters

There are no parameters for this method.

Returns

The name of the node. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code retrieves the local name of all child nodes of PAGE1.FIELD4 and displays the results in a JavaScript alert() message.

function testGetLocalName(theForm) {
  var fieldNode, tempNode;
  var s;
  
  s = "--- Results of testGetLocalName test ---\n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD4", 0, 
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(fieldNode == null){
    s += "Cannot find PAGE1.FIELD4";
  } else {
    tempNode = fieldNode.getChildren();
    while(tempNode != null){
      s += "Local Name: " + tempNode.getLocalName() + "\n";
      tempNode = tempNode.getNext();
    }
  }
  alert(s);
}
A typical message displayed in the alert box by the sample code might be:
--- Results of getLocalName test ---
 Local Name: myValue
 Local Name: value
 Local Name: focused
 Local Name: mouseover
 Local Name: itemprevious
 Local Name: itemnext

getNamespaceURI method

Description

This method returns the namespace URI for the node.

Each namespace is defined in the form by a namespace declaration, as shown:

   xmlns:xfdl="http://www.ibm.com/xmlns/prod/XFDL/7.5" 
   xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom"

Each namespace declaration defines both a prefix and a URI for the namespace. In this sample, the prefix for the XFDL namespace is xfdl and the URI is http://www.ibm.com/xmlns/prod/XFDL/7.5.

Tags within the form are assigned specific namespaces by using the defined prefix. For example, to declare that an option was in the custom namespace you would use the prefix custom as shown:

   <field sid="testField">
      <custom:custom_option>value</custom:custom_option>
   </field>

Method

String getNamespaceURI ( );   

Parameters

There are no parameters for this method.

Returns

The namespace URI. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code retrieves the namespace URI for each child node of PAGE1.FIELD4 and displays the results in a JavaScript alert() message.

function testGetNamespaceURI(theForm) {
  var fieldNode, tempNode;
  var s;
  
  s = "--- Results of testGetNamespaceURI test ---\n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD4", 0, 
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(fieldNode == null){
    s += "Cannot find PAGE1.FIELD4";
  } else {
    tempNode = fieldNode.getChildren();
    while(tempNode != null){
      s += "Local Name: " + tempNode.getNamespaceURI() + "\n";
      tempNode = tempNode.getNext();
    }
  }
  alert(s);
}
A typical message displayed in the alert box by the sample code might be:
--- Results of getNamespaceURI test ---
 Namespace: http://www.sample.uri/processing
 Namespace: http://www.ibm.com/xmlns/prod/XFDL/7.5
 Namespace: http://www.ibm.com/xmlns/prod/XFDL/7.5
 Namespace: http://www.ibm.com/xmlns/prod/XFDL/7.5
 Namespace: http://www.ibm.com/xmlns/prod/XFDL/7.5
 Namespace: http://www.ibm.com/xmlns/prod/XFDL/7.5

getNamespaceURIFromPrefix method

Description

This method returns the namespace URI that corresponds to a specific prefix. You can call this method from any node in the form, as long as that node either declares or inherits the namespace in question.

Each namespace is defined in the form by a namespace declaration, as shown:

   xmlns:xfdl="http://www.ibm.com/xmlns/prod/XFDL/7.5" 
   xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom"

Each namespace declaration defines both a prefix and a URI for the namespace. In this sample, the prefix for the XFDL namespace is xfdl and the URI is http://www.ibm.com/xmlns/prod/XFDL/7.5.

Tags within the form are assigned specific namespaces by using the defined prefix. For example, to declare that an option was in the custom namespace you would use the prefix custom as shown:

   <field sid="testField">
      <custom:custom_option>value</custom:custom_option>
   </field>

Method

String getNamespaceURIFromPrefix (
   String prefix
);

Parameters

Table 26. Method parameters
Expression Type Description
prefix String The namespace prefix. For example, xfdl.

Returns

The namespace URI. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code retrieves the namespace URI associated with the prefix "xfdl", the prefix "custom", and the prefix "temp". The results are displayed in a JavaScript alert() message.

function testGetNamespaceURIFromPrefix(theForm) {
  var fieldNode;
  var s, sPrefix;
  
  s = "--- Results of getNamespaceURIFromPrefix test ---\n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD4", 0, 
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(fieldNode == null) {
    s += "Cannot find PAGE1.FIELD4";
  } else {
    sPrefix = fieldNode.getNamespaceURIFromPrefix("xfdl");
    s += " Namespace for prefix 'xfdl': " + sPrefix + "\n";
    sPrefix = fieldNode.getNamespaceURIFromPrefix("custom");
    s += " Namespace for prefix 'custom': " + sPrefix + "\n";
    sPrefix = fieldNode.getNamespaceURIFromPrefix("processing");
    s += " Namespace for prefix 'processing': " + sPrefix + "\n";
    sPrefix = fieldNode.getNamespaceURIFromPrefix("temp");
    s += " Namespace for prefix 'temp': " + sPrefix + "\n";
  }
  alert(s);
}
A typical message displayed in the alert message by the sample code might be:
--- Results of getNamespaceURIFromPrefix test ---
 Namespace for prefix 'xfdl': http://www.ibm.com/xmlns/prod/XFDL/7.5
 Namespace for prefix 'custom': http://www.ibm.com/xmlns/prod/XFDL/Custom
 Namespace for prefix 'temp': null

getNext method

Description

This method, along with getPrevious, is used to traverse horizontally along the form hierarchy. getNext returns the next node in the tree. For instance, the page node corresponding to the first page of your form can be reached by calling getNext on the global page node.

Method

FormNodeP getNext( );   

Parameters

There are no parameters for this method.

Returns

The FormNodeP that represents the next node or null if the next node does not exist. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The example uses the getNext method to retrieve all child nodes of the field PAGE1.FIELD4. The results are formatted into a string and displayed in a JavaScript alert() message.

function testGetNext(theForm) {
  var fieldNode, tempNode;
  var s;
  
  s = "--- Results of getNext test ---\n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD4", 0, 
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(fieldNode == null){
    s += "Cannot find PAGE1.FIELD4";
  } else {
    tempNode = fieldNode.getChildren();
    while(tempNode != null){
      s += " Local Name: " + tempNode.getLocalName() + "\n";
      tempNode = tempNode.getNext();
    }
  }
  alert(s);
}
A typical message displayed in the alert message might look like this:
--- Results of getNext test ---
 Local Name: myValue
 Local Name: value
 Local Name: focused
 Local Name: mouseover
 Local Name: itemprevious
 Local Name: itemnext

getNodeType method

Description

This method returns the type for a node (for example, page, item, option, and array). This allows you to quickly determine the type of node you are working with and what depth you are at in the node hierarchy.

Method

Number getNodeType( );   

Parameters

There are no parameters for this method.

Returns

One of the following constants:
  • FormNodeP.UFL_FORM — The root node of the form.
  • FormNodeP.UFL_PAGE — A page level node.
  • FormNodeP.UFL_ITEM — An item level node.
  • FormNodeP.UFL_OPTION — An option level node.
  • FormNodeP.UFL_ARRAY — An argument level node, such as an array element.
On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code calls getNodeType on each node that it finds while traversing down the node tree, starting at the second child node of PAGE1. It also collects the localname of each node and displays the results in a JavaScript alert() message.

function testGetNodeType(theForm) {
  var pageNode, tempNode;
  var s, nodeType;
  
  s = "--- Results of getNodeType test ---\n";
  pageNode = theForm.dereferenceEx(null, "PAGE1", 0,
             FormNodeP.UFL_PAGE_REFERENCE, null);
  if(pageNode == null){
    s += "Cannot find PAGE1";
  } else {
    /* get the second child node of PAGE1 */
    tempNode = pageNode.getChildren().getNext();
    
    while(tempNode != null){
      nodeType = tempNode.getNodeType();
      switch (nodeType) {
        case FormNodeP.UFL_FORM:
          s += " Node type for " 
            + tempNode.getLocalName() + ": Form\n";
            break;
        case FormNodeP.UFL_PAGE:
          s += " Node type for "
            + tempNode.getLocalName() + ": Page\n";
            break;
        case FormNodeP.UFL_ITEM:
          s += " Node type for " 
            + tempNode.getLocalName() + ": Item\n";
            break;
        case FormNodeP.UFL_OPTION:
          s += " Node type for " 
            + tempNode.getLocalName() + ": Option\n";
            break;
        case FormNodeP.UFL_ARRAY:
          s += " Node type for " 
            + tempNode.getLocalName() + ": Array\n";
            break;
        default:
          s += " Node type: Unknown\n"; break;
      }
      tempNode = tempNode.getChildren();
    }
  }
  alert(s);
}
A typical message displayed in the alert window might look like this:
--- Results of getNodeType test ---
 Node type for field: Item
 Node type for itemlocation: Option
 Node type for x: Array

getParent method

Description

This method, along with getChildren, is used to traverse vertically along the form hierarchy. getParent returns the parent of a node. If the node has no parent, null is returned. A form's structure can be traversed up to the root node using an iterator such as a while loop.

Method

FormNodeP getParent ( );   

Parameters

There are no parameters for this method.

Returns

The FormNodeP that represents the parent node or null if no such parent exists. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code retrieves the parent node of PAGE1.FIELD4.value and each subsequent parent node, all the way up to the root node. It also collects the local name of each node and displays the result in a JavaScript alert() window.

function testGetParent(theForm) {
  var valueNode, tempNode;
  var s;
  
  s = "--- Results of getParent test ---\n";
  valueNode = theForm.dereferenceEx(null, "PAGE1.FIELD4.value", 0,
              FormNodeP.UFL_OPTION_REFERENCE, null);
  if(valueNode == null){
    s += "Cannot find PAGE1.FIELD4.value";
  } else {
    tempNode = valueNode.getParent();
    while(tempNode != null){
      s += " Local Name: " + tempNode.getLocalName() + "\n";
      tempNode = tempNode.getParent();
    }
  }
  alert(s);
}   
A typical message displayed in the alert window might look like this:
--- Results of getParent test ---
 Local Name: field
 Local Name: page
 Local Name: XFDL

getPrefix method

Description

This method returns the namespace prefix for the node.

Each namespace is defined in the form by a namespace declaration, as shown:

   xmlns:xfdl="http://www.ibm.com/xmlns/prod/XFDL/7.5" 
   xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom"

Each namespace declaration defines both a prefix and a URI for the namespace. In this sample, the prefix for the XFDL namespace is xfdl and the URI is http://www.ibm.com/xmlns/prod/XFDL/7.5.

Tags within the form are assigned specific namespaces by using the defined prefix. For example, to declare that an option is in the custom namespace, use the prefix custom as shown:

   <field sid="testField">
      <custom:custom_option>value</custom:custom_option>
   </field>
Note: A given prefix may not always resolve to the same namespace. Different portions of the form may define the prefix differently. For example, the custom prefix may resolve to a different namespace on the first page of a form than it does on the following pages.

Method

String getPrefix ( );   

Parameters

There are no parameters for this method.

Returns

The prefix for the node's namespace. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code retrieves the prefix of the namespace for the first child node of PAGE1.FIELD4. The XFDL fragment that the sample code works with is as follows:
<field sid="FIELD4" xmlns:processing="http://www.sample.uri/processing">
   <processing:myValue>10</processing:myValue>
   <value>This is FIELD4</value>
</field>
The results are displayed in a JavaScript alert() window.
function testGetPrefix(theForm) {
  var fieldNode, tempNode;
  var s;
  
  s = "--- Results of getPrefix test ---\n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD4", 0,
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(fieldNode == null){
    s += "Cannot find PAGE1.FIELD4";
  } else {
    tempNode = fieldNode.getChildren();
    s += " Namespace prefix for "  + tempNode.getLocalName() 
      + ": " + tempNode.getPrefix() + "\n";
  } 
  alert(s);
}   
The message displayed in the alert window should look like this:
--- Results of getPrefix test ---
 Namespace prefix for myValue: processing

getPrefixFromNamespaceURI method

Description

This method returns the namespace prefix for a specific namespace URI. You can call this method from any node in the form, as long as that node either declares or inherits the namespace in question.

Each namespace is defined in the form by a namespace declaration, as shown:

   xmlns:xfdl="http://www.ibm.com/xmlns/prod/XFDL/7.5" 
   xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom"

Each namespace declaration defines both a prefix and a URI for the namespace. In this sample, the prefix for the XFDL namespace is xfdl and the URI is http://www.ibm.com/xmlns/prod/XFDL/7.5.

Tags within the form are assigned specific namespaces by using the defined prefix. For example, to declare that an option is in the custom namespace, use the prefix custom as shown:

   <field sid="testField">
      <custom:custom_option>value</custom:custom_option>
   </field>

Method

String getPrefixFromNamespaceURI(
   String uri
);

Parameters

Table 27. Method parameters
Expression Type Description
uri String The namespace URI. For example:
http://www.ibm.com/xmlns/prod/XFDL/7.5

Returns

The namespace prefix. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code first retrieves the prefix of the namespace for a form that has a declaration for the custom namespace but no declaration for the processing namespace. Next, the code retrieves the prefix of the namespace for PAGE1.FIELD4, assuming that FIELD4 is defined with the following XFDL fragment:
<field sid="FIELD4" xmlns:processing="http://www.sample.uri/processing">
   <processing:myValue>10</processing:myValue>
   <value>This is FIELD4</value>
</field>
The results are displayed in a JavaScript alert() window.
function testGetPrefixFromNamespaceURI(theForm) {
  var fieldNode;
  var s, prefix;
  
  s = "--- Results of getPrefixFromNamespaceURI test ---\n";
  s += " First: (Form) \n";
  prefix = theForm.getPrefixFromNamespaceURI(
           "http://www.ibm.com/xmlns/prod/XFDL/Custom");
  s += "  Namespace prefix for http://www.ibm.com/xmlns/prod/XFDL/Custom: " 
          + prefix + "\n";
  prefix = theForm.getPrefixFromNamespaceURI(
           "http://www.sample.uri/processing");
  s += "  Namespace prefix for http://www.sample.uri/processing: "
          + prefix + "\n";
  
  s += " Second: (PAGE1.FIELD4) \n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD4", 0, 
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(fieldNode == null){
    s += "Cannot find PAGE1.FIELD4";
  } else {
    prefix = fieldNode.getPrefixFromNamespaceURI(
             "http://www.ibm.com/xmlns/prod/XFDL/Custom");
    s += "  Namespace prefix for http://www.ibm.com/xmlns/prod/XFDL/Custom: " 
            + prefix + "\n";
    prefix = fieldNode.getPrefixFromNamespaceURI(
             "http://www.sample.uri/processing");
    s += "  Namespace prefix for http://www.sample.uri/processing: " 
            + prefix + "\n";
  }
  alert(s);
}   
The message displayed in the alert window should look like this:
--- Results of getPrefixFromNamespaceURI test ---
 First: (Form) 
  Namespace prefix for http://www.ibm.com/xmlns/prod/XFDL/Custom: custom
  Namespace prefix for http://www.sample.uri/processing: null
 Second: (PAGE1.FIELD4) 
  Namespace prefix for http://www.ibm.com/xmlns/prod/XFDL/Custom: custom
  Namespace prefix for http://www.sample.uri/processing: processing

getPrevious method

Description

This method, along with getNext, is used to traverse horizontally along the form hierarchy. getPrevious returns the previous node in the tree. For instance, if you call getPrevious on the Page1 node in your form, it will return the global page node.

Method

FormNodeP getPrevious ( );   

Parameters

There are no parameters for this method.

Returns

The FormNodeP that represents the previous node or null if no such node exists. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code retrieves the list of nodes that are previous to PAGE1.FIELD4. The local name of each of the previous nodes is saved in a string and displayed in a JavaScript alert() window.

function testGetPrevious(theForm) {
  var fieldNode, tempNode;
  var s;
  
  s = "--- Results of getPrevious test ---\n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD4", 0, 
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(fieldNode == null){
    s += "Cannot find PAGE1.FIELD4";
  } else {
    tempNode = fieldNode.getPrevious();
    while(tempNode != null){
      s += " Local Name: " + tempNode.getLocalName() + "\n";
      tempNode = tempNode.getPrevious();
    }
  }
  alert(s);
}
A typical message displayed in the alert window might look like this:
--- Results of getPrevious test ---
 Local Name: label
 Local Name: field
 Local Name: label
 Local Name: list
 Local Name: popup
 Local Name: combobox
 Local Name: field
 Local Name: global

getReferenceEx method

Description

This method returns the reference string that identifies the node. For example, a value node might return a reference of Page1.Field1.value. The reference will either begin at the page level of the form or at a level specified by the caller.

Method

String getReferenceEx(
   String scheme,
   FormNodeP NSNode,
   FormNodeP startPoint,
   boolean addNamespaces
);

Parameters

Table 28. Method parameters
Expression Type Description
scheme String Reserved. This must be null.
NSNode FormNodeP A node that defines which namespace prefixes are used when constructing the reference. Only namespace prefixes that this node inherits are used. Use null if the node that this method is operating on has inherited the necessary namespaces.
startPoint FormNodeP A node that determines the starting point of the reference. This node must be a parent of the current node. The reference will begin one level below the start point node. For example, if you provide a page node the reference will begin at the item level. Use null to start the reference at the page level.
addNamespaces boolean Use true to add declarations for unknown namespaces to the namespace node (NSNode). Otherwise, use false.

Returns

A string containing a reference to the node. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

Creating a reference string:

For more information about creating a reference, see About references .

Working with namespace prefixes:

In some cases, you may want to use the getReferenceEx method to get the reference to a node that uses a different prefix for a known namespace. For example, consider the following form:

   <label sid="Label1" xmlns:data="URI">
      <value></value>
   </label>
   <field sid="Field1" xmlns:processing="URI">
      <value></value>
      <processing:myValue>10<processing:myValue>
   </field>

In this form, processing and data are prefixes for the same namespace, since they both refer to the same URI. However, both namespaces have limited scope since they are declared at the item level. This means that Label1 node does not understand the processing prefix, and that the Field1 node does not understand the data prefix.

This becomes a problem if you want to refer to a namespace from a location that does not understand that namespace. For example, suppose you want to set the value of Label1 to be a reference to the myValue node in Field1. Normally, you would locate the myValue node and use getReferenceEx as shown:

In this case, getReferenceEx would return the following reference: Page1.Field1.processing:myValue. However, because the processing namespace is not defined for Label1, a reference to the processing namespace is not understood. This means that you cannot set the value of Label1 to equal this reference, since the node would not understand that content.

Instead, you must generate a reference that includes a known namespace prefix, such as the data namespace. You can do this by including a second node in the getReferenceEx method. The second node must understand the appropriate namespace. For example, you could include the Label1 node in the method, as shown:

In this case, the method will substitute the data prefix for the processing prefix, since they both resolve to the same namespace. As a result, the method will return: Page1.Field1.data:myValue. Since the data prefix is defined within Label1, you can use this reference to set Label1's value node.

Working with unknown namespaces:

In some cases, you may want to use the getReferenceEx method to get the reference to a node that uses an unknown namespace. For example, consider the following form:

   <page sid="Page1" xmlns:processing="URI1">
      <global sid="global">
         <processing:info></processing:info>
      </global>
      <field sid="Field1" xmlns:data="URI2">
         <value></value>
         <data:info>data</data:info>
      </field>

In this example, you might want to store a reference to the <data:info> element in the <processing:info> element. getReferenceEx would return the following reference for the <data:info> element: Page1.Field1.data:info. However, this reference includes the data namespace, which is not defined for the page global. This means that you could not store this reference in the <processing:info> element, because it would not understand the reference.

To solve this problem, you can use the addNamespaces flag in the getReferenceEx method. When this flag is set to true, the method will add unknown namespaces to the theNSNode.

For example, if you set theNSNode to be the global item node for Page1, and set the addNamespace flag to true, as shown:

   dataNode.getReferenceEx(Null, pageGlobalNode, Null, true)

The method would return the reference to the <data:info> element, but would also modify the global item node to include the unknown data namespaces, as shown:

   <global sid="global" xmlns:data="URI2">

You could then store the reference in that global item or any of its descendants, since the namespace is now properly defined.

Example

The sample code demonstrates the effects of various parameter values on the results returned by getReferenceEx when run on a form that has the following field definition on PAGE1:
 <field sid="FIELD4" xmlns:processing="http://www.sample.uri/processing">
   <processing:myValue>10</processing:myValue>
   <value>This is FIELD4</value>
 </field>
function testGetReferenceEx(theForm) {
  var fieldNode, childNode;
  var s, value;
  
  s = "--- testGetReferenceEx results ---\n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD4", 0, 
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(fieldNode != null) {
    childNode = fieldNode.getChildren();
  }
  if(fieldNode == null | childNode == null) {
    s += "Cannot find either PAGE1.FIELD4 or its first child node";
  } else {
    value = childNode.getReferenceEx(null, null, null, false);
    s += " Test 1: " + value + "\n";
    value = childNode.getReferenceEx(null, null, fieldNode, false);
    s += " Test 2: " + value + "\n";
    value = childNode.getReferenceEx(null, fieldNode.getParent(), null, false);
    s += " Test 3: " + value + "\n";
    value = childNode.getReferenceEx(null, fieldNode.getParent(), null, true);
    s += " Test 4: " + value + "\n";
  }
  alert(s);
} 
The message displayed by the alert box should be:
--- Results of getReferenceEx test ---
 Test 1: PAGE1.FIELD4.processing:myValue
 Test 2: processing:myValue
 Test 3: PAGE1.FIELD4.(null):myValue
 Test 4: PAGE1.FIELD4.processing:myValue

getSecurityEngineName method

Description

This method returns the name of the appropriate security engine for a given button or signature node. This is useful for determining which validation call you need to make to validate the signature.

Method

String getSecurityEngineName (
   Number operation
);

Parameters

Table 29. Method parameters
Expression Type Description
operation Number The operation that you want the security engine for. Possible values are:

FormNodeP.SEOPERATION_SIGN — the engine that is needed to sign the form.

FormNodeP.SEOPERATION_VERIFY — the engine that is needed to verify the signature.

FormNodeP.SEOPERATION_LISTIDENTITIES — the engine that is needed to generate a list of valid certificates for signing.

Returns

A string containing the name of the security engine. The possible names are:
  • CryptoAPI
  • Netscape
  • ClickWrap
  • HMAC-ClickWrap
  • PenOp
On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code retrieves the security engine name for each of the operations and displays the results in a JavaScript alert() window.

function testGetSecurityEngineName(theForm) {
  var buttonNode;
  var s, value;
  
  s = "--- testGetSecurityEngineName results ---\n";
  buttonNode = theForm.dereferenceEx(null, "PAGE1.BUTTON1", 0, 
               FormNodeP.UFL_ITEM_REFERENCE, null);
  if(buttonNode == null) {
    s += "Cannot find PAGE1.BUTTON1";
  } else {
    value = buttonNode.getSecurityEngineName(
            FormNodeP.SEOPERATION_SIGN);
    s+= " Test 1: " + value + "\n";
    
    value = buttonNode.getSecurityEngineName(
            FormNodeP.SEOPERATION_VERIFY);
    s+= " Test 2: " + value + "\n";
    
    value = buttonNode.getSecurityEngineName(
            FormNodeP.SEOPERATION_LISTIDENTITIES);
    s+= " Test 3: " + value + "\n";
  }
  alert(s);
}
If PAGE1.BUTTON1 is a signature button and the form has been signed with the Click Wrap signature engine, then the message displayed in the alert window should look like this:
--- Results of getSecurityEngineName test ---
 Test 1: ClickWrap
 Test 2: ClickWrap
 Test 3: ClickWrap

getSigLockCount method

Description

This method returns the signature lock count of a node. If 0 is returned, the node is not signed by any digital signature, but it may have descendants that are signed.

Method

Number getSigLockCount ( );   

Parameters

There are no parameters for this method.

Returns

The number of locks on the given node. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code retrieves the number of signature locks on PAGE1.FIELD1 and displays the result in a JavaScript alert() window.

function testGetSigLockCount(theForm) {
    var fieldNode;
    var s;
    
    s = "--- testGetSigLockCount results ---\n";
    fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD1", 0,
                FormNodeP.UFL_ITEM_REFERENCE, null);
    if(fieldNode == null) {
      s += "Cannot find PAGE1.FIELD1";
    } else {
      s += " Signature lock count for PAGE1.FIELD1: " 
        + fieldNode.getSigLockCount() + "\n";
    }
    alert(s);
}
If PAGE1.FIELD1 is covered by one signature, then the message displayed in the alert window should be:
--- Results of getSigLockCount test ---
 Signature lock count for PAGE1.FIELD1: 1

getSignatureVerificationStatus method

Description

When called, this method checks to see if the digital signatures in a given form are valid.

Method

Number getSignatureVerificationStatus ( );   

Parameters

There are no parameters for this method.

Returns

a Number having one of the following values:

Table 30. return codes
Code Status
FormNodeP.UFL_SIGS_OK The signatures are valid.
FormNodeP.UFL_SIGS_NOTOK One or more signatures are broken.
FormNodeP.UFL_SIGS_UNVERIFIED One or more signatures are unverifiable.

On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code determines the validity of the signatures on a form and displays the results in a JavaScript alert() window.

function testGetSignatureVerificationStatus(theForm) {
    var s;
    var status;
    
    s = "--- Results of getSignatureVerificationStatus test ---\n";
    status = theForm.getSignatureVerificationStatus();
    switch (status) {
    case FormNodeP.UFL_SIGS_OK:
      s += " All signatures are valid.\n";
      break;
    case FormNodeP.UFL_SIGS_NOTOK:
      s += " One or more signatures are broken.\n";
      break;
    case FormNodeP.UFL_SIGS_UNVERIFIED:
      s += " One or more signatures are unverifiable.\n";
      break;
    default:
      s += " Unknown status.\n";
      break;
    }
    alert(s);
} 
If all the signatures on the form are valid, then the message displayed in the alert window should be:
--- Results of getSignatureVerificationStatus test ---
 All signatures are valid.

isSigned method

Description

This method determines whether a node is signed.

Method

boolean isSigned (
  boolean excludeSelf
);

Parameters

Table 31. Method parameters
Expression Type Description
excludeSelf boolean A signature node is always self-signed. To determine whether a second signature has been applied to that node, you must exclude the self-signing from this check.

To exclude the self-signing from the signature check, set this to true. To include the self-signing, set this to false.

Returns

Returns true if the node is signed, false if it is not. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code checks PAGE1.FIELD1 and PAGE1.FIELD2 for signatures. The results are displayed in a JavaScript alert() window.

function testIsSigned(theForm) {
    var s;
    var node;
		
    s = "--- Results of isSigned test ---\n";
    node = theForm.dereferenceEx(null, "PAGE1.FIELD1", 0,
           FormNodeP.UFL_ITEM_REFERENCE, null);
    if(node == null) {
      s += "Could not find FIELD1 on the form.\n";
    } else {
      s += " FIELD1 is ";
      if(node.isSigned(true) == false) s += "not ";
      s += "signed.\n";
    }
    node = theForm.dereferenceEx(null, "PAGE1.FIELD2", 0,
           FormNodeP.UFL_ITEM_REFERENCE, null);
    if(node == null) {
      s += "Could not find FIELD2 on the form.\n";
    } else {
      s += " FIELD2 is ";
      if(node.isSigned(true) == false) s += "not ";
      s += "signed.\n";
    }
    alert(s);
}   
If FIELD1 is signed, but FIELD2 is not signed, then the message displayed in the alert window should be:
--- Results of isSigned test ---
 FIELD1 is signed.
 FIELD2 is not signed.

isValidFormat method

Description

This method returns the boolean result of whether a string is valid according to the setting of the node's format option.

Method

boolean isValidFormat (
   String string
);

Parameters

Table 32. Method parameters
Expression Type Description
string String

A string to be checked against the format. For example, to check 23.2 against a specific format, the string would be “23.2”.

Returns

The method returns true if the string matches the format, but false if the string does not match the format. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code checks to see if the strings '42' and '20071001' are valid for PAGE1.FIELD1. The results are displayed in a JavaScript alert message.

 function testIsValidFormat(theForm) {
  var s;
  var node;
  
  s = "--- Results of isValidFormat test ---\n";
  node = theForm.dereferenceEx(null, "PAGE1.FIELD1", 0,
         FormNodeP.UFL_ITEM_REFERENCE, null);
  if(node == null) {
    s += "Could not find FIELD1 on the form.\n";
  } else {
    s += " The value '42' is ";
    if(node.isValidFormat("42") == false) s += "not ";
    s += "a valid format for FIELD1.\n";
    s += " The value '20071001' is ";
    if(node.isValidFormat("20071001") == false) s += "not ";
    s += "a valid format for FIELD1.\n";
  }
  alert(s);
}
If PAGE1.FIELD1 has a date format, the message displayed in the alert box should be:
--- Results of isValidFormat test ---
 The value '42' is not a valid format for FIELD1.
 The value '20071001' is a valid format for FIELD1.

isXFDL method

Description

This method determines whether a node belongs to the XFDL namespace.

Each namespace is defined in the form by a namespace declaration, as shown:

   xmlns:xfdl="http://www.ibm.com/xmlns/prod/XFDL/7.5" 
   xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom"

Each namespace declaration defines both a prefix and a URI for the namespace. In this sample, the prefix for the XFDL namespace is xfdl and the URI is http://www.ibm.com/xmlns/prod/XFDL/7.5.

Tags within the form are assigned specific namespaces by using the defined prefix. For example, to declare that an option is in the custom namespace, use the prefix custom as shown:

   <field sid="testField">
      <custom:custom_option>value</custom:custom_option>
   </field>

Method

boolean isXFDL ( );   

Parameters

There are no parameters for this method.

Returns

Returns true if the node is in the XFDL namespace, false if it is not. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code calls the isXFDL function on several nodes, starting with the global page node and moving down the hierarchy one child node at a time. The results are displayed in a JavaScript alert() window.

function testIsXFDL(theForm)
{
    var fieldNode, tempNode;
    var s;
    
    s = "--- Results of isXFDL test ---\n";
    fieldNode = theForm.dereferenceEx(null, "global", 0,
                FormNodeP.UFL_PAGE_REFERENCE, null);
    if(fieldNode == null) {
      s += "Cannot find the global page on this form.\n";
    } else {
      tempNode = fieldNode;
      while(tempNode != null) {
        s += " The node '" + tempNode.getLocalName() + "' is ";
        if(tempNode.isXFDL() != true) s += "NOT ";
        s += "in the XFDL namespace.\n";
        tempNode = tempNode.getChildren();
      }
    }
    alert(s);
}   

If the form is created in the designer (which adds the <designer:date> element to the global page) then the message displayed in the alert box should be similar to this:

--- Results of isXFDL test ---
 The node 'globalpage' is in the XFDL namespace.
 The node 'global' is in the XFDL namespace.
 The node 'date' is NOT in the XFDL namespace.

removeAttribute method

Description

This method removes a specific attribute from a node. For example, the following XFDL represents a value node:

   <value custom:myAtt="x"></value>

To remove the custom attribute from this node, you would use removeAttribute.

Method

void removeAttribute(
   String uri,
   String localName
);

Parameters

Table 33. Method parameters
Expression Type Description
uri String The namespace URI for the attribute. For example:
http://www.ibm.com/xmlns/prod/XFDL/7.5
localName String The local name of the attribute. For example, compute, encoding, and so on.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

Attributes and the null namespace:

If an attribute is on a node in a non-XFDL namespace, and that attribute has no namespace prefix, then the attribute is in the null namespace. For example, the following node is the custom namespace, as is the first attribute, but since the second attribute does not have a namespace prefix, it is in the null namespace:

   <custom:processing custom:stage="2" user="tjones">

When an attribute is the null namespace, you may either provide a null value for the namespace URI or use the namespace URI for the containing element.

For example, to indicate user attribute on the processing node, you could use the null namespace or the custom namespace URI.

Attributes and namespace prefixes:

If you refer to an attribute with a namespace prefix, removeAttribute first looks for a complete match, including both prefix and attribute name. If it does not find such a match, it will look for a matching attribute name that has no prefix but whose containing element has the same namespace.

For example, assume that the custom namespace and the test namespace both resolve to the same URI. In the following case, looking for the id attribute would locate the second attribute (test:id), since it has an explicit namespace declaration:

   <a xmlns:custom="ABC" xmlns:test="ABC">
      <custom:myElement id="1" test:id="2">
   </a>

However, in the next case, the id attribute does not have an explicit namespace declaration. Instead, it inherits the custom namespace. However, since the inherited namespace resolves to the same URI, the id attribute is still located:

   <custom:myElement id="1">

Example

The sample code removes two attributes from PAGE1.LABEL1. Note that it is not an error to attempt to remove attributes that do not exist.

function testRemoveAttribute(theForm) {
  var s;
  var pageNode;
  
  s = "--- Results of removeAttribute test ---\n";
  pageNode = theForm.dereferenceEx(null, "PAGE1.LABEL1", 0,
             FormNodeP.UFL_ITEM_REFERENCE, null);
  if(pageNode == null) {
    s += " Could not find PAGE1.LABEL1 on the form.";
  } else {
    pageNode.removeAttribute("http://www.ibm.com/xmlns/prod/XFDL/Custom", "test");
    pageNode.removeAttribute(null, "test");
    s += " Attributes were removed from PAGE1.LABEL1\n";
  }
  alert(s);
}   
The message displayed in the alert box should be:
--- Results of removeAttribute test ---
 Attributes were removed from PAGE1.LABEL1

removeEnclosure method

Description

This method will either remove an enclosure from a specific datagroup or delete the enclosure from the form. Call this method on the FormNodeP that contains the enclosure that you want to remove.

Method

void removeEnclosure(
   String dataGroup
);

Parameters

Table 34. Method parameters
Expression Type Description
dataGroup String The datagroup that contains the enclosed item. If null, the item will be removed from all datagroups. If an item no longer belongs to any datagroups, it is deleted from the form.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code locates a data node with dereferenceEx then removes it from the form with removeEnclosure. The results are displayed in a JavaScript alert box.

function testRemoveEnclosure(theForm) {
  var s;
  var groupNode;
  
  s = "--- Results of encloseFile test ---\n";
  groupNode = theForm.dereferenceEx(null, "PAGE1.xmldata", 0,
              FormNodeP.UFL_ITEM_REFERENCE, null);
  if(groupNode == null) {
    s += " Could not find data group.";
  } else {
    groupNode.removeEnclosure(null);
    s += " The enclosure was removed from the form";
  }
  
  alert(s);
}   
If the group node PAGE1.xmldata exists on the form, then the JavaScript alert message should be:
--- Results of encloseFile test ---
 The enclosure was removed from the form

removeOnBlur method

Description

This method deregisters an event handling function that was previously registered with the addOnBlur method.

Method

void removeOnBlur (
   Function handler
);

Parameters

Expression Type Description
handler Function The name of the function to deregister.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code removes an onBlur event handler from BUTTON1.

function deregisterButtonEvent(theForm) {
  var buttonNode;
  var s;
  
  s = "--- Results of deregisterButtonEvent function call ---\n";
  buttonNode = theForm.dereferenceEx(null, "PAGE1.BUTTON1", 0, 
               FormNodeP.UFL_ITEM_REFERENCE, null);
  if(buttonNode == null) {
    s += " Could not find BUTTON1 on the form.\n";
  } else {
    buttonNode.removeOnBlur(button1OnBlur);
    s += " Function button1OnBlur deregistered.\n";
  }
  alert(s);
}   
The JavaScript alert message should be:
--- Results of deregisterButtonEvent function call ---
  Function button1OnBlur deregistered.

removeOnChange method

Description

This method deregisters an event handling function that was previously registered with the addOnChange method.

Method

void removeOnChange (
   Function handler
);

Parameters

Expression Type Description
handler Function The name of the function to deregister.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code removes an onChange event handler from BUTTON1.

function deregisterButtonEvent(theForm) {
  var buttonNode;
  var s;
  
  s = "--- Results of deregisterButtonEvent function call ---\n";
  buttonNode = theForm.dereferenceEx(null, "PAGE1.BUTTON1", 0, 
               FormNodeP.UFL_ITEM_REFERENCE, null);
  if(buttonNode == null) {
    s += " Could not find BUTTON1 on the form.\n";
  } else {
    buttonNode.removeOnChange(button1OnChange);
    s += " Function button1OnChange deregistered.\n";
  }
  alert(s);
}   
The JavaScript alert message should be:
--- Results of deregisterButtonEvent function call ---
 Function button1OnChange deregistered.

removeOnClick method

Description

This method deregisters an event handling function that was previously registered with the addOnClick method.

Method

void removeOnClick (
   Function handler
);

Parameters

Expression Type Description
handler Function The name of the function to deregister.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code removes an onClick event handler from BUTTON1.

function deregisterButtonEvent(theForm) {
  var buttonNode;
  var s;
  
  s = "--- Results of deregisterButtonEvent function call ---\n";
  buttonNode = theForm.dereferenceEx(null, "PAGE1.BUTTON1", 0, 
               FormNodeP.UFL_ITEM_REFERENCE, null);
  if(buttonNode == null) {
    s += " Could not find BUTTON1 on the form.\n";
  } else {
    buttonNode.removeOnClick(button1OnClick);
    s += " Function button1OnClick deregistered.\n";
  }
  alert(s);
}   
The JavaScript alert message should be:
--- Results of deregisterButtonEvent function call ---
  Function button1OnClick deregistered.

removeOnFocus method

Description

This method deregisters an event handling function that was previously registered with the addOnFocus method.

Method

void removeOnFocus (
   Function handler
);

Parameters

Expression Type Description
handler Function The name of the function to deregister.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code removes an onFocus event handler from BUTTON1.

function deregisterButtonEvent(theForm) {
  var buttonNode;
  var s;
  
  s = "--- Results of deregisterButtonEvent function call ---\n";
  buttonNode = theForm.dereferenceEx(null, "PAGE1.BUTTON1", 0, 
               FormNodeP.UFL_ITEM_REFERENCE, null);
  if(buttonNode == null) {
    s += " Could not find BUTTON1 on the form.\n";
  } else {
    buttonNode.removeOnFocus(button1OnFocus);
    s += " Function button1OnFocus deregistered.\n";
  }
  alert(s);
}   
The JavaScript alert message should be:
--- Results of deregisterButtonEvent function call ---
   Function button1OnFocus deregistered.

setActiveForComputationalSystem method

Description

This method sets whether the computational system is active. When active, all computes in the form are evaluated on an on-going basis. When inactive, no computes are evaluated.

Note that turning the computational system on causes all computes in the form to be re-evaluated, which can be time consuming.

Method

void setActiveForComputationalSystem ( 
   boolean activeFlag
);

Parameters

Table 35. Method parameters
Expression Type Description
activeFlag boolean Set to true to activate the compute system or false to deactivate the compute system.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code turns the compute system off before creating a compute on PAGE1.FIELD2 that copies the value of FIELD1. It then uses getLiteralByRefEx to store the value of FIELD2 before turning the compute system back on and making another call to getLiteralByRefEx. Finally, it displays the results in a JavaScript alert box.

function testSetActiveForComputationalSystem(theForm) {
  var s;
  var fieldNode;
  
  s = "--- Results of setActiveForComputationalSystem test ---\n";
  fieldNode = theForm.dereferenceEx(null, "PAGE1.FIELD2.value", 0,
              FormNodeP.UFL_OPTION_REFERENCE, null);
  if(fieldNode == null) {
    s += " Could not find PAGE1.FIELD2.value on the form.";
  } else {
    theForm.setActiveForComputationalSystem(false);
    fieldNode.setFormula("PAGE1.FIELD1.value");
    s += theForm.getLiteralByRefEx(null, "PAGE1.FIELD2.value", 0, null) + "\n";

    theForm.setActiveForComputationalSystem(true);
    s += theForm.getLiteralByRefEx(null, "PAGE1.FIELD2.value", 0, null) + "\n";
  }
    alert(s);
}
   
The message displayed in the alert box should be similar to this:
--- Results of setActiveForComputationalSystem test ---
This is field 1
This is field 2

setAttribute method

Description

This method sets the value of a specific attribute for a node. For example, the following XFDL represents a value node:

   <value custom:myAtt="x"></value>

To change the custom attribute, you would use setAttribute. If the attribute does not already exist, setAttribute will create it and assign the appropriate value.

Note: Do not use setAttribute to set the compute attribute. Instead, use
setFormula

Method

void setAttribute (
   String uri,
   String localName,
   String value
);

Parameters

Table 36. Method parameters
Expression Type Description
uri String The namespace URI for the attribute. For example:
   http://www.ibm.com/xmlns/prod/XFDL/7.5
localName String The local name of the attribute. For example, encoding.
value String The value to assign to the attribute.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

Attributes and the null namespace:

If an attribute is on a node in a non-XFDL namespace, and that attribute has no namespace prefix, then the attribute is in the null namespace. For example, the following node is the custom namespace, as is the first attribute, but since the second attribute does not have a namespace prefix, it is in the null namespace:

   <custom:processing custom:stage="2" user="tjones">

When an attribute is the null namespace, you may either provide a null value for the namespace URI or use the namespace URI for the containing element.

For example, to indicate user attribute on the processing node, you could use the null namespace or the custom namespace URI.

Attributes and namespace prefixes:

If you refer to an attribute with a namespace prefix, setAttribute first looks for a complete match, including both prefix and attribute name. If it does not find a match, it will look for a matching attribute name that has no prefix but whose containing element has the same namespace.

For example, assume that the custom namespace and the test namespace both resolve to the same URI. In the following case, looking for the id attribute would locate the second attribute (test:id), since it has an explicit namespace declaration:

   <a xmlns:custom="ABC" xmlns:test="ABC">
      <custom:myElement id="1" test:id="2">
   </a>

However, in the next case, the id attribute does not have an explicit namespace declaration. Instead, it inherits the custom namespace. However, since the inherited namespace resolves to the same URI, the id attribute is still located:

   <custom:myElement id="1">

Example

The sample code adds two attributes to PAGE1.LABEL1. The first attribute is in the custom namespace, and the second attribute is in the null namespace.

function testSetAttribute(theForm) {
  var s;
  var pageNode;
  
  s = "--- Results of setAttribute test ---\n";
  pageNode = theForm.dereferenceEx(null, "PAGE1.LABEL1", 0,
             FormNodeP.UFL_ITEM_REFERENCE, null);
  if(pageNode == null) {
    s += " Could not find PAGE1.LABEL1 on the form.";
  } else {
    pageNode.setAttribute(
             "http://www.ibm.com/xmlns/prod/XFDL/Custom",
             "test", "value");
    pageNode.setAttribute(null, "test", "value");
    s += " Attributes were added to PAGE1.LABEL1\n";
  }
  alert(s);
}
The message displayed in the alert box should be:
--- Results of setAttribute test ---
 Attributes were added to PAGE1.LABEL1

setFormula method

Description

This method sets the formula for a node.

Method

void setFormula(
   String theFormula
);

Parameters

Table 37. Method parameters
Expression Type Description
formula String The formula to assign to the node. If null, the formula is assigned as null.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code adds a simple compute to the PAGE1.FIELD3.value node. The compute copies the value of PAGE1.FIELD1 into the value of PAGE1.FIELD3.

function testSetFormula(theForm) {
  var s;
  var node;
  
  s = "--- Results of setFormula test ---\n";
  node = theForm.dereferenceEx(null, "PAGE1.FIELD3.value", 0,
         FormNodeP.UFL_OPTION_REFERENCE, null);
  if(node == null) {
    s += " Could not find PAGE1.FIELD3.value on the form.";
  } else {
    node.setFormula("PAGE1.FIELD1.value");
    s += " Compute was added to PAGE1.FIELD3.value\n";
  }
  alert(s);
}
The message displayed in the alert box should be:
--- Results of setFormula test ---
 Compute was added to PAGE1.FIELD3.value

setLiteralByRefEx method

Description

This method finds a particular FormNodeP as specified by a reference string. Once the FormNodeP is found, its literal will be set as specified. If the FormNodeP does not exist, this method will create it, but only if the FormNodeP would be an option or argument node.

If necessary, this method can create several nodes at once. For example, if you set the literal for the second argument of an itemlocation, this method will create the itemlocation option node and the two argument nodes and then set the literal for the second argument node.

The node that you call this method on is used as the starting point for the search.

Note: It is not necessary to call this method when you are using XForms. Use the updateXFormsInstance method instead.

Method

void setLiteralByRefEx(
   String scheme,
   String reference,
   Number referenceCode,
   FormNodeP NSNode,
   String literal
);
   

Parameters

Table 38. Method parameters
Expression Type Description
scheme String Reserved. This must be null.
reference String A string that contains the reference.
referenceCode Number Reserved. Must be 0.
NSNode FormNodeP A node that is used to resolve the namespaces in theReference parameter (see “Determining Namespace” in the Notes section below). Use null if the node that you are calling this method on has inherited the necessary namespaces.
literal String The string that will be assigned to the literal. If null, any existing literal is removed.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

FormNodeP:

Before you decide which FormNodeP to use this method on, be sure you understand the following:

  1. The FormNodeP you supply can never be more than one level in the hierarchy above the level at which your reference string starts. For example, if the reference string begins with an option, then the FormNodeP can be no higher in the hierarchy than an item.
  2. If the FormNodeP is at the same level or lower in the hierarchy than the starting point of the reference string, the method will attempt to locate a common ancestor. The method will locate the ancestor of the FormNodeP that is one level in the hierarchy above the starting point of the reference string. The method will then attempt to follow the reference string back down through the hierarchy. If the reference string cannot be followed from the located ancestor (for example, if the ancestor is not common to both the FormNodeP and the reference string), the method will fail. For example, given a FormNodeP that represents "field_1" and a reference of "field_2", the method will access the "page" node above "field_1", and will then try to locate "field_2" below that node. If the two fields are not on the same page, the method will fail.
Creating a reference string:

For more information about creating a reference, see About references.

Digital signatures:

Do not set a node that is digitally signed. Doing so will break the digital signature and produce an error.

Determining namespace:

In some cases, you may want to use the setLiteralByRefEx method to set the value for a node that does not have a globally defined namespace. For example, consider the following form:

   <label sid="Label1">
      <value>Field1.processing:myValue</value>
   </label>
   <field sid="Field1" xmlns:processing="URI">
      <value></value>
      <processing:myValue>10<processing:myValue>
   </field>

In this form, the processing namespace is declared in the Field1 node. Any elements within Field1 will understand that namespace; however, elements outside of the scope of Field1 will not.

In cases like this, you will often start your search at a node that does not understand the namespace of the node you are trying to locate. For example, you might want to locate the node referenced in the value of Label1. In this case, you would first locate the Label1 value node and get its literal. Then, from the Label1 value node, you would attempt to locate the processing:myValue node as shown:

   Label1Node.setLiteralByRefEx(null, "Field1.processing:myValue", 0,
      null, null, "20")

In this example, the setLiteralByRefEx method would fail. The method cannot properly resolve the processing namespace because this namespace is not defined for the Label1 value node. To correct this, you must also provide a node that understands the processing namespace (in this case, any node in the scope of Field1) as a parameter in the method:

   Label1Node.setLiteralByRefEx(null, "Field1.processing:myValue", 0,
      null, Field1Node, "20")

Example

The sample code sets several values on the node PAGE1.FIELD3 then displays a success or failure message in an alert box.

function testSetLiteralByRefEx(theForm) {
  var s;
  var node;
  
  s = "--- Results of setLiteralByRefEx test ---\n";
  node = theForm.dereferenceEx(null, "PAGE1.FIELD3", 0,
         FormNodeP.UFL_ITEM_REFERENCE, null);
  if(node == null) {
  	s += " Cannot locate PAGE1.FIELD3 on the form.\n";
  } else {
      node.setLiteralByRefEx(null, "fontinfo[fontname]", 0, null, "Verdana");
      node.setLiteralByRefEx(null, "fontinfo[fontsize]", 0, null, "10");
      node.setLiteralByRefEx(null, "bgcolor", 0, null, "#ff0000");
      node.setLiteralByRefEx(null, "fontcolor", 0, null, "white");
      node.setLiteralByRefEx(null, "value", 0, null, "This is field 3");
      s += " New properties added to PAGE1.FIELD3.\n";
    }
  }
  alert(s);
}   
The message in the alert box should be:
--- Results of setLiteralByRefEx test ---
 New properties added to PAGE1.FIELD3.

setLiteralEx method

Description

This method sets the literal of a node. You should only set the literal for option or argument nodes.

Note: It is not necessary to call this method when you are using XForms. Use the updateXFormsInstance method instead.

Method

void setLiteralEx(
   String literal
);
   

Parameters

Table 39. Method parameters
Expression Type Description
literal String The literal to assign to the node. If null, any existing literal is removed.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

Digital signatures:

Do not set the literal of a node that has already been signed. Doing so will break the digital signature and produce an error.

Example

The sample code moves PAGE1.FIELD3 to a new location.

function testSetLiteralEx(theForm) {
  var s;
  var nodeX, nodeY;
  
  s = "--- Results of setLiteralEx test ---\n";
  nodeX = theForm.dereferenceEx(null, "PAGE1.FIELD3.itemlocation[x]", 0,
          FormNodeP.UFL_ARRAY_REFERENCE, null);
  nodeY = theForm.dereferenceEx(null, "PAGE1.FIELD3.itemlocation[y]", 0,
          FormNodeP.UFL_ARRAY_REFERENCE, null);
  if(nodeX == null || nodeY ==null) {
    s += " Could not find PAGE1.FIELD3.itemlocation[x] or [y] on the form.\n";
  } else {
    nodeX.setLiteralEx("150");
    nodeY.setLiteralEx("350");
    s += " The node 'PAGE1.FIELD3' has been relocated.\n";
  }
  alert(s);
}   
The message in the alert box should be:
--- Results of setLiteralEx test ---
  The node 'PAGE1.FIELD3' has been relocated.

updateXFormsInstance method

Inserts data anywhere within the XForms instance data, or replaces it entirely. It automatically updates the XForms data model.

Description

Call this method on the root node of the form or an instance node.

Note: Use caution when calling this method. It can silently break a digital signature if signed instance data is modified.

Method

void updateXFormsInstance(
   String modelID,
   String nodeRef,
   FormNodeP NSNode,
   String data,
   Number updateType
);

Parameters

Table 40. Method parameters
Expression Type Description
modelID String The ID of the affected model. You must use null to use the default model.
nodeRef String An XPath reference to a node in the instance that you want to update. An empty string indicates the document node of the default instance of the selected model.
NSNode FormNodeP A node that inherits the namespaces used in the reference. This node defines the namespaces for the method. Use null if the node that this method is operating on has inherited the necessary namespaces.
data String The XML data that will be inserted into the XForms instance.
updateType Number One of the following constants:

XFDL.UFL_XFORMS_UPDATE_REPLACE — Replaces the node that is referenced by theNodeRef with the input instance data.

XFDL.UFL_XFORMS_UPDATE_REPLACE_TEXT — Replaces the text of the node that is referenced by theNodeRef with the input data.

XFDL.UFL_XFORMS_UPDATE_APPEND — Adds the input data as the last child node of the node that is referenced by theNodeRef.

XFDL.UFL_XFORMS_UPDATE_INSERT_ BEFORE — Adds the input data as a sibling of the node that is referenced by theNodeRef. You cannot insert before the root element of the instance.

XFDL.UFL_XFORMS_UPDATE_DELETE — Deletes the node that is referenced by theNodeRef. You cannot delete the entire instance.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

XForms data model:

The updateXFormsInstance and the extractXFormsInstance methods are the only methods that are intended to modify the XForms data model.

Example

The sample code inserts the city Moscow into an existing instance, and replaces Paris with Montreal. It then displays the new instance data in a JavaScript alert box.

Instance data:

<xformsmodels>
   <xforms:model>
      <xforms:instance id="instance1" xmlns="">
         <document>
            <cities>
               <city>Paris</city>
               <city>Beijing</city>
            </cities>
         </document>
      </xforms:instance>
   </xforms:model>
</xformsmodels>   

Sample code:

function testUpdateXFormsInstance(theForm) {
  var s, sData;
  
  s = "--- Results of updateXFormsInstance test ---\n\n";

  sData = "<city>Moscow</city>"
  theForm.updateXFormsInstance(null,
          "instance('instance1')/cities",
          null, sData, XFDL.UFL_XFORMS_UPDATE_APPEND);
  sData = "<city>Montreal</city>"
  theForm.updateXFormsInstance(null,
          "instance('instance1')/cities/city[1]",
          null, sData, XFDL.UFL_XFORMS_UPDATE_REPLACE);
  
  s += "The updated XForms instance:\n";
  s += theForm.extractXFormsInstance(null, "", true, true, null);

  alert(s);
  
}
The message displayed in the JavaScript alert box should be:
--- Results of updateXFormsInstance test ---

The updated XForms instance:
<document>
   <cities>
      <city>Montreal</city>
      <city>Beijing</city>
      <city>Moscow</city>
   </cities>
</document>

verifyAllSignatures method

Description

This method verifies the correctness of all digital signatures in a given form whose root node is provided. It finds all items of type signature and calls verifySignature for each signature. Errors are logged for all non valid signatures.

This method checks the following conditions for each signature:

  • The signature item contains mimedata.
  • The mimedata contains a hash value and signer certificate.
  • The signer certificate contains the same ID as that recorded in the signature item's signer option.
  • The signer certificate has not expired.

Method

Number verifyAllSignatures(
   boolean reportAsErrorsFlag
);

Parameters

Table 41. Method parameters
Expression Type Description
reportAsErrorsFlag boolean Set to true if you want errors about the signatures to be reported by the error reporting system, or false if you want the error code to be only returned through the return value.

Returns

One of the following values:

Table 42. return codes
Code Status
FormNodeP.UFL_SIGS_OK The signatures are valid.
FormNodeP.UFL_SIGS_NOTOK One or more signatures are broken.
FormNodeP.UFL_SIGS_UNVERIFIED One or more signatures are unverifiable.
FormNodeP.UFL_SIGS_VERIFIEDBUTNOTAUTHENTICATED This value will only be returned on items that have an HMAC signature. It means that the data is valid, but the shared secret could not be checked for validity.

If one or more of the signatures is not valid and the reportAsErrorsFlag is true, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code verifies all of the signatures on the form then displays the results in a JavaScript alert box.

 function testVerifyAllSignatures(theForm) {
    var s;
    
    s = "--- Results of verifyAllSignatures test ---\n";
    switch(theForm.verifyAllSignatures(false)) {
    case FormNodeP.UFL_SIGS_OK:
      s += " All signatures on the form are valid.\n";
      break;
    case FormNodeP.UFL_SIGS_NOTOK:
      s += " One or more signatures are broken.\n";
      break;
    case FormNodeP.UFL_SIGS_UNVERIFIED:
      s += " One or more signatures cannot be verified.\n";
      break;
    default:
    
    }
    alert(s);
}   
The message in the alert box should be:
--- Results of verifyAllSignatures test ---
 All signatures on the form are valid.

verifySignature method

Description

This method verifies the correctness of the given digital signature. You supply the root of the form that contains the signature you want to verify. This method checks the following conditions:

  • The signature item contains mimedata.
  • The mimedata contains a hash value and signer certificate.
  • The signer certificate contains the same ID as that recorded in the signature item's signer option.
  • The signer certificate has not expired.

A plain text representation of the form (filtered by the signature item's filter) is constructed and the result is hashed. This hash value must match the hash value stored in the signature.

Method

short verifySignature(
   FormNodeP signatureItem,
   StringHolder theCertChain,
   boolean reportAsErrorsFlag
);

Parameters

Table 43. Method parameters
Expression Type Description
signatureItem FormNodeP The signature to verify.
reportAsErrorsFlag boolean Set to true if you want errors about the signatures to be reported by the error reporting system or false if you want the error code to be returned through the return value.

Returns

A Number having one of the following values, depending on the status of the signature:

Table 44. return codes
Code Status
FormNodeP.UFL_DS_OK The signature is verified.
FormNodeP.UFL_DS_ALGORITHMUNAVAILABLE The appropriate verification engine for the signature is not available.
FormNodeP.UFL_DS_CERTEXPIRED The certificate has expired.
FormNodeP.UFL_DS_CERTNOTFOUND The certificate cannot be located.
FormNodeP.UFL_DS_CERTNOTTRUSTED The certificate is not trusted.
FormNodeP.UFL_DS_CERTREVOKED The certificate has been revoked.
FormNodeP.UFL_DS_CRLINVALID The certificate revocation list is invalid.
FormNodeP.UFL_DS_F2MATCHSIGNER The certificate does not match the signer's name.
FormNodeP.UFL_DS_HASHCOMPFAILED The document has been tampered with.
FormNodeP.UFL_DS_ISSUERCERTEXPIRED The issuer's certificate has expired.
FormNodeP.UFL_DS_ISSUERINVALID The issuer is invalid for the certificate used to sign.
FormNodeP.UFL_DS_ISSUERKEYUSAGE UNACCEPTABLE The issuer certificate's key usage extension does not match what the key was used for.
FormNodeP.UFL_DS_ISSUERNOTCA The certificate's issuer is not a Certificate Authority.
FormNodeP.UFL_DS_ISSUERNOTFOUND The issuer's certificate was not located.
FormNodeP.UFL_DS_ISSUERSIGFAILED Verification of the issuer's certificate failed.
FormNodeP.UFL_DS_KEYREVOKED The key used to create the signature has been revoked.
FormNodeP.UFL_DS_KEYUSAGEUNACCEPTABLE The certificate's key usage extension does not match what the key was used for.
FormNodeP.UFL_DS_KRLINVALID The Key Revocation List is invalid.
FormNodeP.UFL_DS_NOSIGNATURE There is no signature.
FormNodeP.UFL_DS_NOTAUTHENTICATED The signer cannot be authenticated.
FormNodeP.UFL_DS_POLICYUNACCEPTABLE The certificate's policy extension does not match the acceptable policies.
FormNodeP.UFL_DS_SIGNATUREALTERED The signature has been tampered with.
FormNodeP.UFL_DS_UNEXPECTED An unexpected error occurred.
FormNodeP.UFL_DS_UNVERIFIABLE The signature cannot be verified.

If the signature is not valid and the reportAsErrorsFlag is true, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code attempts to verify the signature item PAGE1.BUTTON1_SIGNATURE_405824760, and checks for a subset of the possible return values. The results are displayed in an alert box.

function testVerifySignature(theForm) {
  var sigNode;
  var s;
  
  s = "--- Results of verifySignature test ---\n";
  sigNode = theForm.dereferenceEx(null, "PAGE1.BUTTON1_SIGNATURE_405824760", 0,
            FormNodeP.UFL_ITEM_REFERENCE, null);
  if(sigNode == null) {
    s +=" Could not find the signature item.";
  } else {
    switch(theForm.verifySignature(sigNode, false)) {
    case FormNodeP.UFL_DS_OK:
      s += " The signature is verified.\n";
      break;
    case FormNodeP.UFL_DS_ALGORITHMUNAVAILABLE:
      s += " Appropriate verification engine is not available.\n";
      break;
    case FormNodeP.UFL_DS_CERTEXPIRED:
      s += " The certificate has expired.\n";
      break;
    case FormNodeP.UFL_DS_UNEXPECTED:
      s += " An unexpected error occured.\n";
      break;
    case FormNodeP.UFL_DS_UNVERIFIABLE:
      s += " The signature cannot be verified.\n";
      break;
    default:
      s += " Signature not valid for unknown reason.\n";
    }
  }
  alert(s);
}
The message in the alert box should be:
--- Results of verifySignature test ---
 The signature is verified.

xmlModelUpdate method

Description

This method updates the XML data model in the form. This is necessary if computes have changed the structure of the data model in some way, such as changing or adding bindings. These sorts of changes do not take effect until the xmlModelUpdate method is called.

Method

   void xmlModelUpdate( );   

Parameters

There are no parameters for this method.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code uses setLiteralByRefEx to change the binding in the form, then calls xmlModelUpdate so that the XML data model reflects the change.

function testXMLModelUpdate(theForm) {
  var s;

  s = "--- Results of verifySignature test ---\n";
  theForm.setLiteralByRefEx(null,
          "global.global.xmlmodel[bindings][0][boundoption]",
          0, null, "PAGE1.FIELD3.value");
  theForm.xmlModelUpdate();
  s += " Bound option changed.";

  alert(s);
}
The message in the alert box should be:
--- Results of verifySignature test ---
 Bound option changed.

XFDL object

The XFDL object contains functions to register and deregister forms in a Web page. You must include the script file LF_XFDL.js at the top of each page that uses the JavaScript API.

Although typed parameters are not used in JavaScript, they are included in the method descriptions to indicate the types that are expected by each method. You declare variables for these parameters using the normal JavaScript var statement.

getCurrentForm method

The getCurrentForm method returns a reference to the form that contains your web page.

The getCurrentForm method is applicable only when getting a reference to the form that is a parent of your web page. To obtain a reference to a form that is a child of your web page, use the ibmForms[] array.

Method

FormNodeP XFDL.getCurrentForm()

Parameters

This method has no parameters.

Returns

The FormNodeP object that represents the form, or Null if a form cannot be found.

Example

The sample code retrieves the version of the form and converts it to a string for display in a JavaScript alert window.

function testGetCurrentForm() {
  var version, s;

  s = "--- Results of getCurrentForm test ---\n";
  version = XFDL.getCurrentForm().getFormVersion().toString(16);
  s += " Form Version: " + version;

  alert(s);
}

A typical message displayed in the alert window might look like this message, depending on the version of your form:

--- Results of getCurrentForm test ---
 Form Version: 8000300

registerAPIExceptionHandler method

This method registers a custom function that handles exceptions thrown by the JavaScript API.

Method

void XFDL.registerAPIExceptionHandler(
   Function handler
);

Parameters

Expression Type Description
handler Function The name of the function that will be called when a JavaScript API exception is thrown.

Returns

Nothing

Notes

Exceptions thrown by the underlying processing code are intercepted by the error handling mechanism of the JavaScript API. Because of this, they cannot be caught with the normal JavaScript try-catch mechanism. Instead, they are either displayed as an error in a JavaScript alert box, or passed to the custom exception handler that you register with the XFDL.registerAPIExceptionHandler method.

The exception handler that you register should take a JavaScript error object as its input parameter. The following code sample demonstrates a simple custom exception handler:
function customHandler(ex) {

  var s;

  s = "Details of the error:\n"
  s += "Name: " + ex.name + "\n"
  s += "Description: " + ex.message + "\n"
  alert(s);

}

Example

The sample code registers a custom error handler. The function is given the name customHandler, but you can use any name that you want.

function OnLoadForm() {

  /* web page initialization goes here */

  XFDL.registerAPIExceptionHandler(customHandler);

}   

registerForm method

An HTML page can host one or more XFDL forms. Use the registerForm method to add the forms to the ibmForms[] forms array.

Call this method after the HTML page has been loaded. After you add a form to the ibmForms[] array, the form becomes accessible to the JavaScript API.

Method

void XFDL.registerForm(
   FormNodeP theForm,
   String objectID
);

Parameters

Expression Type Description
theForm FormNodeP The FormNodeP that represents the form to be registered.
objectID String The id of the HTML object element that contains the Viewer ActiveX control.

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Notes

After the form has been registered, you can reference it with ibmForms[objectID]. For example, the following code fragment displays the version of the form registered with objectID equal to the string "Main":
alert(ibmForms["Main"].getFormVersion().toString(16));

Example

The sample code creates a new FormNodeP object, then registers the form.

function OnLoadForm () {
    
  var theForm = new FormNodeP(objectID);
  XFDL.registerForm(theForm, objectID);

  /* web page initialization code goes here */

}   

deregisterForm method

This method removes a previously registered form from memory. After calling this method, the form is no longer available to the JavaScript API.

Method

void XFDL.deregisterForm(   
   FormNodeP theForm
);

Parameters

Expression Type Description
theForm FormNodeP The FormNodeP that represents the form to be deregistered

Returns

Nothing. On error, the custom error handler registered by the XFDL.registerAPIExceptionHandler method is called with the details of the error. If no handler is registered, the details of the error are displayed in a JavaScript alert() message.

Example

The sample code deregisters the form that is passed in as the parameter.

function deregister() {

  XFDL.deregisterForm(ibmForms[objectID]);

}
   

About references

References allow you to identify a specific page, item, option, or argument by providing a "path" to that element. This means that you can access an element directly without having to locate any of its ancestors. The syntax of a reference follows this general pattern:

   page.item.option[argument]

Each element of the reference is constructed as follows:

You can create references to any level of the node hierarchy. For example, the following table illustrates a number of references starting at different levels of the form:

Start At Ref to Page Ref to Item Ref to Option Ref to Argument
Page Page1 Page1.Field1 Page1.Field1.format Page1.Field1.format[message]
Item Field1 Field1.format Field1.format[message]
Option format format[message]
Argument [message]

Supported XFDL options

Webform Server supports almost all XFDL options.

Table 45. Table of supported XFDL options.
Option Supported
acclabel Y
activated Y
active Y
bgcolor Y
border Y
borderwidth Y
boundingbox Y
colorinfo Y
columnwidth Y
coordinates Y
data Y
datagroup Y
delay Y
dirtyflag Y
display Y
editstate Y
excludedmetadata Y
filename Y
first Y
focused N4
focuseditem N4
fontcolor Y
fontinfo Y
format Y
formid Y
fullname Y
group Y
help Y
image Y
imagemode N1
itemfirst Y
itemlast Y
itemlocation Y
itemnext Y
itemprevious Y
itemtag Y
justify Y
keypress N
label Y
labelbgcolor Y
labelborder Y
labelbordercolor Y
labelborderwidth Y
labelfontcolor Y
labelfontinfo Y
last Y
layoutinfo N
linespacing Y2
mimedata Y
mimetype Y
mouseover N
next Y
padding Y
pagefirst Y
pageid Y
pagelast Y
pagenext Y
pageprevious Y
previous Y
printbgcolor Y
printfontcolor Y
printing Y
printlabelbgcolor Y
printlabelfontcolor Y
printsettings N3
printvisible Y
readonly Y
rtf N
requirements N
rowpadding Y
saveformat Y
scrollhoriz Y
scrollvert Y
signature Y
signatureimage Y
signdatagroups Y
signdetails N
signer Y
signformat Y
signgroups Y
signitemrefs Y
signitems Y
signnamespaces Y
signoptionrefs Y
signoptions Y
signpagerefs Y
size Y
suppresslabel Y
texttype N
thickness Y
transmitdatagroups Y
transmitformat Y
transmitgroups Y
transmititemrefs Y
transmititems Y
transmitnamespaces Y
transmitoptionrefs Y
transmitoptions Y
transmitpagerefs Y
triggeritem Y
type Y
url Y
value Y
visible Y
visiblerows Y
webservices N
writeonly Y

1The imagemode option only respects the default setting, which is resize.

2Setting the linespacing option too small will result in text overlapping. Make sure to test your form if you are using this option.

3The printsettings option only allows you to set which pages are printed. It does not respect dialog or border settings.

4By default, the focused and focuseditem options are not supported. Focus changes are not posted to the server, and you cannot use computations to dynamically set the focus. If you modify the translator.properties file (by setting focusNotificationItems to all), the form will post focus changes to the server; however, this will result in very high network traffic.

Notices

This information was developed for products and services offered in the U.S.A.

IBM may not offer the products, services, or features discussed in this document in other countries. Consult your local IBM representative for information on the products and services currently available in your area. Any reference to an IBM product, program, or service is not intended to state or imply that only that IBM product, program, or service may be used. Any functionally equivalent product, program, or service that does not infringe any IBM intellectual property right may be used instead. However, it is the user's responsibility to evaluate and verify the operation of any non-IBM product, program, or service.

IBM may have patents or pending patent applications covering subject matter described in this document. The furnishing of this document does not grant you any license to these patents. You can send license inquiries, in writing, to:

IBM Director of Licensing
IBM Corporation
North Castle Drive
Armonk, NY 10504-1785
U.S.A.

For license inquiries regarding double-byte (DBCS) information, contact the IBM Intellectual Property Department in your country or send inquiries, in writing, to:

Intellectual Property Licensing
Legal and Intellectual Property Law
IBM Japan Ltd.
1623-14, Shimotsuruma, Yamato-shi
Kanagawa 242-8502 Japan

The following paragraph does not apply to the United Kingdom or any other country where such provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties in certain transactions, therefore, this statement may not apply to you.

This information could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; these changes will be incorporated in new editions of the publication. IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this publication at any time without notice.

Any references in this information to non-IBM Web sites are provided for convenience only and do not in any manner serve as an endorsement of those Web sites. The materials at those Web sites are not part of the materials for this IBM product and use of those Web sites is at your own risk.

IBM may use or distribute any of the information you supply in any way it believes appropriate without incurring any obligation to you.

Licensees of this program who wish to have information about it for the purpose of enabling: (i) the exchange of information between independently created programs and other programs (including this one) and (ii) the mutual use of the information which has been exchanged, should contact:

IBM Corporation
5 Technology Park Drive
Westford Technology Park
Westford, MA 01886
U.S.A.

Such information may be available, subject to appropriate terms and conditions, including in some cases, payment of a fee.

The licensed program described in this document and all licensed material available for it are provided by IBM under terms of the IBM Customer Agreement, IBM International Program License Agreement or any equivalent agreement between us.

Trademarks

IBM, the IBM logo, ibm.com, Lotus, and Notes are trademarks or registered trademarks of International Business Machines Corporation in the United States, other countries, or both. These and other IBM trademarked terms are marked on their first occurrence in this information with the appropriate symbol (® or ™), indicating US registered or common law trademarks owned by IBM at the time this information was published. Such trademarks may also be registered or common law trademarks in other countries. A current list of IBM trademarks is available on the Web at http://www.ibm.com/legal/copytrade.shtml

Java and all Java-based trademarks and logos are trademarks or registered trademarks of Oracle and/or its affiliates.

Linux is a registered trademark of Linus Torvalds in the United States, other countries, or both.

Microsoft and Windows are trademarks of Microsoft Corporation in the United States, other countries, or both.

UNIX is a registered trademark of The Open Group in the United States and other countries.

Other company, product, or service names may be trademarks or service marks of others.

End of document