XForms reference

The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

XForms Package

Introduction

The purpose of the XForms package is to provide an optimized mechanism for producing complex display and data-entry forms on the client, while shielding the developer from writing the HTML required to create these displays. This implementation doe not comply with W3C XForms Specification, it is at best "inspired by" that specification.

At the heart of every XForm are three pieces:

  • an [#XForm_Object XForm object]
  • an [#XModel_Object XModel object]
  • a [#data_instance data instance]

The XForm object specifies functionality and appearance of the form. The meat of the XForm consists of a list of "items", each of which has some representation on the screen (see [#XForm_Items XForm Items]). Many of the item types are visual (e.g. labels, text fields, checkboxes and buttons), while some are provided for grouping or aggregating sets of form items for display purposes. A facility is provided for switching the set of fields displayed (much like a tabbed preference dialog or a wizard, where different sets of options are presented sequentially), and also for handling lists of items, where the XForm will automatically create as many rows in the display form as there are rows in the instance data. XForm items are dynamically shown or hidden (see [#relevant relevant] property) as instance data changes, to hide controls that are not relevant due to the current state of the data instance.

The XModel object specifies the shape of the data -- how the data is organized hierarchically, data types and any constraints (validators) on the data. The XModel is essentially a static set of items (referred to herein as "modelItems", to distinguish them from form "items"), and is used mainly to access and set property values in the current data instance, as well as to guarantee that data written to the instance is consistent with all constraints. (see [#XModel_Items XModel Items]). An XForm can be instantiated without an XModel, in which case the XForm will create an "empty" XModel automatically. It is common to have a number of XForms that point to a single XModel ("Singleton" pattern) -- for example, one might specify "simple display", "full display", "simple edit" and "full edit" forms that all point to the same piece of data, and thus share a single XModel.

The data instance is either a simple Javascript object, or an instance of a Javascript class. The ultimate purpose of the XForms mechanism is to display and modify this data. By default, the XModel will access the properties of the instance directly according to XPath expressions embedded into the modelItem descriptions. Within the XModel, a facility is provided to use functions to [#xmodel_getter get] or [#xmodel_setter set] various properties of the instance data to provide for calculated values, use multi-part widgets to control a single instance attribute, etc. Also note that the XForm will save values into with the widget as the user interacts with the form -- when the user types a new value into a text field, that value will be saved in the instance when the user leaves the field. If you want to provide the user with the facility to cancel editing actions on a form, you may want to clone the instance, and pass the clone into the form, then write any changed values back into the original instance when they hit "save."

The XForm Object

You will create a single XForm for every display, input form, etc that you want to create in your application. You can either create a generic XForm and customize it by setting its items, etc. or you can subclass the XForm class itself and create instances of that. Note that the XForm is an instance of the DwtComposite class -- in the standalone prototype mode (where DWT is not provided), a very basic DwtComposite is created -- (see [#Standalone_Mode Standalone Mode]).

The basic procedure to create and display an XForm goes like so:

  1. Create the [#XForm_Items list of items] to be shown in the XForm.
  2. (optional) [#new_XModel Create an XModel] that describes the data instance.
  3. [#new_XForm Create the XForm], passing in the list of items (in the attributes argument) and the XModel.
  4. Create the instance that the XForm will display and [#setInstance make the form aware of it]. Note: you may want to clone the instance before handing it to the form; (see [#Handling_Changes_to_the_Form Handling Changes to the Form]).
  5. [#draw Draw the form] to display it.
  6. The user interacts with the form, [#Getting_and_Setting_Instance_Values values are automatically saved] in the instance. The form is hidden when it is no longer used.
  7. At some point later, when the user wants to edit/display a new instance, simply [#setInstance point the form at the new instance] and show the form again.

Note that the XForm is very smart about drawing -- it only creates the various widgets in the form once, then simply updates the values in these widgets dynamically as the instance data changes.

In the Model-View-Controller paradigm, an XForm can be thought of as a both a View -- in that it visually presents the instance data to the user -- and as a Controller -- in that it actually modifies the data. It accomplishes this through managing (controlling) the set of XForm Items, which themselves present a view (of a small piece of the instance data) and a controller (the INPUT, SELECT, TEXTAREA, etc) that allows the user to change this datum. This concept of nested views and controllers is very common in the MVC paradigm.

Because your form is probably a part of a larger system, say an entire DHTML application, the XForm understands that it in turn might be managerd by another controller. When creating your form, you can [#setController set its controller], then make references within the form and form items to this controller. For instance, you might have a button in your xform that needs to show a dialog that is not part of the form. The "onActivate" script of XFormItem that represents your button can be: onActivate:"this.getForm().getController().showSomeOtherDialog()" By setting up the reference from your form to the controller, you can avoid having to use static references to the controller within your form. E.g., you want to avoid code like the following for the aforementioned onActivate trigger: onActivate:someGlobalController.getRef() + ".showSomeOtherDialog()" because it makes your code conceptually more confusing, and makes it harder to re-use this piece of code in other circumstances (where there might be a different controller).

XForm Attributes of Interest

The following are properties of an XForm that you can add on instantiation to control how the form is rendered. Pass these as the attributes of the form on instantiation, e.g.:

        var myXForm = new XForm({
                        id:"myForm",
                        cssClass:"myFormClass",
                        cssStyle:"border:1px solid blue;",
                        items:[
                                {type:_OUTPUT_, value:"Instructions for using this form..."},
                                {ref:"name"},
                                {ref:"phone"}
                        ],
                        defaultItemType:_TEXTFIELD_,
                        itemDefaults:{
                                _OUTPUT_:     { cssClass:"myFormOutput" },
                                _TEXTFIELD_:  { width:200  }
                        }
                }, myXModel);
Attribute (type) Description
id (string) Sets the DOM id of the HTML container that the XForm is drawn in, as well as the internal id of the xform in the Javascript context. Because this is the DOM id of the form container, you can have an id'd CSS attribute in a CSS file that styles the container for the form, e.g., in a CSS file, #myForm { border:1px solid blue; } will style the container for the above form.

Note that if you instantiate more than one form with the same id, the second and subsequent forms will have a number appended to their name to make them unique, eg: myForm, myForm2, myForm3, etc.

To get a pointer to an XForm with a particular id, use: XFG.cacheGet(id)

If you do not provide an id, forms wll default to ids of _XForm, _XForm2, etc.

items (array) The list of (possibly nested) [#XForm_Items xform items] that this form will display.

Default is a form with no items (which is not very interesting).

cssClass (string) CSS CLASS attribute for the outer container of the form. E.g., the form above would match an entry in a CSS file like so: .myFormClass {border: 1px solid blue;}

Default is null (no class applied).

cssStyle (string) CSS STYLE attribute for the outer container of the form. Enter styles here in quotes, as you would place them in a CSS file. Note that it is generally a better practice to use logical css classes for your form, rather than relying on setting css styles for everything.

Default is null (no style applied).

numCols (number) Specifies the number of columns (including columns for labels) for the outer display of the form. See [#Layout_Considerations Layout Considerations] for more details.

Default is 2, one column for labels and one for form item widgets.

colSizes (array) Specifies an array of column sizes to output for the outer display of the form. See [#Layout_Considerations Layout Considerations] for more details.

Default is null.

defaultItemType (string) XFormItem type which will be used to instantiate the form's items, when an item does not specify an explicit type. In the above example, both name and phone would be created as _TEXTFIELD_ items.

Default is _OUTPUT_.

itemDefaults (object) Use this to customize different XFormItem types for this form. The syntax is an object with typename:propertylist pairs. For this form only, the defaults that you provide for each type name will override the normal default properties for that type. E.g., in our example above, all _OUTPUT_ formItems will have a cssClass of "myFormOutput" and all _TEXTFIELD_ items will be 200 pixels wide. You can override any properties of the formItems you want, including methods.

Note that a current limitation of this implementation is that the defaults will only apply to the particular formItem type you specify in the itemDefaults, not to subclsses of that formItem type. E.g. setting a default for the _TEXTFIELD_ formitem type will not apply to the _PASSWORD_ formitem type, even though the _PASSWORD_ implementation derives from _TEXTFIELD_.

Default is null (no customization).

XForm Methods of Interest

To create an XForm

<code>new XForm(attributes [,xmodel] [,instance] [,dwtContainer])</code>
  • attributes: object literal, all properties of which will be copied into the instance of the form. Specifically, this should at the least contain an "items" property which specifies the list of form items to display (see [#XForm_Items XForm Items]).
  • xmodel: (optional) instance of an [#The_XModel_Object XModel] or subclass. If not provided, the form will make an empty XModel automatically.
  • instance: (optional) instance of data to be displayed by the form. Can also be [#setInstance provided later] (or switched out at any time).
  • dwtContainer: (optional) DWT container object to set as the parent of the form.

To draw an XForm

<code>xform.draw([parentElement])</code>
  • parentElement: (optional) parent element to draw in. If not specified, will use the getHTMLElement() call from DWTContainer.

Note: only needs to be done once. After the initial draw, use the [#refresh refresh()] method to update the form display.

To set the XForm to a particular data instance

<code>xform.setInstance(instance)</code>
  • instance: data instance (simple JS object or instance of a JS class) that the form should display. The form will automatically update to show the new instance data.

To set the controller of the form

<code>xform.setController(yourController)</code>
  • yourController: Any controller object.

To get a reference to the controller of the form

<code>xform.getController()</code>
  • returns: Pointer to the controller object.

Note that within the context of a formItem, you can use the convenience method getFormController(), e.g.

<code>formItem.getFormController()</code>
<code>formItem.getForm().getController()</code>

XForm Events of Interest

The following are events that you can observe on an XForm, to be notified when interesting things happen with the form. The form uses the standard LsListener syntax to set up and remove listeners, eg: var listener = new LsListener(yourObject, yourCallbackMethod);yourXForm.addListener(DwtEvent.XFORMS_READY, listener); Then, when the appropriate thing happens in the form, your method will be called: yourObject.yourCallbackMethod(event) where event has one or more of the following properties:

  • form: pointer to the form signalling the event
  • formItem: pointer to the formItem signalling the event
  • detail: details specific to the particular event, enumerated below

DwtEvent.XFORMS_READY

Called when the form finished its inital [#draw draw()]. Event attributes:

  • event.form - pointer to the form

DwtEvent.XFORMS_VALUE_CHANGED

Called when a formItem in the form has been changed, eg: the user changed a value and it passed validation. This will be called after the value has actually been saved in the data instance, but before XFORMS_FORM_DIRTY_CHANGE. Event attributes:

  • event.form - pointer to the form
  • event.formItem - pointer to the formItem that was changed
  • event.details - new value saved for that item.

DwtEvent.XFORMS_FORM_DIRTY_CHANGE

Set whenever the "dirty" state of the form changes. This is called:

  • When the form is set to a new data instance. (event.details == false)
  • When a form item is actually changed (eg: the user changed a value and it passed validation). (event.details == true)

Event attributes:

  • event.form - pointer to the form
  • event.details - boolean: true means the form is now "dirty", false means it is "clean" (eg: form was set to a new data instance, was saved, etc).

DwtEvent.XFORMS_VALUE_ERROR

Set when a field in a form has an error. I.e.: when a user entered an invalid value into a field. This event usually originates from an input validation method of a form item. Event attributes:

  • event.forrm - pointer to the form
  • event.details - value that is entered into the form
  • event.formItem - pointer to the formItem that generated the error

XForm Items

XForm items are the things that are actually displayed in the the form. Each widget is automatically converted to be an instance of a XFormItem subclass when the form is initialized.

XForm items fall into five basic categories:

  • [#widget_item_types Widgets] (input, output, select, etc)
  • [#composite_item_types Composite Items] (date, etc)
  • [#grouping_item_types Grouping Items] (group, switch, case)
  • [#repeating_item_types Repeating structures] (repeat)
  • [#appearance_item_types Form appearance] items (spacer, separator)

At a minimum, each form item has a type attribute which controls how it is displayed (as a text field, selection box, text label, etc). In addition to the [#W3C_Compliance standard XForm types], this implementation includes a large number of additional item types, allowing you to create very complex forms. If the type of a form item is not specified, it is assumed to be of the output type.

Many form items also specify a ref attribute, which links this form item to a modelItem, specified in the XModel for the form. Form items with refs will automatically display the value contained in the current instance when the form is updated. Note that grouping items can also specify a ref attribute; any sub-items of the group with a ref will be nested under the ref of the group. e.g.:

                {type:_GROUP_, ref:"address", items:[
                                {type:_INPUT_, ref:"street"},
                                {type:_INPUT_, ref:"city"},
                                {type:_INPUT_, ref:"state"},
                                {type:_INPUT_, ref:"zip"},
                        ]
                }

Each of the input elements within the group will inherit the address reference from the group, so their references are effectively "address/street", "address/city", etc. The XForm handles setting this up with the appropriate XModel modelItems automatically.

XFormItem Types

Note that when specifying widgets in JavaScript you should use constants defined by the XFormItem classes to reference the different types of widgets. E.g. {type:_OUTPUT_, ref:"foo"} will create an "output" type widget. When specifying widgets in XML, use the lowercase widget names specified below, eg: <output ref="foo" />

The item types detailed below are divided into the following categories:

  • Widget Item Types
  • Composite Item Types
  • Grouping Item Types
  • Repeating Item Types
  • Form Appearance Item Types
  • External Widget Adaptor Types

Most of the XForm items consist of a label, a field and an error message. To see how each item is rendered in HTML, look at outputHTML method of the item's implementing JavaScript class as well as at XForm.prototype.outputItemList. All items extend XFormItem class and inherit the following common attributes:

  • ref - reference to an XModel item in the data model
  • labelLocation (default value: _LEFT_) - location of label in relation to the form field (_LEFT_, _NONE_, _RIGHT_)
  • containerCssClass (default value: xform_container) - CSS class for the container HTML <div> element.
  • containerCssStyle - additional CSS style string for the container
    element
  • tableCssClass (default value: xform_table) - CSS class of the HTML <table> element that contains item's label and field. <table> element is rendered inside the <div> element.
  • tableCssStyle - additional CSS style string for the container HTML <table> element
  • cssClass - CSS class of the HTML element that represents the item field
  • labelCssClass (default value: xform_label) - CSS class for item's label element
  • errorCssClass (default value xform_error) - CSS class class for item's error element
  • labelWrap - boolean, indicates weather label text can be wraped
  • align - _LEFT_, _RIGHT_, _NONE_, _CENTER_, _MIDDLE_, _TOP_, _BOTTOM_
  • valign - _LEFT_, _RIGHT_, _NONE_, _CENTER_, _MIDDLE_, _TOP_, _BOTTOM_
  • focusable (default value: false) - boolean, indicates weather the item can grab input focus
  • bmolsnr (default false) - boolean, indicates weather the item should subscribe to DwtEvent.XFORMS_VALUE_CHANGED events generated by this item's model item. This is useful for items whose value may change as a result of user's interaction with some other form item. I.e. a value of an _OUTPUT_ item may reflect the value of another _TEXTFIELD_ item.

Widget Item Types

Note: this is not a full list of widget item types available in the framework. This list covers the most common items that are used in the Zimbra Administration Console.

_OUTPUT_ ("output")

Draws a static piece of text within the form. If the item specifes a ref, the value displayed will change as the instance changes. If an _OUTPUT_ widget specifies a choices attribute, the XForm will look up the current instance value in the choices list and display the label that matches the value. e.g., if you have a formItem defined as: {type:_OUTPUT_, ref:"someRef",    choices:{a,"AAAA", b:"BBB"} and the value of instance.someRef is "a", the _OUTPUT_ will show the string "AAAA".

_INPUT_ ("input")

Specifies a form control that is text-entry widget. If an _INPUT_ is hooked up to a modelItem through its <ref>ref</ref> property. _INPUT_ will guess the type of data by the type of corresponding model item and will pick the type of widget to display that best fits the model item. If an _INPUT_ is hooked up to a _DATE_ modelItem, it should render as a date selection widget. However, it is recommended that developers always use more explicit widget types detailed below (e.g. _TEXTFIELD_, _CHECKBOX_, etc) when possible as it will be clearer to maintainers of your code exactly what is being specified and will ensure consistent display.

_TEXTFIELD_ ("textfield")

Specifies a text entry widget, rendered as an HTML <input> element.

_SECRET_ ("secret")

Specifies a text entry widget where the value is masked visually, generally by asterisks or dots. You can specify this type either as _SECRET_ or _PASSWORD_ -- the implementation is the same. This item implements extends _TEXTFIELD_ item and inherits all attributes of _TEXTFIELD_ item.

_PASSWORD_ ("password")

Same as _SECRET_

_TEXTAREA_ ("textarea")

Implements a multi-line HTML <textarea> widget. This item implements extends _TEXTFIELD_ item and inherits all attributes of _TEXTFIELD_ item. In addition to those attributes it also has the following atrributes: Set the width of the _TEXTAREA_ to "100%" to make it fill the entire horizontal space of the form.

  • width (default value: 100%)
  • height (default value: 100)

_CHECKBOX_ ("checkbox")

| Implements a checkbox, e.g. a box with a check in it when true and empty when false. Note that according to desktop user interface specifications, the label of a _CHECKBOX_ is rendered to the right of the box, rather than to the left as it is with most fields.

Specify the trueValue and falseValue properties to save particular values in the form when the checkbox is checked or unchecked, respectively, e.g. {ref:"present", type:_CHECKBOX_,    trueValue:"Y", falseValue:"N"} will save the value "Y" in instance.present if the checkbox is checked, and "N" if it is unchecked.

_RADIO_ ("radio")

Implements a radio button, which allows the user to select one of a number of choices.

_ANCHOR_ ("anchor")

Provides an anchor (eg: HTML <a href=...>) tag. By default, label property will be the visible label of the anchor, and the href of the anchor will be whichever comes first of the following:

  • If a ref was specified, the value of the ref'd field in the data instance.
  • If a href is specified, the href as a static value.
  • Alternatively, you can specify an onActivate method on the item to have that invoked instead when the anchor is clicked. If you're doing this, make sure you do not specify either a ref or href property for the anchor.

Use the showInNewWindow property to show the resulting URL in a new window (does not apply if you're specifying an onActivate handler). Item-specific attributes:

  • href - will be used for "href" property of the <a> element
  • onActivate - function reference or string of JavaScript code
  • showInNewWindow - weather to open the link destination in a new window

_URL_ ("url")

A variant of the _ANCHOR_ type where the href and label of the anchor are both set by the value of the ref of the formitem. Use this for a data value that is itself a URL that you want the user to be able to click on.

_MAILTO_ ("mailto")

A variant on the _ANCHOR_ type used to make clickable email addresses. The label of the anchor will be the value of the ref of the formItem, and the href will be "mailto:" + refValue.

_OSELECT1_ ("select1")

Implements a single-line select box with a pop-up menu. Note, that implementation is not based on <select> tag, but uses DwtMenu class to render value choices. Specify the options of the widget with the choices property. See Working with Choices for more details about specifying options for this widget. Attributes specific to this item type:

  • choices
  • editable

_OSELECT_ ("select")

Implements a multi-line HTML <select multiple=true> widget. Specify the options of the widget with the choices property. See [#Working_with_Choices Working with Choices] for more details about specifying options for this widget. Attributes specific to this item type:

  • choices

_DYNSELECT_ ("dynselect")

Implements a single-line select box with a pop-up menu and auto-complete. User can type into a text fields that is part of the widget and the widget will display matching items in the pop-up menu. _DYNSELECT_ extends _OSELECT1_ and inherits all its attributes. Attributes specific to this item type:

  • dataFetcherClass - JavaScript class that is instantiated when fetching auto-complete results
  • dataFetcherMethod - JavaScript function that is called to fetch auto-complete results
  • dataFetcherTypes - object types to be returned by SOAP request that is executed to fetch auto-complete results (refer to SearchDirectoryRequest in Zimbra Server documentation)
  • dataFetcherAttrs - attributes to be returned by SOAP request that is executed to fetch auto-complete results (refer to SearchDirectoryRequest in Zimbra Server documentation)
  • inputPreProcessor - function reference. This function is called before user input is passed on to dataFetcherMethod for fetching auto-complete results
  • dataFetcherInstance - boolean. If TRUE, the widget will use XForm data instance as context for executing dataFetcherMethod

Auto-complete in _DYNSELECT_ works as following. When user types something in the text box, the widget checks dataFetcherInstance attribute. If dataFetcherInstance is TRUE, the widget calls dataFetcherMethod in the context of XForm's data instance. If dataFetcherInstance is FALSE, the widget creates an instance of the JavaScript class referenced in dataFetcherClass and calls the method referenced in dataFetcherMethod in the context of that instance. Method referenced in dataFetcherMethod should fetch the auto-complete results and update the choices object. When choices object is updated, it notifies the widget, and widget updates the pop-up menu.

Example of using _DYNSELECT_
<code>
{ref:ZaAccount.A_COSId, type:_DYNSELECT_,label: null, 
	inputPreProcessor:ZaAccountXFormView.preProcessCOS,
	toolTipContent:ZaMsg.tt_StartTypingCOSName,
	onChange:ZaAccount.setCosChanged,
	emptyText:ZaMsg.enterSearchTerm,						
	enableDisableChecks:[[ZaNewAccountXWizard.isAutoCos], [ZaItem.hasWritePermission,ZaAccount.A_COSId]],
	enableDisableChangeEventSources:[ZaAccount.A2_autoCos],
	visibilityChecks:[],
	dataFetcherMethod:ZaSearch.prototype.dynSelectSearchCoses,
	choices:this.cosChoices,
	dataFetcherClass:ZaSearch,
	editable:true,
	getDisplayValue:function(newValue) {
		if(ZaItem.ID_PATTERN.test(newValue)) {
			var cos = ZaCos.getCosById(newValue, this.getForm().parent._app);
			if(cos)
				newValue = cos.name;
		} 
		if (newValue == null) {
			newValue = "";
		} else {
			newValue = "" + newValue;
		}
		return newValue;
	}
}
</code>

DWT Item Types

|- | _DWT_BUTTON_* ("dwt_button") | An adaptor for using DwtButtons within an XForm.

Set the label of the formItem to be the label of the button, and the onActivate method of the formItem to set what happens when the button is clicked. The onActivate method is called in the context of the formItem, so you have access to the form, form controller, etc. within this script. | * [#label label]: null

  • [#width width]: null
  • [#height height]: null
  • [#cssClass cssClass]: null
  • [#onActivate onActivate]: null


|- | _DWT_SELECT_* ("dwt_select") | An adaptor for using DwtSelect items within an XForm.

Note that the implementation of the DwtSelect is fairly slow -- consider using the _OSELECT_ class instead. | * [#ref ref]: null

  • [#choices choices]: null


|- | _DWT_DATE_* ("dwt_date") | Implements a date selector as a DwtDate widget -- a label that shows the date, and a button that shows a mini-calendar to allow them to select a date. | * [#ref ref]: null


|- | _DWT_DATETIME_* ("_DWT_DATETIME_") | This item is a composite of a _DWT_DATE_ and a _TIME_ object. | * [#ref ref]: null


|- | colspan="3" | === Composite Item Types ===


|- | _COMPOSITE_* ("composite") | This is the base class for all composite formItems -- items composed of a set of other items. Extend this class to create your own composite items.

Set the items property of your composite to the set of items that you want to show for each instance of the composite. The xforms mechanism will automatically duplicate the items for each instance of the composte that is created.

See [#Creating_New_Widget_Types Creating New Widget Types] for an explanation of subclassing _COMPOSITE_ to create a new item type. | * [#ref ref]: null

  • [#items items]: null
  • [#numCols numCols]: 2


|- | _DATE_* ("date") | Use this composite item type to show a date input widget. The default implementation shows:

  • A _SELECT1_ widget to set the month
  • A _SELECT1_ widget to set the date
  • A _TEXTFIELD_ widget to set the year


| * [#ref ref]: null


|- | _TIME_* ("time") | Use this composite item type to show a time input widget. The default implementation shows:

  • A _SELECT1_ widget to set the hour
  • A _SELECT1_ widget to set the minutes
  • A _SELECT1_ widget to set AM/PM


| * [#ref ref]: null


|- | _DATETIME_* ("datetime") | Use this composite item type to allow the user to input a date and time as a single item. It is a composite of a _DATE_ and a _TIME_ widget. | * [#ref ref]: null


|- | colspan="3" | === Grouping Item Types ===


|- | _GROUP_ ("group") | Use this to group a set of formItems either logically or visually. For example, if you have a number of formItems that you want to show or hide all together, place them in a _GROUP_ and set the relevant property of the group rather than setting it on each item.

Alternatively, if you want to have more than one item appear in one logical cell in the [#layout_considerations form layout], place those items in a _GROUP_.

Within the _GROUP_, the items property is the set of items that the group will display. The system will take care of initializing these objects for you.

Note that if you're using a _GROUP_ to put more than one item in a single "cell" in the outer form, you might want to specify a label on the _GROUP_ itself rather than on the first item within the group. This will make the label line up with the other labels in the form properly.

See also this note about [#group_item_ref group items specifying a ref property for their sub-items].

Note that it is currently not possible to set the style of a _GROUP_ element. See [#layout_considerations Layout Considerations] for more details. | * [#ref ref]: null

  • [#items items]: null
  • [#numCols numCols]: 2
  • [#colSizes colSizes]: null
  • [#useParentTable useParentTable]: false
  • [#label label]: null


|- | _SWITCH_ ("switch") | Use a _SWITCH_ formItem to display one of a number of sets of formItems. i.e. all tabbed views are implemented as _SWITCH_ items with each tab being a _CASE_ item.

Another example of where we use a _SWITCH_ is a wizard interface where each wizard step is presented by a _CASE_ item. | * [#ref ref]: null

  • [#items items]: null
  • [#numCols numCols]: 1
  • [#colSpan colSpan]: "*"
  • [#useParentTable useParentTable]: false


|- | _CASE_ ("case") | A _CASE_ formItem is functionally identical to a _GROUP_, but is specifically called for by the W3C Spec when using a _SWITCH_. Visibility of a _CASE_ item within a _SWITCH_ item is controlled by two properties: caseVarRef and caseKey. Default value of caseVarRef is “currentStep”. Property caseKey does not have a default value. In order to determine weather a _CASE_ item should be visible the form compares the value of “currentStep” property of the data instance with the value of “caseKey” property of the _CASE_ item.

Example: A wizard would typically have one _SWITCH_ item with several _CASE_ item, where each _CASE_ item corresponds to one of the steps of the wizard. We assign the number of the current step to “currentStep” property of the data instance. For each _CASE_ item's “caseKey” property, we assign a number that corresponds to a step of the wizard. Whenever the value of “currentStep” property changes, each of the _CASE_ items are notified that their visibility state may have changed and one of the _CASE_ items becomes visible. | * [#ref ref]: null

  • [#items items]: null
  • [#numCols numCols]: 2
  • [#useParentTable useParentTable]: false


|- | _ZATABCASE_ | _ZATABCASE_ extends _CASE_ to create a container suitable for tabbed views. Main differences from _CASE_ item are:

  • uses ‚ÄúcurrentTab‚Äù property instead of ‚ÄúcurrentStep‚Äù
  • has resize handlers
  • has bottom margin


| *


|- | colspan="3" | === Repeating Item Types ===


|- | _REPEAT_ ("repeat") | This formItem type is used to show a repeating data structure. Hook the ref of the repeat up to a modelItem of type _LIST_ and the _REPEAT_ will duplicate all of its items for each item in the the list of the data instance.

Set the items of the _REPEAT_ to a list of formItems to be duplicated for each row in the data instance. You can place any formItems in there as you want. The numCols of the repeat will set the number of columns displayed per line within the repeated items. Set the number property of the repeat to the minimum number of repeat rows of you want visible at all times -- usually this is fine set to 1.

The showAddButton and showRemoveButton properties, when true, will show the formItems addButton and removeButton for each repeated row. Note that the default behavior is that the addButton is only shown on the last row of the repeat. You can have different addButtons and removeButtonss by simply specifying these properties in your repeat instance -- look at the implementation for how to code these buttons. | * [#ref ref]: null

  • [#items items]: null
  • [#numCols numCols]: 2
  • [#number number]: 1
  • [#showAddButton showAddButton]: true
  • [#showRemoveButton showRemoveButton]: true
  • [#addButton addButton]: (form item)
  • [#removeButton removeButton]: (form item)


|- | colspan="3" | === Form Appearance Item Types ===


|- | _SPACER_* ("spacer") | Use this to output a spacer in the form that takes up an entire row in the form display. Specify the width and height of the spacer to change the amount of space it takes up.

If you place the _SPACER_ in a row that still has some columns in it, it will eat all of the columns to the end of the row and stop (and not take any additional vertical space). If you place the spacer at the start of a new row, it will provide the amount of vertical space specified in its height property. | * [#width width]: 1

  • [#height height]: 10
  • [#colSpan colSpan]: "*"


|- | _CELL_SPACER_* ("cell_spacer") | Use this to output a spacer that takes up only a single column in the form. | * [#width width]: 10

  • [#height height]: 10
  • [#colSpan colSpan]: 1


|- | _SEPARATOR_* ("separator") | Use this to make a horizontal line separating parts of a form. The appearance of the line is set by the cssClass of the formItem: by default, the system will output a single pixel black line that will be centered within the height of the formItem.

This line will behave in the same way as the [#_SPACER_ _SPACER_] formItem in terms of eating columns and/or lines. | * [#cssClass cssClass]: "xform_separator"

  • [#height height]: 10
  • [#colSpan colSpan]: "*"


|- | colspan="3" | === External Widget Adaptor Types ===


|- | _WIDGET_ADAPTOR_* ("widget_adaptor") | Use this item type to adapt an external widget for use within an XForm.

See the file ButtonGrid.js for an example of creating a simple widget class and integrating it with the XForms system. |

|- | _DWT_ADAPTOR_* ("dwt_adaptor") | An abstract class for use in adapting DWT widgets for use in XForms. See the implementation for how to do this with different form types. |

|}

XForm Item Attributes

The following is a list of the attributes that can be applied to an XForm item. Just as HTML provides some default properties that apply to certain tags (e.g. anchors have underlines, headings show a larger font size, etc.), the XForm class provides defaults for each of the [#XForm_Items form item types] that you can define. In this way, you get a reasonable default behavior without having to write properties on each widget.

It is often convenient to provide defaults for the behavior and appearance of form items in the modelItems that the form item links to. For example, for a given instance attribute, the list of choices is likely to be the same whether the attribute is displayed as a select, output as a label, etc. To some extent, the list of internal values and external labels for these values can be thought of as properties of the model -- by default, each form or field that displays these values should have the same set of choices, with a particular field, of course, being able to override these defaults. So for most form item attributes, we'll look up values like so:

  1. Look in the form item attributes provided by the author when the form was created.
  2. Look in the prototype chain for the formItem type.
  3. Look in the modelItem that corresponds to the field (if provided).

Thus the system can provide reasonable defaults, the model can provide defaults, but the form item itself can always override these defaults. Note that there are a small number of properties that do not use this inheritance mechanism -- those wil be called out in the table below.

Note that you can use the [#xform.itemDefaults itemDefaults] property of your form to customize the defaults for one or more item types.

The following is the current list of form item attributes. Items with an asterisk (*) after them are not specified in the W3C XForms spec or have different semantics than those specified in the spec.

  • group
  • case
  • repeat
  • any [#creating_composite_items composite item] types.


Attribute (type) Description Applies to types
Basic attributes
ref (string) Reference to a modelItem with a particular id in the xmodel for this form. This is how the form items and modelItems are associated. To use the same value as a parent item, use ref:".".

Note that this value is not inherited -- only the value in provided in the item itself will be used.

(all types)
id (string) Identifier for this item. If ommitted, an id will be created automatically, based on the id of the XForm (and any parent items). Note that if an id is provided, it will be made unique by appending a number to it -- this allows for the developer to specify ids for items to be repeated in the form.

Note that this value is not inherited -- only the value in provided in the item itself will be used.

(all types)
value (string) Specifies a static value to be displayed in the item. Used mainly in output item types to specify a static string to be displayed.

Note that the XForms spec explicitly states that input item types that specify a value attribute should be treated as checkbox items. This behavior is replicated in this implementation. If for some reason you want to specify a text field that has a value, use the textfield item type instead.

Note that this attribute is not inherited -- we will only look in the form item specified, and not in the modelItem or the defaults for each item type.

* output (to specify a static value to be displayed)
  • input (to specify that a checkbox item should be used. The checkbox will be checked if the value of the item's ref is the same as the value specified.


items (array) An array of sub-items for this item. Note that the ref of this master item will be automaticaly appended to that of any sub-items that also specify a ref * group
  • switch
  • case
  • repeat
  • any [#creating_composite_items composite item] types.


editable Boolean flag that defines weather user can type into the form item. For OSELECT and DYNSELECT items, this results in rendering the item as an <input type=”text”> HTML element. * oselect
  • dynselect


choices (array or object) Provides a list of value:label pairs for an item (similar to the list of OPTIONs for an HTML SELECT). Can be specified as:
  • an array of {value:"string", label:"string"} objects.
  • an array of strings or numbers (which will be used for both the value and label).

It is often convenient to place the choices attribute on the modelItem that a form refers to -- that way it can be used by all fields in all xforms that refer to that modelItem. An individual xform/field instance can always override with a different choices list.

* select
  • select1
  • output (used to map an internal value to a displayed label)
  • image (used to map an internal value to a specific set of image references)


getDisplayValue (function) (Optional) Function called to get the value actually displayed in a form item. The getDisplayValue() function will be passed the value from the modelItem, and can transform that value to make it appropriate for display in the particular widget for the formItem. For example, a _DATE_ field might be a composite item, made of three _SELECT1_ widgets. For the "month" selector, you want to transform the value (a Date object) into the number of the month. You would use getDisplayValue() for this.

The exact call to be made is: item.getDisplayValue(value)

where value is the value from the data instance of the form that corresponds to this form item. The function should massage the value however it needs to and return the value to be displayed.

You can specify the getDisplayValue() handler in one of three ways:

  • a Function instance
  • the string name of a function currently defined on the xform instance, or
  • a script to be converted to a function (with the arguments shown above).


Attributes for controlling item appearance
cssClass* (string) Specifies a css CLASS tag to be written out for the item element. If an item draws as a native HTML widget (e.g. an INPUT field), the cssClass will be applied to that widget. If the item is an output type, a group, a composite or inserted widget, the cssClass will be applied to the DIV that the widget will be drawn in.

Default varies according to item type.

Note that this corresponds to the class attribute in the W3C XForms spec.

(all types)
cssStyle* (string) Specifies any css style properties you wish to write into the element tag for the item, allowing you to completely customize the display of an item without having to create a myriad of css classes.

e.g. cssStyle:"margin:10px;padding:2px;"

Default is that no extra style properties will be applied.

(all types)
label (string) Specifies a label for this item. May be shown depending on the items labelLocation property.

Note that button and anchor item types use the label for the text that appears to the user in the element, rather than a separate label for the field itself.

Note that unlike the W3C XForms spec, labels are not required in this implementation.

(all types)
labelLocation* (enum) Specifies where the label should appear for this item. Set to one of the following values:
  • _NONE_: Don't show the label, even if one is specified (default for case, switch, button, anchor, separator, spacer types).
  • _LEFT_: Show the label to the left of the item (default for most item types).
  • _RIGHT_: Show the label to the right of the item (default for checkbox and radio item types).
  • _TOP_: Show the label on a separate line, above of the item. You might use this for a text area that wants to use the whole width of the form.
  • _BOTTOM_: Show the label on a separate line, below of the item.


(all types)
labelCssClass* (string) Allows you to specify a css CLASS attribute for the label of an item. Only used for items whose labelLocation attribute is not _NONE_.

Default is xform_label for most item types, xform_label_checkbox for checkbox and radio item types.

(all types)
labelCssStyle* (string) Allows you to specify arbitrary css style properties for the label of an item. (all types)
labelWrap* (boolean) Allows you to specify whether the label of an item should wrap when it goes over the assigned space for the label.

Default is false.

(all types)
containerCssClass* (string) Specifies a css CLASS attribute for the containing element for a formItem. The container is currently a <td>, although this may change in the future.

The default is xform_container.

(all types)
errorCssClass* (string) Specifies a css CLASS attribute for the error message that will show up above a formItem when it fails validation.

Default is xform_error.

(all types)
tableCssClass* (string) CSS class for the <table> tag used to write a grouping, repeating or composite item. Not all such objects require that a table tag be written.

Note: only applies to items that have useParentTable set to false, otherwise the item will not write out a table.

Default is xform_table.

* group
  • case
  • repeat
  • _COMPOSITE_ types

which specify useParentTable:false

useParentTable* (boolean) Boolean that indicates whether a nesting item (_GROUP_, etc) should create its own table context, or should fold its items into the table context of its parent item. If you are using a _GROUP_, etc. and your layout is not doing what you're expecting, there's a good chance you need to change the useParentTable attribute.

See [#Layout_Considerations Layout Considerations] for more details.

Default is false.

* group
  • case
  • repeat
  • _COMPOSITE_ types


width* (number) Specifies the width of an element. Automatically added to the cssStyle of the element or its container, as appropriate.

Note: it is recommended that you specify the width in this way (rather than in the cssStyle property) as it will in future allow for resizing semantics.

(all types)
height* (number) Specifies the height of an element. Automatically added to the cssStyle of the element or its container, as appropriate.

Note: it is recommended that you specify the height in this way (rather than in the cssStyle property) as it will in future allow for resizing semantics.

(all types)
overflow* (enum) Specifies the HTML overflow property for the container of the form element. Use this to make the container clip or scroll the contents. Note that the overflow property is not well defined if you do not specify width and/or height for your formItem.

Set to one of:

  • _VISIBLE_ to allow the container to expand with the size of the contents.
  • _HIDE_ to clip the contents to the specified width and height.
  • _AUTO_ to clip the contents, adding scrollbar(s) if necessary.
  • _SCROLL_ to clip the contents and always show both scrollbars.

Default is _VISIBLE_.

(all types)

Note: not tested very much!

numCols* (number) Specify the number of columns to show in a grouping, repeating or composite item.

See [#Layout_Considerations Layout Considerations] for more details.

Default is 1.

* group
  • case
  • repeat
  • any [#creating_composite_items composite item] types.


colSizes* (array) Specifies an array of column sizes for a grouping, repeating or composite item. See [#Layout_Considerations Layout Considerations] for more details.

Default is null.

colSpan* (number or "*") Similar to the usage in an HTML <table>, colSpan pecifies the number of columns an item should take up in the output table. Set to a number for a specific number of columns, or "*" to indicate an item should take all the remaining columns in the row it is placed in.

See [#Layout_Considerations Layout Considerations] for more details.

Default is 1.

(all types)
rowSpan* (array) Similar to the usage in an HTML <table>, colSpan pecifies the number of rows an item should take up in the output table. Set to a number for a specific number of rows.

See [#Layout_Considerations Layout Considerations] for more details.

Default is 1.

(all types)
align* (enum) Horizontal alignment for this element (or children if a grouping/repeating element). Set to one of the following constants:
  • _LEFT_: align to the left (default).
  • _RIGHT_: align to the right.
  • _CENTER_: center the item(s) in the parent container.
  • _MIDDLE_: synonym for _CENTER_.


(all types)

Note: may not work for all item types.

valign* (enum) Vertical alignment for this element (or children if a grouping/repeating element). Set to one of the following constants:
  • _TOP_: align to the top
  • _MIDDLE_: align to the middle of the cell (default).
  • _CENTER_: synonym for _MIDDLE_
  • _BOTTOM_: align to the bottom of the cell.


(all types)

Note: may not work for all item types.

Attributes for handling changes in the form
onChange* (function) Function to call when the form item is changed. The exact call to be made is: item.onChange(value, event, form)

You can specify the onChange handler in one of three ways:

  • a reference to a defined function (i.e. instance of Function)
  • the string name of a function currently defined on the xform instance, or
  • a script to be converted to a function (with the arguments shown above).

The default assumption is that items which specify an onChange function will explicity set any values in the model that need to be set, rather than relying on the default saving behavior. This allows the onChange method to change more than one value in the instance, etc.

Note that when _BUTTON_ or _ANCHOR_ objects are clicked, they will fire onActivate instead of onChange.

See [#Handling_Changes_to_the_Form Handling Changes to the Form] for more details on change handling.

For better performance, it is recommended to define this function as a reference to a defined function.

* _INPUT_
  • _TEXTFIELD_
  • _FILE_
  • _TEXTAREA_
  • _PASSWORD_
  • _SECRET_
  • _CHECKBOX_
  • _SELECT1_
  • _SELECT_
  • _DWT_SELECT_
  • _OSELECT1_
  • _OSELECT_
  • _DATE_
  • _TIME_
  • _DATETIME_
  • _BUTTON_GRID_


onActivate* (function) Function to call when the an anchor or button is clicked. The exact call to be made is: item.onActivate(event)

You can specify the onActivate handler in one of three ways:

  • a reference to a defined function (i.e. instance of Function)
  • the string name of a function currently defined on the xform instance, or
  • a script to be converted to a function (with the arguments shown above).

Note that the onChange event is not called for these item types.

For better performance, it is recommended to define this function as a reference to a defined function.

* _BUTTON_
  • _TRIGGER_
  • _SUBMIT_
  • _ANCHOR_
  • _DATA_ANCHOR_
  • _MAILTO_


elementChanged* (function) Function that is called when the HTML widget that the user actually interacts with is manipulated, i.e., they type a new value into a _TEXTFIELD_ or select a different value from a _SELECT1_.

The exact call is: item.elementChanged(elementValue, instanceValue, event), where

  • elementValue is the newly changed value
  • instanceValue is the value previously stored in the data instance for this item, and
  • event is the browser event.

The default implementation is to call this.getForm().itemChanged(this, elementValue, event) which will validate the value and insert it back into the model, as appropriate.

You might want to override this, for example, in a composite item that is setting a single part of a complex value. For example, lets say you have a _DATE_ field that is composed of three simple widgets. Each of those widgets is setting a part of the date (the month, day, etc). You want a change to any sub-item of the _DATE_ widget to represent a change the actual date, rather than exposing that they changed only a piece of the date. To do this, you'll implement an elementChanged handler that will compose the changed bit with the current date, then call itemChanged() on the form with the new value. e.g. for the "month" pulldown:

  elementChanged:function(elementValue, instanceValue, event) {
    // elementValue is the number of the new month that they selected
    // instanceValue is the original date stored for this value
    instanceValue.setMonth(elementValue);
    this.getForm().itemChanged(this.getParentItem(), instanceValue, event);
  }

Note we call itemChanged() on the parent item (the _DATE_ widget): this ensures that if there is a validation error, the error will be displayed above the entire _DATE_ widget, rather than just above the "month" pull-down.

* _INPUT_
  • _TEXTFIELD_
  • _FILE_
  • _TEXTAREA_
  • _PASSWORD_
  • _SECRET_
  • _CHECKBOX_
  • _SELECT1_
  • _SELECT_
  • _DWT_SELECT_
  • _OSELECT1_
  • _OSELECT_
  • _DATE_
  • _TIME_
  • _DATETIME_
  • _BUTTON_GRID_


onRemove Function that is called when an element is removed from _REPEAT_ item. * repeat


valueChangeEventSources This is an array of references to form items that may affect the value in this form item. Each reference is a string that should correspond to “ref” attribute of some other item. Whenever user interacts with any of the items referenced in valueChangeEventSources array, the form will also update this item with a value from the data instance. * All items


enableDisableChecks This is an array of functions that are called to determine if a form item should be enabled for user input (“enabled” state). When the form needs to decide weather to enable an item, the form calls each of the functions referenced in enableDisableChecks array of the item, and if any of the functions return “false”, the item will be disabled.

Each entry in the array can have either a function reference or an array. If an entry is an array, the first element must be a function reference and succeeding elements are passed to the function as arguments.

Example of using function references in enableDisableChecks array:

enableDisableChecks:[ZaNewDomainXWizard.getGalSyncLdapFilterEnabled,ZaNewDomainXWizard .checkSomethingElse]

Example of using arrays in enableDisableChecks array:

enableDisableChecks:[[XForm.checkInstanceValue,ZaDomain.A_GALSyncUseGALSearch,"FALSE"],
[XForm.checkInstanceValue,ZaDomain.A_GALSyncEnabled,"TRUE"]]

Example of using arrays and function references in enableDisableChecks array:

enableDisableChecks:[[XForm.checkInstanceValue,ZaDomain.A_GALSyncUseGALSearch,"FALSE"],ZaNewDomainXWizard.isGalSyncEnabled]
* All items


enableDisableChangeEventSources This is an array of references to form items that may affect “enabled” state of this item. i.e.: this can be used in order to enable a text input by checking a checkbox. Each reference is a string that should correspond to “ref” attribute of some other item. Whenever user interacts with any of the items referenced in enableDisableChangeEventSources, the form will check if this item should be enabled by running through enableDisableChecks stack, and will change it's “enabled” state accordingly. * All items


visibilityChecks This is an array of functions that are called to determine if a form item should be visible. When the form needs to decide weather to show or hide an item, the form calls each of the functions referenced in visibilityChecks array of the item, and if any of the functions return “false”, the item will be hidden.

Each entry in the array can have either a function reference or an array. If an entry is an array, the first element must be a function reference and succeeding elements are passed to the function as arguments.

Example of using function references in visibilityChecks array:

visibilityChecks:[ZaNewDomainXWizard.getGalSyncLdapFilterVisible,ZaNewDomainXWizard .checkSomethingElse]

Example of using arrays in enableDisableChecks array:

visibilityChecks:[[XForm.checkInstanceValue,ZaDomain.A_GALSyncUseGALSearch,"FALSE"],
[XForm.checkInstanceValue,ZaDomain.A_GALSyncVisible,"TRUE"]]

Example of using arrays and function references in enableDisableChecks array:

visibilityChecks:[[XForm.checkInstanceValue,ZaDomain.A_GALSyncUseGALSearch,"FALSE"],ZaNewDomainXWizard.isGalSyncVisible]
* All items


visibilityChangeEventSources This is an array of references to form items that may affect visibility of this item. i.e.: this can be used in order to hide an input field by checking a radio button. Each reference is a string that should correspond to “ref” attribute of some other item. Whenever user interacts with any of the items referenced in visibilityChangeEventSources, the form will check if this item should be visible by running through visibilityChecks stack, and will show or hide the item accordingly. * All items


Attributes specific to [#Repeating_Form_Structures repeat][#Repeating_Form_Structures type items]
number (number) Specifies the minimum number of rows to show in the repeated structure. At least this number of rows will always be shown, regardless of the actual number of rows specified in the data instance.

Default is 1. Set to 0 to not show any elements when the data instance has no elements.

* repeat


showAddButton (boolean) If true, the form will automatically show [#addButton add] button after the last repeated element

Default is true.

* repeat


showRemoveButton (boolean) If true, the form will automatically show “remove” button next to each repeated element.

Default is true

* repeat


showMoveUpButton If true, the form will show “Move Up” button next to each repeated element.

Default is false

* repeat


showMoveDownButton If true, the form will show “Move Down” button next to each repeated element.

Default is false

* repeat


alwaysShowAddButton* (boolean) Set to true to always show the [#addButton add] button on each row of the repeated items.

Default is false.

* Repeat


removeButtonLabel Defines the text displayed on “remove” button * Repeat


addButtonLabel Defines the text displayed on “add” button * repeat


showAddOnNextRow If true, “add” button will be rendered underneath the last repeated element. If false, “add” button will be rendered to the left of the last repeated element.

Default:false

* repeat


removeButtonWidth Width of the “remove” button. By default, form will try to render “remove” button wide enough to fit the text onto the button. * repeat


addButtonWidth Width of the “add” button. By default, form will try to render “add” button wide enough to fit the text onto the button * repeat


Attributes specific to checkbox type items
trueValue* (string, number or boolean) Will show the checkbox as checked if the value stored in the data instance is equal to the trueValue. Also specifies what is stored in the data instance when the checkbox is changed from unchecked to checked.

You may want to change this if the internal representation of your boolean value is:

  • "Y" == true and "N" == false, or
  • 1 == true and 0 == false, etc.

The default is true.

* checkbox


falseValue* (string, number or boolean) Specifies what is stored in the data instance when the checkbox is changed from checked to unchecked.

The default is false.

* checkbox


Properties specific to image type items
src* (string) For images that don't specify a [#ref ref][#ref property], specifies the url for the image, relative to the srcPath of the item. The actual path will be: item.srcPath + src

Where src is:

  1. the dynamic value of the data instance for this formItem (if the item specified a ref property, or
  2. the static item.src specified when the formItem was created.

Note also, that if the image supplies a [#choices choices][#choices property], the choices will be used to map an internal value to a url. Thus for an item specified like so:

        {type:_IMAGE_, ref:"someProperty", href:"spacer.gif",
                choices:[
                        {value:"a",       label:"image_a.gif"},
                        {value:"b",       label:"image_b.gif"}
                ]
        }

Conceptually, the system will get the href for the image tag like so:

  1. set currentHref the someProperty property in the data instance.
  2. if the currentHref is null, use the value item.href
  3. Regardless of how the value was obtained in step 1 or 2, attempt to match the currentHref to the value of one of the items in the choices property and use the label for that choice as the href. (eg: if the href at this point was a, it would get mapped to image_a.gif).
  4. If no choice was found whose value matched, just use currentHref specified.

or, in pseudocode:

        currentHref = instance.someProperty;
        if (currentHref == null) currentHref = item.href;
        if (getChoiceWithValue(currentHref) != null) {
                currentHref = getChoiceWithValue(currentHref).label;
        }

A couple of examples with the formItem defined above:

  • If the someProperty value is b, the href at the end will be: image_b.gif.
  • If the someProperty value is null, the href at the end will be spacer.gif (coming from the href property, and falling through the choices array unchanged).
  • If the someProperty value is image_c.gif, the href will end up as image_c.gif (falling through the choices array unchanged).


* image


srcPath* (string) Sets the path prefix for the image to be displayed. Thus the actual URL used for the image will be: item.srcPath + src

Where [#src src] is as specified above.

* image


Properties specific to anchor type items
href* (string) For anchors that don't specify a [#ref ref][#ref property], sets the href for the actual <a> tag written into the form. Thus the href of the anchor will be:
  1. the dynamic value of the data instance for this formItem (if the item specified a ref property, or
  2. the static item.href specified when the formItem was created.


* _ANCHOR_


showInNewWindow* (boolean) If true, an anchor or subtype will open a new _blank window when the anchor is clicked upon. Set to false to take over the current window.

Default is true.

* _ANCHOR_
  • _DATA_ANCHOR_
  • _MAILTO_
  • _URL_


XFormItem Methods of Interest

The following are useful methods you can call on a XFormItem, for example, in a relevant script, an onActivate handler, etc.


To get a pointer to the form
xformItem.getForm()
  • returns: Form that contains the form item.


To get a pointer to the form's Controller
xformItem.getFormController()
  • returns: Controller that controls the form.


To get a pointer to the model
xformItem.getModel()
  • returns: XModel that this item's form is hooked up to.


To get a pointer to the current data instance
xformItem.getInstance()
  • returns: Data instance that the form is currently displaying.


To get a pointer ot the modelItem for this form
xformItem.getModelItem()
  • returns: a XModelItem, or null if no ref defined for this item.


To get a pointer to the parent item of an item in a _COMPOSITE_, _GROUP_, etc
xformItem.getParentItem()
  • returns: Pointer the the parent item, or null if no parent defined.


To get the value of the current data instance for this formItem
xformItem.getInstanceValue()
  • returns: Value contained in the data instance for this item. May be null.


To get the number of items in a _LIST_ modelItem
xformItem.getInstanceCount()
  • returns: The number of items in the _LIST_ for this form item. Returns -1 if no list found.


To return a global refence to a formItem (i.e., for use in a callback string)
xformItem.getGlobalRef()
  • returns: String value that, when executed in the global context, will return a pointer to this formItem.


xformItem.()
  • returns:


xformItem.()
  • returns:


xformItem.()
  • returns:


xformItem.()
  • returns:


Drawing Semantics

When the system draws an XForm, it runs through the entire (nested) list of items, and does the following things:

  1. initialize each item (hooking it up to its modelItem, figuring out nested references, subscribing to events, etc),
  2. write each item's HTML into the HTMLOutput stream

(Note that drawing can proceed without a data instance being attached to the form).

Handling Changes to the Form

When the user manipulates a form widget to make a change to the data, the xform calls the method xform.itemChanged(itemId, value, event). This routine:

  1. Checks to see if the item has defined a [#onChange onChange] function, and if it has, it calls this routine. Treats the value returned by the onChange handler as if the original form widget had returned that value.
  2. If there was no onChange function, the routine will save the value in the instance by calling model.set(fullItemXPath, newValue). See [#Getting_and_Setting_Instance_Values Getting and Setting Instance Values] for how the model saves the value into the form.
  3. Notifies all listeners that are registered to listen to updates from this item.


Creating New Widget Types

The default set of controls provided with this XForms package is sufficient for most tasks. However, the implementation allows new types of controls to be added dynamically for those situations where the provided controls are not appropriate or do not fulfil the requirements. This section describes how to implement custom controls for the following two cases:

  • a value in the data instance is complex and needs to be handled using multiple controls; and
  • a custom user interface is needed to display a value.

A _COMPOSITE_ control allows you to create a new control that is an aggregate of other controls. This allows you to take a single, complex value in the data instance and have separate controls manage each part. You can also use a composite to handle parts of the data instance as a single re-usable form unit.

There are three steps to creating and using a composite component:

  1. register new type with the XFormItemFactory;
  2. set the list of child components as the items property of the new type's prototype object; and
  3. use the new type in your form.

The following example creates a composite control that displays the red, green, and blue components of a color in the data instance using separate input fields. First, we register new type with the XFormItemFactory. Adding some convenience methods on the object prototype helps us in the next step when we define the form items.

function ColorInput() { }
XFormItemFactory.createItemType("_COLOR_", "color", ColorInput, _COMPOSITE_);
// NOTE: setXXX(value) methods replace hex color component value in 
//       color strings that match "#RRGGBB"
ColorInput.prototype.setRed = function(value) {
    var ivalue = this.getInstanceValue();
    return '#' + value + ivalue.substr(3,4);
}
ColorInput.prototype.setGreen = function(value) {
    var ivalue = this.getInstanceValue();
    return '#' + ivalue.substr(1,2) + value + ivalue.substr(5,2);
}
ColorInput.prototype.setBlue = function(value) {
    var ivalue = this.getInstanceValue();
    return '#' + ivalue.substr(1,4) + value;
}

Next, we set the list of child components as the items property. We implement the getDisplayValue method on each child component to map the data value to the component value; and we implement the onChange method in order to map changes back to the data value.

ColorInput.prototype.items = [
    // NOTE: This child component references the same data as the
    //       parent level using ref: "."
    { ref: ".", type: _INPUT_, label: "R", width: "3em",
        getDisplayValue: function(value) { return value.substr(1,2); },
        onChange: function(value, event, form) {
            // NOTE: the parent item is of type ColorInput
            return this.getParentItem().setRed(value);
        }
    },
    { ref: ".", type: _INPUT_, label: "G", width: "3em",
        getDisplayValue: function(value) { return value.substr(3,2); },
        onChange: function(value, event, form) {
            return this.getParentItem().setGreen(value);
        }
    },
    { ref: ".", type: _INPUT_, label: "B", width: "3em",
        getDisplayValue: function(value) { return value.substr(5,2); },
        onChange: function(value, event, form) {
            return this.getParentItem().setBlue(value);
        }
    }
];

Finally, we can now use the new _COLOR_ type in our form.

var myform = {
    { ref: 'color', type: _COLOR_ }
};

In addition to creating composite controls, you can also create custom controls that are bound to data instance values. Continuing our color example, we will create a color swatch that shows the currently entered color as the background of the new control.

There are four steps to create a custom control:

  1. define object;
  2. add object methods for form rendering;
  3. register new type and add factory method; and
  4. use the new type in your form.

Because the new control is not based on an existing type, we first need to create a new object type. The constructor should take an attributes object (which can be used to map DWT attributes to the new control).

function ColorSwatch(attributes) {
    // copy any properties passed to the object
    for (var prop in attributes) {
        this[prop] = attributes[prop];
    }
}
ColorSwatch.prototype.value = 'white'; // default bgcolor

Next, we define some object methods for use when the control is being used. The resetStyle method sets the CSS of the displayed component — we call this method when the data value changes and the HTML needs to be updated.

ColorSwatch.prototype.setValue = function(value) {
    this.value = value;
}
ColorSwatch.prototype.resetStyle = function(element) {
    element.style.backgroundColor = this.value;
    // NOTE: extra style info should be part of CSS class
    element.style.width = '30px';
    element.style.border = 'black solid 1px';
}

Now that our object is defined, it must have two methods defined for the XForms framework to render it: insertIntoXForm and updateInXForm. The former method is called when the control is first rendered and the latter is called when the bound data value changes and the display needs to be updated.

ColorSwatch.prototype.insertIntoXForm = function(form, item, element) {
    // NOTE: this method returns the control's HTML but
    //       we don't display anything but the bgcolor
    element.innerHTML = " ";
}
ColorSwatch.prototype.updateInXForm = function(form, item, value, element) {
    this.setValue(value);
    this.resetStyle(element);
}

After that is done, the new type is registered with the XFormItemFactory using _WIDGET_ADAPTER_ as the base type. To allow the widget adapter to construct your new component object, though, the constructWidget method must be implemented.

function ColorSwatchWidget() { }
XFormItemFactory.createItemType("_COLOR_SWATCH_", "color_swatch", ColorSwatchWidget, _WIDGET_ADAPTOR_);
ColorSwatchWidget.prototype.constructWidget = function() {
    var attributes = {
        // place widget attributes here
    };
    return new ColorSwatch(attributes);
}

Finally, the new control can be used in your form.

var myform = {
    items: [
        { ref: "color", type: _COLOR_SWATCH_ }
    ]
};

The XModel Object

The XModel object itself is simple very simple, and tends to be static. You will generally create one XModel for each data type you have (e.g. an "appointment" or "contact" object) and then use that in one or more forms. Rather than creating instances of the model to apply to each form, you assign a single instance of the model to all forms that use it. When the form wants the model to display a value, it will explicitly pass it the data instance that the model is to use.

Note: more docs to come here.

XModel Methods of Interest

  • To create an XModel, call: new XModel(attributes)
    • attributes: object literal, all properties of which will be copied into the instance of the form. Specifically, this should at the least contain an "items" property which specifies the list of modelItems that the model will interact with. (see [#XModel_Items XModel Items]).

XModel Items

The meat of the model specification is the list of items.

Note: more docs to come here.

XModel Item Attributes

Attribute (type) Description Applies to types
Basic attributes
type (enum) Data type of this modelItem. Currently the following types are supported:
  • _STRING_: String value.
  • _NUMBER_: Numeric value.
  • _DATETIME_: Javascript Date object.
  • _LIST_: Array of any other type or of sub-objects.
  • _OBJECT_: Object with various properties.

Default if not specified is the _STRING_ type.

(all types)
id (string) Identifier for this item. This is what the xform uses to match up an xform item with an xmodel modelItem. (i.e. xform.item.ref == xmodel.item.id).

Note that ids must be unique within each level of the xmodel (but you can use the same id within two distinct sets of sub-items.

(all types)
ref (string) Reference to a particular attribute of the data instance. Note that the references are nested -- if a modelItem specifies both a ref and an items array, all sub-items will be found under the ref of their parent. e.g.


    {id:"address",  ref:"address", type:_LIST_, items:[
            {id:"street",  ref:"street",  type:_STRING_},
            {id:"city",    ref:"city",    type:_STRING_},
            {id:"state",   ref:"state",   type:_STRING_},
            {id:"zip",     ref:"zip",     type:_STRING_},
        ]
    }

Each of the input elements within the _LIST_ will inherit the address reference from the list, so their references are effectively "address/street", "address/city", etc.

Note that the system will automatically use the id of the modelItem if you do not specify a ref. So the above example could more easily have been written:


    {id:"address", type:_LIST_, items:[
            {id:"street"}, {id:"city"},
            {id:"state"},  id:"zip"},
        ]
    }
(all types)
items (array) An array of sub-items for this item. Note that the ref of this master item will be automaticaly appended to that of any sub-items that also specify a ref.

If this item is a _LIST_ type, the system assumes that this item is an array of objects. If this item is a _OBJECT_ object, the system assumes that the sub-items are attribtues of the object.

* _LIST_
  • _OBJECT_


getter* (function) A function that the model will call to get the value of a form instance. Specify a getter if you are providing a calculated value for a field. You can specify a getter in one of the following ways:
  1. the name of a method on the instance, which will be called as: getter.call(instance, xpath)
  2. the name of a method on the xmodel itself, which will be called as: getter.call(xmodel, instance, xpath)
  3. a function defined on the modelItem itself, called as: getter.call(xmodel, instance, xpath)
  4. a bit of script, which will be converted to a function and called as #3 above.
    In all cases, the getter should return the value to be displayed for the xpath provided.


(all types)
setter* (function) A function that the model will call to set the value of a form instance. Specify a setter if you are providing a calculated value for a field. You can specify a setter in one of the following ways:
  1. the name of a method on the instance, which will be called as: setter.call(instance, value, xpath)
  2. the name of a method on the xmodel itself, which will be called as: setter.call(this, instance, value, xpath)
  3. a function defined on the modelItem itself, called as: setter.call(this, instance, value, xpath)
  4. a bit of script, which will be converted to a function and called as #3 above.
    In all cases, the setter should return the value to be displayed for the xpath provided.
    Note: constraints are not currently implemented.


(all types)
constraints* (array of objects) An array of constraints that a new value must pass before being inserted back into the data instance.

See [#Constraints Constraints] for specifics, as well as the list of constraints that you can add to model items.

Note: constraints are not currently implemented.

(all types)
required* (boolean) If true, this item is required. This will be indicated visually within the xform display somehow.

See [#Constraints Constraints] for specifics.

Note: not currently implemented.

(all types)
readonly* (boolean) If true, this item cannot be edited by the user. This will be indicated visually within the xform display somehow.

Note: not currently implemented.

(all types)
Datatype facet attributes
length (number) Required length of input value. _STRING_
minLength (number) Minimum length of input value. _STRING_
maxLength (number) Maximum length of input value. _STRING_
pattern (string, regex, array) Regular expression pattern that input value must match. This value may be specified as a RegExp object; or a string representing the regular expression; or an array of either RegExp objects or strings.

When an array of regular expressions is specified, they are are combined as branches of the same regular expression, as defined in the XML Schema Datatypes specification. For example: [ /a/, /b/ ] is equivalent to /a|b/.

Note: changed from regex to pattern to match XML Schema datatype facet name.

Note: not currently implemented for _DATETIME_.

_STRING_, _NUMBER_, _DATETIME_
enumeration (array) Array of literal values. Input value must match one of the literals to be valid.

Note: document how this relates to the choices attribute

Note: not currently implemented for _DATETIME_.

_STRING_, _NUMBER_, _DATETIME_
whiteSpace (enum) Specifies how whitespace within the input value is to be handled. Supports the following values:
  • "preserve": leaves whitespace as-is (default)
  • "replace": replaces tabs, newlines, and carriage-returns with a space
  • "collapse": same as "replace" but also trims leading and trailing whitespace and replaces sequences of spaces with a single space

Note: not currently implemented for _DATETIME_.

_STRING_, _NUMBER_, _DATETIME_
maxInclusive (number) Restricts input value to less than or equal to specified value.

Note: not currently implemented for _DATETIME_.

_NUMBER_, _DATETIME_
maxExclusive (number) Restricts input value to less than specified value.

Note: not currently implemented for _DATETIME_.

_NUMBER_, _DATETIME_
minInclusive (number) Restricts input value to greater than or equal to specified value.

Note: not currently implemented for _DATETIME_.

_NUMBER_, _DATETIME_
minExclusive (number) Restricts input value to greater than specified value.

Note: not currently implemented for _DATETIME_.

_NUMBER_, _DATETIME_
totalDigits (number) Restricts total number of digits in numeric input value. _NUMBER_
fractionDigits (number) Restricts number of digits in fractional part of numeric input value. _NUMBER_

Getting and Setting Instance Values

First and most important – you should never manipulate instance values directly unless you intend to bypass all event handling mechanisms of XForms.

Constraints

Note: constraints are not currently implemented.

W3C Compliance

Note: more docs to come here.

Standalone Mode

Note: more docs to come here.

Jump to: navigation, search