Custom Layout

 

Documentation home

 

See also: Containers, Layouts, Introduction to Styling, Styling Assistants, Controls, Velocity User Guide, Programming API

 

Introduction. 1

Template Programming Basics 1

Worked Example. 3

Ebase variable names 5

Use of $FIELD_HEADER and $FIELD_TRAILER variables 9

Syntax Errors 9

Minimum Template. 9

 

Introduction

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:

 

  • Implement a specific combination of HTML/CSS which has been designed and standardized in your organization; this applies particularly to data entry forms
  • Layout all fields/buttons in an unordered list using <ul> and <li> tags
  • Layout fields in a tabular way using divs instead of tables
  • Apply specific layout depending on field types e.g.
    • Use an unordered list (<ul> and <li> tags) to display a radio button list
    • Display text areas with the label above the editor portion
  • Apply a specific one-off layout to a certain Repeater control

 

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:

 

  • Write out layout HTML to hold all child controls
  • Write out child controls that are not hidden
  • Write out messages for child controls where applicable

 

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.

Template Programming Basics

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.

 

Worked Example

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 Ajax enabled. Similarly the $LIST_TRAILER variable must be the last thing in this section. More information on this below.

 

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.

 

Ebase variable names

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:

 

None

No help text displayed

To right of editor

Help text is displayed at the location configured in the template

Underneath editor

Help text is displayed at the location configured in the template

As popup window

Help icon is displayed at the location configured in the template, when clicked the text is displayed in a popup window.

 

<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

 

$LIST_HEADER

Used to generate an inline block div which is required for the correct operation of Ebase with Ajax enabled. This variable must be positioned at the start of the editor section of a radio button or checkbox list, before any HTML content. Must be terminated with $LIST_TRAILER.

<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.

 

 

 

 

Use of $FIELD_HEADER and $FIELD_TRAILER variables

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:

 

  • HTML Element Properties configured on the Root of a Field Control
  • Styling applied using the Field tab of a Field Control’s styling assistant
  • The ability to select the Field Control in the designer WYSIWYG view and use the field as a target for drag and drop operations

 

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

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.

Minimum Template

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.