ShowTable of Contents
The following article will attempt to give IBM Form developers a step by step guide as to how to best go through the form development process. The order of development tasks is important, so pay special attention to that - and consider the reasons why you would want to complete one task before continuing onto the next.
The development tasks are shown in the table of contents above
Identify data dependancies
If a dependancy between the form data and other systems exist define and finalize a structure of XML that will act as the interface between the form and the dependant system.
This should be done before starting work on the form.
This XML structure can be expressed as a schema, or in an XML instance.
Even if no dependancy exists, it's still a good idea to define your own XML structure. One easy way to do this is to allow the IBM Forms Designer to generate an instance for you: This is called the 'Generated' instance. But once you've completed the layout of form, it's important to convert that Generated instance to a custom instance.
Identify UI design standards
If there is a specific UI design requirement then the layout design, color scheme, size of images, etc, should be defined and agreed upon before work should start on the form.
Concepts to consider:
- Consistent font styles and sizes between same groupings
- Headers
- Section headers
- Page headers
- Field labels
- Horizontal and vertical spacing
- Choose a set of colors that is used within the form
- Minimize use of custom graphics and non-standard fonts
Once the data dependancies and UI design is understood, then the form development can begin.
If form development starts before the UI design and data dependancies are understood, then this will likely cause lots of rework, causing form development to take much longer than it should.
In a multiform application, some consideration should be given to shared or common UI structures between forms like a banner or logo.
Also shared components (like web services or list of common choices) should be identified as well and implemented as Form Parts.
Identify internationalization requirements
Identify if the form needs to support multiple languages
- If so, then you'll need to determine if you wish to build a single form that supports many different languages or have many forms where each form supports a different language.
- Single form approach requires labels to get their text from a 'language' instance. Where each label is bound to this language instance, and the language instance is likely populated with the desired language specific strings at run-time before being sent to the user. This requires a slightly more complicated design effort, but maintenance of the form is easier, as there's only one form to update in the case when business logic changes. The various language instance strings should be defined and provided to the form developer before form development begins, as the form developer needs to know how much space they have to work with.
- The multiform approach requires rework (essentially you're building the same form many times), but simplifies the development effort. Maintenance is more complicated as any changes need to be made to multiple forms. This can be made easier with the use of Form Parts that contain common business logic / instances between the forms.
- locale should be considered as well as the form will display dates and currencies differently based on the locale setting. The locale can not be computed or changed at run-time.
Add data instances
Either generate XML Instances from schema, create with Instance View, or manually add via Source View.
This XML should contain all the possible XML elements that the form might ever need to work with.
Some thought should be given to how the form data is broken up into different instances.
- Control instances (temporary variables, state information, etc) should be kept separate from data instances.
- Data for choice lists should be in their own instances
- if business or validation logic will need to occur between different elements in the XML data, then a having all the XML in a single instance would be desired, so that references can be made relatively, and not force the XML parser to start from the top of the tree.
- Some consideration as to what data really needs to be submitted to the back-end should be done, as that should all be contained in a single instance, and this data should only have what the back-end requires, and be able to be submitted via a single xforms submission, or extracted via a single extractXFormsInstance call.
- Repeating structures should be contained within a single parent node.
If no external data dependancy exists, then this step can be skipped as a 'Generated' instance will be created for you as you create form items on the page..
Layout form structure
Add sections or panes to the form
Bind those sections to logical elements in the instance data (probably parent nodes of common logical data in an instance)
Add non-input items (boxes, static labels, lines, etc) to the form sections.
If a group of items needs to visibly react to a common data (for example a set of fields needs to go invisible if a certain checkbox is checked), then place those items inside a pane - and add visible logic to the pane via a relevance bind
if a wizard style form is required, then the Designer's Form Wizard should be used.
Add non-static form items
If possible, drag and drop from Instance View
- Item will be automatically bound to appropriate XML element
- If schema has been used, then the item will be of the appropriate type (for example for a Boolean type, a checkbox will be created)
If form has sections that are bound to instance data, then for items that are inside the section, relatively bind them to children elements inside what the pane is bound to.
- For example for an Address Block section. The pane might be bound to something like instance('formData')/buyerAddress, and the fields inside the pane should be bound to street and city and not instance('formData')/buyerAddress/street and instance('formData')/buyerAddress/city.
Add dynamic labels to the form
- Dynamic labels (labels that get their value from instance data) can be added by dropping a Text Label on the canvas, and then dragging and dropping the appropriate instance element onto it
- Or an xforms:output can be created, and then specify the desired XPath expression in the value attribute. This allows performing calculations to determine the label's value - as opposed to having to retrieve the entire value from the instance data
If a repeating structure is needed, then the Designer's Table Wizard should be used.
Set desired properties for form items
- All properties BUT visible, active, mandatory, read-only, and value should be set via either properties view, or properties dialog
Define relative positioning if it's needed
- Once relative positioning is used on a page, all items on the remainder of the page must also be defined with relative positioning
- Another approach to this is to place content that needs to move together inside a pane - and then only relative align the pane.
Remove redundant itemlocation specifications
- When you ask the designer to position an item relatively to another item, it simply appends the itemlocation entry after whatever was existing. Something like x, y, after, below, after, below could be changed to a single below entry.
Use cases (switch and groups) sparingly: Unnecessary overuse can impact performance
Rename “Generated” instance before adding business or validation logic and ensure that no items are bound to the Generated instance
- The Generated instance is meant to be a temporary instance that is provided so that the form is always valid from an XForms standpoint
- The structure of the Generated instance automatically changes when moving or renaming form items.
- As such, any logic that refers to an element in the Generated instance might become invalid.
- You should either bind the form items to a custom instance, or convert the Generated instance to a custom instance.
Add business logic
When possible all business logic should be added to the form via XForms
- This business logic should be specified in some type of xforms:bind
- The visible, active, readonly, and value of any item (or pane) can be controlled through an xforms relevance, readonly, or calculate bind
- XForms binds are very powerful: a single xforms relevance bind can control the visibility of many form items
A note on relevance:
- Relevance only effects the visible property of items
- When an item is not visible, it still takes up space on the page.
- For an item to not take up any space on the page, you need to set the item's display property to 'off'.
- Computing the display with a compute="'xformsenabled" is a common way for relevance to control that. as xformsenabled will return 'off' if an item is determined to be non-relevant.
All other item properties (like bgcolor, font color) can be computed in an XFDL compute
Add validation
When possible all validation logic should be added to the form via XForms
- The validation logic should be specified in some type of xforms:bind
- The type, mandatory, and constraint of any item can be controlled through an xforms type, required, or constraint bind
- XForms binds are very powerful: a single xforms required bind can control the mandatory setting of many form items.
XFDL computes should be used only when the desired requirement cannot be met with XForms - things like controlling the bgcolor of an item
- hint: multiple operations can occur in a single XFDL compute by appending the commands together using +.
Use checkValidity to complete page, form, item, or data level data validation checks. checkValidity should be used instead of checkValidFormats
here's an example of a submit button that uses a compute to call checkValidity and stops the submission if something fails validation: (it also shows an example of using the +. operator to concatenate commands together.
<button sid="SUBMIT1">
<itemlocation>
<x>10</x>
<y>10</y>
</itemlocation>
<value>Submit</value>
<type>submit</type>
<printvisible>off</printvisible>
<custom:checkValidity xfdl:compute="toggle(activated, 'off', 'on') == '1'
? (checkValidity('UI-validation report-all') != ''
? (set('activated', 'off') +. viewer.messageBox('You need to fill all mandatory fields before you can submit.'))
: '')
: ''"></custom:checkValidity>
</button>
Add navigation elements
When possible all navigation logic should be added to the form via xforms
- Should be specified in some type of xforms:action that calls setfocus.
Navigation between cases in a switch should be done via state property
- So that items outside of case can also react to current 'state' of switch.
Basic static page navigation can be done via an XFDL button of type pagedone
Specify tab order
Tab order will default to the build order
Where possible, change the build order to get the tab order default
Explicitly adding form item tab order properties can add unnecessary bulk to a form
If defining tab order, don't forget to take the reverse tab order into consideration
Add submission details
Use Designer's Web Services Wizard if consuming of web services is required
- If you need to make changes to a form due to a change to a web service that it consumes - then follow this article for a guide for how to do that: How to maintain Web Services using the Web Services Wizard
- Consider placing web services in a Form Part, as often many forms use the same web service. So if the web service changes, then updating all the forms that consume that web service is much easier if the web service was implemented as a FormPart. A Form Part does not have to contain UI - so could just contain the Web Service.
Perform xforms:submission if backend systems only requires the XML data the form captured
Perform XFDL submissions if backend system needs to store entire form, or validate signature, or extract attachments.
- When performing an XFDL submission from Webform Server, ensure that the form is being submitted to a Servlet that extends the IBM Forms Framework.
Define printing requirements
Set the various print settings to control which pages get printed, and control which items get printed via printvisible.
Use print filters to only print those pages that need to be printed
Using default product pagination
- tileInOneDiretion: Will place extra content that does not fit in a single page, onto more pages. When printing to pdf with the Webform Server, the server attempts to not pagebreak in the middle of words.
- ShrinkToPage: Will shrink all page content so that it will fit in a single printed page
Can also control pagination programmatically
Signatures
Signatures should always be added at the very end of form development
- Changes in form items can mean that some fields are omitted from the signature if not signing the entire page
- Where possible, use “omit” rather than “keep” logic when not signing entire form
- This reduces the risk that form items will be unintentionally excluded from the signature