General Interface is an open source project hosted by the Dojo Foundation

Appendix B Control Statements

When authoring a template, you use a combination of HTML and control statements to help with conditional processing (for-each and if-else). You can use any HTML node such as span or div where noted below. Any node not listed by name in the table is assumed to be an HTML node that should be painted.
 

Control Statements 
Node Name Can be a Parent of Description
transform model | template | @xmlns | @xmlns:u | version The root node for the template. Declare as follows (the namespace declarations must be included, but are removed in some of the usage examples for readability):
<transform xmlns=
   "http://gi.tibco.com/transform/"
xmlns:u=
   "http://gi.tibco.com/transform/user"
version="1.0"></transform>

@xmlns [http://gi.tibco.com/]
transform/
This is the namespace declaration for the template. All element nodes within the template belong to this namespace.
@xmlns:u [http://gi.tibco.com/]
transform/user
Use to add custom attributes to a given HTML tag in your template without having the given attribute render to the view.
version 1.0 This is the template version. General Interface release 3.6 supports version 1.0.
model var | import Contains all locally declared variables (resolvers) used by the template when painting. It is unnecessary to declare this tag if you do not need any special formatting for your template.
var
[parent
::model]
#text | @id | @name | @type | @triggers | @defaultvalue Declares a variable resolver in the model. Although it is often easier to implicitly define resolvers by simply using them within the template, it is sometimes useful to explicitly declare them in the model in order to retain full control over how the given resolver is run. For example:
<transform>
  <model>
   <var id="mycolor"
     name="background-color"
     type="css"
     triggers="jsxcolor"
     defaultvalue="red">
     return this.jsxcolor;
    </var>
  </model>
  <template>
   <span style="
      background-color:
        {mycolor};">
   <text>whirled peas</text>
   </span>
  </template>
</transform>

@id #text This is the ID for the variable. It should be unique for the template. It should not begin with a $, because the system owns this prefix to identify its own variable resolvers.
var
[parent
::model]/
@name
#text The name attribute is used when the variable is rendered as final HTML. For css and box type variables, this is the CSS property name. For attributes and events, this is the attribute or event name. For example, this structure
<transform>
  <model>
   <var id="mycolor"
     name="background-color"
     type="css"
     triggers="jsxcolor"
     defaultvalue="red">
     return this.jsxcolor;
    </var>
  </model>
  <template>
   <span style="
      background-color:
        {mycolor};">
   <text>whirled peas
   </text></span>
  </template>
</transform>

generates this HTML:

<span style=
   " background-color:red;">
   whirled peas
</span>

var
[parent
::model]/
@type
box | attribute | event | css (default) The variable type lets the template engine know how a given variable should be projected into the view. For example, to add a src attribute to an img tag, declare its type as attribute:
<transform>
  <model>
   <var id="url" name="src"
     type="attribute"
     triggers="url">
     return this.url;
    </var>
  </model>
  <template>
   <img src="{url};"/>
  </template>
</transform>

The template engine also allows for implicit variable declarations by simply using a variable inline. For example, the following syntax is exactly equivalent to the explicit declaration above:

<transform>
  <template>
   <img src="{url};"/>
  </template>
</transform>

var
[parent::
model]/
@triggers
#text Template variables can implement a triggers field to let the template engine know which updates to the model should trigger changes in the view. For example, when updating the url property on a GUI object (this.url = 'x'), a controller function can call setProperty. This compound method first updates the model with the new value and then triggers an update to the view to ensure that the model and view remain synchronized.
function setURL(strURL) {
  this.setProperty("url", strURL);
}

Given the method call above, the following template would be triggered to update the url variable. The img tag would then be updated to reflect the new url value on-screen.

<transform>
  <model>
   <var id="url" name="src"
     type="attribute"
     triggers="url">
     return this.url;
    </var>
  </model>
  <template>
   <img src="{url};"/>
  </template>
</transform>

Note: The triggering system is many-to-many. A single template variable can implement multiple triggers and a single trigger can be applied to multiple variables. For example, in the following template both variables are updated when the url trigger is fired, because both implement the url trigger.

<transform>
  <model>
    <var id="url" name="src"
       type="attribute"
       triggers="url
       triggera tribbgerb">
         return this.url;</var>
    <var id="fullurl" name="path"
       type="attribute"
       triggers="url">
       return this.fullurl;</var>
  </model>
  <template>
<img src="{url};"
     path="{fullurl}"/>
  </transform> | </template>

var
[parent::
model]/
@defaultvalue
#text <<Is this fixed?>> The defaultvalue field is used to assign a variable default when its resolver function returns null. Therefore, the following two variable declarations are equivalent:
<var id="url" name="src"
     type="attribute">
     return this.url != null ?
     this.url : "abc.gif";
    </var>

or

<var id="url" name="src"
     type="attribute"
     defaultvlaue="abc.gif">
     return this.url;
    </var>

Default values can also be implicitly declared inline within the body of the template using a pipe character (|). Therefore, the following implicit declaration is equivalent to the two explicit declarations above:

<img src="{url|abc.gif}"/>

If no defaultvalue field is used and the resolver function returns null, it will result in the given property being removed from the object when painted, while an empty string results in an empty value. For example, a variable named 'src' that returns null (and with no defaultvalue field) would result in the following HTML:

<img/>

While an empty string would
be expressed as follows:

<img src=""/>


inlinebox
HTML | for-each | attach | var | drawspace | if | if-else | left | top | width | height | position | border | padding | margin | text | empty | attribute-group | style-group | @u:id  The inlinebox tag is an HTML span tag with a CSS display property appropriate to the target browser environment. Using this tag allows a GUI control to have layout (width and height) even if it is relatively positioned or flowed inline with text. This enables the control to be positioned either relatively or absolutely without having cross browser differences corrupt the layout. Use this tag instead of an HTML span if you anticipate needing to flow the object inline with other text while retaining its width and height.
import @resolver | @set | @library This allows for re-use of common resolvers and is used to import variable resolvers declared and used by other widget libraries and classes. . For example, the following statement imports the variable resolver named $color :
<import resolver="$color"/>

Variable resolvers can belong to a namespace. If you create a variable named "color" and the resolver belongs to the class my.Spinner, then another class can import the variable resolver by using the following declaration:

<import resolver="color"
   set="my.Spinner"/>

To import every resolver from another class, pass the name of the class as the library name:

<import library="my.Spinner"/>

System resolvers (those beginning with "$") do not need to be imported. This means that simply using a system resolver is the appropriate way to declare its import. For example, note how the url resolver must be explicitly imported from the class named my.Spinner, while the system resolver, $position, does not:

<transform>
  <model>
   <import resolver="color"
     set="my.Spinner"/>
  </model
  <template>
    <img src="{url};"
      style="position:
        {$position}"/>
  </template>
</transform>

template HTML | @onbeforeinit | @oninit | @onbeforepaint | @onpaint | @onbeforeresize | @onresize | @onbeforeresizechild | @dom | @recalc Contains the HTML template
@onbeforeinit text/javascript Called immediately before the template profile is created for a given GUI widget. The template profile is a list of variables that are merged with the template to render the final HTML.
@oninit text/javascript Called immediately after the templates profile is created
@onbeforepaint text/javascript Called immediately before paint. If this method returns an alternate string of text/HTML, the control will not attempt to paint and will instead use the provided string.
@onpaint text/javascript Called after the HTML has been painted and rendered by the browser. Called in a separate call stack from the paint method.
@onbeforeresize text/javascript Called immediately before a resize event. Return a Boolean false to cancel the resize for the control.
@onresize text/javascript Called immediately after a resize event. The object's dimensions will have been updated in both the model and view, but its descendant objects may not have been resized yet.
@onbeforeresize child text/javascript Called immediately before a child is resized. The method will be passed one parameter: a reference to the child about to be resized. Return a Boolean False to cancel the resize for the child.
@recalc true|false (default) Called immediately after the HTML has been painted and rendered by the browser, causing the resize engine to apply any dynamic position calculations to the painted control. Use this feature in your template if you declare any <var> elements within the <template> section that affect box properties like left, top, width, padding, border, etc.
@dom dynamic | static (default) Some templates result in different HTML output. For example, a template with if/else conditional statements, may create an on-screen DOM that differs each time it is rendered. In such a situation, specify that the HTML content is dynamic and therefore must be located using named IDs. In other words when the DOM is dynamic, then each HTML node in the template needs a corresponding unique ID, using the user namespace. For example:
<template dom ="dynamic">
  <span u:id="someid">
    <if-else>
      <if test="isInput()">
        <input u:id="myinput"
          value="{mytext}"
          type="text"/>
      </if>
      <else>
        <span u:id="myspan">
           <text>{mytext}
           </text></span>
      </else>
    </if-else>
  </span>
</template>

Note: If your template uses a for-each iterator, it must use a static DOM.

var
[ancestor::
template]
text/javascript | @id Declares a local variable within the body of the template. This allows a given variable to be dynamically updated during execution. For example:
<for-each select="this.getMyRows()">
  <var id="rowid">
    $$target.getAttribute(\'jsxid\')
  </var>
  <var id="rtext">
    $$target.getAttribute(\'jsxtext\')
  </var>
  <div id="{rowid}">
    <text>{rtext}</text>
  </div>
</for-each>

  var declarations in the body of the template execute differently than var declarations made within the model. This means that a variable that returns the color red would be declared like this, if declared within the model:

<transform>
  <model>
   <var id="abc">return "red"
   </var>
  </model>
  <template>
   <span><text>{abc}</text>
   </span>
  </template>
</transform>

  However, when declared within the template, a local variable declaration will not be stored as a global function, and therefore should not use a return statement:

<transform>
  <template>
    <var id="abc">"red"</var>
    <span>
      <text>{abc}</text>
    </span>
  </template>
</transform>

HTML HTML | for-each | attach | var | drawspace | if | if-else | left | top | width | height | position | border | padding | margin | text | empty | attribute-group | style-group | @u:id | @u:\protected Any valid HTML tag can be used in a template. All attributes on the tag will be rendered on the tag except for those belonging to the http://gi.tibco.com/transform/user namespace. <<What should this URL be changed to?>>
@u:\protected true Use on an HTML tag to denote that its dimensions should not be managed by the General Interface layout engine. The tag can still use the replacement variable engine, but its layouts will be unaffected. For example, the following template:
<input u:\protected="true"
   style="width:100%;height:100%;
   color:{mycolor};"/>

results in the following HTML when painted

<input style="width:100%;
   height:100%;color:red;"/>

However, if the u:\protected attribute had not been used, the layout engine would have replaced the percentages with absolute pixel values to reflect the dimensions allowed by the containing HTML tag. For example,:

<input style="width:80px;
   height:235px;color:red;"/>

left text/javascript Can be used to specify the left position of an HTML node. For example:
<span style=
    "position:absolute;">
  <left>$$parentwidth - 10
  </left>
</span>

  Note: The syntax above is not required, but can be used for greater control over layout, since it accepts any valid JavaScript statement. However, it generally more common to simply declare the style inline and have the system automatically handle the calculation. For example, note how the CSS accepts the calculated value, 100% - 10:

<span style="position:absolute;
   left:100%-10px;"></span>

Replacement variables can be used in both situations. Whether expanded:

<span style="position:absolute;">
  <left>{$left}</left>
</span>

or inline:

<span style="position:absolute;
   left:{$left};"></span>

  Two custom style properties are also provided for convenience when doing calculations: right and bottom. These simplify left and top declarations that use calculations. For example, the following two style declarations are equivalent:

<span style="position:absolute;
   *right:10px;*"></span>

or

<span style="position:absolute;
   *left:100%-10px;*"></span>

top text/javascript See the description for left.
width text/javascript See the description for left.
height text/javascript See the description for left.
position absolute | relative (default) Can be used to specify the relative/absolute position of an HTML node. For example:
<input style="color:blue;">
  <position>relative
  </position>
</input>

The template engine does not require the expanded syntax, but can be used for greater control over layout, since it accepts any valid JavaScript statement. However, it is generally more common to simply declare the style inline and have the system automatically handle the calculation. For example:

<input style="position:relative;
   color:blue"/>

Replacement variables can be used in both situations. Whether expanded:

<input style="color:blue;">
  <position>{$position}</position>
</input>

or inline:

<input style="position:{$position};
   color:blue;"/>

Unlike the calculated fields, left, top, width, and height, this field is treated as a string, assuming the value is either relative, absolute, or the value of a given replacement variable. Only relative and absolute are accepted as values by the layout engine; however, the variable replacement engine accepts any value. For example, note how the type attribute is declared as css (not box) and the specific node is specified as protected (u:\protected) :

<transform>
  <model>
   <var id="myposition" type="css"
     name="position">return "fixed";
   </var>
  </model>
  <template>
   <div u:\protected="true"
      style="position:{myposition};">
      <text>{abc}</text>
    </div>
  </template>
</transform>

empty true Use when a given node should render as an empty node. Note that img, br, and input nodes are automatically tagged and need not specify this value. For example:
<input type="text">
  <empty>true</empty>
</input>

will render as:

<input type="text"/>

attribute-group #text Use to inject a group of attributes (that is, src="a.gif" width="1") into an HTML node in the template. For example:
<img> <attribute-group>
   {myAttListVar}</attribute-group>
</img>
will render as:
<img src="a.gif" width="1"/>

style-group #text Similar to attribute-group. Use to inject a group of CSS styles (that is, color:blue;font-weight:bold;) into an HTML node in the template. Consider the expanded syntax:
<img>
  <style-group>{someVarWithStyles}
  </style-group>
</img>

And the inline syntax:

<img style="font-size:10px;
   style-group:{someVarWithStyles};"/>

This is how the tag renders:

<img style=" font-size:10px;
   color:blue;font-weight:bold ;"/>

border #text See the description for position. The value for this node is best expressed in the simplified General Interface notation, using the pattern, "style-width-color", as the four compass positions are defined for the border, beginning with north. For example:
<span>
  <border>solid 1px red;
     dashed 2px red;0px;
     solid 1px red;</border>
</span>

Note that when using a replacement variable for the border, it is easier to simply declare it inline:

<span style="border:{$border};">
</span>

Due to the way that the template engine parses styles, you should NOT specify complex border declarations or CSS border variants such as border-top and border-color inline, as in the following example:

<span style="border:0px;
   solid 1px gray;
   0px;0px;"/>

However, you can implicitly define a variable as a way to inline a complex style. Note that the pipe character ( |) is used to separate the named variable from its default value (the value to use if the given variable returns null). By wrapping the complex border declaration within a variable, the template engine will parse the values correctly. The variable name in such cases is unimportant and need only be unique among other variables declared in the template.

<span style="border:
   {myborder|0px;
   solid 1px gray;0px;0px;};">
</span>

padding #text See the descriptions for position and border. Also note that the value for this node is best expressed in the simplified General Interface notation, using implied pixel units. For example, to specify 8 pixel padding, use 8. To specify each side individually, use the four compass positions starting at north and moving clockwise. For example:
<span>
  <padding>8 2 2 8</padding>
</span>

Or inline:

<span style="padding:8 2 2 8;"
</span>

CSS syntax can be used inline, but it must use pixels and it must not use any padding variants such as padding-top and padding-left. For example:

<span style="padding:8px;">
</span>

margin #text See the description for padding.
tagname #text See the description for position. Use to dynamically replace the tagname for a given HTML node. For example, if a given node should render as a DIV or a SPAN, use the following to allow this property to be dynamic, using a replacement variable:
<span>
  <tagname>{$tagname}
  </tagname>
</span>

text #text Use to wrap any text content in your template. All text content must come first before any descendant nodes and must be wrapped in a single text tag. For example, this template structure:
<span>
  <text>Hello world</text>
</span>

renders as the following HTML:

<span>Hello world</span>

for-each HTML| var | for-each | drawspace | if | if-else | @select Use to add an iterator to the template. For example, assume the given template should output a table row for each CDF record in its cached XML document:
<table>
 <tbody>
  <for-each select=
    "this.getIterableRecords()">
   <var id="myid">
    $$target.getAttribute("jsxid")
   </var>
   <var id="mytext">
    $$target.getAttribute("jsxtext")
   </var>
   <tr id="{myid}>
    <td><text>
     {mytext}
    </text></td>
   </tr>
  </for-each>
 </tbody>
</table>

Note that the select statement must return an instance of jsx3.util.Iterator. For example, the getIterableRecords method (a controller method) can be expressed as follows:

widget.getIterableRecords =
  function() {
    var objCDF = this.getXML();
    return objCDF ?
      objCDF.selectNodeIterator
         ("//record") :
      (new jsx3.util.List()).
        iterator();
};

attach drawspace | @select Use to attach descendant content. Similar to a for-each iterator, the select statement expects an instance of jsx3.util.Iterator. The context variable, $$target is available within the attach tag, meaning any variable declaration can access the current item in the iterator by using it. For example:
<div>
  <attach select=
    "(new jsx3.util.List(
      this.getChildren())).
      iterator()">
    <drawspace top=
      "$$target.getChildIndex()*8"
    />
  </attach>
</div> 

drawspace @parentwidth | @parentheight | @left |@top | @width | @height | @position Use to modify the drawspace. A drawspace tag can either be a child of an attach tag (as a way to modify the default drawspace that would be sent to a given child). The drawspace tag can also be used. See attach and @left for usage examples.
continue   Use inside of a conditional tag (if/if-else) to skip execution of a given iteration. For example, the following skips a for-each iteration whenever the given target (a CDF record) does not implement a jsxid attribute.
<table>
 <tbody>
  <for-each select=
    "this.getIterableRecords()">
   <var id="myid">
    $$target.getAttribute("jsxid")
   </var>
   <if test=
     "jsx3.util.strEmpty(myid)">
    <continue/>
   </if>
   <var id="mytext">
     $$target.
     getAttribute("jsxtext")
   </var>
   <tr id="{myid}>
    <td>
     <text>{mytext}</text>
    </td>
   </tr>
  </for-each>
 </tbody>
</table>

break   Similar to continue, except that the entire loop is exited early, not just the iteration.
return   Similar to break and continue, except that the function is completely exited. Useful for intercepting normal processing of a template and exiting early for improved runtime performance. A local variable, MODE, defines the mode the template is being run in. This variable can be queried at any time to know which action is being invoked by the template engine:
paint, update, create,
dimension, and paintchild

For example, you can abort the update event for your template (assuming you know that there is no reason to continue resizing descendant objects):

<if test="MODE=='update'
     &amp;&amp;
     someCondition()">
  <return/>
</if>

if-else if | else Use to wrap a complex conditional (choice). For example:
<if-else>
  <if test="somevalue == 1">
    <span><text>a</text></span>
  </if>
  <if test="somevalue == 2">
    <span><text>b</text></span>
  </if>
  <else>
    <span><text>c</text></span>
  </else>
</if-else>

if HTML | break | continue | var | for-each | attach | drawspace | if | if-else | return | @test Use to wrap a simple condition. For example:
<if test="$$target==false">
  <break/>
</if>

else HTML | break | continue | var | for-each | attach | drawspace | if | if-else | return See the description for if-else.
@parentwidth text/javascript Sets the parentwidth on the drawspace. The value is calculated and accepts any valid JavaScript. For example, to tell all children that their allowed drawspace is exactly 100 pixels wide, use the following:
<div>
<attach select=
    "(new jsx3.util.List
       (this.getChildren()))
         .iterator()">
    <drawspace
      parentwidth="100"/>
  </attach>
</div>

@parentheight text/javascript See the description for @parentwidth.
@left text/javascript The attributes, left, top, width, height, border, margin, position, and padding, can be set on a drawspace node to force the next HTML node into a particular position, regardless of its setting. For example, the following SPAN will be placed at left position 12, even though it specifies that it render at position 10:
<div style="width:100%;
     height:100%;">
  <drawspace left="12"/>
  <span style="left:10px;">
  </span>
</div>

@top text/javascript See the description for @left.
@width text/javascript See the description for @left.
@height text/javascript See the description for @left.
@border text/javascript See the description for @left. In the following example, note how the border is wrapped in apostrophes, because it is a string:
<div>
  <attach select=
    "(new jsx3.util.List
    (this.getChildren()))
      .iterator()">
    <drawspace border=
      "'solid 1px gray'"/>
  </attach>
</div>

@margin text/javascript See the description for @left.
@position text/javascript See the description for @left.
@padding text/javascript See the description for @left.
@padding text/javascript See the description for @left.

Contents

Searching General Interface Docs

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.