

First Edition
Published December 2010

© Copyright IBM Corporation 2000, 2010
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.
If you would like to provide feedback about this document, see the Lotus Documentation Feedback Web site.
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.
The new features for the Viewer 4.0 are listed below.
This section describes the available accessibility features for the IBM Lotus Forms Viewer.
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.
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.
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 |
This section contains two reference cards which provide information on keyboard shortcuts and accessibility options.
This reference card provides a list of Viewer keyboard commands used to navigate a form without the use of a mouse.
| 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. |
| 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. |
This reference card provides descriptions of the Viewer preferences available for modification.
| 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. |
| 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. |
| 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. |
| 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. |
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 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:
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>
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.
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:
You can also modify the display area of the form with the following optional attributes:
| 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"> |
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>
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:
<PARAM NAME="XFDLID" VALUE="XFDLData">
<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).
<PARAM NAME="refresh_URL"
VALUE="http://www.serv1/IRS/Sched22.htm">
<PARAM NAME="TTL" VALUE="15">
If you are using data instances, several additional values may be included:
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="."">
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="."">
</OBJECT>
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:
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.
When modifying the parameters, make sure that you have a comma after each one. You do not need a comma after the last parameter.
<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>
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:
<SCRIPT language="XFDL">
<PARAM NAME="XFDLID" VALUE="XFDLData">
<SCRIPT id="XFDLData">
<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.
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>
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>
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:
<SCRIPT language="XFDL">
<OBJECT ... object attributes ...>
<PARAM NAME="instance_1"
VALUE="new_Instance old_Instance
append[custom:record][custom:name]">
... other params ...
</OBJECT>
<SCRIPT id="new_Instance">
<SCRIPT type="application/vnd.xfdl; wrapped=comment">
The type and wrapped parameters must be separated with a semi-colon.
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:
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="."">
</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>
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>
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
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.
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.
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:
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:
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.
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.
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.
HTMLPane\dojo\dijit HTMLPane\dojo\dojo HTMLPane\dojo\dojox HTMLPane\JavaScript
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.
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>
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.
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>
After creating the form and the web page, open the form in Viewer.
To use the HTML in pane project:
In this tutorial, you will learn how to implement two-way communication between an HTML web page inside the Modal Dialog and an XFDL form.
The project that you build in this tutorial consists of two files. One file is a simple XFDL form that contains data, a label, a field, and a button. The other file is a web page that implements a Dojo slider control and is displayed inside the Modal Dialog. The web page uses the Lotus Forms JavaScript API to transfer data between the slider control and the form.
When you click the button on the form, the Modal Dialog opens and loads the web page. A script on the web page copies the value from the XForms model into the slider control. When you click Update Form in the Modal Dialog, the script copies the value of the slider control into the XForms model, which updates the value that is displayed in the field.
The first task is to verify that you have the appropriate files installed on your computer. Next, you create the XFDL form that opens the Modal Dialog. After you create the form, you create the web page that is displayed inside the Modal Dialog. Finally, you deploy and use the Modal Dialog project.
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 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.
ModalDialog\dojo\dijit ModalDialog\dojo\dojo ModalDialog\dojo\dojox ModalDialog\JavaScript
The form contains a label, a button, and a field. The form also contains an XForms model that supplies the value for the field.
Before you begin, make sure that you have set up your environment by creating the folder structure and copying the Dojo files and the JavaScript API files.
The button opens the Modal Dialog using the XFDL viewer.launchModalDialog function.
In a later stage of the tutorial, you will create the web page for the Modal Dialog. The web page will contain a short piece of JavaScript that uses the Lotus Forms JavaScript API to obtain the value of the <slider> element from the XForms instance. The value becomes the initial value for the slider control. When the Update Form button on the web page is clicked, the script updates the <slider> element in the form before closing the Modal Dialog.
Here is the complete file:
<?xml version="1.0" encoding="UTF-8"?>
<XFDL xmlns="http://www.ibm.com/xmlns/prod/XFDL/8.0"
xmlns:custom="http://www.ibm.com/xmlns/prod/XFDL/Custom"
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 id="slider-value" xmlns="">
<data>
<slider>9</slider>
</data>
</xforms:instance>
</xforms:model>
</xformsmodels>
</global>
</globalpage>
<page sid="PAGE1">
<global sid="global">
<label>Modal Dialog</label>
</global>
<label sid="LABEL1">
<value>Modal Dialog Tutorial</value>
</label>
<button sid="BUTTON1">
<value>Open Modal Dialog</value>
<layoutflow>block</layoutflow>
<custom:option xfdl:compute="toggle(activated, 'off', 'on') == '1' ?
viewer.launchModalDialog('TutorialModalDialog.html', '',
'380', '200', 'false', 'false') : ''"></custom:option>
</button>
<field sid="FIELD1">
<xforms:input ref="instance('slider-value')/slider">
<xforms:label></xforms:label>
</xforms:input>
<size>
<width>2</width>
</size>
<justify>right</justify>
<value></value>
</field>
</page>
</XFDL>
In this stage of the tutorial, you create the web page for the Modal Dialog.
The web page contains a short piece of JavaScript that uses the Lotus Forms JavaScript API to obtain the initial value of the slider control. When the Update Form button on the web page is clicked, the script updates the slider element in the form before closing the Modal Dialog.
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.require("dijit.form.TextBox");
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) {
dojo.byId("sliderValue").value = value;
}
},
"slider");
dojo.byId("sliderValue").value = slider.value;
});
function update()
{
// Use the updateXFormsInstance method from the Lotus Forms
// JavaScript API to update the form
XFDL.getCurrentForm().updateXFormsInstance(null,
"instance('slider-value')/slider",
null, dojo.byId("sliderValue").value,
XFDL.UFL_XFORMS_UPDATE_REPLACE_TEXT);
}
function cancel()
{
XFDL.getCurrentForm().getDialog().close();
}
</script>
</head>
<body class="nihilo">
<div style="position:absolute;left:34px;top:30px;width:302px;height:150px">
<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>
<table>
<tr>
<td style="text-align:center;width:318px;height:38px;">Selected Value:
<label style="width:30px" id="sliderValue" dojoType="dijit.form.TextBox"></label>
</td>
</tr>
<tr>
<td style="text-align:center;width:318px;height:38px;">
<button onclick="javascript:update();">Update Form</button>
<button onclick="javascript:cancel();">Close</button>
</td>
</tr>
</table>
</div>
</body>
</html>
After creating the form and the web page, open the form in Viewer.
To use the Modal Dialog project:
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.
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.
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.
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.
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.
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.
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.
Use a Web server to deliver a form for display in the Viewer.
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:
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.
<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>
var formMain = ibmForms[objectID];
Now you are ready to add the JavaScript.
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:
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.
<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 
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' 

: ((PAGE1.CURRENTMONTH.value > PAGE1.BIRTHMONTH.value) or 

! ( ! (PAGE1.CURRENTMONTH.value == PAGE1.BIRTHMONTH.value) or 

! (PAGE1.CURRENTDAY.value > PAGE1.BIRTHDAY.value)) 

? PAGE1.CURRENTYEAR.value - PAGE1.BIRTHYEAR.value 

: PAGE1.CURRENTYEAR.value - PAGE1.BIRTHYEAR.value - '1')

">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
presented in the IBM(R) Lotus(R) Forms Server - API Installation & Setup Guide.

Fill out and save this input form. Run the Calculate Age application.
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>
You also learned how to register a form and then access it through the global array ibmForms[].
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.
<script type="text/javascript" src="LF_FormNodeP.js"></script>
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>
| 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. |
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.
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);
}
--- Results of addNamespace test --- Namespace added to form. Namespace added to PAGE1.FIELD1.
void addOnBlur ( Function handler );
| Expression | Type | Description |
|---|---|---|
| handler | Function | The name of the function that will be called when the onBlur event occurs. |
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.
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());
}
void addOnChange ( Function handler );
| Expression | Type | Description |
|---|---|---|
| handler | Function | The name of the function that will be called when the onChange event occurs. |
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.
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());
}
void addOnClick ( Function handler );
| Expression | Type | Description |
|---|---|---|
| handler | Function | The name of the function that will be called when the onclick event occurs. |
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.
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());
}
void addOnFocus ( Function handler );
| Expression | Type | Description |
|---|---|---|
| handler | Function | The name of the function that will be called when the onFocus event occurs. |
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.
function button1OnFocus(xfdlEvent) {
alert(xfdlEvent.type);
alert(xfdlEvent.source.getInfoEx(FormNodeP.IDENTIFIER));
}
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());
}
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.
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.
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);
}
--- Results of checkValidFormats test --- These nodes have non valid formats: Node: PAGE1.FIELD1
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.
| 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. |
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.
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);
}
--- Results of createCell test --- Cells added to the popup item.
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 ("").
| Expression | Type | Description |
|---|---|---|
| signatureItem | FormNodeP | The signature node to delete. You can retrieve this node by calling dereferenceEx |
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.
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.
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);
}
--- Results of deleteSignature test -- The signature has been deleted.
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.
FormNodeP dereferenceEx(
String scheme,
String reference,
Number referenceCode,
Number referenceType,
FormNodeP NSNode
);
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.
Before you decide which FormNodeP to use this method on, be sure you understand the following:
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
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.
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.
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)
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);
}
--- 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.
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.
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);
}
--- Results of destroy test --- PAGE1.FIELD2 has been destroyed.
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.
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.
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);
}
--- Results of duplicate test --- FIELD1 duplicated and new field relocated.
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.
FormNodeP encloseFile( String data, String dataEncoding, String mimeType, String dataGroup, String identifier );
| 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. |
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.
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);
}
--- Results of encloseFile test --- XML encoding test: Success. The data was enclosed.
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.
void encloseInstance(
String instanceID,
String data,
Number flags,
String scheme,
String rootReference,
FormNodeP NSNode,
boolean replaceNode
);
| 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. |
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.
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);
}
--- 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>
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.
| Expression | Type | Description |
|---|---|---|
| dataEncoding | String | A string that represents the encoding of the returned data. Valid values are: "xml", "base64", and "base64-gzip". |
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.
<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);
}
--- 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=='
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.
String extractInstance ( String instanceID, FormNodeP triggerItem, String includeNamespacePrefixes, Number flags, String scheme, String rootReference, FormNodeP NSNode );
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.
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);
}
--- 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>
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.
String extractXFormsInstance(
String modelID,
String instanceXPath,
boolean respectRelevantMIP,
boolean ignoreFailures,
FormNodeP NSNode,
);
| 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. |
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.
XForms data model
The updateXFormsInstance and the extractXFormsInstance methods are the only methods that are intended to modify the XForms data model.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.
<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);
}
--- 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>
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>
| 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. |
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.
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">
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.
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);
}
--- Results of getAttribute test --- The sid of the first child node of PAGE1: 'global' The language of the form is: 'en-US'
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.
String[] getAttributeList( Number namespaces );
| 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. |
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.
<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);
}
--- Results of getAttributeList test -- Attribute 1: 'http://www.ibm.com/xmlns/prod/XFDL/Custom', 'id'. Attribute 2: 'null', 'sid'.
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.
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.
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);
}
--- Results of getChildren test --- The first child node of PAGE1.FIELD3 is: itemlocation.
Returns a reference to the Modal Dialog object.
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:
| 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. | |
getDialog ();
This method has no parameters.
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.
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>
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.
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);
}
--- Results of getFormVersion test --- Form Version: 7050300
This method retrieves information about a particular node. If you do not want information about a particular property, set it to null.
String getInfoEx( Number property );
| 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. |
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.
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:
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);
}
--- Results of getInfoEx test --- Type: undefined Literal: This is the value for FIELD3 Formula: PAGE1.FIELD3.value Identifier: value
This method finds a particular FormNodeP on the basis of a reference string. Once the FormNodeP is found, its literal is retrieved.
String getLiteralByRefEx( String scheme, String reference, Number referenceCode, FormNodeP NSNode );
| 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. |
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.
aNode.dereferenceEx(scheme, reference, referenceCode,
UFL_OPTION_REFERENCE | UFL_SEARCH_AND_CREATE,
theNamespaceNode).getLiteralEx();
Before you decide which FormNodeP to call the method on, be sure you understand the following:
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.
For more information about creating a reference, see About references .
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)
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);
}
--- getLiteralByRefEx results --- First test: This is Field 1 Second test: null Third test: 10
This method retrieves the literal of a node. The literal is returned in the specified character set.
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.
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);
}
--- Results of getLiteralEx test --- The value is: This is FIELD4
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".
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.
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);
}
--- Results of getLocalName test --- Local Name: myValue Local Name: value Local Name: focused Local Name: mouseover Local Name: itemprevious Local Name: itemnext
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>
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.
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);
}
--- 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
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>
| Expression | Type | Description |
|---|---|---|
| prefix | String | The namespace prefix. For example, xfdl. |
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.
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);
}
--- 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
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.
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.
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);
}
--- Results of getNext test --- Local Name: myValue Local Name: value Local Name: focused Local Name: mouseover Local Name: itemprevious Local Name: itemnext
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.
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);
}
--- Results of getNodeType test --- Node type for field: Item Node type for itemlocation: Option Node type for x: Array
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.
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.
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);
}
--- Results of getParent test --- Local Name: field Local Name: page Local Name: XFDL
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>
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.
<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);
}
--- Results of getPrefix test --- Namespace prefix for myValue: processing
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>
| Expression | Type | Description |
|---|---|---|
| uri | String | The namespace URI. For example: http://www.ibm.com/xmlns/prod/XFDL/7.5 |
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.
<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);
}
--- 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
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.
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.
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);
}
--- 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
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.
String getReferenceEx( String scheme, FormNodeP NSNode, FormNodeP startPoint, boolean addNamespaces );
| 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. |
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.
For more information about creating a reference, see About references .
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.
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.
<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);
}
--- 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
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.
| 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. |
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);
}
--- Results of getSecurityEngineName test --- Test 1: ClickWrap Test 2: ClickWrap Test 3: ClickWrap
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.
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.
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);
}
--- Results of getSigLockCount test --- Signature lock count for PAGE1.FIELD1: 1
When called, this method checks to see if the digital signatures in a given form are valid.
a Number having one of the following values:
| 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.
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);
}
--- Results of getSignatureVerificationStatus test --- All signatures are valid.
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.
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);
}
--- Results of isSigned test --- FIELD1 is signed. FIELD2 is not signed.
This method returns the boolean result of whether a string is valid according to the setting of the node's format option.
| 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”. |
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.
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);
}
--- Results of isValidFormat test --- The value '42' is not a valid format for FIELD1. The value '20071001' is a valid format for FIELD1.
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>
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.
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.
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.
| 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. |
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.
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.
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">
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);
}
--- Results of removeAttribute test --- Attributes were removed from PAGE1.LABEL1
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.
| 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. |
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.
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);
}
--- Results of encloseFile test --- The enclosure was removed from the form
This method deregisters an event handling function that was previously registered with the addOnBlur method.
void removeOnBlur ( Function handler );
| Expression | Type | Description |
|---|---|---|
| handler | Function | The name of the function to deregister. |
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.
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);
}
--- Results of deregisterButtonEvent function call --- Function button1OnBlur deregistered.
This method deregisters an event handling function that was previously registered with the addOnChange method.
void removeOnChange ( Function handler );
| Expression | Type | Description |
|---|---|---|
| handler | Function | The name of the function to deregister. |
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.
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);
}
--- Results of deregisterButtonEvent function call --- Function button1OnChange deregistered.
This method deregisters an event handling function that was previously registered with the addOnClick method.
void removeOnClick ( Function handler );
| Expression | Type | Description |
|---|---|---|
| handler | Function | The name of the function to deregister. |
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.
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);
}
--- Results of deregisterButtonEvent function call --- Function button1OnClick deregistered.
This method deregisters an event handling function that was previously registered with the addOnFocus method.
void removeOnFocus ( Function handler );
| Expression | Type | Description |
|---|---|---|
| handler | Function | The name of the function to deregister. |
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.
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);
}
--- Results of deregisterButtonEvent function call --- Function button1OnFocus deregistered.
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.
| Expression | Type | Description |
|---|---|---|
| activeFlag | boolean | Set to true to activate the compute system or false to deactivate the compute system. |
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.
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);
}
--- Results of setActiveForComputationalSystem test --- This is field 1 This is field 2
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.
| 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. |
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.
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.
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">
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);
}
--- Results of setAttribute test --- Attributes were added to PAGE1.LABEL1
| Expression | Type | Description |
|---|---|---|
| formula | String | The formula to assign to the node. If null, the formula is assigned as null. |
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.
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);
}
--- Results of setFormula test --- Compute was added to PAGE1.FIELD3.value
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.
void setLiteralByRefEx( String scheme, String reference, Number referenceCode, FormNodeP NSNode, String literal );
| 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. |
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.
Before you decide which FormNodeP to use this method on, be sure you understand the following:
For more information about creating a reference, see About references.
Do not set a node that is digitally signed. Doing so will break the digital signature and produce an error.
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")
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);
}
--- Results of setLiteralByRefEx test --- New properties added to PAGE1.FIELD3.
This method sets the literal of a node. You should only set the literal for option or argument nodes.
| Expression | Type | Description |
|---|---|---|
| literal | String | The literal to assign to the node. If null, any existing literal is removed. |
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.
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);
}
--- Results of setLiteralEx test --- The node 'PAGE1.FIELD3' has been relocated.
Inserts data anywhere within the XForms instance data, or replaces it entirely. It automatically updates the XForms data model.
Call this method on the root node of the form or an instance node.
void updateXFormsInstance( String modelID, String nodeRef, FormNodeP NSNode, String data, Number updateType );
| 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. |
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.
The updateXFormsInstance and the extractXFormsInstance methods are the only methods that are intended to modify the XForms data model.
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);
}
--- Results of updateXFormsInstance test ---
The updated XForms instance:
<document>
<cities>
<city>Montreal</city>
<city>Beijing</city>
<city>Moscow</city>
</cities>
</document>
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:
| 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. |
One of the following values:
| 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.
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);
}
--- Results of verifyAllSignatures test --- All signatures on the form are valid.
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:
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.
short verifySignature( FormNodeP signatureItem, StringHolder theCertChain, boolean reportAsErrorsFlag );
| 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. |
A Number having one of the following values, depending on the status of the signature:
| 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.
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);
}
--- Results of verifySignature test --- The signature is verified.
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.
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.
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);
}
--- Results of verifySignature test --- Bound option changed.
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.
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.
FormNodeP XFDL.getCurrentForm()
This method has no parameters.
The FormNodeP object that represents the form, or Null if a form cannot be found.
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
This method registers a custom function that handles exceptions thrown by the JavaScript API.
void XFDL.registerAPIExceptionHandler( Function handler );
| Expression | Type | Description |
|---|---|---|
| handler | Function | The name of the function that will be called when a JavaScript API exception is thrown. |
Nothing
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.
function customHandler(ex) {
var s;
s = "Details of the error:\n"
s += "Name: " + ex.name + "\n"
s += "Description: " + ex.message + "\n"
alert(s);
}
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);
}
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.
void XFDL.registerForm( FormNodeP theForm, String objectID );
| 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. |
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.
alert(ibmForms["Main"].getFormVersion().toString(16));
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 */
}
This method removes a previously registered form from memory. After calling this method, the form is no longer available to the JavaScript API.
void XFDL.deregisterForm( FormNodeP theForm );
| Expression | Type | Description |
|---|---|---|
| theForm | FormNodeP | The FormNodeP that represents the form to be deregistered |
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.
The sample code deregisters the form that is passed in as the parameter.
function deregister() {
XFDL.deregisterForm(ibmForms[objectID]);
}
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:
Arguments can also have any depth. For example, you might have an argument that contains arguments. You can reference additional levels of depth by adding another bracketed reference. For example, to refer to the first argument in the first argument of the printsettings option, you could use either [0][0] or the tag names in brackets, such as [pages][filter].
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] |
Webform Server supports almost all 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.
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.
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.