You are on page 1of 20

SBM Composer Form Extensions

Author: Tom Clement


Date: January 23 r d , 2015
Contents
Overview of Form Extensions ....................................................................................................................... 3
What’s in this document? ......................................................................................................................... 3
What are Form Extensions? ...................................................................................................................... 3
What’s the difference between Form Extensions and Custom Form Actions? ......................................... 3
Enabling the use of Composer as a Form Extensions Editor......................................................................... 3
The Sample Custom Widget and the Form Extensions Editor ...................................................................... 4
The .CFX File Structure .................................................................................................................................. 4
The assets Directory...................................................................................................................................... 5
The widgetIcons Directory ............................................................................................................................ 5
The documentation.html File ....................................................................................................................... 5
The logo.png File ........................................................................................................................................... 5
The metadata.xml File .................................................................................................................................. 6
The definition.xml File .................................................................................................................................. 6
The GlobalIncludes Element ..................................................................................................................... 6
Categories ................................................................................................................................................. 7
Restrictions ............................................................................................................................................... 7
RegularExpressions ................................................................................................................................... 8
Aliases ....................................................................................................................................................... 8
Events, Conditions, Actions and Widgets ................................................................................................. 9
Attributes .............................................................................................................................................. 9
Child elements of the Event, Condition and Action elements ............................................................ 12
Widgets ................................................................................................................................................... 13
Attributes ............................................................................................................................................ 13
Child elements of the Widget element ............................................................................................... 13
Raising Property Changed Events ....................................................................................................... 15
Substitution Values for Implementations ........................................................................................... 15
Example and Discussion .............................................................................................................................. 17
The Event ................................................................................................................................................ 18
The Condition .......................................................................................................................................... 18
The Action ............................................................................................................................................... 19
Implementation ...................................................................................................................................... 19

Copyright © 2015 Serena Software, Inc. All rights reserved.


Overview of Form Extensions

What’s in this document?


This document describes the format of the form extension (.CFX) file and the files contained within it.

Note: Custom extension development requires advanced knowledge of SBM, XML, and JavaScript. For customers
with current maintenance contracts, Serena Software will support the infrastructure for creating custom
extensions and importing them into SBM Composer; however support for developing and packaging customer
extensions is not provided as part of the maintenance agreement.

What are Form Extensions?


The form extensions feature is available as of SBM 10.1.5. Form extensions extend the set of available
form actions and widgets in Composer. Form extensions are stored as an archived (zipped) file with an
extension of .CFX. A form extension may include custom form action restrictions (selection lists), events,
conditions and actions as well as packaged custom widgets and assets.

What’s the difference between Form Extensions and Custom Form Actions?
Earlier versions of SBM contained a feature that permitted custom form actions to be defined by Serena
solution developers and added to the list of available form action Events, Conditions and Actions. The
form extensions feature builds on this solution-developer-only capability, adding the ability to define
and add custom widgets to the form palette, along with the new ability to include additional assets in
the package. The assets features allows a Form Extension to include JavaScript, CSS, Image and HTML
files deployed along with the application and used in the implementation of a custom widget.

Unlike the earlier custom form actions, form extensions can be added and removed from an application
by any Composer user and multiple form extensions can be added to an application. (Previously, custom
form actions could be added or removed from an application only by a solution developer and were
represented by a single file.) Existing form action extensions defined by solution developers can be
easily converted into form extensions because they are defined by a subset of the form extension
format.

While Composer Extensions can be imported, exported and used by any Composer user, the creation of
them is a programming task that is not generally available to Composer users. However, when the
solution developer key has been added to the registry, the files in the extension become editable in
Composer.

Enabling the use of Composer as a Form Extensions Editor


Composer permits any user to import and export form extensions. However, the ability to edit a form
extension in Composer is available only when the following key and value exist in the registry:

HKEY_CURRENT_USER\Software\Serena\Studio\Solution Developer
Value: Enabled
Type: REG_SZ
Data: True

Copyright © 2015 Serena Software, Inc. All rights reserved.


After this has key/value been added to the registry, restart Composer to enable in-place Form Extension
editing.

The Sample Custom Widget and the Form Extensions Editor


When the Solution Developer key is set in the registry, a Composer user can create a new Form
Extension by picking “Add New->Empty Form Extension” from the context menu on the Form Extensions
folder in the Application Explorer. This creates a form extension named “Sample Extension” that
demonstrates many of the features of form extensions, including custom widgets with a JavaScript
object implementation, assets and asset references, form actions that operate on the custom widget
and more.

You can directly edit the Name, Revision, Author, Copyright and Description properties using the Form
Extensions editor. Click on the Edit button in the Documentation panel to bring up an HTML editor for
modifying the documentation content for the extension. Click on the image associated with the form
extension to navigate to and specify an image file that represents the form extension in the Add Form
Extension dialog.

Click on the Edit Definition button in the Form Extensions editor to view and modify this basic
implementation, including the definition, JavaScript and CSS files. You can add, delete and rename files
from the form extension using this editor and easily insert the common $$assetspath and $$name tags
in the text.

The Sample Extension is a good starting point for creating your own form extension, because it
demonstrates techniques and best practices for creating an efficient and functional custom widget.

The .CFX File Structure


The .CFX file has four top level files and two directories. The top level structure of the archive file looks
like this:

The assets directory contains additional directories and files used by the form actions and widgets, for
example, JavaScript files implementing widget behavior. These files are deployed along with the
application and are available to the widgets at runtime. The widgetIcons directory contains the icons
representing the custom widgets in the form palette. The documentation.html file is used to provide
documentation about the contents of the extension, such as a listing of the form actions and controls
supported by the extension. This appears in the documentation field of the form extension editor. The
logo.png file defines the image that appears when displaying the extension in the Add Form Extension
Copyright © 2015 Serena Software, Inc. All rights reserved.
dialog and in the form extension editor. The metadata.xml file contains information about the
extension, like name, revision, author etc. The definition.xml file defines the form actions and custom
widgets contained in the extension and includes both declarative information as well as JavaScript code.

These files and directories are described in greater detail below.

The assets Directory


When an application containing a form extension is deployed, the assets directory is copied verbatim to
a directory under the application engine’s bin directory. The location is:

ComposerExtensions/[ApplicationUUID]/[ExtensionName]

JavaScript and HTML that reference assets use a special tag (“$$assetpath”) that resolves to this path.
For example, to reference a JavaScript file in the javascript subdirectory of the assets path, you would
use:
<script type="text/javascript" src="$$assetpath/javascript/slideshow.js"></script>

Special $$ tags will be discussed in more detail in the definition.xml section below.

The widgetIcons Directory


Custom widgets defined in form extensions will appear in the form palette in Composer. The
widgetIcons directory contains icons for each custom widget. These are used to identify and distinguish
the widget in the Composer form palette, and to identify and distinguish the widget at design time when
it is placed on a form. It has no meaning at runtime. The icon associated with a widget is identified by
the icon attribute on the Widget element in the definition.xml (as described in greater detail below).

The documentation.html File


This file can contain any valid HTML content. The form extension developer should strive to provide
enough information that a user can understand the purpose of the form extension and read about any
contained custom widgets and form action events, conditions and widgets. When the solution developer
key is set, Composer permits the user to directly edit this file by clicking on the Edit button in the form
extension editor.

The logo.png File


This is an image that represents the form extension file in the form extensions list in the Add Form
Extension dialog. It should help the user identify the purpose and content of the form extension.
Serena recommends that you use a 128x128 pixel image.

Copyright © 2015 Serena Software, Inc. All rights reserved.


The metadata.xml File
This file contains general information about the form extension. For example, the following describes a
sample slideshow form extension.

<?xml version="1.0" encoding="UTF-8"?>


<FormExtension>
<Revision>1.0</Revision>
<Author>Serena Software, Inc.</Author>
<Name>Slideshow</Name>
<Copyright>© 2015 Serena Software, Inc.</Copyright>
<Description>Sample Composer form extension implementing a slideshow custom
widget and associated form actions.
</Description>
</FormExtension>

When the solution developer key is set, Composer permits the user to directly edit these properties in
the form extension editor.

The definition.xml File


The following sections describe the format of the definition.xml file. The schema document installed
with Composer (\Program Files\Serena\SBM\Composer\Schema\FormLogic.xsd) provides a more formal
description of the extension format. All elements described below appear under the <FormLogic>
document element.

The GlobalIncludes Element


<GlobalIncludes> is an optional element that contains one or more <Include> child elements. Each
<Include> element contains a path to a JavaScript or .CSS file to be included with the page. For example,
the following:
<GlobalIncludes>
<Include>$$assetpath/styles/sample.css</Include>
</GlobalIncludes>

causes the sample.css file located in the styles directory in the form extension assets to be included in
the form. In the form, the $$assetpath tag is resolved, and the following HTML is generated:
<link rel="stylesheet" type="text/css"
href="ComposerExtensions/[ApplicationUUID]/SampleExtension/styles/sample.css" />

If the file is a JavaScript, like this:


<GlobalIncludes>
<Include>$$assetpath/javascript/SampleCustomWidget.js</Include>
</GlobalIncludes>

the generated HTML will be:


<script language="Javascript" name="SampleCustomWidget.js"
src="ComposerExtensions/[ApplicationUUID/SampleExtension/javascript/SampleCustomWidget.
js"></script>

The <GlobalIncludes> element differs from the <Includes> child element of the Events, Conditions,
Actions and Widgets elements because it will be added to the form whether or not a widget or form
action defined in the form extension is used on the form.

Copyright © 2015 Serena Software, Inc. All rights reserved.


Categories
The <Categories> element contains a list of <Category> elements that define the groupings under which
Events, Conditions and Actions appear in the drop down lists in the editor. Each category must be given
a unique name, by which it will be referred in the Event, Condition or Action element’s category
attribute. For example the base implementation contains the following categories:
<Categories>
<Category name="PageEvents">Form Events</Category>
<Category name="FieldEvents">Field Events</Category>
<Category name="ControlEvents">Control Events</Category>
<Category name="FieldConditions">Field Conditions</Category>
<Category name="ControlConditions">Control Conditions</Category>
<Category name="FieldActions">Field Actions</Category>
<Category name="ControlActions">Control Actions</Category>
</Categories>

Restrictions
The <Restrictions> element contains a list of <Restriction> elements that defines selection lists that can
be used as values for menus that appear in events, conditions and actions. For example, a condition may
include a reference to whether a control is visible or hidden, while an action may include an instruction
to either show or hide a control.

Basic Example
An example of a restriction is:

<Restriction name="VisibleHidden">
<Value>visible</Value>
<Value>hidden</Value>
</Restriction>

This is used in both events and conditions and is referenced using the [VisibleHidden] notation in the
display attribute string. For example, in the base implementation the condition condition_FieldShown
has the display attribute "{Field} is [ShownHidden]".

The ‘for’ attribute


Restrictions can also have a for attribute which describes the field and control types to which they apply.
When the display attribute of a condition contains the special ‘[?]’ notation, the system scans through
the list of restrictions until it finds one with a for attribute containing the type of the specified field or
control. For example, the following restriction:
<Restriction name="StringOperator" for="{Field.Text | EditControl}">
<Value>equals</Value>
<Value>contains</Value>
<Value>does not contain</Value>
<Value>is contained by</Value>
<Value>is not contained by</Value>
</Restriction>

is shown for the operator of the condition_FieldOperatorValue condition when a Field.Text field is
chosen, because the display attribute of the condition contains ‘[?]’ and the StringOperator restriction’s
for attribute contains Field.Text. This restriction is also used for the condition_ControlOperatorValue
condition when the left side is an EditControl because its display attribute (“{InputControl} [?] {?}")
contains ‘[?]’ and the StringOperator restriction’s for attribute contains EditControl.
Because the system chooses the first restriction that contains a type specification in the for attribute
that matches the left hand side control or field, each type should appear in only one restriction. In other
words, the for type specification should uniquely identify the restriction to use.
Copyright © 2015 Serena Software, Inc. All rights reserved.
RegularExpressions
The <RegularExpressions> element contains a list of <RegularExpression> elements that are used as pre-
defined values for conditions that match regular expressions. You can add new types of regular
expressions to this list to meet the domain specific needs of your application. By defining a regular
expression with the same name as an existing one, you can replace it in the list. For example, if you’d
like to offer a different date format, you can define a new <RegularExpression name=”Date”…> element.

The expression editor displays a drop down list box containing these pre-defined regular expressions as
well as a text area in which the user can specify a custom regular expression. This dialog appears as the
value editor for Conditions with a display attribute containing the {RegularExpression} notation. Because
regular expressions can contain characters that may not be valid in an XML element, the content of the
RegularExpression element should be CDATA escaped.

Attributes for the <RegularExpression> element include:

 The name attribute is the unique identifier of the regular expression in the system.
 The ignoreCase attribute specifies whether this regular expression should be case insensitive.
Valid values are “true” and “false”.
 The description attribute specifies the text that will be shown in the drop down list in the regular
expression picker.

All three attributes are required.

Aliases
The <Aliases> element contains a list of <Alias> elements that are used to define a text string that will be
substituted for a given display parameter when shown in the editor as unbound (i.e. when the tag has
not yet been given a value. For example, given an Alias element:
<Alias param="{StaticControl | InputControl | ActionControl | WidgetControl}">a control</Alias>

the text “a control” will automatically be substituted whenever the parameter { StaticControl |
InputControl | ActionControl | WidgetControl} is encountered in a display string for an unbound
parameter.

NOTE: The system automatically constructs human readable text for unbound parameters in a display
string, based on the Field or Control types referenced in it. The Alias element allows you to override this
default string with a custom one if needed.

Copyright © 2015 Serena Software, Inc. All rights reserved.


Events, Conditions, Actions and Widgets
The Event, Condition, Action and Widget elements are used to define new events, conditions, actions
and widgets. All four share the same definition structure except as specified below. The Event,
Condition, Action and Widget elements must be uniquely named. The Widget elements include
additional attributes and child elements described in a separate section below.

Attributes
Attributes for the <Event>, <Condition>, <Action> and <Widget> elements are:

name attribute
This is a unique name for the event, condition, action or widget. (Required)

display attribute
For the <Widget> element, this is the name used to identify the widget in the form palette. For other
types, the display attribute specifies the display string to be shown in the form action editor. It should
contain display parameter references for any parameters that will be passed to the implementation. In
other words, the display attribute is a format string describing the event, condition or action, including
parameter tags that identify changeable values that will be passed to the implementation. The display
attribute is required. The following special parameter tags are supported in the display string.

o The {control type}, {field type}, {control type | field type…} parameter tags

Control types and field types can be or’ed. For example, {EditControl}, {Field.Text},
{EditControl | Field.Text}, and {StaticControl | EditControl} are all valid parameter tags. This
construct results in a drop down menu containing all available fields and controls that match
the types specified.

Valid control types that can appear in this construct are:

 EditControl -> an Edit box


 ComboBoxControl -> a Combo box
 ListBoxControl -> a List box
 MutipleListboxControl -> a Multi-select List box
 StaticControl -> a Static control
 InputControl -> EditControl | ComboBoxControl | ListBoxControl |
MultipleListBoxControl,
 ActionControl -> ButtonControl | ImageControl | LinkControl,
 WidgetControl -> a Widget
 Tab -> a Tab
 SectionControl -> a Section
 Control -> StaticControl | EditControl | ComboBoxControl |
ListBoxControl | MultipleListBoxControl | ActionControl |
SectionControl | Tab | WidgetControl,
 ButtonControl -> a Button

Field types that can appear in this construct consist of all fields that can appear on a form
and are identified by the Field.TypeName syntax. Where typename can be any of the
following:
Copyright © 2015 Serena Software, Inc. All rights reserved.
Numeric, Text, DateTime, Selection, Binary, State, User, Project,
Summation, MultipleSelection, Contact, Incident, Folder,
Relational, SubRelational, MultipleRelational, MultipleUser,
MultipleGroup

For example, the parameter tag “{Field.Numeric | Field.Summation}” would correspond to a


menu containing all numeric and summation fields on the form.

Subtypes can be specified for some field types. The following subtypes are supported:

Text.Memo, Text.FixedLength, Text.Journal,Numeric.Integer,


Numeric.Float, Numeric.FixedPrecision, DateTime.DateOnly,
DateTime.DateAndTime, DateTime.TimeOfDay, DateTime.ElapsedTime,
Binary.ComboBox, Binary.RadioButton, Binary.Checkbox,
Binary.Trinary, Binary.ComboboxTrinary, Binary.RadioButtonTrinary

When specifying a subtype in a parameter, only fields with the given subtypes will appear in
the menu. For example, {Field.Numeric.Integer | Field.Numeric.Float} would include
numeric fields with the attribute Integer or Float but not a Fixed Precision numeric field.

Custom Widget types are defined with a type name of “CustomWidget” and a subtype of
the widget name. For example:

CustomWidget.Slideshow

defines a value that can be resolved to any instance of the Slideshow custom widget on the
form. As with other parameter types, if the event, condition or action can act upon multiple
custom widget types, they can be combined the “|” (or) separator.

o The {value editor} parameter tag

You can use any of the following parameter tags to show a value editor for a condition or
action. The editor appears when you click on the corresponding portion of the display string.

String – Shows a dialog for entering a string.


RegularExpression – Shows the Regular Expression dialog
Integer – Shows a dialog for entering integers.
FloatingPoint – Shows a dialog for entering floating point numbers.
FixedPrecision – Shows a dialog for entering fixed precision numbers.
Numeric – Shows the integer, floating point, or fixed precision dialog, depending on
the type of the left side of a condition, or the target of an action.
DateOnly – Shows a dialog for entering a date.
DateAndTime – Shows a dialog for entering a date and time or a date time keyword.
TimeOfDay – Shows a dialog for entering a time of day.
ElapsedTime – Shows a dialog for entering elapsed time.
DateTime = DateOnly | DateAndTime | TimeOfDay | ElapsedTime – Shows
a dialog for entering a date, a date and time, a time of day or an elapsed time
depending on the type of the left side of a condition or the target of an action.

Copyright © 2015 Serena Software, Inc. All rights reserved.


Binary – Shows a dialog for entering a binary (or trinary) value.
SelectionValues – Shows a dialog for selecting one or more selection values (based
on the type of the corresponding field).
Color – Shows a color picker dialog
Transitions – Shows a dialog for picking a transition name.

o The {?} special parameter tag

Depending on the left side of a condition, or the target of an action, displays an appropriate
menu or dialog. This tag cannot be placed first in the display string because it depends on
the selected item to the left.

o The [restriction] parameter tag

A restriction is a list that appears as a drop down menu. The name of the restriction is used
inside the square brackets. The list of options is defined by the <restriction> element
described below.

o The [?] special restriction list tag

The special reserved tag [?] has a special meaning. It is replaced with an appropriate
restriction list depending on the type of the field or control selected for the tag to its left in
the display string. The ‘for’ attribute of the <Restriction> element determines which
restriction will be used.

Examples for the display attribute:


The display string:
{Field} [LosesGains] focus
contains two display tags: {Field} and [LosesGains]. The first, {Field}, can be replaced with any
field type. The second, [LosesGains], can be replaced with any value from the LosesGains
restriction list which it references.

The following example, demonstrates special [?] restriction tag and the {?} the display string:
{InputControl} [?] {?}
when {InputControl} is bound, the [?] tag will allow binding from the restriction list that is
appropriate for the actual type of InputControl bound. Likewise the {?} tag will allow binding
from a value editor that is appropriate for the actual type.

category attribute
The category attribute references a Category as defined below and determines the section into
which the item will be placed in the drop down list. If no category is specified, the item will appear in
the Other category.

description attribute
The description attribute specifies the text to be displayed in the menu when choosing an Event,
Action or Condition item from the list. This is different than the display string that is shown in the

Copyright © 2015 Serena Software, Inc. All rights reserved.


Editor. This attribute is optional and if no description is specified, the generated text from the
display string will be used instead. The Description attribute is not used in the <Widget> definition.

formType attribute
The formType attribute specifies the type of Form to which this Event, Condition or Action will apply.
Valid values are Edit, View, or Print. This attribute is optional and if not specified, the item will apply
to all form types. Form types can be combined with the “|” (or) operators. For example:

formType="Print | View"

Child elements of the Event, Condition and Action elements


The <Event>, <Condition> and <Action> elements have three child elements: <Prototype>, <Includes>
and <Implementation>.

Prototype child element


The <Prototype> contains <Param> child elements that identify the parameters that are specified by the
users (based on the index of the tag in the display attribute above), and the names by which these
values will be passed to the implementations of the event, condition or action. An optional replace
attribute (currently used with regular expressions) causes the value specified in Composer to be
substituted for a $$<index> tag in the implementation. Otherwise, the value is passed as a parameter to
the implementation function. The following <Param> element attributes are supported:

- The position attribute specifies the position in the display string of the parameter being
referenced. Positions are 0-based.

- The name attribute specifies the name to be used in the javascript function prototype. This
name is what should be used to reference the parameter in the implementation.

- The replace attribute specifies whether the parameter will be replaced inline in the
implementation instead of being passed as a function prototype parameter. This attribute is
optional and if not specified defaults to false.

Includes child element


The <Includes> is an optional element that contains one or more <Include> child elements. Each
<Include> element contains a path to a JavaScript or .CSS file to be included with the page. For example,
the following:
<Includes>
<Include>$$assetpath/styles/sample.css</Include>
</Includes>

causes the sample.css file located in the styles directory in the form extension assets to be included in
the form. In the form, the $$assetpath tag is resolved, and the following HTML is generated:
<link rel="stylesheet" type="text/css"
href="ComposerExtensions/[ApplicationUUID]/SampleExtension/styles/sample.css" />

If the file is a JavaScript, like this:


<Includes>
<Include>$$assetpath/javascript/SampleCustomWidget.js</Include>
Copyright © 2015 Serena Software, Inc. All rights reserved.
</Includes>

the generated HTML will be:


<script language="Javascript" name="SampleCustomWidget.js"
src="ComposerExtensions/[ApplicationUUID/SampleExtension/javascript/SampleCustomWidget.
js"></script>

Implementation child element


The <Implementation> element contains the JavaScript code that implements the event, condition or
action. For conditions, this code must return a Boolean value. Return values for events and actions are
ignored. The implementation is typically escaped with <![CDATA[…]]> to simplify the code. See the
example and discussion section below for examples of how the implementation relates to the
prototype. The <Implementation> child element does not appear under the <Widget> element.

Widgets
Widgets defined in the definition.xml file inherit many of the properties of the events, conditions and
actions described above but also include additional elements as described below.

Attributes
The name, display, category and formType attributes for <Widget> elements are described above.

icon attribute
The icon attribute identifies the icon that will appear next to the Widget name in the form palette in
the “Custom Widget” section. It also appears in the form designer in the center of the widget. The
value should be the file name of the .ICO file in the widgetIcons directory in the form extensions
archive file.

Child elements of the Widget element

Prototype child element


The <Prototype> child element of the <Widget> element are defined as described above for Events,
Conditions and Actions. However, the child <Param> elements appear on the Parameters tab of the
widget’s property page, as inputs to the widget. They can be mapped using the Composer “{source}”
syntax like parameters to other widgets. In addition, if the <Param> element includes a restriction, the
corresponding choices will be available on the Parameters tab for the parameter.

GlobalImplementation child element


The <GlobalImplementation> element contains HTML and JavaScript code that appears once in the form
for each Widget type. For example, a widget typically references a JavaScript file that implements
widget functionality and that file would be included only once for each widget type. For example, the
following:

<GlobalImplementation>
<![CDATA[
<script type="text/javascript" src="$$assetpath/javascript/SampleCustomWidget.js">
</script>
<link rel="stylesheet" type="text/css" href="$$assetpath/styles/sample.css"/>
]]>
</GlobalImplementation>

Copyright © 2015 Serena Software, Inc. All rights reserved.


makes the slideshow.js JavaScript available on the form and loads the specified stylesheet. (Note that
this particular usage can also be achieved using the <GlobalIncludes> and <Includes> elements described
above.)

StaticImplementation child element


The <StaticImplementation> element contains HTML and JavaScript code that appears once in the form
for each Widget instance. This may include HTML describing the layout and structure of the widget as
well as JavaScript code that should only be executed once when the form is loaded. For example, the
following:
<StaticImplementation>
<![CDATA[
<div style="border: 1px solid black">
<h2 id="$$name.Text" class="CustomWidget"></h2>
</div>
<!-- Create the widget object instance when the form is loaded. -->
<script>
var g_$$name = new SampleCustomWidget("$$name", "$$assetpath");
</script>
]]>
</StaticImplementation>

defines some HTML elements and a JavaScript variable referencing a JavaScript object. Because we want
this variable created only once when the form is loaded, it is defined in this element.

DynamicImplementation child element


The <DynamicImplementation> element contains HTML and JavaScript code that appears once in the
form for each Widget instance. Unlike the code in the <StaticImplementation> element, this part of the
document is refreshed every time the widget is refreshed. It typically contains code that initializes the
widget, and will be added to the HTML DOM again (and hence executed) whenever the conditions
specified on the “Refresh” tab of the widget are met (e.g. on page load, on data change or on click.) For
example, the following:

<DynamicImplementation>
<![CDATA[
<script>
g_$$name.Initialize("$$0", "$$1");
</script>
]]>
</DynamicImplementation>

calls a method on the SampleCustomWidget object instance created in the StaticImplementation above,
passing in the current values of the two parameters to the widget.

Properties child element


Unlike the HTML/JavaScript widget, custom widgets can define properties that other field, controls and
widgets can use as inputs. For example, the Text property of a widget named ACustomWidget can be
referenced in the Refresh tab of an EditBox control using the syntax {ACustomWidget.Text}. The
<Properties> element under the <Widget> contains one or more <Property> child elements. The
<Property> element has a name attribute. The content is an expression used for accessing the property
it exposes. For example:

Copyright © 2015 Serena Software, Inc. All rights reserved.


<Property name="Text">
<![CDATA[
g_$$name.GetText()
]]>
</Property>

defines a property named Text. The content of that element is a call to the GetText() method on the
current instance of the object that implements the widget. Note that there is no ‘;’ in the expression as
it will be used in-line to obtain the value. You could also implement this by defining a method in the
StaticImplementation that took the widget instance name as a parameter, like GetText(widgetName).

When any of the properties you have defined change, controls that reference them may need to be
refreshed (the refresh tab, “On data change” option.) Because of this, the code that implements the
widget will need to raise a changed event when a property changes. The next section describes how to
do this.

Raising Property Changed Events


When a property of a custom widget is referenced by a control, field or widget on its refresh tab, and
the “On data change” refresh option is chosen, an event listener is automatically added that causes the
object to refresh when the referenced value changes. However, it is the responsibility of the custom
widget author to raise these events when the property changes. The JavaScriptAPI defines a
RaiseCustomChangedEvent() method to achieve this. When a property changes, to notify other controls
of the change, call this method with the name of the custom widget instance as the first parameter and
the name of the property as the second, like this:
RaiseCustomChangedEvent (_self._id, "Text");

In this example, _self._id is the name of the widget on the form and “Text” is the property name.

Substitution Values for Implementations


There are some values needed for addressing custom widgets and assets that are not available when
you are designing a form action or widget. Special substitution values represent these strings in the
definition.xml. These are:

$$assetpath: The relative path from the form HTML directory to the root directory of the
assets after they have been deployed to AE. This resolves to
ComposerExtensions/[ApplicationUUID]/[ExtensionName].
It is used for accessing images and HTML files and referencing JavaScript and
CSS files that are deployed with the assets. This applies to the content of the
following tags:

<Include>
<Implementation>
<GlobalImplementation>
<StaticImplementation>
<DynamicImplementation>

$$name: This is the name of instance of the current widget on the form (e.g.
“TopPageSlideshow” not “Slideshow”.) It applies only in the
Copyright © 2015 Serena Software, Inc. All rights reserved.
<StaticImplementation> and <DynamicImplemenation> elements under the
<Widget> element.

In addition to these tags, the existing $$0, $$1, etc. tags are important for creating widgets and form
actions that reference them. Form actions that reference instances of widgets need to be able to
address variables that manipulate them. The widget name is typically passed in as a parameter (with the
replace="True" attribute) and used to construct a variable corresponding to the widget instance. For
example, if the <StaticImplementation> of the widget created a variable as follows:
var g_$$name = new SampleCustomWidget("$$name", "$$assetpath");

the implementation of a form action that references it could use that variable as follows:
if(g_$$0) g_$$0.DoAction();

In the widget generation, the instance name is represented by $$name and the form action’s first
parameter is the widget name, so it can be used to generated the g_[widgetInstanceName] variable.

Copyright © 2015 Serena Software, Inc. All rights reserved.


Example and Discussion
See the Sample Form Extension created by selecting the “Add New -> Empty Form Extension” context
menu in SBM Composer for an example of how to implement a custom widget.

This section demonstrates and discusses the implementation of events, conditions and actions. Consider
the following defined action named ChangeBackColor:

When
ebText changes value
If
ebText equals ‘(Empty string)’
Then
set background color of ebText to (157, 218, 78)

This results in the following JavaScript being defined on the form:

event_InputControlChanged("ebText", fn_ChangeBackColor)

function fn_ChangeBackColor()
{
if(condition_ControlOperatorValue("ebText", "equals", ""))
{
action_ControlBackgroundColor("ebText", "rgb(34, 177, 76)");
}
}

In most cases, the parameters specified in the Form Actions dialog appear only in these statements, and
are passed to the functions corresponding to the implementations ( event_InputControlChanged(),
condition_ControlOperatorValue() and action_ControlBackgroundColor()). (The exception is when the
replace attribute is set to true in the <Prototype> element.)

When the form is loaded, the fn_ChangeBackColor() callback is registered for the ebText control using
the event_InputControlChanged() implementation function. When the control changed event occurs,
that function is called, causing the condition to be tested using the implementation of the condition
(condition_ControlOperatorValue()), and then the action is taken using the implementation of the action
(action_ControlBackgroundColor()).

The generated implementation code for these functions is:

function event_InputControlChanged(source, _actionName)


{
AddChangeCallback( source, _actionName );
}
function condition_ControlOperatorValue(source, operator, value)
{
return evaluateControlOperatorValue( source, operator, value );
}
function action_ControlBackgroundColor(source, value)
{
SetBackgroundColor( source, value );
}

Copyright © 2015 Serena Software, Inc. All rights reserved.


Note that these functions are parameterized, so once an <Event>, <Condition> or <Action> is used once,
other uses of it (for example, in other form actions) do not repeat the implementation, just call it with
different parameters.

The Event
The “When” portion of this statement corresponds to the following <Event> definition:
<Event name="event_InputControlChanged" category="ControlEvents" display=
"{InputControl} changes value" description="an input control changes value">
<Prototype>
<Param position="0" name="source" />
</Prototype>
<Implementation>
<![CDATA[
AddChangeCallback( source, _actionName );
]]>
</Implementation>
</Event>

The display attribute indicates that when displayed to the user in the Form Actions dialog, the
{InputControl} tag will be replaced by a link bringing up a menu containing all valid input controls on the
form. In the example, the user has selected the ‘ebText’ control for this value. The <Prototype> element
indicates that this value should be passed as the first (position 0) parameter to the AddChangeCallback()
function.

NOTE: As a special case for Event implementations, the keyword _actionName is used as a placeholder
for the name of the generated form action function. In this way, when the code is generated, the name
of the function to be registered in the callback is automatically used in place of this keyword.

The Condition
The “If” portion of this statement corresponds to the following <Condition> definition:
<Condition name="condition_ControlOperatorValue" category="ControlConditions"
display="{InputControl} [?] {?}" description="an input control [operator] a
value">
<Prototype>
<Param position="0" name="source" />
<Param position="1" name="operator" />
<Param position="2" name="value" />
</Prototype>
<Implementation>
<![CDATA[
return evaluateControlOperatorValue( source, operator, value );
]]>
</Implementation>
</Condition>

The display attribute contains three tags. In the Form Actions dialog, the first tag, {InputControl}, is
replaced by a link bringing up a menu containing all valid input controls on the form. The second tag, [?],
is replaced by a menu contain a restriction list determined by the type of the first parameter. (See the
section below on <Restrictions> for more details on how this is done. ) The third tag {?} is replaced by
link bringing up a value editor corresponding to the type of the first parameter. The values the user
specifies for these tags are used as parameters to the condition_ControlOperatorValue() function call
according to the <Param> elements in the <Prototype> element.

Copyright © 2015 Serena Software, Inc. All rights reserved.


The Action
The “Then” portion of the statement corresponds to the following <Action> definition:
<Action name="action_ControlBackgroundColor" category="ControlActions"
display="set background color of {Control} to {Color}"
description="set the background color of a control to a color">
<Prototype>
<Param position="0" name="source" />
<Param position="1" name="value" />
</Prototype>
<Implementation>
<![CDATA[
SetBackgroundColor( source, value );
]]>
</Implementation>
</Action>

The display attribute contains two tags {Control} and {Color}. In the Form Actions dialog, the first tag,
{Control}, is replaced by a link bringing up a menu containing all available controls on the form. The
second tag, {Color}, is replaced a link bringing up a color picker dialog. The values selected by the user
are used as parameters to the action_ControlBackgroundColor() function according to the <Param>
elements in the <Prototype> element.

Implementation
The Implementation element defines the javascript to be executed for the Event, Condition or Action.
The implementation should reference the prototype parameters either by name or by index via the $$#
notation if the parameter is marked as replace.

Example:

Consider the following Condition:


<Condition name="condition_TextFieldRegularExpression" category="FieldConditions"
display="{Field.Text} matches {RegularExpression}" description="a text field matches a
regular expression">
<Prototype>
<Param position="0" name="source" />
<Param position="1" name="pattern" replace="true" />
</Prototype>
<Implementation>
<![CDATA[
var fieldValue = GetFieldValue( source );
if ( fieldValue == null ) return false;

return fieldValue.match( $$1 );


]]>
</Implementation>
</Condition>

It defines two parameters, {Field.Text} and {RegularExpression}. When displayed in the dropdown list,
the description value (“a text field matches a regular expression”) will be used. When selected from the
list and displayed in the editor, the system will generate the display string “a text field matches a regular
expression” when the parameters are unbound (unless an Alias is specified for either parameter). When
bound, the field/control name or value will be used instead. E.g. “Title matches /^[2-9]\d{2}-\d{3}-
\d{4}$/i”.

Copyright © 2015 Serena Software, Inc. All rights reserved.


The parameter {Field.Text} will be passed to the implementation as a function parameter named
“source”. The {RegularExpression} parameter will be replaced inline in the implementation (in this case,
the name attribute is ignored). Therefore, given a regular expression value of “^[2-9]\d{2}-\d{3}-\d{4}$”
which is case insensitive, the generated function will look like:

function condition_TextFieldRegularExpression( source )


{
var fieldValue = GetFieldValue( source );
if ( fieldValue == null ) return false;

return fieldValue.match( /^[2-9]\d{2}-\d{3}-\d{4}$/i );


}

Copyright © 2015 Serena Software, Inc. All rights reserved.

You might also like