Custom Layout
See also: Containers, Layouts, Introduction to Styling, Styling Assistants, Controls, Velocity User Guide, Programming API
Use
of $FIELD_HEADER and $FIELD_TRAILER variables
A Custom Layout allows you to configure the HTML used to layout child controls. It is implemented as a Velocity template that contains a mixture of programming logic, static HTML and replaceable variables. These replaceable variables are substituted at runtime with dynamic content for an individual control. Here are some of the reasons you might use a Custom Layout:
To configure a Custom Layout, select Custom as the layout type for a container control such as a Panel Control, then click on Layout properties. The template editor is then displayed where you can configure the template and see the results in the preview panel. A default template is created the first time you do this – you can either amend this or create your own from scratch.
In general terms, the functions performed by all layouts in the Ebase Xi system are:
If you are creating a layout for general use – i.e. you don’t know in advance which child controls it will contain – then your layout should perform all these functions. The minimum template to accomplish this is shown here. But you might also create a template for use in one specific situation where you know precisely which child controls will exist. In this situation, it might not be necessary to check for hidden controls or messages as you know in advance that these will not exist.
A note of caution: if you decide to skip some of the tasks shown above that are normally performed by a layout, you might find that you get some unexpected behaviour e.g. messages are not written out because your layout is not checking for them.
Velocity programming statements begin with a # e.g. #if, #set, #foreach. Block statements such as #if and #foreach are terminated with #end e.g.
#if
(condition)
..
#else
..
#end
The foreach statement is used to iterate through a collection or array e.g.
#foreach ($var in $collection)
..
#end
The #set statement allows you to set up your own variables:
#set
(assignment)
e.g.
#set
($var1 = "Test")
#set
($var2 = 123)
#set
($var1 = $var2)
And ## represents a comment. See the Velocity User Guide for full syntax details.
All variables begin with $ and can be referred to as either $varname or ${varname}. Some of these variables have specific names which are recognised by Ebase and will be substituted with dynamic HTML content e.g. $LABEL represents a field label; click here for a complete list of these variables and the content which they generate. Any other variables are local variables and you are free to create as many of these as necessary.
Probably the most significant of these Ebase special variables is $ctrl which represents a control and is supplied in the following statement which will loop through all the child controls contained within the layout. Your template will almost certainly contain this statement.
#foreach(
$ctrl in $child_controls )
..
#end
$ctrl represents a single Control and this is the same Control object that is used by the programming API and it has the same attributes and methods e.g.
#if ( $ctrl.showing )
#if ( $ctrl.displayOnly )
If the control is a Field Control, you can address the related field like this:
#if ($ctrl.elementType == "Field Control")
#set ($field = $ctrl.field)
#end
This Field object is the same WebFormField object as used by the programming API and it has the same attributes and methods e.g. you can check it’s display type like this:
#if ($ctrl.field.displayType = "RADIO")
..
#end
You also have access to the entire programming API using the same names used in script programming preceded by a $ e.g. $system, $fields, $tables, $client, $controls etc. So for example, you could check if the end user is using a mobile device with:
#if ($client.mobile)
..
#end
You could also load a table from a database, call a web service and all the other things that the programming API supports. However, you should bear in mind that this template is being executed during the generation of an output page and therefore some functions of the API might not be applicable e.g. $form.callForm() should not be used.
Everything else in the template - i.e. not a Velocity programming statement or a $ variable – is treated as HTML content and will be written to the output page.
We’ll work through the following example explaining each bit as we go. Here is the complete template – this is very close to the default template created when you first select Custom layout:
<div>
##
Loop through all child controls
#foreach(
$ctrl in $child_controls )
## Write out any pending messages
#if ( $ctrl.messagesShowing )
$MESSAGES
#end
## Only write a control if it's not hidden
#if ( $ctrl.showing )
## For Field Controls, $LABEL, $EDITOR
and $HELP can be separately configured
#if ($ctrl.elementType
== "Field Control")
<div
class="form-fields">
$FIELD_HEADER
## Write out the field label – all
field types
<div class="field-label">$LABEL</div>
## For list fields, the list items can be separately configured using
$LIST_BUTTON and $LIST_LABEL
#if ($ctrl.editableRadioOrCheckboxList)
$LIST_HEADER
<ul
class="list-fields">
#foreach( $list_item in $list_items )
<li
class="list-items">$LIST_BUTTON $LIST_LABEL</li>
#end
</ul>
$LIST_TRAILER
#else
## Write out the field editor –
non-list fields
<div class="field-editor">$EDITOR</div>
#end
## Write out field help
<div class="field-help">$HELP</div>
$FIELD_TRAILER
</div>
#else
## Write all controls excluding Field
Controls
<div>$CONTROL</div>
#end
#end
#end
</div>
The first line contains <div> which acts as a container for the rest of the content, this is terminated with </div> on the last line of the template.
We then have the line..
#foreach(
$ctrl in $child_controls )
..which loops through all child controls setting variable $ctrl to point to each child control in turn. $child_controls is one of the Ebase variable names recognised by the system and this name should not be changed. The $ctrl variable represents an individual control – this is the same Control object used with Javascript programming and has all the same methods and attributes e.g. $ctrl.hidden, $ctrl.displayOnly can all be used.
The next section checks for and displays any error or warning messages for the control..
#if ( $ctrl.messagesShowing )
$MESSAGES
#end
..where $MESSAGES is an Ebase variable name that will be substituted with any messages that exist. The #if statement around $MESSAGES is optional as messages will only be displayed if they exist.
The next line checks if the control is visible..
#if ( $ctrl.showing )
..this checks that the control is not hidden and that none of its parents are hidden.
The next section checks for Field Controls as we are going to handle these separately. For each Field Control, the label, editor and help portions can be positioned and styled individually and this is done in this example using <div>s with classes form-fields, form-label etc. $LABEL, $EDITOR and $HELP are Ebase variable names and the system will replace these with the content for the appropriate part of the field. Note that the editor and label portions will be connected using “label for” syntax as part of the generated content.
The $FIELD_HEADER variable is optional, but if used it should be placed as the first thing after any wrapping HTML element – a <div> in this example- it generates an inline block div which is required for the correct operation of some Ebase features including using HTML Element Properties; click here for more detail on this. Similarly the $FIELD_TRAILER variable must be the last thing in this section before any wrapping HTML element is closed.
#if ($ctrl.elementType == "Field Control")
<div class="form-fields">
$FIELD_HEADER
<div
class="field-label">$LABEL</div>
<div
class="field-editor">$EDITOR</div>
<div
class="field-help">$HELP</div>
$FIELD_TRAILER
</div>
In this example template, the field editor portion is subdivided and fields that have lists that are rendered with radio buttons or checkboxes are treated separately..
#if ($ctrl.editableRadioOrCheckboxList)
$LIST_HEADER
<ul
class="list-fields">
#foreach( $list_item in $list_items )
<li
class="list-items">$LIST_BUTTON $LIST_LABEL</li>
#end
</ul>
$LIST_TRAILER
The first statement in this section..
#if ($ctrl.editableRadioOrCheckboxList)
..checks for a radio button or checkbox
list, and this will only be true if the control is not display only. The
$LIST_HEADER variable must appear next before any HTML content – it generates
an inline block div which is required for the correct operation of Ebase with
We then loop through all items in the list with statement:
#foreach( $list_item in $list_items )
..and each item is rendered with an <li> tag and the $LIST_BUTTON and $LIST_LABEL Ebase variable names are substituted with a button (a radio button or checkbox) and the list item text respectively.
The final section..
#else
<div>$CONTROL</div>
#end
..processes all controls other than Field Controls where $CONTROL is the Ebase variable name that will be substituted with the markup content for each control. This can be used for all controls including Field Controls if required.
The table below shows all the $ variable names that are recognised by Ebase within a Custom Layout Template, and also shows typical content that will be substituted. The How Styled column shows how to configure style using the Ebase page designer; you might choose to use this Ebase-supplied styling or alternatively configure your own in the template.
Variable Name |
Description and use |
Typical output |
How Styled |
||||||||
$child_controls |
Returns a list of all child controls in the order they appear on the page. |
None |
|
||||||||
$CONTROL |
Generates HTML content for the current control. Can only be used when inside a #foreach block iterating through controls such as: #foreach( $ctrl in $child_controls
) $CONTROL #end |
e.g. for a Button Control: <input
class=”CTID-4-_ eb-4-Button “
style=”cursor:pointer;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px”
type=”submit” name=”CTRL:4:_” value=”Click me” title=””> |
Styled using styling control assistants or classes applied with HTML Element properties. This is the same as with all other layouts. |
||||||||
$MESSAGES |
Generates HTML content to display error and warning messages for a control. Can only be used when inside a #foreach block iterating through controls such as: #foreach( $ctrl in $child_controls
) $MESSAGES #end If no messages exist, no output is generated. Can optionally be enclosed in a check of whether messages exist e.g. #if ( $ctrl.messagesShowing ) $MESSAGES #end |
<div class=”eb-CONTROL_MESSAGE eb-SCROLL-0 errorMessage
eb-0-errorMessage “>Please enter your social security number</div> This content is only generated if messages exist. |
Styled using the Message
options property for each control. This is the same as with all other
layouts. |
||||||||
$FIELD_HEADER |
Generates an inline block div which acts as a container for subsequent content. Use of this variable is optional, and if used any subsequent content must be terminated with $FIELD_TRAILER. If this variable is
omitted, some Ebase functionality for the Field
Control is lost, click here
for details. Can only be used when inside a #foreach block iterating through controls and when the current control is a Field Control: #foreach( $ctrl in $child_controls
) #if ($ctrl.elementType
== “Field Control”) $FIELD_HEADER $LABEL $EDITOR $FIELD_TRAILER #end #end |
<div class="CTID-4-_ eb-4-Field " style="display:inline-block;zoom:1;*display:inline;"> |
Styled using the Field
tab within the Field Control styling
assistant including classes and style applied using the Advanced Properties button. Classes
from the Root tab of HTML Element Properties can also be
used. |
||||||||
$FIELD_TRAILER |
Closes the inline block div created by variable $FIELD_HEADER. |
</div> |
n/a |
||||||||
$LABEL |
Generates HTML content for a field label. Can only be used when inside a #foreach block iterating through controls and when the current control is a Field Control: #foreach( $ctrl in $child_controls
) #if ($ctrl.elementType
== “Field Control”) $LABEL #end #end |
<div
class=”eb-3-Label “ style=”display:inline-block;zoom:1;*display:inline;”><label
for=”CTID-3-_-A”>First name</label></div> Note that the
generated output contains the “label for” syntax to link the label with the
corresponding field editor ($EDITOR). |
Styled using the Label
Cell tab within the Field Control
styling assistant including classes and style applied using the Advanced Properties button. Classes
from the Label tab of HTML Element Properties can also be
used. |
||||||||
$EDITOR |
Generates HTML content for a field editor, including the calendar icon for fields of type Date and any info pattern e.g. for fields of type DATETIME. Can only be used when inside a #foreach block iterating through controls and when the current control is a Field Control: #foreach( $ctrl in $child_controls
) #if ($ctrl.elementType
== “Field Control”) $LABEL $EDITOR #end #end |
Generated output varies depending on the field type. Here is an example of a simple text entry box: <div
class=”eb-3-Editor” style=”display:inline-block;zoom:1;*display:inline;”> <input id=”CTID-3-_-A” class=”CTID-3-_-A eb-3-EditorInput “ type=”text” name=”CTRL:3:_:A” size=”30” title=”First name”></div> |
Styled using the Editor Cell tab within the Field Control styling assistant including classes and style applied using the Advanced Properties button. Classes from the Editor tab of HTML Element Properties can also be used. |
||||||||
$HELP |
Generates HTML content for the help section of a field. Can only be used when inside a #foreach block iterating through controls and when the current control is a Field Control: #foreach( $ctrl in $child_controls
) #if ($ctrl.elementType
== “Field Control”) $LABEL $EDITOR <div>$HELP</div> #end #end The field
property Help text position is used
as follows with a Custom Layout:
|
<div
class=”eb-3-Info “ style=”display:inline-block;zoom:1;*display:inline;”>Random
help text</div> |
Styled using the Info
tab within the Field Control styling
assistant including classes and style applied using the Advanced Properties button. Classes
from the Info tab of HTML Element Properties can also be
used. |
||||||||
$list_items |
Used to loop through list items and can only be used when the current control is a Field Control, the field has a list, and the control is editable i.e. it’s not display only. $LIST_BUTTON and $LIST_LABEL can then be used to generate the output for each list item e.g. #foreach( $ctrl in $child_controls
) #if ($ctrl.elementType
== “Field Control”) #if ($ctrl.editableRadioOrCheckboxList) $LIST_HEADER <ul
class=”list-fields”> #foreach( $list_item in $list_items )
<li>$LIST_BUTTON $LIST_LABEL</li> #end </ul> $LIST_TRAILER #end #end #end |
None |
|
||||||||
Used to generate an inline block div which is required for
the correct operation of Ebase with |
<div class="CTID-4-_-A eb-4-EditorInput " style="display:inline-block;zoom:1;*display:inline;" validationinput="ICTRL:4:_:A"> |
Styled using the Editor
Cell tab within the Field Control
styling assistant including classes and style applied using the Advanced Properties button, Input Style. |
|||||||||
$LIST_BUTTON |
See $list_items |
<input
id=”CTID-4-_-A-4” class=”CTID-4-_-A-4 “ type=”radio” name=”CTRL:4:_:A”
value=”Mr” title=”Title”> |
No styling is applied from styling assistants - use $LIST_HEADER
or apply your own styling in the template. Classes from the Editor tab of HTML Element Properties are applied. |
||||||||
$LIST_LABEL |
See $list_items |
<label
for=”CTID-4-_-A-4”>Mr</label> Note that the generated output contains the “label for” syntax to link the label with the corresponding list button ($LIST_BUTTON). |
No styling is applied from styling assistants - use
$LIST_HEADER or apply your own styling in the template. Labels are placed inside
buttons and can be styled using classes applied to these buttons. |
||||||||
$LIST_TRAILER |
Closes the inline block div created by variable $LIST_HEADER. This variable must be positioned at the end of the editor section of a radio button or checkbox list. |
</div> |
n/a |
||||||||
$client $components $controls $fields $form $system $pages $tables |
These variables provide addressability to the Ebase script programming API. These variables will not be resolved in the designer environment, but will work at runtime. |
|
|
These two variables act as a pair to provide a container – an inline block div – around the content for a field. Use of these variables is optional, but omitting them means that the following will not function correctly:
The inclusion of this extra inline block div is required for this functionality to work, but from a page design perspective we want it to have no impact on the layout. To achieve this, it should normally be included inside another block element e.g. a <div>, <li>, <td> etc. Here’s an example:
<ul>
#foreach(
$ctrl in $child_controls )
#if ($ctrl.elementType
== “Field Control”)
<li> ## This <li> acts as a block container for the Field Control
$FIELD_HEADER ## This inline block div has no
impact on layout because it appears inside a block element - <li>
$LABEL
$EDITOR
$FIELD_TRAILER
</li>
#end
#end
</ul>
Syntax errors in Velocity programming statements are displayed in the preview panel at the top of the display. HTML errors are not checked for: probably the easiest way to check for these errors is to apply the layout to a control in a form, submit it, then use the browser tools to check for errors.
The minimum requirement for a template is shown below; this loops through all controls, displays any messages and shows all non-hidden controls. There is no specific processing for Field Controls or for field lists.
##
Loop through all child controls
#foreach( $ctrl in $child_controls
)
## Write out any pending messages
$MESSAGES
## Only write a control if it's not hidden
#if ( $ctrl.showing
)
$CONTROL
#end
#end
This template is equivalent to specifying no layout.