Rationale
A number of pre-built XBL components ship with Orbeon Forms. You can use those components:
- From Form Builder: Choose the control you want to use in the left side-bar.

- In your own XForms code, the definitions of fr:* components located under oxf:/xbl/orbeon are automatically included by xforms-widgets.xsl if you use them. In other words, just use and enjoy: you don't have anything special to do to use any of the components shown below.
Components
Autocomplete
Overview
Autocomplete is a feature provided by many applications, and this component makes it easy to add an autocomplete field to your form. The autocomplete controls is not unlike selection controls ( <xforms:select> and <xforms:select1>): - You use a single-node binding attribute to bind the control to the node holding the current value for the control.
- You use a combination of
<xforms:itemset> and <xforms:item> to define the values suggested to the user. Just as with <xforms:select> and <xforms:select1>, what is visible to users are item's labels and what is stored in the node to which your autocomplete is bound is the selected item's value. - Just like the
<xforms:select> and <xforms:select1>, the autocomplete only implements a closed selection: users will only be able to select a value which exists in the itemset. The value of the node bound to the autocomplete won't be set to the value typed by users in the field, unless they select an item from the suggestion list or type text which is identical to one of the item's label.
Auto Complete field used for a list of countriesThe autocomplete control can work in either one of the following ways: - In static itemset mode
- In dynamic itemset mode
Static Itemset
- When to use the static itemset mode?
- When you can reasonably determine the full list of suggested values without having to do any processing (such as submissions to a service you provide) as users type in the field. You will typically use this mode when the list of suggested values isn't extremly large. Examples include a list of states, of countries, or of departments in your company.
- When the default filtering mechanism works for you (more on this below).
- Does the itemset really need to be static?
This mode doesn't require you to know the list of suggested values is when you generate the page. You can still fetch the list from a service using an <xforms:submission>, and this list can change depending on other values entered by users in other fields of the page. But you can't change the list of suggested values depending what users are currently typing in the field.
- How does the filtering work?
In this mode, the autocomplete field determines which values are shown in the suggestion based on what users typed in the field. It will only show items which label starts with the text entered by users. The comparison is not case sensitive. For instance, typing "ar" in a field that expects a list of countries with show "Argentina", amongst other countries, but not "Saudi Arabia".
- What does the syntax look like?
<fr:autocomplete ref="instance('instance-static')/country-name" dynamic-itemset="false" style="width: 15em"> <xforms:label>Enter a country name: </xforms:label> <xforms:itemset nodeset="instance('all-countries')/country"> <xforms:label ref="name"/> <xforms:value ref="name"/> </xforms:itemset> </fr:autocomplete>
Dynamic Itemset
- When to use the dynamic itemset mode?
- When the list of suggested values is so large that it wouldn't be reasonable to load all of them in an instance at any point in time. This mode allows you to run a submission that retrieves new itemset as the user types in the field. For instance, you might want to use this mode for a field to enter a company name (say, to do a stock quote lookup) or a product name from a large catalog (say, to lookup the product on Amazon).
- When the default filtering mechanism provided by the static itemset mode does not do exactly what you want.
- How to update the itemset?
In most cases, you will want to update the itemset as users type, based on the value they entered. For this, listen to the event fr-search-changed on the <fr:autocomplete>, and run an action that updates the itemset. You are in control of where the data comes from, what subset of the data is to be displayed in the suggestion list based on what the user types, and when the suggestion is to be made.
For instance, in the following code reacting to the fr-search-changed event is written is a such a way that:
- The suggestion list shows up only after users enter at least 2 characters.
- The suggestion list is updating by running a submission which calls a service, providing the text typed by users so far.
<fr:autocomplete ref="instance('selected-countries')/dynamic" id="dynamic-autocomplete"
dynamic-itemset="true" style="width: 15em">
<!-- React to user searching -->
<xforms:action ev:event="fr-search-changed">
<xxforms:variable name="search-value" select="event('fr-search-value')"/>
<xxforms:variable name="make-suggestion" select="string-length($search-value) >= 2"/>
<xforms:action if="$make-suggestion">
<!-- Update itemset -->
<xxforms:variable name="make-suggestion" select="string-length() >= 2"/>
<xforms:setvalue ref="instance('search-dynamic')/country-name" value="$search-value"/>
<xforms:send submission="update-countries"/>
</xforms:action>
<xforms:action if="not($make-suggestion)">
<!-- Delete itemset -->
<xforms:delete nodeset="instance('searched-countries')/country"/>
</xforms:action>
</xforms:action>
<xforms:label>Country code: </xforms:label>
<xforms:itemset nodeset="instance('searched-countries')/country">
<xforms:label ref="name"/>
<xforms:value ref="us-code"/>
</xforms:itemset>
</fr:autocomplete>
Eventsfr-search-changed – What did the user type in the field?
When using the autocomplete in dynamic itemset mode, you can listen on the fr-search-changed event to be notified when the value typed in the field changes. This event is dispatched as users type in the field, just like the xforms-value-changed event would for an incremental <xforms:input>. The preceding example uses this event to update the itemset as users type in the field.
xforms-value-changed – When did the user make a selection?
Just as with other XForms controls, you can listen on xforms-value-changed to be notified when the value of the node bound to the autocomplete changes. That event is also dispatched when users make a selection from the suggestion list, or when they happen to have typed a value that exactly matches one of the items in the itemset.
Setting the content of the text field
You can set the content of the text field by sending the fr-set-label event to the autocomplete component, with label as context information. For instance: <xforms:dispatch ev:event="DOMActivate" target="my-autocomplete" name="fr-set-label">
<xxforms:context name="label" select="'Canada'"/>
</xforms:dispatch>
Just as if users had typed that label, if you are in dynamic itemset mode, this will trigger the fr-search-changed event, upon which your code can change the itemset. If you do change the itemset, and there is a single value corresponding to the label you specified, then the node to which the autocomplete is bound is set to that value. Maximum number of displayed results
By default, the autocomplete displays a maximum of 10 items. You can have the autocomplete display less of more results by: - Adding attribute
max-results-displayed. You would typically use this attribute to provide a static value. For instance:
<fr:autocomplete max-results-displayed="20">
- Adding a nested element <fr:max-results-displayed>, which supports single node binding attributes (
ref, model, and bind) as well as the value attribute. For instance:
<fr:autocomplete> <fr:max-results-displayed value="/configuration/max-results-displayed"/>
- By defining the property:
<property as="xs:integer" name="oxf.xforms.xbl.fr.autocomplete.max-results-displayed" value="10"/>
When several configurations are used for an autocomplete component, the <fr:max-results-displayed> element has priority over the max-results-displayed attribute, which has priority over the global property. Styling
Datatable
Overview The datatable component displays tabular information in a spreadsheet like fashion and supports re-sizable columns, scrolling, sort, pagination and more... Its look an feel is similar to the datatable YUI component to which it borrows its CSS but its implementation is mostly based on XForms rather than JavaScript.
Using a datatable component is very similar to embedding an xforms:repeat control within an (X)HTML table. It's basically just a matter of replacing the xhtml:table element by the fr:datatable bound element and adding a few attributes to control the features of the datatable. The table displayed above can be defined as: <fr:datatable scrollable="both" width="800px" height="500px">
<thead>
<tr>
<th fr:sortable="true" fr:resizeable="true">Date</th>
<th fr:sortable="true" fr:resizeable="true">Author</th>
<th fr:sortable="true" fr:resizeable="true">Title</th>
</tr>
</thead>
<tbody>
<xforms:repeat nodeset="/atom:feed/atom:entry">
<tr>
<td>
<xf:output ref="atom:published" xxforms:format="format-dateTime
(., '[M01]/[D01]/[Y] - [h01]:[m01]:[s01]')"/>
</td>
<td>
<a href="{atom:author/atom:uri}">
<xf:output value="atom:author/atom:name"/>
</a>
</td>
<td>
<xf:output value="atom:title"/>
</td>
</tr>
</xforms:repeat>
</tbody>
</fr:datatable>
Attributes
The attributes that control behavior of the datatable are split between the bound element for those that are global to the datatable and the headers for those that are specific to a column: scrollable: defines in which directions the datatable is scrollable and can take the values "vertical", "horizontal" and "both". By default, datatables are not scrollable. For scrollable datatables:
height: defines the height of the datatable using the CSS syntax (write "500px" rather than "500"). This attribute is mandatory for datatables that are vertically scrollable. It isn't used for datatables without vertical scroll bars due to issues in web browser compatibility.
width: defines the width of the datatable using the CSS syntax (write "800px"
rather than "800"). This attribute is mandatory for datatables that are horizontally scrollable. For datatables that have no horizontal scroll bar, it defines the initial width and the table is resized when one of its columns is resized.innerTableWidth: for horizontally scrollable
datatables, forces the width of the internal table that would otherwise
be computed to minimize the table height.
paginated: defines if the datatable should be paginated and can take the values "true" or "false" (default). For paginated datatables:
sortAndPaginationMode: internal (default) if the datatable should support the sort and/or pagination, external if it's handled by the XForms application outside of the datatable.
rowsPerPage: defines the number of rows per page (default = 10)maxNbPagesToDisplay: defines the maximum number of pages to display on the page selectors (default = display all the pages)- When the pagination is not handled by the datatable (
sortAndPaginationMode="external"): page: XPath expression that calculates the current page numbernbPages: XPath expression that calculates the number of pages
loading: XPath expression provided by the application that returns true if the data displayed by the datatable is still loading and if a loading indicator must be shown.- Experimental/development features:
dynamic: temporary (as of October 2009) indicator to force to use the new algorithm that supports dynamic column sets (see RFE #313661) even when there are no dynamic column sets in the datatable (default = false, i.e. use the previous, safer, algorithm).debug: when set to true, display the content of the datatable local instance (default = false). Only supported by the dynamic column sets algorithm.
The attributes that control column properties are located on the xhtml:th (or xhtml:td when the datatable is simplified, see below). Belonging to an XHTML element, they need to be prefixed to be distinguished from XHTML attributes. These attributes are:
fr:sortable: defines if the column is sortable. Can take the values "true" or "false" (default).
fr:sortType: overrides the guess done by the component which normally determines the sort type from the datatype bound to the node displayed in the column. Can take the values "text" (default) and "number". Note that the datatable works with instance values and can reliably sort ISO dates with the "text" sort type even if these dates are displayed in a more user friendly format.
fr:sorted: declares that a column is already sorted so that the component can adapt its display. Can take the values "ascending" or "descending".
fr:resizeable: defines if the column is resizeable. Can take the values "true" ot "false"(default).fr:sortMessage: for sortable columns and when the sort is performed externally to the datatable, this XPath expression provided by the application to the datatable returns the message to display when the mouse hoovers over the column header.
EventsThe datatable dispatches the following events to the external application: fr-goto-page when the pagination is handled externally to the datatable and a new page needs to be fetched. The value of the new page number is passed as the fr-new-page context.fr-update-sort when the sort is handled externally to the datatable and the sort order needs to be updated. The value of the column index where the user has clicked is passed as the fr-column context.
Simplifications
The component supports two syntactical simplifications or abbreviations.
xforms:repeat/xhtml:tr can be replaced by xhtml:tr/@repeat-nodeset. The fragment:
<xforms:repeat nodeset="/atom:feed/atom:entry">
<tr>
...
</tr>
</xforms:repeat>
Can be written: <tr repeat-nodeset="/atom:feed/atom:entry">
...
</tr>
- Headers can be generated from cells labels.
It is very common that columns consist of a single xforms:output control. In that case, it can be considered simpler to provide an xforms:label rather than explicitely define table headers. Our example could be written: <fr:datatable scrollable="both" width="800px" height="500px">
<tbody>
<tr repeat-nodeset="/atom:feed/atom:entry">
<td fr:sortable="true" fr:resizeable="true">
<xf:output ref="atom:published" xxforms:format="format-dateTime (., '[M01]/[D01]/[Y] - [h01]:[m01]:[s01]')">
<xf:label>Date</xf:label>
</xf:output>
</td>
<td fr:sortable="true" fr:resizeable="true">
<a href="{atom:author/atom:uri}">
<xf:output value="atom:author/atom:name">
<xf:label>Author</xf:label>
</xf:output>
</a>
</td>
<td fr:sortable="true" fr:resizeable="true">
<xf:output value="atom:title">
<xf:label>Title</xf:label>
</xf:output>
</td>
</tr>
</tbody>
</fr:datatable>
This is more compact and arguably easier to read than the original form because the definition of each column is grouped together instead of being split between the body and the header.
Main Restrictions
The datatable component has been designed to look like the syntax of an
ordinary (X)HTML table and will usually behave as expected. That being
said, under the cover, the component needs to analyze the table
structure and to implement features such as sort and pagination it has
to rewrite the nodeset expression of the main xforms:repeat with pieces
of XPath expressions cut from XForms controls fetched from table cells. This
is a fairly complex task that is implemented in XBL and XSLT and that
imposes several constraints to the structure of the datatable and the
XPath expressions that can be used. - "Current" algorithm
The current (as of October 2009), robust, algorithm that does not support dynamic column sets imposes the following restrictions on the table structure after the simplifications have been processed:
- The content of the header and body rows must be composed of
th (for the header) and td (for the body) elements. No other elements are supported. - The number of columns should be the same in header and body rows.
- There must be exactly one header row in the table header and no other content.
- There must be exactly one
xforms:repeat embedded in the table body and no other content.
The new algorithm implemented to support dynamic column sets (see RFE #313661) extends these restrictions to accept xforms:repeat elements as wrappers to header and body cells. These xforms:repeat can be freely mixed with th (in header) and td (in body) elements but there should be an exact and immediate match between the structure of the table body and headers. A single level of xforms:repeat is supported and other XForms controls (such as xforms:group or xforms:switch are not supported (support of xforms:group has been entered as RFE #314349). Other important restrictions are dictated by the XPath "cut and paste" algorithm involved when the datatable supports sort and pagination internally. These restrictions can be summarized by the fact that the expressions used in XForms controls that will be used as sort keys must be valid in an element that is external to the xforms:repeat where they appear. The main effect of this issue is that they cannot use local variables (see issue #314323).
Sort and paginations are implemented in XForms by rewriting the xforms:repeat nodeset expression. This means that context functions such as index() or position() are evaluated in the context of the sorted and paginated node set. Loading indicator
The datatable is good candidate on which to apply the delay expensive submissions tuning technique. The datatable offers a way for you to indicate that the data is being loaded using the optional loading attribute. The value of this attribute is an XPath expression, and its result is interpreted as a boolean value. Typically, you will: - Use a node in an instance (say
<loading>) a way to keep track of whether the data is being loaded or has already been loaded. You initially store true in that node (e.g. <loading>true</loading>). - You make your datatable point to that node (e.g.
<fr:datatable loading="/path/to/loading = 'true'"/>). - You delay the expensive submission until after the form is loaded.
- When the submission is done, you set the content of the node to
false.
With this in place, while the data is loading, the datatable will show a spinning icons, as in: The datatable CSS uses the class fr-datatable-is-loading to set a background image (in this case a spinning icon) for the central area of the datatable. You can change this by overriding in your CSS the default style defined for the fr-datatable-is-loading.
See also
Date
The <fr:date> components builds on the <xforms:input> bound to node of type xs:date but provides the following additional functionality: - You can use the
appearance="fr:inline" to have the date picker shown inline in the page (instead of having the date picker shown when you click in the input field). When you use this appearance, no text filed is displayed and you need to click on a date in the date picker to select it.
- You can use the
mindate and maxdate properties to put a constraint on the dates that can be selected in the date picker. Dates before the mindate and after the maxdate will be grayed out. You can set a "static" mindate or maxdate using an attribute:
<fr:date ref="date" mindate="2009-05-06" maxdate="2009-05-24">
<xforms:label>Contract start date:</xforms:label>
</fr:date>
Or you can have a "dynamic" mindate or maxdate using sub-elements:
<fr:date ref="date" appearance="fr:inline"> <xforms:label>Contract start date:</xforms:label> <fr:mindate ref="../mindate"/> <fr:maxdate ref="../maxdate"/> </fr:date>
The above control might be rendered as follows if the current date is May 15, the mindate is May 5 and the maxdate is May 25:
- The date picker opens at a given month:
- If the bound node holds a valid date, then the date picker will show the month corresponding to that date.
- If the bound node does not hold a valid date, then the date shows the month corresponding to today's date.
- You can override the above behavior, which is inherited from
<xforms:input> bound to a node of type xs:date, by setting the pagedate property.
You can set a "static" pagedate using an attribute:
<fr:date ref="date" pagedate="1970-01-01"> <xforms:label>You birth date:<xforms:label> </fr:date>
Or you can have a "dynamic" pagedate using a sub-element:
<fr:date ref="date" pagedate="1970-01-01">
<xforms:label>You birth date:<xforms:label> <fr:pagedate ref="../pagedate"/>
</fr:date>
Setting a pagedate is particularly useful when you don't have an initial date, because no date has been set yet, but you know that the date to be entered won't be around the current date, but rather around some other date.
Date Picker
The date picker component works very much like like an <xforms:input> bound to a node of type xs:date, except instead of the date being editable through a text field, the date is printed next to the date picker icon. Using this component instead of an <xforms:input> will guarantee you that the date entered by users is valid.

To use the component, write:
<fr:date-picker ref="date" id="data-picker">
<xforms:label>Arrival date</xforms:label>
</fr:date-picker>
Inside the control, you can use the usual <xforms:label>, <xforms:hint>, <xforms:help>, and <xforms:alert>, as you would with XForms controls. You must make the ref attribute point to a node of type xs:date.
Map
XBL component which is rendered as a Google Maps widget on the page. It is bound to an address, and optionally to a longitude/latitude. In essence:
- An initial location can be provided to the component. When
provided, if found by the Google Maps API, a marker will be placed on the map
at that location.
- If a lat/long is provided, it takes precedence over the address and the marker will be placed at that lat/long instead of at the address.
- The user can move the pin to choose another location. The lat/long for the new position of the marker will be stored.
You use the map component with:
<fr:map address-ref="address" id="unittest-map"
longitude-ref="longitude" latitude-ref="latitude"
style="width: 500px; height: 300px"/>
- address-ref points to a node containing the address, as one string.
- longitude-ref and latitude-ref points to the nodes optionally containing the initial longitude and latitude. The initial value can be empty. If the marker is moved by the user, the longitude/latitude of the new position will be stored in those nodes.
- style used as-is on the <div> which contains the actual map. You will typically want to use that attribute to set the size of the map.
If you wish to deploy a form using the map component (other than accessing your form with a URL such as http://localhost:8080/orbeon/...), you need to apply for a Google Maps API Key. After you obtained your key, indicate it in the following property that you add to your config/properties-local.xml: <property as="xs:string" name="oxf.xforms.xbl.fr.map.key" value="..."/>
Currency
Rationale The currency component is an input field specialized to capture amounts in a particular currency. When the input field doesn't have the focus, it shows a formatted currency, such as $ 1,234.00. When the control has the focus, it shows the plain number, such as 1234. Currency prefix By default the dollar sign ($) is used as a currency prefix. You can override this either: - Globally for all your forms in your properties-local.xml by setting the following property:
<property as="xs:string" name="oxf.xforms.xbl.fr.currency.prefix" value="£"/>
- For a particular instance of the component:
- With the prefix attribute, for static values.
- With the <fr:prefix> element, for dynamic values.
Digits after the decimal sign By default, the component shows rounds the value to 2 digits after the decimal sign. You can override this either: - Globally for all your forms in your properties-local.xml by setting the following property:
<property as="xs:string" name="oxf.xforms.xbl.fr.currency.digits-after-decimal" value="3"/>
- For a particular instance of the component:
- With the digits-after-decimal attribute, for static values.
- With the <fr:digits-after-decimal> element, for dynamic values.
If you set digits-after-decimal to 0, then the decimal separator isn't shown. ExamplesCase | Code | Screenshot | Control without focus
| <fr:currency ref="value"/>
| | Control with focus
| (Same as above)
| | Setting a static prefix with the prefix attribute
| <fr:currency ref="value" prefix="£"/> | | Setting a dynamic prefix with the <fr:prefix> element
| <fr:currency ref="value"> <fr:prefix ref="/config/prefix"/> </fr:currency>
| | Showing 3 digits after decimal sign
| <fr:currency ref="value" digits-after-decimal="3/> |
| Showing 0 digits after the decimal sign
| <fr:currency ref="value"
digits-after-decimal="0/> | | Read-only input field, because bound to node set as read-only with a MIP.
| <xforms:bind nodeset="readonly-node" readonly="true()"/> <fr:currency ref="readonly-node"/>
|
|
Accordion menu Overview The accordion menu component is not unlike the <xforms:switch>: it defines a number of "cases", each with a title and some content. Each case can be selected (visible) or not (hidden). The screenshot below shows an accordion menu component with 3 cases: You used the accordion menu component with: <fr:accordion class="fr-accordion-lnf" id="my-accordion"> <fr:case> <fr:label>First section (lorem ipsum)</fr:label> <xhtml:div> Lorem ipsum dolor sit amet, [...] </xhtml:div> </fr:case> <fr:case selected="true" id="my-second-case"> <fr:label>Second section (XForms input)</fr:label> <xforms:input ref="cost"> <xforms:label>Cost</xforms:label> </xforms:input> </fr:case> ... </fr:accordion>
Note: - The <fr:case> elements define the different sections of the accordion menu.
- For each case, you specify the label for that case with <fr:label>.
- Inside the <fr:case>, after the <fr:label>, you can put any markup (XForms, XHTML) you want.
- You can specify a class on the <fr:accordion>. By using fr-accordion-lnf, as in the code above, you pick the default style. Should you want to use a completely different style, specify another class on <fr:accordion> and create your CSS using that class as appropriate.
- You can specify which cases should be selected (i.e. open) when the accordion is first shown, by addition the attribute selected="true".
Events You can programmatically open an close cases by dispatching events to the accordion control. It supports the following events: - fr-toggle – to toggle a specific case. Like the XForms <xforms:toggle> action used with cases, this event changes the state of a case. The dispatch target is the corresponding <fr:case> element.
<xforms:trigger appearance="minimal"> <xforms:label>Toggle one</xforms:label> <xforms:dispatch ev:event="DOMActivate" target="my-second-case" name="fr-toggle"/> </xforms:trigger>
- fr-show – to show a specific case. This event shows the given case. The dispatch target is the corresponding <fr:case> element.
<xforms:trigger appearance="minimal"> <xforms:label>Show one</xforms:label> <xforms:dispatch ev:event="DOMActivate" target="my-second-case" name="fr-show"/> </xforms:trigger>
- fr-hide – to hide a specific case. This event hides the given case. The dispatch target is the corresponding <fr:case> element.
<xforms:trigger appearance="minimal"> <xforms:label>Hide one</xforms:label> <xforms:dispatch ev:event="DOMActivate" target="my-second-case" name="fr-hide"/> </xforms:trigger>
- fr-show-all – to open or close all the cases at once. The dispatch target is the corresponding <fr:accordion> element.
<xforms:trigger appearance="minimal"> <xforms:label>Show all</xforms:label> <xforms:dispatch ev:event="DOMActivate" target="my-accordion" name="fr-show-all"/> </xforms:trigger>
- fr-hide-all – to open or close all the cases at once. The dispatch target is the corresponding <fr:accordion> element.
<xforms:trigger appearance="minimal"> <xforms:label>Hide all</xforms:label> <xforms:dispatch ev:event="DOMActivate" target="my-accordion" name="fr-hide-all"/> </xforms:trigger>
Deprecated events: - Deprecated: fr-accordion-toggle-all – to open or close all the cases at once. This event takes a context parameters selected which value must be either true (to open all cases) or false (to close all cases). For instance:
<xforms:trigger appearance="minimal"> <xforms:label>Open all</xforms:label> <xforms:dispatch ev:event="DOMActivate" target="my-accordion" name="fr-accordion-toggle-all"> <xxforms:context name="selected" select="true()"/> </xforms:dispatch> </xforms:trigger>
- Deprecated: fr-accordion-toggle – to open or close a specific case. This events supports the selected context parameter (as fr-accordion-toggle-all described above). It also supports the case-id which must be the ID of an <fr:case>. For instance:
<xforms:trigger appearance="minimal"> <xforms:label>Open second case</xforms:label> <xforms:dispatch ev:event="DOMActivate" target="my-accordion" name="fr-accordion-toggle"> <xxforms:context name="case-id" select="'my-second-case'"/> <xxforms:context name="selected" select="true()"/> </xforms:dispatch> </xforms:trigger>
Keeping only one case open
In certain cases, you don't want users to have multiple cases of a given accordion open at the same time. For instance, if a case A is open, and they click on the title of another case B, instead opening B and keeping A open, you would like this action to close A and open B. You can instruct the accordion to behave in this way by setting the open-closes-others property to true (it is false by default). You can do this either globally in your properties-local.xml: <property as="xs:boolean" name="oxf.xforms.xbl.fr.accordion.open-closes-others" value="true"/>
Or you can set this property on a specific accordion by setting the corresponding attribute: <fr:accordion open-closes-others="true">
Note that cases will close automatically only if the user opens a case by clicking on the title of that case. This option has no effect on events you send to the accordion. Using events you send to the accordion, you can still have more than case open, if this is indeed what you decide want to do. Repeats You can use an <xforms:repeat> inside the <fr:accordion> to dynamically generate cases. For instance: <fr:accordion class="fr-accordion-lnf" id="my-accordion"> <xforms:repeat nodeset="path/to/nodes"> <fr:case id="my-case-repeat"> ... </fr:case> </xforms:repeat> </fr:accordion>
When you have a repeat around cases, and use the fr-accordion-toggle event specifying the ID of the case ( my-case-repeat in the example above), the current case in the repeat is opened.
In-place Input
Like <xforms:input>, this control allows entering a single line of text. The value of this control initially appears as if shown with <xforms:output>: it is read-only and does not appear like a regular input field. When the user clicks on the text, the control morphs into an input field, allowing editing the value. After entering a value, the user has the choice of applying the change or canceling. The control supports the usual label, hint, alert, and help nested elements. <fr:inplace-input ref="name"> <xforms:label>Name:</xforms:label> <xforms:hint>Click here to enter your name</xforms:hint> <xforms:alert>Invalid name</xforms:alert> <xforms:help> This control is an in-place input: when you click on the text, it morphs into an input field which allows you to edit the value. </xforms:help> </fr:inplace-input>
If the control's value is empty, the control shows inline the value provided by a nested <xforms:hint>, if any. It is recommended to provide such a hint so that there is a clear area to click on and make the input field appear.
Alert dialog
The alert dialog allows you to build simple dialogs for those cases where you need to inform users of something that happened, or ask a question which can be answered by a yes or a no. Example Let's assume that you want to ask a yes/no question which produces a dialog as shown below, and that you want to react to users choosing Yes.  First declare the dialog, with: <fr:alert-dialog id="overwrite-file-dialog">
<fr:label>Copy</fr:label>
<fr:message>
An item with the same name already exists.
Do you want to replace it with the one you're moving?
</fr:message>
<fr:negative-choice/>
<fr:positive-choice>
<xforms:toggle ev:event="DOMActivate" case="replaced-case"/>
</fr:positive-choice>
</fr:alert-dialog>
- You gave an id to the dialog (
overwrite-file-dialog).
- You defined what the dialog title and message are with
<fr:label> and <fr:message>. - You use the
<fr:negative-choice> and <fr:positive-choice> elements to indicate which buttons you want to have, and in which order they should be shown. - You placed an event handler inside the
<fr:positive-choice>, which will run when/if users press the Yes button.
You open this dialog by dispatching the event fr-show to the dialog: <xforms:dispatch target="overwrite-file-dialog" name="fr-show"/>
Buttons The alert dialog supports 3 buttons, that correspond to a positive choice, a negative choice, and a neutral choice. Each one has a default label and a default icon, as shown in the table below. For each button, you can: - Override the label by placing your own
<fr:label> inside the button element. For instance, you would change the label for positive choice from Yes to OK and for the negative choice from No to Cancel with:
<fr:positive-choice><fr:label>OK</fr:label></fr:positive-choice>
<fr:negative-choice><fr:label>Cancel</fr:label></fr:negative-choice>
- Override the icon shown inside the button with CSS. You will find an
<xhtml:span> with the class indicated in the table below around each button, which allows you to have a different style depending on the button type. For instance, if you can use the following CSS rule to remove the icon for the positive choice button:
.yui-skin-sam .xbl-fr-alert-dialog-positive .xbl-fr-button .yui-button button { background: none; padding: 0 10px 0 10px; }
Element
| Default representation
| CSS class
| <fr:positive-choice>
| | xbl-fr-alert-dialog-positive
| <fr:negative-choice>
| | xbl-fr-alert-dialog-negative | <fr:neutral-choice>
| | xbl-fr-alert-dialog-neutral
|
In most cases, you will be using either the positive and negative choice together, or the neutral choice alone. You can use the 3 buttons at the same time, to create a Yes-No-Cancel type of dialog. In this case however, you should consider giving labels to buttons that more description than Yes-No-Cancel. For instance, if you want to ask users whether they want to leave this form without saving, you could label the buttons Save data, Discard data, Continue editing. Dialog icon
Depending on the number of buttons you place in your dialog, a different icon is used next to the message. Just like icons in buttons, you can change the icon by overriding the default CSS: - When you have 2 or 3 buttons, the dialog is considered to be a question. The CSS class is
xbl-fr-alert-dialog-question and the dialog looks like:
- When you have 1 button, the dialog is considered to be informational. The CSS class is
xbl-fr-alert-dialog-info and the dialog looks like:
FusionCharts
With this component you can easily add to your form a chart rendered by FusionCharts. Setup - Note that since FusionCharts is a commercial product, it is not bundled with Orbeon Forms. So first download a copy of FusionCharts.
- Unzip the distribution, and copy the directory that contains all the swf files somewhere in your resources directory.
- Add the following property to your properties-local.xml, to specify the path to the directory that contains the FusionCharts swf files (here assuming that the swf files are under FusionCharts inside the resources):
<property as="xs:string" name="oxf.xforms.xbl.fr.fusion-charts.uri-to-swf" value="/FusionCharts"/>
Usage - Store the XML defining the chart in an instance, per the FusionCharts documentation.
- Use the following markup to insert the chart in your form:
<fr:fusion-charts ref="column-3d/chart" swf="Column3D" width="600" height="400"/>
All the attributes on <fr:fusion-charts> are required: - ref points to a node which is the root of your chart definition (which can be stored anywhere in an instance).
- swf defines what type of chart you want to use. It is the name of the swf file to use, without the extention.
- width and height define the size of the chart.
If you the values for swf, width, or height are not statically defined but come from an instance, instead of the attribute you can use a nested element of the same name, with a single node binding pointing to the node containing the value. But note that those values are used when the chart is rendered (when the component receives xforms-enabled), and that they can't be changed at a later time. The XML defining the chart (pointed to by ref) can change at any time. The component will react to changes and will automatically update the chart.
|