The Component Store contains over 40 ready-made components for use in Remote Forms and the JavaScript Client. The components are displayed under the JavaScript Components tab in the Component Store when a remote form is opened in design mode, while some are available under the JavaScript Native Components tab; the standard JS components and Native components are listed in this chapter in alphabetical order, starting with the Activity Control.
You can create your own custom JavaScript components, defined using JSON, which will appear under the JSON Components tab in the Component Store: these are described in the JSON Components chapter.
The JavaScript Apps Gallery on the Omnis website showcases many of the JavaScript Components and provides a sample app which you can download and run in the latest version of Omnis Studio. View the gallery here:
https://www.omnis.net/platform/#jsgallery
or you can use the shortcut: tinyurl.com/jsgallery10
Many of the example apps in the online gallery are featured in the example code in this chapter, and many of them also appear under the Samples section in the Hub in the Studio Browser, so refer to this for example code and apps.
In addition, the Applets option under the Hub in the Studio Browser has several sample web apps that use many of the JavaScript Components, including a Contacts app, a Holidays app, and a Webshop app which has a product catalog and a prototype shopping cart. You can examine the remote forms and components in these example apps, and look at the code behind each component: you can double-click on a JavaScript component in design mode to see its code methods in the method editor.
The following components are available for JavaScript remote forms under the “JavaScript Components” tab (group button) in the Component Store, plus there are a few “native” components under the “JavaScript Native Components” tab (List, Slider & Switch), also listed here.
Component | Description |
Activity Control | Animated image to display during a long process or Omnis Server activity |
Background Control | Object you can set to Rectangle, Line, Triangle, or Image |
BarChart Control | Displays a bar chart based on a list of values |
Button Control | Standard pushbutton which reacts to clicks |
Checkbox Control | Check box for on/off values |
ComboBox | Field combining entry box and droplist |
Complex Grid | Grid which can display all types of data and formatting |
Data Grid Control | Simple grid for text and numerical data display |
Date Picker Control | Data picker with touch selection |
Device Control | Allows access to hardware and services on mobile device |
Droplist Control | List that drops down when clicked |
Edit Control | Standard edit field for data entry or display |
File Control | Allows end users to upload or download files |
HTML Object | Object to display HTML content |
Hyperlink Control | List containing hyperlink style options |
Label Object | Basic label object |
List Control | Standard list field for displaying list variable data |
Map Control | Displays a Google map for specified location(s) |
Native List | List control with platform dependent appearance |
Native Slider | Slider control with platform dependent appearance |
Native Switch | Switch control with platform dependent appearance |
Navigation Bar Control | Navigation with touch selection |
Navigation Menu Object | Dropdown menu with hierarchical options |
Page Control | Allows selection of page pane using touch |
Paged Pane | Can contain fields on multiple panes |
Picture Control | Standard field for displaying images |
PieChart Control | Displays a pie chart based on a list of values |
Popup Menu Control | A menu that pops up when clicked |
Progress Bar Control | Shows progress of server process or calculation |
RadioGroup Control | Displays a group of radio buttons for exclusive selection |
Rich Text Editor Control | Rich text editor allowing end users to edit and format text |
Segmented Control | Navigation control with different buttons or “segments” |
Slider Control | Slider component for setting values |
Split Button Control | A button with a droplist of alternative options |
Subform | Allows you to display another remote form class as a subform in the main form (or you can create a subform set) |
Switch Control | Allows on/off selection; you specify an icon for on/off state |
Tab Control | Multiple tabs to control selection of page pane |
Timer Control | Timer object triggers an event at a specified interval |
Toolbar Control | Toolbar with custom buttons (icons and text), auto overflow and optional side menu |
TransButton Control | Interactive button with alternate hover image |
Tree List Control | List for displaying hierarchical data or list of options |
Video Control | Plays a YouTube or other hosted video |
The “JavaScript Native Components” group contains components that have a more familiar or “native” appearance when they are displayed on different mobile platforms – their appearance is rendered in the JavaScript Client using CSS customized for each platform. The different appearance for each platform is handled by Omnis automatically, therefore you only need to setup the component once in design mode. The Native components include the Native List, Native Slider, and Native Switch.
When running on a supported device, these controls will render and work in a manner close to a device’s native versions. For example, a Native Switch control will look like an iOS switch on an iOS device, an Android switch on an Android device, and so on, while using a single control and set of methods in design mode in your remote form.
JavaScript Remote forms have an Appearance property called $defaultappearance which determines both how a native control is displayed in the design window, and how it would render on non-supported clients (e.g. Desktop browsers). The property is either kAppearanceiOS or kAppearanceAndroid (kAppearanceBlackberry is no longer supported).
The $defaultappearance property can also be switched using the ‘Native Components Display As’ context menu option of a JavaScript Remote Form (right-click on the form to open the context menu). You can also cycle through the values using the keyboard shortcut Ctrl-Shift-N on Windows or Cmd-Shift-N on macOS when the remote form is the top window.
It is recommended that you set $disablesystemfocus property to kTrue for any native controls you have used, to prevent the focus ring being drawn around a controls when it is selected – otherwise the focus ring may interfere with the native appearance.
To create or add a JavaScript Component to a remote form, you need to open the remote form in design mode and open the Component Store: the latter should open automatically when you design a remote form, but you can open it, or bring it to the top, by pressing the CStore button on the main Omnis toolbar or by pressing the F3 key on Windows or Cmnd-3 on macOS. The JavaScript Components tab (group button) should be selected by default, showing the standard JavaScript Components, plus there are a few “native” controls under the JavaScript Native Components tab.
You can Right-click on the background of the Component Store and select Large/Small Icons and/or Text to alter the display of the Component Store, you can resize the window, and you can use the Save the window setup option from the context menu to save the layout and positioning of the Component Store.
Before adding any JavaScript components to your remote form, you may want to change the current Layout Breakpoint or add a new one. A new remote form has two breakpoints 320 and 768 pixels, and you are advised to add components to the larger breakpoint first and then rearrange or resize the components on the smaller breakpoint (the 768 breakpoint is selected by default). You can Right-click on the background of a remote form and choose Copy Layout From Breakpoint to copy the position and size of components from one breakpoint to the current breakpoint.
To create or add a new JavaScript component, you can:
Drag a component icon from the Component Store and drop it onto the remote form in the required position; in this case, the component is added at the default size
Double-click on a component icon in the Component Store; the component is added to the center of the remote form at the default size
Select a component icon in the Component Store and press Return to add the component (has the same effect as double-clicking)
Select a component icon in the Component Store, then in the remote form click and drag the cursor to draw the component the size you want; note some components have a standard size, or the size of some elements are fixed, e.g. the round button icon for radio buttons is a fixed size.
Once you have placed the component on the remote form you can resize or re-position it; if the form already contains other components, the Position Assistance feature will help you align the new component to the existing ones.
You can set the properties for the component using the Property Manager; if the Property Manager is hidden, press F6 on Windows or Cmnd-6 on macOS to open it or bring it to the top. The following screen shot shows the Pie Chart example app (available in the Hub under Samples), with the JavaScript Pie Chart component selected; the Property Manager on the right shows the properties of the currently selected object, under different tabs such as General or Appearance. See the JavaScript Component Properties for more details.
In design mode, you can use the standard Copy/Paste menu options in the Edit menu, or Ctrl-C and Ctrl-V keyboard options, to copy and paste a component on the same form. Alternatively, you can hold down the Ctrl key on Windows or the Alt/Option key on macOS, then click and drag a component to a new position on the form to make a copy of the component.
You can also drag a component from one remote form and drop it onto another remote form to make a copy of a component (for forms with the old kLayoutTypeScreen layout type, the forms must be set to the same value of $screensize to copy objects in this way).
All JavaScript components have their own set of properties which you can view and set in the Property Manager (F6).
The variable specified in the $dataname property of a JavaScript component must be an instance variable, or in some cases a column in a row instance variable in the form VarName.ColumnName. The Property Manager will display an error message if you try to assign an invalid $dataname property. (This applies to $dataname as well as other similar properties such as $listname which require a variable.)
When you create a component in your remote form, a name is generated automatically and assigned to the $name property of the component. This is usually in the format <remoteformname>_<component-type>_<number>, such as ‘rftest_edit_1001’ for an edit control on a remote form called rftest. However, you can enter your own name for a component which may better describe the object within the context of your form; for example, an edit field to allow the end user to enter their first name could be named Firstname. You can change $name of a component in the Property Manager.
The name you assign to an object does not have to conform to any convention other than any conventions you may like to use in your forms or the application to identify different objects. However, the name of a component (specifically, the value in $name) is used in the Omnis notation and throughout your library to refer to the object. Therefore, you should not use spaces and try to use alphanumeric characters only for object names to avoid any possible conflicts in your code. For example, an object name should not include the dollar sign ($) since this would cause a conflict when you reference the object using the Omnis notation which prefixes property and method names with the dollar sign.
The “floating edge” ($edgefloat) capabilities for JavaScript components allow the components to be resized automatically, when the end user resizes their web browser window or when the layout changes on a breakpoint. The $edgefloat property can be set to one of the kEF… constants which determines which edges of the component, if any, will “float” or resize when the browser window is resized. The possible values for $edgefloat are:
kEFall and kEFnone
All or no edges float
kEFbottom
Bottom edge only floats
kEFleftRight
Left and right edges float; in effect, the component floats to the right or left and does not resize
kEFleftRightBottom
Left, right and bottom edges float
kEFright and kEFrightBottom
Right edge only floats, or Right and bottom edges float
kEFtopBottom
Top and bottom edges float; in effect, the component floats up or down and does not resize
kEFrightTopBottom
Right, top and bottom edges float
kEFcenterLeftRight, kEFcenterTopBottom, kEFcenterAll
means the Left & Right edges float, or the Top & Bottom edges float, or All edges will float, and the control will also be centered horizontally and/or vertically within its parent
kEFposn… positioning constants
all edgefloat constants prefixed with kEFposn… will reposition the control in the specified region of the screen; as you select one of these constants in design mode the control will snap to the chosen region, and when the form is resized at runtime the control will “stick” to this region; the kEFposnClient constant stretches the control to fit the available area within its parent or subform
You can store a different setting of the $edgefloat property for each component, for each different layout breakpoint. When setting $edgefloat in the Property Manager in design mode, you can set the value of $edgefloat for a component on all breakpoints by holding the Control key when selecting the $edgefloat value.
The setting of $edgefloat for a component is used to resize the component (or not if set to kEFnone) when the form or container field is resized at runtime, and when one or more of the following occurs:
When the component is in a subform and the subform is resized (that is, its size at runtime is different to the size of the subform class)
When applying a different mobile device size while running in a mobile device custom wrapper
When the component is in a resizable subform in a subform set and the subform is resized
There are some kEF… contstants to control how objects are centered relative to the remote form or parent: kEFruntimeLeftRightCenter, kEFruntimeTopBottomCenter and kEFruntimeAllCenter. They are only applied at runtime, and in this case, their behavior is identical to kEFleftRight, kEFtopBottom or kEFall respectively, except that the offset is divided by two, to keep an object or a number of objects centered within the parent.
In addition, the Align context menu for the remote form editor contains options to allow you to center objects vertically, horizontally (or both) in their parent.
To understand what kind of edgefloat properties you can use, you can look at the PicsWebForm in the Pics2.lbs available in the tutorial download (or in the ‘welcome/tutorial/final’ folder); or you could create your own remote form using the form wizard. The PicsWebForm remote form was created using the SQL Remote Form wizard and uses edgefloat properties to control the floating edge behavior of the controls. The form has two layout breakpoints, 768 and 320, and the edgefloat properties is set differently for some of the controls on each breakpoint. The following image shows the layout for the 768 breakpoint, and the $edgefloat setting (a kEF.. constant) for each control is shown in red.
The PicsWebForm uses a Page pane containing all the data controls, e.g. Pic_Category, Pic_Name, etc; the $edgefloat property of the Page pane is set to kEFrightBottom to ensure it stretches across to the right and down as the form is resized in a browser window or is displayed on different sized tablet screens.
The $edgefloat property for most of the controls inside the page pane is set to kEFright, so the right edge “floats” or stretches to the right, but the bottom edge is not resized; the ID field has no floating edges so it keeps its size. The $edgefloat property for the push buttons on the right of the form is set to kEFleftRight (i.e. both left and right edges), which means the buttons will “float” from right to left horizontally, but they will not resize or move vertically. The combination of all these edgefloat settings on all of the controls, means that the push buttons keep to the right-hand edge of the browser window or device screen, while the data controls will resize to accommodate any screen or device size. Now examine the layout for the 320 breakpoint:
The push buttons on the 320 layout breakpoint are positioned at the top of the form and their $edgefloat property is set to kEFnone, so they will not move or resize as the form is resized. The $edgefloat property for the data controls is set to kEFright so their right edges will stretch to accommodate different phone sizes (widths), from 320 pixels upwards.
As the form is resized, on a web browser window or is displayed on a larger device screen, the controls will resize to fill the screen, until the next breakpoint is reached, which in this case is a screen or device width of 768 pixels, and the layout for that breakpoint is loaded.
End users can resize some JavaScript components dynamically at runtime in their web browser by dragging the border of the component. When the end user’s mouse is over the edge of a component that can be resized, the cursor changes to indicate that the border can be dragged and resized.
To allow this functionality, JavaScript components have the $dragborder property, which only applies when a component has its $edgefloat property set to one of the kEFposn… constants (other than kEFposnClient or kEFposnJoinHeaders). If $dragborder is set to true, and you have set $edgefloat as above, the end user will be able to resize the component in the browser by dragging the border of the component with the mouse.
You can store a different setting of the $dragborder property for each component, for each different layout breakpoint, therefore components on the same form could be resizable for web desktop browsers and not for mobile devices. When setting $dragborder in the Property Manager in design mode, you can set the value of $dragborder for all layout breakpoint values by holding the Control key when selecting the $dragborder value.
The appearance of the drag border area can be modified by editing the styles div.omnis-db-vert and div.omnis-db-horz in omnis.css.
You can set the formatting for Date and Time type data for some of the JavaScript components including Edit controls, Combo boxes, Data grids, Droplists, Hyperlink lists and standard Lists. These components have the properties:
$dateformatcustom
a date-time format string using the characters described below (e.g. D m y, the default); alternative formats can be provided separated by |. If $dateformat is kFormatCustom, and the data is of type 'Date Time', this property is used to format the data. If empty, it defaults to the format set using the client command 'setcustomformat'
$dateformat
the format used to display 'Date Time' data, a kJSFormat... constant as follows:
Format constant | Description |
kJSFormatNone | No format |
kJSFormatTime | Default time format for client locale |
kJSFormatShortDate | Default short date format for client locale |
kJSFormatShortDateTime | Default short date and time format for client locale |
kJSFormatMediumDate | Default medium date format for client locale |
kJSFormatMediumDateTime | Default medium date and time format for client locale |
kJSFormatLongDate | Default long date format for client locale |
kJSFormatLongDateTime | Default long date and time format for client locale |
kJSFormatFullDate | Default full date format for client locale |
kJSFormatFullDateTime | Default full date and time format for client locale |
kJSFormatCustom | Use the custom format in $dateformatcustom |
The following standard date formatting characters are supported for $dateformatcustom:
Format character | Description |
---|---|
D | Day (12) |
V | Day of week (Fri) |
w | Day of week (Friday) |
E | Day of year (1..366) |
n | Month (June) |
M | Month (06) |
m | Month (JUN) |
y | Year (1989) |
Y | Year (89) |
A | AM/PM |
H | Hour (0..23) |
h | Hour (1..12) |
Some additional characters are supported for Date/Time formatting for the JavaScript Client components only, as follows:
Format character | Description |
j | day with no leading zero (6) |
P | month with no leading zero (6) |
K | hour with no leading zero (0..23) |
k | hour with leading zero (1..12) |
a | am/pm |
O | timezone offset (+01:00) |
The date codes are listed on the Constants tab in the Catalog (F9) under “Date codes” (some are not JS client) and "Date codes (JavaScript Client only)".
When the client connects, the server sends it the date formats, day names and month names for the client locale (the server reads these from ICU). If you assign $ctask.$stringtablelocale in $construct of your remote task, the server sends the client the formats and so on for the assigned $stringtablelocale locale.
All JavaScript controls that can display number data have the property $numberformat, which specifies how Number and Integer data is formatted or displayed in the control. The JavaScript controls affected include the Edit Control, Combo box, Data grid, Droplist, Hyperlink list and standard List control. The formatting is used when the control displaying the data does not have the focus, that is, the formatting is only applied when the end user tabs or clicks away from the number field.
The $numberformat property uses a single % format tag for the number followed by one or more elements, for example, the number format %.2F displays a number with 2 decimal places with a thousand separator. The following elements are available (in this order):
An optional "+" sign that forces to precede the result with a plus or minus sign on numeric values. By default, only the "-" sign is used on negative numbers.
An optional padding specifier used for padding (if padding is required). Possible values are 0 or any other character preceded by a '. The default is to pad with spaces.
An optional "-" sign, that causes the string to left-align the result of this placeholder. The default is to right-align the result.
An optional number that says how many characters the result should have. If the value to be returned is shorter than this number, the result will be padded.
An optional precision modifier consisting of a "." (dot) followed by a number, specifies how many digits should be displayed for floating point numbers. When used on a string, it causes the result to be truncated.
A type specifier that can be any of the following:
Type specifier | Description |
% | display a literal "%" character |
b | display an integer as a binary number |
c | display an integer as the character with that ASCII value |
d | display an integer as a signed decimal number |
D | as above but include thousand separators |
e | display a float as scientific notation |
u | display an integer as an unsigned decimal number |
f | display a float as is |
F | as above but include thousand separators |
o | display an integer as an octal number |
s | display character(s) after the s specifier as a string, e.g. to display hours you could use %sh to display 5h |
x | display an integer as a hexadecimal number (lower-case) |
X | display an integer as a hexadecimal number (upper-case) |
Numbers will be displayed using the default decimal and thousand separators specified by the language set in the client’s browser, so you do not need to do anything to display the correct decimal and thousand separators for a client. However, you can override the default separators by changing the thouChar and dpChar items in the jOmnis client object: you can do this using JavaScript in the $init method for a JavaScript form, for example:
You can enable automatic scrolling for Edit controls, Lists, Tree lists, Hyperlink controls, Pictures and Html controls by enabling the $autoscroll property. If this property is kTrue for the control, and the client is not a mobile device, the client automatically displays scrollbar(s) when not all of the content in a field is visible.
Setting $autoscroll to kTrue changes $horzscroll and $vertscroll to kFalse, and in doing so means you cannot set $horzscroll and $vertscroll. By default, $autoscroll is enabled for Edit controls, Lists and Tree lists, while for Hyperlink controls, Pictures and HTML controls $autoscroll is set to kFalse.
Note that in addition to controlling scroll bars, Data Grids and Lists have the $vscroll and $hscroll properties which allow you to scroll a grid or list vertically or horizontally at runtime in the client browser: the numeric value of these properties is either column or row offset for grids, or the row number for lists.
The borders of JavaScript components are drawn within the bounds of the control, for both Windows and macOS, and have the same dimensions for both platforms. The color is controlled using $bordercolor.
Some components can have rounded borders by specifying the corner radius in pixels in the $borderradius property; for buttons this is $buttonborderradius (single value only). To set all the corners of the object to the same radius you can enter a single value, or to specify the radius for different corners you can use the syntax "n-n-n-n" which follows the same rules as CSS 3 rounded border syntax. The order for the radius parameters is top-left, top-right, bottom-right, bottom-left. If bottom-left is omitted the top-right value is used, if bottom-right is omitted the top-left value is used, if top-right is omitted the top-left value is used.
All JavaScript controls have a base class name to allow you to control the appearance of controls using CSS, to allow you to apply a consistent appearance for each type of JavaScript control. (Note that from Studio 10.2 onwards you can use JS Themes to manage the colors for controls on a remote form.)
The classnames listed below can be added to the ‘user.css’ and CSS properties applied to the classname to control the appearance of each type of control. Note these classnames are contained in the JavaScript controls by default and if they are added to the user.css are applied to the control automatically, that is, these classnames do not need to be included in the $cssclassname property of a control to be applied (this property is used to apply your own custom style names, see below).
JS Control | Class Name | Additional notes |
---|---|---|
‘Frame’ element for all controls | omnis-[control]-frame | |
Activity Control | omnis-activity | |
Background Control | omnis-background | |
BarChart Control | omnis-barchart | |
Button Control | omnis-button | |
Checkbox Control | omnis-checkbox | |
ComboBox Control | omnis-combo | The dropped list has “ctrl-drop-list” assigned. If ($cssclassname) the opened items list will be assigned the class of the first class in $cssclassname suffixed with ”-dropped-list” |
Complex Grid | omnis-complexgrid | omnis-complexgrid-header and omnis-complexgrid-hheader for header and horizontal header areas. Each row has omnis-complexgrid-row and either ‘odd’ or ‘even’ depending on their line number. If ($cssclassname) the header/hheader will have class $cssclassname+”-header” and “-hheader” |
Date Picker Control | omnis-date | |
Data Grid Control | omnis-datagrid | |
Droplist Control | omnis-droplist | The dropped list has “ctrl-drop-list” assigned. If ($cssclassname) the opened items list will be assigned the class of the first class in $cssclassname+”-dropped-list” |
Edit Control | omnis-input | |
File Control | omnis-file | |
HTML Object | omnis-html | |
Hyperlink Control | omnis-hyper | |
Label Object | omnis-label | |
List Control | omnis-list | |
Map Control | omnis-map | |
Menu - used for context menus, popup menus and tab menus | omnis-menu | omnis-menu-main for containing <div> omnis-menu-table for table <div> omnis-menu-row for row <div> omnis-menu-cellcheck for check or icon element in the menu omnis-menu-celltext for the text element omnis-menu-cellcascade for the cascading menu element Popup and tab menus will implement If ($cssclassname) the opened items list will be assigned the class of the first class in $cssclassname+”-opened-menu” |
Native List Control | omnis-nativelist | |
Native Slider Control | omnis-nativeslider | |
Native Switch Control | omnis-nativeswitch | |
Navigation Bar Control | omnis-navbar | |
Navigation Menu Object | omnis-navmenu | |
Page Control | omnis-pagectl | |
Paged Pane | omnis-pagedpane | |
Picture Control | omnis-picture | |
Popup Menu Control | omnis-popup | Also contains the classes from omnis-menu as it uses this object for the menu element of the control. |
PieChart Control | omnis-piechart | |
Progress Bar Control | omnis-progress | |
RadioGroup Control | omnis-radio | |
Rich Text Editor Control | omnis-rich | |
Segmented Control | omnis-segmented | |
Slider Control | omnis-slider | |
Subform | omnis-subform | |
Switch Control | omnis-switch | |
Tab Control | omnis-tabs | Also contains the classes from omnis-menu as it uses this object for the menu element of the control. |
TransButton Control | omnis-trans | omnis-trans-text To address text element of a trans button. |
Video Control | omnis-video |
For example, to add CSS styling to all the Edit controls in your remote forms you could add the following CSS to the user.css file in the ‘html/css’ folder in the main Omnis folder: in this case, the base classname .omnis-input is used with the properties 2px solid grey border and a 6px radius.
You can create your own CSS classes or styles (in addition to the base class names listed above) and apply them to the objects in your web and mobile apps, allowing you to have more control of the styling, coloring, and overall design of your apps.
All the JavaScript components have a property called $cssclassname which allows you to apply your own CSS class to the component. You can add the CSS classes to a file called ‘user.css’ which is located in the ‘html/css’ folder in the main Omnis Studio folder. A style can be applied to a control by setting its $cssclassname property to the name of a style. The properties you define for each style in user.css must be flagged as !important to override the JavaScript Client inline styles.
When you deploy your application on the Omnis App Server, you must put your custom ‘user.css’ file in the ‘html/css’ folder on the server.
It is possible to display form errors either to the right or under controls in a remote form. This makes it easier for end users to fill out forms in your web and mobile applications by providing them with helpful tips if they make a mistake in the form. The errors appear on the form as a text field either under a control, or to the right of a control, so you need to design your remote forms to allow space for the error text. The style of the error text and the outer HTML of the control containing the error are controlled in CSS which you can change if required.
All JavaScript Client controls have the $errortext property which contains the text to be displayed when there is an error in the field or control. The initial value of $errortext when a form is constructed is empty.
The $errortext property is only supported for subform controls when they are not scrollable, i.e. when $vertscroll & $horzscroll are both kFalse and the subform class is not responsive.
The $errortextpos property specifies the position of the error text set using $errortext. The value can be one of:
kJSErrorTextPosUnder
The error text is positioned under the control, the default.
kJSErrorTextPosRight
The error text is positioned to the right of the control.
kJSErrorTextPosHidden
hides the error text, so just the control outline indicates that there is an error (default is a red border). This might be useful where there is limited space to display the error text in the remote form, but you still want to show the end user that there was an error
Note that Omnis stores a separate value of $errortextpos for each screen size. As a shortcut when designing a form, you can hold the control key down when assigning $errortextpos, in order to assign the value to all screen sizes.
$errorline is a runtime property of the JavaScript Complex Grid control, used when assigning $errortext to an object in the row section of a complex grid. The line number to which $errortext will apply.
The client command “clearerrors” allows you to clear all error text messages for the form:
equivalent to assigning $errortext to empty for all controls on the form which have error text.
The following CSS classes control the appearance of the error text and border. These classes are stored in the omnis.css which you can edit if required.
div.om-error-text
This class styles the error text.
div.om-error-border
This class styles the outer div of a control which has error text.
The Field List provides a list of all the components on a remote form, including all those controls in container fields, and is often useful if you need to select a specific component which is partly obscured or hidden in the form, or is hidden deep inside the object hierarchy. To open the Field list, Right-click/Cmnd-click on the form or a component and select the Field List option.
The currently selected component is checked in the Field list, expanding the tree nodes and scrolling the list if necessary. Conversely, you can open the Field List and check a component name in the list to select it in the form. For example, in the following screenshot, the Order Now button has been checked in the Field List and the corresponding control is selected in the remote form, scolling the design screen if required to locate the control.
When the focus is in the Field List, you can use the arrow keys to navigate up and down the list and use Space bar to select a control, as required. The Shift-Space keypress allows you to select (or deselect) multiple, discontinuous controls in the list.
The Field list can be useful if you need to select the background of a form, for example to set its properties in the Property Manager, but the form is completely filled with components and no form background is available to click on, as can be the case for mobile forms. To select the form in this case, you can open the Field List and check the form name at the top of the list (which will deselect any components), or if you click on any individual component, then shift-click it to deselect it, the focus will be returned to the form background and its properties will be shown in the Property Manager.
Most of the JavaScript components report events which you can handle in a special method called an “event method” which is inserted behind the component. The event method for a component must be named $event. For example, when the end user clicks a button, an evClick is generated which you can trap in the $event method for the button; this method could contain code to display a message, call another method or determine some other action depending on the code in the event method itself. Most of the components contain a template $event method with a code stub for you to use as a starting point to handle the event.
To report an event, the event must be enabled for the component. Many of the components have their events enabled by default, but for some you may need to enable specific events in the $events property for the component.
To enable an event
Select the component and open the Property Manager (press F6)
Click on the $events property in the Property Manager to drop down the list of events for that component (the property will show “No Events” when no events are selected)
Check (enable) the events you wish to trigger for this component
You can select multiple objects of the same type and specify the events for all of the objects at the same time. For example, you can select a number of check boxes and enable the evClick event under the $events property to enable the event for all the selected check boxes.
If you double-click a component in design mode, the Method Editor will open displaying the method for that individual component. For components with events, the $event method will be shown automatically. For example, if you double-click on a button, the Method Editor will open displaying the $event method containing the code On evClick; you can add more code after this line to be run when the end user clicks the button. See the example code for each component for example $event methods.
For some components, the $event method may not contain any template code including the On event command, but you can add you own. You will need to enter the On command and select the appropriate event code (a constant beginning ev) from the Helper window in the Code Editor.
Omnis validates the event codes you have entered when adding or editing On event commands in the Code Editor. Therefore, Omnis will check to see if the event code is valid for the current object, and if not, it will flag it as an error.
If the event is not specified in the $events property, Omnis will add it to $events automatically when editing a method named $event in a non-inherited object (Omnis displays a temporary status bar message when it does this).
You can turn off this validation using the validateEventsForOnCommand entry in the methodEditor group of config.json; set it to false to turn off event method validation.
Most JavaScript fields or controls report the evBefore and evAfter events, which are triggered when the focus is about to enter or leave the control, respectively. Note that for edit controls, if the data does not change then an evAfter is not triggered as the focus leaves the control.
You can use the On event command to detect events in your event handling methods, and for most controls the $event method will contain a template event handling method into which you can add your own code. For example, in the $event method for an Edit control you could use the following commands to detect the evBefore or evAfter event.
Buttons and all the list type JavaScript controls report the evClick event, as well as evBefore and evAfter; and some list types also report the evDoubleClick event. For example, the Data Grid control reports evDoubleClick which you could detect and initiate a search based on the content of the grid line clicked on.
When an event is being executed in the JavaScript client, such as a click on a button, a transparent overlay is applied to the whole remote form, to prevent user interaction anywhere else in the form and to maintain the Omnis event ordering. If the user clicks on this overlay, the click will be prevented, although most events happen almost instantaneously so in this case the overlay is not displayed.
For evAfter events that show the overlay, Omnis shows a feedback effect at the point of the click when the overlay prevents the click, to make it clear to the user that their click was not registered. The feedback effect is a No Entry icon, with “bubble” animation, that appears and disappears directly after the user click. In this case, the click will be queued and will fire once the overlay is removed.
Unfortunately, Firefox does not treat the active state of elements in the same way as other browsers. As such, it was not possible to implement these changes for that browser.
All JavaScript controls report the evDragBorder which is triggered when the border is dragged – the event is reported to the control containin the border being dragged and any that share the border area being dragged. When it is triggered it could mean that the end user has resized the field (and therefore other fields in the same parent have resized) using the drag border.
Some of the JavaScript Controls, such as the Button control, allow you to add an icon to create a better appearance and UX for your apps. Such controls that support icons have the $iconid property which allows you to specify an icon image file to be used for the control. From Omnis Studio 10.2 onwards, you can use SVG image files for JavaScript component icons, as well as PNG image files, as supported in previous versions. You can use SVG image files in an icon set, alongside an existing icon set containing PNG files, and these will appear in the Select Icon dialog when you assign an icon to a JS component.
You can assign an icon to a JavaScript Component by setting its $iconid property in the Property Manager under the Appearance tab: when you click on the dropdown menu for the $iconid property the Select Icon dialog opens, allowing you to select an icon image from those available in Omnis.
When you first open the Select Icon dialog you should see the ‘material’ icon set from which you can select an icon; the 48x48 icon size may be selected under the Size list but you can select a different icon size, including 16x16 or 32x32. You can scroll the list of material icons to find an icon, or you can enter a search string into the Search box to filter the list; the following screen shows the 48x48 material icons and the search ‘add’.
You can add your own icons to the Select Icon dialog by adding your own icon set; see below. You should use scalable SVG icons for your web and mobile applications, which will be displayed correctly in high definition on phones, tablets and HD monitors. In most cases, you should add your own icon set, tailored to the unique functionality or style of your application, and for all new applications you are advised to use SVG images for icons.
You can use the icons in the ‘studio’ icon set but these are PNG image files and may not lend themselves to your application, so you are advised to source your own SVG icons.
IMPORTANT: You are advised not to use any icons listed under ‘Omnispic’, ‘Userpic’, ‘#ICONS’, or ‘IPHONECONTROLS’ since these only contain low definition or non-alpha image files and are only present for backwards compatibility with older applications.
SVG icon image files must be stored in an icon set, which is a sub-folder of the ‘iconsets’ folder in the main Omnis tree (do not use the ‘icons’ folder which contains legacy icon datafiles). Note that an icon set cannot be named ‘datafile’, ‘lib’, ‘studio’, or ‘studioide’ since those names are already in use and would cause a conflict.
In order to use any icons in an icon set, you need to add the icon set name to the $iconsets library preference, which is a list of icon sets for the library: note this preference was called $iconset in versions prior to Studio 10.2 and only allowed a single icon set to be used. Once you have added an icon set to $iconsets for a library, the icons will appear in the Select Icon dialog, prefixed SET.
Icons can potentially be stored in various locations in Omnis including the ‘studio’ icon set, as well as any icon sets you have added, plus the various icon data files used in older versions of Omnis: this may become an issue where duplicate icon names or IDs exist across the different locations, so Omnis employs a specific ‘icon search order’ that determines how icons are located and displayed. If an icon with the same name or ID is included in another folder, after an icon has been found, it is ignored in subsequent folders and an error is written to iconsetlog.txt. You should therefore avoid having the same icon names, IDs, or icon set names in multiple folders to avoid any potential confusion. Omnis looks in the following icon sets or datafiles in this order:
1. The icon set(s) specified in the $iconsets library preference, in the order listed in the property
2. #ICONS for the library, if used (would only be the case for older applications not using SVG or HD PNGs)
3. User icon datafiles (other than Omnispic and Userpic), if used; this is for legacy apps only
4. The ‘studio’ icon set, under the ‘iconsets’ folder
5. Omnispic or Userpic (.df1 files located in ‘icons’ folder), if used
When using a web server for deploying your web or mobile application, any icon sets used in your library must be placed in the ‘html/icons’ folder in the web server tree, even if they are in one of the other folders in the Omnis Server tree.
During SCAF generation (for the serverless client), the Omnis Server now passes all the files for all icon sets in $iconsets to the serverless client library.
SVG images are vector based and are inherently scalable, therefore a single SVG file can provide multiple sizes for icons: in practice, an SVG icon will scale to fit the icon area available in a control, such as a button (unless you fix its size, see below). By contrast, PNG images have a fixed size and therefore you have to create a separate image file for each icon size or resolution you wish to support and place all the separate files in an icon set in the Omnis tree. In addition, a single SVG image will have a much smaller file size than mulitple PNG files, giving your app a smaller footprint on the client.
On macOS, SVG icons only render in the thick client when using macOS 10.13 or later.
On Windows, SVG icons only render when using the Windows 10 Creators Update or later. In general, support for SVG in Windows is more limited than on macOS, for example, Windows does not support classes in SVG files – read here about Windows SVG support:
https://docs.microsoft.com/en-us/windows/win32/direct2d/svg-support
Google provides a large set of SVG icons in its Material design scheme, which are issued under the Apache License Version 2.0 (https://fonts.google.com/icons), and you are free to use these in your Omnis applications with the proper attribution in your product licensing.
We have selected over 100 of the Material icons (from the “black rounded” style) and placed them in an icon set folder called ‘material’ under the ‘html\icons’ folder in the Omnis tree. The material icon set will appear in the Select Icon dialog by default, and you are free to use these in your applications; the following screenshot shows some of the material icons, with the 16x16 size selected.
These material icons have been ‘themed’ using the Omnis Themer tool and therefore support JS Themes. You could download other icons from the Material website and add them to this folder, if required, and use the themer tool if you want them to support themes.
To use JS Themes, an SVG icon needs to be converted to a “themed” SVG file. Such themed icons only appear in the Select Icon dialog for JavaScript remote forms (and Remote Menus), but not for window class controls. The Material icons in the ‘material’ icon set, provided in the main Omnis iconsets folder, have been themed. See the Themed Icons section about how to theme icons.
If a JavaScript component can support SVG icons (and most do), then the icon names of any SVG icons will appear in the Select Icon dialog when you assign the icon via the Property Manager and the Select Icon dialog (if a component does not support SVG icons, then they are not shown in the Select Icon dialog).
In general, SVG icons are supported by any controls that previously required an icon, including the following classes or features:
Remote Form class components (JavaScript Client controls), including buttons, menus, toolbars, lists, tabs, check boxes
Styled text, including styled text on reports sent to the Omnis PDF report destination
The background icon for the main Omnis window on the Windows platform ($root.$prefs.$backgroundiconid)
The $componenticon class property
You should note the following for JS controls only:
Some JS controls use background-image CSS, so when using an SVG image, it will not always scale as expected if the aspect ratio in the SVG is fixed, and the desired dimensions of the background-image do not have the same aspect ratio.
JS Popup menu and JS Navmenu controls have hot iconid properties – in this case, the hot and equivalent non-hot iconid properties must either both use SVG or both use PNG
You can create your own SVG icons, or you may be able to acquire a set of icons from a third-party, either paid-for or for free (subject to the appropriate licensing). SVG image files must be saved with the .svg file extension (see naming below) and should be placed in an icon set in the ‘iconsets’ folder in the Omnis tree, and the icon set name needs to be added to the list of icon sets in the $iconsets preference in your library.
From our testing, we found that Adobe® Illustrator® allows you to export vector images in SVG format, and on the export to SVG options dialog you can select the ‘Inline Style’ option to ensure classes are not used in the output SVG. There are many other image editors that can output SVG.
The base icon ID of an SVG icon is the name of the SVG file, without the file extension, and converted to lower case, up to a maximum of 32 characters. The naming restrictions for SVG icons are as follows:
The base icon ID must not represent an integer (the icon ID had to be an integer for PNGs, but does not have to be for SVG image files)
The base icon ID must not contain the characters + # , ; = ? (plus, hash, comma, semicolon, equals, or question mark); note + is used to add a size restriction, see below
An icon ID or name can now be either an integer or a string, and integer icon IDs work exactly as they did before (the naming of PNG icon images remains the same).
You cannot use the same file name with different case in an icon set folder, plus it’s always good practice to make icon IDs or names unique across different icon sets, since the icon with the first instance of a specific icon ID or name is used.
Any errors related to the naming requirements are written to the icon set log file, which is in the folder logs/iconsets, in the data part of the Omnis tree.
If you want to include icons for different states of a control (for example, checked, highlighted, and checked highlighted for a check box control), you can include separate SVG files with a suffix in their name:
_c for checked
_h for highlighted
_ch for checked and highlighted
For example, SVG files for a check box could include the files: checkbox.svg (for the unchecked icon), checkbox_c.svg, checkbox_h.svg and checkbox_ch.svg (for the different states). These 4 files all result in a single icon with id ‘checkbox’, and Omnis will select the correct SVG file according to the state of the checkbox.
An SVG icon will always expand to fit the available space within a control, but it is possible to fix or restrict the size of an icon by adding size information to the end of the icon ID name. The size information has the syntax +<w>x<h> where <w> is the integer width and <h> is the integer height. For example, an SVG icon ID could be any of the following:
testsvg (unrestricted size)
testsvg+16x16 (restricted to 16x16, for example, for a menu)
testsvg+32x48 (restricted to 32 wide x 48 high)
When selecting an SVG icon, the size list includes the configured sizes from config.json, and the current size of the icon, in addition to the standard sizes and kDefSize. There is a + button in the heading of the size list that allows you add a new size. There is an option on the dialog to add the new size to config.json.
The ‘customSizes’ item in the ‘svg’ section of config.json allows you to add other sizes. The size list in the Select Icon dialog will show any other sizes specified in the config.json file:
When a custom size is selected in the size list for a full page SVG icon, in addition to the + button, there is a - button which you can use to remove the size from the list, and optionally remove it from config.json.
Omnis uses the default width and height specified in an SVG file to determine the aspect ratio of the icon image. To obtain this, Omnis looks for the width and height attributes of the svg element in the SVG file and uses these if present. If width and height are not present, Omnis uses the viewBox attribute of the svg element to determine the aspect ratio. In this case, you can add a size using the + button in the Select Icon dialog, and use the Keep Aspect Ratio option, to fix the aspect ratio.
Certain controls, such as the Icon Array, use a list column to contain an icon ID. To make use of SVG icons, this column needs to be defined as Character. Where you use a mixture of SVG icons and existing PNG icons, the icon IDs can be specified as strings or integers as appropriate.
You can control the cache size for all icon sets (using PNG and SVG icons) in config.json using the maxCachedIconSetBitmaps entry. This is an integer, which defaults to 1000 bitmaps. If Omnis needs to create a new bitmap for an icon from an icon set, and the current number of cached bitmaps is at this limit, Omnis will free up the least recently used bitmap.
When you set the $iconid of a JavaScript control you can also assign a URL. In server methods, if the value being assigned is a character value that contains a “/” character then Omnis treats it as a URL generated by the iconurl function (meaning that it can contain alternative icon files for the different client resolutions, and also that the server will pick the correct icon for the client resolution).
In client methods, if the value being assigned is not an Icon ID (a literal integer or integer + icon size constant) then Omnis treats the value as a URL generated by the iconurl function on the server, and the client picks the correct icon for its resolution.
You could generate the required URLs with iconurl() (see below) in the $construct() method of your remote form, and store them in an instance variable list which could then be used in client executed code to assign the correct image to each object.
For the JavaScript Tree control, the iconid column is an iconurl column, and the $iconurlprefix property is redundant although existing libraries that use $iconurlprefix will continue to work. Instead, the iconurl column should be defined to be of type character, and it should be populated using a server-only function, iconurl(iconid), which returns a URL string containing the name of the image file or a semi-colon separated list of file names if an icon exists in more than one resolution. This enables the client to pick the correct icon for its resolution.
You may want to use some existing icons located in an Icon Datafile and either add to or replace some of them with higher resolution versions. To enable you to export existing icons as separate files, there is a tool in the Tools>>Add Ons menu, called the ‘JS Icon Export’ tool, which is available in the ‘Web Client Tools’ dialog (scroll to the bottom of the list of Web Client tools). The ‘JS Icon Export’ tool will export all the icons in a selected Icon Datafile and place them in a folder in the ‘iconsets’ folder, applying the correct image file names. The $iconid property of a control will now reference the external image file in the icon set and not the icon datafile image, since Omnis looks in the iconset folder for the library before any icon datafiles. The Icon Export tool will only export icon images that support Alpha, i.e. the icon page containing the existing icon(s) must be set to Alpha.
Apache often redirects a URL with "/icons/" to the /usr/share/apache2/icons folder, and you would then need to place all the icons for your app in that folder. Therefore, if you deploy your web or mobile app to an Apache server, you may want to rename the ‘icons’ folder in Omnis by editing (adding) an entry in the Omnis configuration file (config.json). The "iconsFolder":"omnis_icons" configuration item in the server group of config.json defaults to "icons" if omitted or is empty, so you can change the name by adding your own value. You are recommended to use the same value for development and runtime, since the folder name is stored in the HTML for each remote form class.
From Studio 10.2 onwards, you are advised to use SVG images for component icons, although you can still use PNG images. In this case, you should create PNG image files that are 16x16, 32x32, or 48x48 pixels either at a standard pixel density suitable for displaying on standard monitors, or image files that are 1.5 and 2 times the size, suitable for displaying on phones and other HD devices. When your app is displayed on different devices and screen resolutions, Omnis will display the correct icon and resolution.
Each PNG image file within an icon set must conform to the following naming convention:
<text> is a string, i.e. the name of image, which must not contain underscore. This string is used in the icon picker dialog when you set an object’s $iconid in the Property Manager so it should describe the icon. Icon files that are the same image, but different resolutions should have exactly the same <text> name.
<id> is the positive integer id to be used as the icon id. It can be in the range 1 to 10000000. Icon files that are the same image, but different resolutions should have exactly the same <id>.
<size> is the CSS pixel size of the image, i.e. the resolution independent size of the image, meaning that for all resolutions of the same image this has the same value.
The value of <size> has the form <width>x<height>, where the values 16x16, 32x32 and 48x48 are special values since they correspond to the standard icon sizes supported by Omnis.
<resolution> is the factor by which the pixel density is greater than a standard monitor and is one of the following:
“_2x” for HD devices such as the Retina display
“_15x” for some devices e.g. certain Android phones that have a 1.5x pixel density.
an empty string is the default and is for standard resolution devices, equivalent to _1x
Any files (or folder names) that do not conform to the naming conventions are ignored.
Note that the image file names are case insensitive and they must be unique across all platforms and file systems (that is the case of file names is ignored).
If you are unsure about the file naming for PNG icons, you can examine the icons in the ‘iconsets/studioide’ folder.
You can use PNG images for check box and radio button icons, using the following naming:
<state> is the checked, highlighted, or normal state of the icon for multi-state icons and can be one of the following:
an empty string for the normal state of the icon
“c” is the checked state of the icon
“h” is the highlighted state of the icon
“x” is the checked highlighted state of the icon
You do not have to create an icon PNG image for all resolutions, although it would be advisable to do this for the best appearance. Omnis will use an icon image closest to the resolution being referenced, scaling as appropriate, and as with all image scaling it is better to force Omnis to scale an image down rather than scale it up. In this case, you may like to provide the highest possible resolution image for your icons and allow Omnis to scale the images down to display an icon for lower resolutions, but the scaling may produce unexpected results.
When the JavaScript Client connects, it sends its resolution to the Omnis App Server. This allows the server to use the appropriate icon when setting iconid properties in server methods.
You can create PNG images with a size other than the standard sizes (16x16, 32x32, 48x48) by creating the image at a non-standard size and including the image size in the file name when the file is saved. For example, you can create an image 100x200 pixels and name it something like “mygraphic_1688_100x200.png”, and you can create a high resolution version at 200x400 pixels and name it “mygraphic_1688_100x200_2x.png”. (This is the equivalent of an ‘Icon Page’ in older versions of Omnins.)
NOTE TO EXISTING USERS: The method of storing icons in #ICONS or an Icon data file (such as Omnispic) and assigning the numeric Icon ID ($iconid) to controls will continue to work, but this is only useful for icon images that are 16x16 pixel (or 32x32 for high def). In this case, if you run your application on an HD display and your library uses an icon data file or #ICONS, Omnis will try to use a 32x32 icon (if it exists and the icon page is marked as containing 32x32 icons), in place of the corresponding 16x16 icon. If a 32x32 image does not exist in your icon data file or #ICONS, the existing 16x16 image will be used which may have a very poor visual appearance on newer screens and devices. In order to support high definition 16x16 icons you will need to create a new version of each image at 32x32 pixels and import each one into the icon data file or #ICONS into the 32x32 section on the same icon page using the same icon IDs.
If you have used 32x32 or 48x48 pixel icons in your libraries (in #ICONS or an Icon data file), and you wish to display them on HD displays, then you will need to adopt the use of icon sets, which support icon images up to 96x96 pixels, that is, 2x the largest 48x48 icon size. Note that icons in an icon set will take precedence over icons in #ICONS, Omnispic or Userpic in the icon search order.
Drag and drop for the JavaScript Client provides the ability for end users to drag data from one JavaScript control in a remote form, and drop that data onto another JavaScript control. In addition, end users can drag files from their desktop and drop them onto a JavaScript control within a remote form displayed in their web browser.
IMPORTANT NOTE: Support for drag and drop in JavaScript remote forms is limited to desktop browsers only, including Chrome, Edge, Firefox, IE 11, and Safari – drag and drop is not supported in mobile browsers. Also note drag and drop only applies from one control to another control, or a file onto a control – you cannot drag data to or from a remote form.
To drag and drop some data, the end user can click and hold down the pointer over a JavaScript control on a remote form, then drag the highlighted control onto another control and release the pointer when the target control is highlighted. To enable drag and drop, you have to set various properties in the source and target JavaScript controls, and handle various events in each control as the drag and drop events occur.
Existing users should note that the event constants and their parameters work in a very similar manner to those for the drag and drop mechanism in the thick client, with the addition of the pDropId parameter which identifies the area of a control over which the drop is to occur (see under Events).
There is an example library demonstrating how you can drag and drop images between JavaScript controls, and the library allows image files to be dropped onto a control from the desktop. The example library is called Drag and Drop and is available in the Samples section in the Hub in the Studio Browser, in the JavaScript Component Gallery.
Dragging data is limited to certain data-bound JavaScript controls and is not possible for all types of JavaScript controls. JavaScript client controls that support dragging data will have the $dragmode property. This can be set to either kNoDragging or kDragData.
Note that the $dragiconid property used in the thick client is not supported for drag and drop in the JavaScript client, for a number of technical limitations in various browsers. The dragged image is typically an image of the dragged element created by the browser, using the content of the element when the drag starts – the client performs various temporary adjustments to the element to make the dragged image correspond to the dragged data as appropriate.
A drop can occur on any JavaScript control, but remotes forms do not accept drops. You can specify that a control can accept dropped data by setting its $dropmode property. When a control can accept some data, the JavaScript client highlights the destination control. For JavaScript client controls, $dropmode can be one of the following constants:
kAcceptControl
Data from a JavaScript client control can be dropped onto this control.
kAcceptFiles
Files dragged from the system (desktop) can be dropped onto this control; this would allow you to upload the file, for example, which is described in Dragging and Dropping Files
In addition, the list, tree list and data grid controls have the $hiliteline property, indicating that data can be dropped on a specific list line or tree node rather than the entire control. This also means that rather than highlighting the entire control, the client highlights the current destination line or node when a drop can occur.
When the end user is dragging data, they can scroll a destination control vertically by placing and holding the pointer near the bottom or top of the control. This is useful with long lists, grids or tree controls, when the $hiliteline property is enabled.
In order to process a drag and drop procedure, you have to handle some events in the $event method in the source and target controls. The drag and drop events must be enabled as required in the $events property for a control.
The client sends evDrag when the user attempts to start a drag. evDrag must be executed in a client-executed $event method, and it has the following event parameters:
Parameter | Description |
---|---|
pDragType | Always set to the value kDragData |
pDragValue | Described in the Drag Values section below. |
If you use Quit event handler (discard event) during evDrag, you prevent the drag from starting.
Since it is not always convenient to mark $event for a control as client-executed, the client provides an alternative mechanism. You can implement a client-executed method named $drag for the object, with two parameters (type Var): pDragType and pDragValue. $drag returns true if the drag is allowed, false if not.
The client first attempts to call $drag. If $drag exists and returns true or false, then the drag starts or is not allowed to start respectively. If $drag does not exist, or does not return a value, Omnis sends evDrag if it is selected to execute in $events, and if $event is client-executed.
The drag will only fail to start if $drag executed and returned false, or if evDrag was sent and discarded by Quit event handler.
Data grids, lists and tree controls may select a line or node when the drag starts. This will result in a click event being sent just before $drag is called or evDrag is sent. If the click is sent to the server, it will execute in parallel with evDrag or $drag.
The client sends evDragFinished when the user has finished a drag (released the pointer). It has no event-specific parameters. evDragFinished can be server or client executed.
The client sends evCanDrop when the pointer is over a control that can accept a drop of the current drag type (kDragData or kDragFiles). evCanDrop must be executed in a client-executed $event method, and it has the following event parameters:
Parameter | Description |
---|---|
pDragType | kDragData if data is being dragged from a control, or kDragFiles if a file or files are being dragged from the system |
pDragValue | Described in the Drag Values section below. Note that if pDragType is kDragFiles, this is empty during evCanDrop, since information about the files being dragged is not provided by the browser |
pDragField | If pDragType is kDragData, this contains the name of the field from which data is being dragged. If pDragType is kDragFiles, this is empty |
pDropId | The identifier of the area of the control over which the drop is to occur. Either a line number or ident (when $hiliteline is true), or zero if the control is not list-based (or $hiliteline is false). |
If you use Quit event handler (discard event) during evCanDrop, you prevent a drop on to the current control and pDropId combination.
Since it is not always convenient to mark $event as client-executed, the client provides an alternative mechanism. You can implement a client-executed method named $candrop for the object, with four parameters (type Var): pDragType, pDragValue, pDragField and pDropId. $candrop returns true if the drop is allowed, false if not.
The client first attempts to call $candrop. If $candrop exists and returns true or false, then the drop is allowed or not allowed respectively. If $candrop does not exist, or does not return a value, Omnis sends evCanDrop if it is selected to execute in $events, and if $event is client-executed.
The drop will only be denied if $candrop executed and returned false, or if evCanDrop was sent and discarded by Quit event handler.
The client sends evWillDrop when a drop occurs over a control and drop id combination for which which a drop is allowed according to the can drop processing. The client sends evWillDrop to the control being dragged - therefore, evWillDrop is not sent when dragging files from the system. evWillDrop can be server or client executed. It has the following event parameters:
Parameter | Desciption |
---|---|
pDragType | kDragData |
pDragValue | Described in the Drag Values section below. |
pDropField | The name of the control where the data is being dropped. |
pDropId | The identifier of the area of the control over which the drop is occurring. Either a line number or ident (when $hiliteline is true), or zero if the control is not list-based (or $hiliteline is false). |
Quit event handler with discard event has no effect on evWillDrop.
The client sends evDrop when a drop occurs over a control and drop id combination for which a drop is allowed according to the can drop processing. evDrop can be server or client executed. It has the following event parameters:
Parameter | Description |
---|---|
pDragType | kDragData if data is being dragged from a control, or kDragFiles if a file or files are being dragged from the system |
pDragValue | Described in the Drag Values section below. |
pDragField | If pDragType is kDragData, this contains the name of the field from which data is being dragged. if pDragType is kDragFiles, this is empty |
pDropId | The identifier of the area of the control over which the drop is occurring. Either a line number or ident (when $hiliteline is true), or zero if the control is not list-based (or $hiliteline is false). |
Quit event handler with discard event has no effect on evDrop.
The following $event method is behind an image control and processes the dropped data (this is available in the example library).
This section describes both the controls for which data can be dragged, and the drag values generated for each drag.
pDragValue is the selected text dragged from the current selection in the entry field component of the combo box. To drag text, you must click and hold the pointer somewhere in the selection before dragging.
pDragValue is a list. For a single select data grid, the list has one line, containing the list line being dragged. For a multiple select data grid, the list contains the selected lines being dragged.
pDragValue is the selected text dragged from the current selection in the entry field. To drag text, you must click and hold the pointer somewhere in the selection before dragging.
pDragValue is a list containing the list line being dragged.
pDragValue is a character string containing the URL of the picture being dragged. If the picture is populated using a variable and $mediatype, the URL is a data URL.
pDragValue is the selected text dragged from the current selection in the entry field component of the rich text control; note that this is the plain text without any formatting. To drag text, you must click and hold the pointer somewhere in the selection before dragging.
The tree only supports dragging when it is in dynamic mode (i.e. when $datamode has the value kKSTreeDynamicLoad). pDragValue is a row containing information about the node being dragged. The row has 3 columns:
Column | Description |
---|---|
ident | The ident of the node |
tag | The tag of the node (a character string) |
text | The node text |
If the $hiliteline property is kTrue for a tree control, and the dropmode indicates that the tree is a potential drop target, the client will expand a node when the pointer enters it while dragging.
The tab control contains some special logic that allows you to switch tabs while dragging, if this is the functionality you require. For can drop, it sets pDropId to the tab number of the tab under the pointer (or it sets pDropId to the current tab number if the pointer is over an area of the control which is not a tab). To switch tabs, implement a client-executed $candrop method for the tab control which executes:
In addition to dragging and dropping data from one control to another, end users can drag files from their desktop and drop them onto a JavaScript control in a remote form in their browser. There are two client commands that allow you to process dropped files, using the $clientcommand method.
The client records file idents (and their JavaScript File objects) in a table. Use closefile to remove the table entry and release resources. You should really do this for every ident passed in the drag value to evDrop, unless you use readfile which removes the table entry after reading the file.
The row passed to the “closefile” $clientcommand has a single column, which is the ident of the file to remove from the table. If you pass a row where the ident is zero, the client removes all entries from the table.
The readfile client command allows you to read the contents of a file identified by its ident. After attempting to read the file, the client removes the ident from the table, so a call to closefile is not required.
The row passed to readfile has the following structure:
The columns are as follows:
Column | Description |
---|---|
ident | The ident of the file |
instance variable name | The name of an instance variable in the form used to call $clientcommand, that will receive the contents of the file. Note that this is a character string containing the instance variable name, not the instance variable itself |
base64 | A Boolean. If true, the file is read as base64; otherwise the file is read as text |
The JavaScript FileReader which the client uses to read the file operates asynchronously, so a call to readfile starts the file reading process. When the file read is complete, the client calls the client-executed method $filereadcomplete in the form used to call $clientcommand. $filereadcomplete has two parameters:
Parameter | Description |
---|---|
ident | The ident of the file. |
error text | Empty if the file was read successfully, meaning that the named instance variable has been populated with the file contents (either as text or base64-encoded text). If not empty, some text describing why the file read failed |
For file dragging, pDragValue is only populated for evDrop. It is a list of the files dragged from the system, with columns defined as follows:
Column | Description |
---|---|
name | The file name. Note this is just a name, not the path to the file |
type | The MIME type of the file if this was determined by the browser before passing it to the drop event |
size | The size of the file in bytes |
ident | An integer, unique in the context of the client, that identifies this dropped file. You can use this with the client commands described in the later section about processing files. |
evCanDrop, evWillDrop and evDrop for the thick client have the pDropId parameter. This is significant when $hiliteline for the control is true, and contains the id of the location in the control where the drop would occur or is occurring, e.g. the list line for a list.
This release contains several enhancements to support the Web Content Accessibility Guidelines (WCAG 2.0) which will help to make your applications more accessible, primarily for people with disabilities. These guidelines have been adopted by many government agencies and guarantee an acceptable level of access to information and services via websites and applications for people with disabilities. You can read the following pages to gain a basic understanding of the WCAG requirements:
https://www.w3.org/WAI/standards-guidelines/
The WCAG implementation in Omnis Studio calls on the ARIA specification, which according to W3.org is “Accessible Rich Internet Applications (ARIA) defines a way to make Web content and Web applications more accessible to people with disabilities. It especially helps with dynamic content and advanced user interface controls developed with [various web technologies],” which includes technologies such as the JavaScript Client in Omnis Studio.
In practice, this means we have added various ARIA compliant properties to the controls for JavaScript remote forms which you can use in your web and mobile apps to support end users with disabilities. These properties will be read automatically when the screen reader capabilities are enabled in the end user’s browser or mobile device. (For testing, we have used ChromeVox by Google, but there are many other screen readers for Chrome and other browsers.)
Most JavaScript controls have a set of basic ARIA and other accessibility properties which are interpreted by the screen reader in the browser. The ARIA properties in Omnis map closely to their equivalent ARIA attributes in HTML.
Several of the JavaScript controls have the following ARIA properties, while some other controls have additional properties (listed below). These properties are designed to work in a similar way as their equivalent ARIA attributes in HTML.
$arialabel
the text for the aria label, which is used when a text label is not visible on the form. If there is a label for the control, use the $arialabelledby property instead
$arialabelledby
the name of a control to act as a label for this control; for example, you could enter the name of a label object to link it to the control. A value in $arialabelledby will override the value in $arialabel; you can use a space separated list of controls to assign multiple controls as labels for the component
$ariadescribedby
the name of a control used to describe this control: similar to $arialabelledby, but could be used to provide more information or a longer description about the control; you can use a space separated list of controls to assign multiple controls as labels
You should note that JavaScript controls now have an $active property which works alongside $enabled allowing you to make controls active, inactive, enabled, or disabled, which helps you control accessibility and tab order in your remote forms.
You can assign an Alt text value to image-based controls, such as Picture and Activity, using the $alttext property:
$alttext
a short text to describe the appearance or function of an image, and equivalent to the “alt” attribute in HTML; this property is relevant for controls that contain an image or have a significant visual appearance, such as the Picture and Activity controls.
So-called “Landmark Roles” in standard accessibility guidelines allow you to identify different areas of a form to allow screen readers to describe the structure of the page to end users. You can define Landmarks in your JS remote forms using Page panes and by assigning the appropriate value to the $landmark property for each pane: the options for $landmark correspond to the same keywords used for landmarks in the accessibility guidelines (Main, Navigation, Banner).
$landmark
specifies a role to make the page pane an ARIA landmark region, a kLandmark… constant with kLandmarkNone as the default.
The Landmark options are:
Landmark option | Description |
---|---|
kLandmarkMain | A “Main” landmark which identifies the primary content of the remote form |
kLandmarkNavigation | A “Navigation” landmark which identifies an area containing navigation type control or list of links used for navigation |
kLandmarkBanner | A “Banner” landmark which identifies an area usually at the top of the form, possibly containing logo, company or application name and search box |
kLandmarkContentinfo | A “Contentinfo” landmark which typically identifies common information at the bottom of a form |
kLandmarkComplementary | A “Complementary” landmark which many contain supplementary information or further links, such as a sidebar |
kLandmarkForm | A “Form” landmark which identifies an area containing a number of input controls or other form controls |
kLandmarkSearch | A “Search” landmark which typically would contain a Search field and button |
kLandmarkNone | No landmark definition |
You can link a Label control to a specific Edit control, or you can tag a label as one of the HTML header types, using the following properties:
$labelfor
links a label to a control. If you use this with some controls such as the Edit control, the linked control will get the focus if the label is clicked. It can be used in addition to $arialabelledby.
$tagtype
can be used to set a label’s HTML tag type to one of the header types (<h1> etc.) which would allow the end user to navigate to different sections of a form: the default value is kJSLabelTypeLabel, which is a standard untagged label, and the other values include H1 to H6 for the header types.
If a control has some text assigned (e.g. a button), the screen reader will read out the text by default, therefore it is not always necessary to assign the ARIA properties to describe such controls. For example, the text for a Button control will be read by the screen reader, if no ARIA properties are specified, however the value in $text will be overridden if you specify $arialabel or $arialabelledby.
The Edit control has the $::contenttip property which is a text string which is displayed in the edit field when it is empty and before the end user has entered any text. This can be used in addition to the ARIA label properties, to help label the edit controls on your forms: note it is good practice to add labels to all the edit controls on your form to help with accessibility, so do not rely solely on content tips to describe edit controls.
As well as the ARIA properties, the behavior when using various keys to navigate a remote form, or inside more complex controls, has been improved. For example, when the end user presses the Tab key, the focus will jump from one control to another in a remote (web) form, or for complex items such as a Tab bar, the Tab key will put the focus inside the control and the arrow keys can be used to move from one element to another. In addition, the Arrow keys can be used to interact with controls, such as dropdown menus, while Enter and Spacebar can be used to select options or items. The Page Up/Down keys can be used to scroll a form or long list which has the focus.
The following table summarizes what keys end users can use in which JS remote form controls:
Key | Action | Applies to which controls |
---|---|---|
Tab | Tab to next field (previous with Shift + Tab) | All controls. More complex controls such as datagrid and complex grid will tab to the next field within the control while editing |
Arrow Keys | Move within list a control | List based controls such as List, Droplist, Combo box, Datagrid and Datepickers |
Page Up Page Down |
Move by multiple lines up or down | List based controls such as List, Droplist, Combo box, Datagrid, Complex Grid |
Home End |
Move to the start or end of a list | List based controls. Complex grid requires Ctrl to be pressed |
Ctrl + [ Ctrl + ] |
Move to next/previous in more complex controls | Complex grid: move to next/previous line Subform sets: move to next/previous subform in set |
The $order property determines the tabbing order for the controls within a remote form. The value of $order for each control is assigned automatically as you add controls to a form in design mode, starting at 1 and increasing by 1 for each control (note the $order values do not change if you move or rearrange the controls on the form). You can change the $order value of a control to change its tab order: when you change the value of one control, the $order value of other controls on the form will be adjusted in sequence automatically.
When you tab into a container, such as a page pane, the tab order takes you through all of the fields in the container, before tabbing out of the container.
The $startfield property specifies which field in a remote form will get the focus when the form is opened, overriding the control with its $order property set to 1; $startfield takes the field number as specified in the $order property of the control. Note this property may have an impact on accessibility, insofar as the field specified in $startfield may not be the first field on the form, thereby going against most accessibility practice.
All JS components have a $taborder read-only property in design mode which shows the resolved tab order within the form, taking into account container fields, such as paged panes. The context menu on a remote form has a "Show $taborder" option, so that you can see the value of $taborder for all controls on the form. You can still alter the tab order of the controls in a form by modifying $order for each control.
All JS components have a property $nexttabobject which allows you to override the default tab order set by the $order property for all the controls in a remote form. The $nexttabobject property allows you to specify the name ($name) of the control you want the end user to tab to after the current object, overriding the tab order set by $order. You should not overuse this property, as it does incur some overhead by setting up additional event listeners.
For increased accessibility in your applications, you should carefully consider the tab order of the controls in your forms. In general, it is good practice to make the tab order run consecutively, that is, from one control to the next in a logical order: this could be from left to right starting at the top of the form, but the exact order may depend on the specific functions of your app. The tabbing order of the controls in the form is also used by the screen reader to “read out” or describe the contents of the form, so it’s important how you specify the tabbing order of the fields in your form.
With the ARIA labels specified and the correct tabbing order defined, the end user can navigate the controls on a form from the keyboard, and, in addition, the screen reader can describe each control or area of the form page in turn.
Consider the following JavaScript remote form. In the first image, as the end user tabs to the First Name edit field, the field border will highlight, the screen reader will say aloud: “First name, Edit text”, and if there is a value in the field, as in this case, it will read that as well: “First name, Peter, Edit text”.
Using the Tab key, the end user can move from one control or area of the form to another. Successive tab presses will enter the Tab bar at the top of the form, then the Right and Left Arrow keys can be used to move along the Tab bar, and the Return key can be used to select a tab. Once the tab is selected, the screen reader will describe the item selected: “Careers / Education Experience, Tab selected, 2 of 4”.
You can apply a consistent set of colors to JavaScript components on a remote form by selecting colors defined in a theme – underlying a theme is a set of CSS styles which are applied to controls at runtime on the client. Omnis has a number themes which you can use to style your JS client applications: a default theme, which provides an effective and pleasing UI across all JS controls and devices, and a range of different color themes, such as the dark theme, which provides an alternative set of darker colors.
When designing a remote form, you can change the current theme in the JS Theme Select dialog by pressing Ctrl-J/Cmnd-J, or select the JavaScript Theme option from the View menu (you can edit a theme from here by Right-clicking on a theme or background of the dialog and selecting the Open JavaScript Theme Editor option). To select a theme, click on the theme preview and close the dialog. The selected theme is applied to the current remote form and to all the remote forms in your library since the theme is an Omnis-wide preference.
The current theme is stored in the Omnis root preference, $javascripttheme (in $root.$prefs), which is set to the default theme initially, and controls which theme is used to render themed colors for all remote forms in design mode (but you can set or change the theme on the client using the ‘settheme’ client command; see later).
When you select the color for a JS control in design mode in the Property Manager, you can choose a theme color from the color picker, under the Theme color button (the default) in the color picker toolbar. For example, select a button, click on the Text tab in the Property Manager and click on the color picker for $textcolor.
The color setting for most properties, such as $textcolor, is set to kColorDefault, which means the appropriate color from the current theme is used. If a text color property is set to kColorDefault, and it sits on an element with a background color which comes from a themed color constant, the text will be rendered in the associated <theme color>Text color. For example, if a button’s $buttoncolor is set to kJSThemeColorPrimary and its $textcolor is set to kColorDefault, the text will be rendered using kJSThemeColorPrimaryText.
The colors defined in a theme and shown on the color picker have corresponding color constants, whose names begin kJSThemeColor, as follows:
kJSThemeColorBackground | kJSThemeColorPrimary |
kJSThemeColorBackgroundText | kJSThemeColorPrimaryDark |
kJSThemeColorBorder | kJSThemeColorPrimaryDarkText |
kJSThemeColorDialog | kJSThemeColorPrimaryLight |
kJSThemeColorDialogText | kJSThemeColorPrimaryLightText |
kJSThemeColorDialogTitle | kJSThemeColorPrimaryText |
kJSThemeColorDialogTitleText | kJSThemeColorSecondary |
kJSThemeColorDisabled | kJSThemeColorSecondaryDark |
kJSThemeColorDisabledText | kJSThemeColorSecondaryDarkText |
kJSThemeColorError | kJSThemeColorSecondaryLight |
kJSThemeColorErrorText | kJSThemeColorSecondaryLightText |
kJSThemeColorFocusedRow | kJSThemeColorSecondaryText |
kJSThemeColorFocusedRowText | kJSThemeColorSurface |
kJSThemeColorNeutral | kJSThemeColorSurfaceText |
kJSThemeColorNeutralText |
You can create JS themes, or modify an existing theme using the JS Theme Editor, available under the Add-Ons > Web Client Tools menu option and select JavaScript Theme Editor.
The editor provides a preview of the current theme on the right side of the editor screen, and you can click on an area or text item within the preview to view or set its color (you can also set colors by clicking in the list on the left).
The colors in a theme are categorized as Primary and Secondary, plus there are specific color for errors, borders, dialogs, and so on. The primary colors are used throughout your application and set the general tone or style of the theme, while the secondary colors provide an accent to certain parts of the UI.
To create a new theme, you can duplicate an existing theme and make any changes to the copy. To do this, open the Theme Editor, select a theme from the dropdown list or use the default theme (selected initially by default), click on Save as and give the new theme a name – then change individual colors and use the Save option to save any modifications. The Set theme option sets the $javascripttheme preference to the theme currently shown in the editor. If you make any modifications to the current theme, all open remote forms will be updated automatically.
A theme is stored as a .json file and an associated .css file in the ‘html/themes’ folder. When deploying your application, the themes folder and its contents must be copied to the corresponding location on the Omnis App Server.
When designing the colors in a new theme, you may want to follow the guidance provided by the Google Material design system, which may help you create a theme containing colors which complement one another and provide maximum usuability and accessibility across different platforms and devices. Google provides a Material Color Tool which you may find useful to create a set of complementary colors for the dark/light variants.
This version of Omnis supports the use of SVG images for component icons (see the next section in this doc regarding how to use SVG icons). For the JS client only, SVG icons can be “themed” which means an icon will be tinted using the control’s text color as specified in the current JS theme (the ‘fill’ color in a themed SVG file is set to the text color from the theme). This allows a single themed SVG icon file to be used with different themes and its color is set automatically.
Omnis includes an icon set named ‘material’ which contains over a 100 themed SVG icons; note that icons from this icon set can only be used with the JS Client. In order to use these icons, you need to add the ‘material’ icon set name to the $iconsets library property in your library ($iconsets now allows a list of icon set names). The material icon set is located in the ‘\html\icons’ folder and if you have used any of the icons in your app the icon set needs to be copied to the Omnis App Server when deploying your application.
The following are examples of a single icon from the material icon set with different color themes applied (note the icon is rendered using the button text color):
SVG icon files can be ‘themed’ using the SVG Themer tool under the Add Ons > Web Client Tools menu option. You can open a single SVG file, preview it using one of the test colors (the preview colors are not saved to the file), and save it using the Export button.
The SVG Themer tool converts a standard SVG image file into an Omnis themed SVG file format: specifically, the first element in the root svg element in the original file is converted to a ‘g element’ with fill="var(--om-tint-color)" and id ‘omTheme’ which reference the color from the current theme. The Image Data tab shows the source for the converted SVG file which you can edit if required, although the converter converts the the SVG file as necessary.
Like other SVG icon files, any themed SVG icons need to placed in an icon set folder. For example, you could create or acquire a set of SVG icons and convert them using the SVG Themer tool ready for use in your JS client apps.
The JS client’s theme is set in the ‘data-themename’ attribute in the omnisobject div in the HTML file for your remote form, e.g. data-themename="dark".
The special value of “_JT_” is used in the HTML template (jsctempl.htm) which is replaced this with the current value of $javascripttheme when Omnis generates the HTML file for your remote form.
In addition, the 'data-appid' attribute specifies the application a page belongs to. It defaults to '<lib name>.<form name>' each time a form is tested (the '_APPID_' placeholder in the template .htm file is replaced when a from is tested).
You can change the theme on the JS client in your code using the ‘settheme’ client command ($clientcommand) which takes a row parameter whose first column is the name of the new theme. Note that a remote form needs to be reloaded in the browser for a change of theme to take effect. Once you have set the theme using the ‘settheme’ clientcommand, the client stores it in the client localStorage and will use that theme for subsequent visits to the page. To revert to the default theme specified in the HTML page, you need to call the 'settheme' clientcommand, passing an empty string as the theme name (or clear the client's localStorage).
The current theme is passed in the $construct row parameter, in a column named theme.
The majority of the JavaScript components have the $alpha and $backalpha properties which allow you to set the transparency of the foreground and background colors of the component.
All JavaScript controls have the $active property, which is set to kTrue for all new controls (except the Label Control which is kFalse). The $active property allows you to control whether a component is active (kTrue) or inactive (kFalse) – in an inactive state, a component cannot be interacted with at all, so the end user cannot tab to it, the contents cannot be selected or scrolled (in a list), and user clicks on an inactive control are ignored. Therefore, when a control is inactive, it is completely ignored in the tabbing order, so when the end user tabs the focus will jump to the next active control – in the context of accessibility, an inactive component will be ignored.
The $enabled property allows you to disable a control, and many controls have this property, including: Bar Chart, Combo Box, Data Grid, Date Picker, Edit, List, Map, Pie Chart, Rich Text, and Tree list.
All controls that have the $enabled property have the $defaultdisabledappearance property. When $enabled = kFalse the $defaultdisabledappearance property defaults to true and the 'omnis-notenabled' css class is applied to the client element of the control. If $defaultdisabledappearance = kFalse, this class is not applied, which is what sets the text colour to grey when disabled.
You can add your own customized JavaScript components to the Component Store under your own tab. This might be useful if you always want to create edit controls or buttons with certain properties (e.g. colors or fonts), so creating your own custom JS components might save you some time. You will need to edit the Component Store library (comps.lbs) to change the contents of the Component Store.
To create your own customized JS components, you need to create a new JS remote form in the Component Library, copy any components you want to customize from the JSFormComponents form, add them to your own form, and then customize then as required.
You can open the Component Library by Right-clicking on the Libraries node in the Studio Browser tree and selecting the Show Comps.lbs option. Unless you want to copy classes from another library to the Component Library, it is recommended that you close all other libraries before you edit the Component Library.
When you select the Show Comps option, the contents of the Component Library is displayed in the Browser Browser. You can switch the Browser to Details view and click on one of the column headings to show the different types of component either by Name or Type. You can hide and show specific types of class in the Component Library using the Class Filter option in the Browser.
We recommend that you do not change the components in the JSFormComponents form since these are the default components that appear in the Component Store, rather you should create your own customized components using the following method.
Add a new JS remote form class to the Component Store library (comps.lbs); note that the name of the new remote form will be used as the tab name in the Component Store toolbar so choose something appropriate. Set the $componenttype property of the remote form to kCompStoreDesignObjects using the Notation Inspector: to do this, open the Notation Inspector, click on the Search button (the cursor changes to a spy glass), click on your remote form in the Studio Browser, and in the Property Manager set $componenttype to kCompStoreDesignObjects (note the $componenttype property will only be displayed via the Notation Inspector). Then set the $layouttype of the new remote form to kLayoutTypeSingle (not kLayoutTypeResponsive).
With your new remote form open, open the JSFormComponents remote form next to it (this form contains all JS components). Drag any JavaScript controls you want to customize from JSFormComponents into your new remote form and change their properties or appearance as required. After you hide the Component Store library, the customized JavaScript controls will be available in the new group in the Component Store.
When you add a JavaScript Component to a remote form in your code at runtime, Omnis uses a template to create the object with all the required properties and methods. There is a template for every type of JavaScript Component, and the templates are located in the \studio\componenttemplates folder.
The component templates match the default components in the Component Store, and should not be edited. There are templates for report and window class components as well.
When you move or resize objects in design mode using the pointer, colored dashed lines and arrows, called Position Assistance, will appear automatically that enable you to easily align and distribute controls and other objects in relation to the design window edges or center and any other nearby objects. As you move or resize objects on a remote form, colored lines are shown automatically, and objects will snap into position to help you arrange the objects in a form. For example, when you place a number of fields on a form Position Assistance can help you align their left-hand or top edges and ensure they are spaced evenly. Position Assistance is also provided when you use the Arrow keys to position or resize objects.
The Show Position Assistance option on the remote form context menu allows you to toggle the Position Assistance feature (enabled by default). There is a single setting for this, shared by all editors, that is saved to omnis.cfg when Omnis shuts down.
Position Assistance for sizing does not apply when Size to Grid is turned on, and for moving object it does not apply when Align to Grid is turned on.
The positioning lines are drawn using the colorhighlight color in the system group of appearance.json. The entry positionAssistantKeyboardTimer in the ‘ide’ section of the config.json specifies the time that the position assistance remains visible after you stop pressing an arrow key; this defaults to 750 milliseconds.
When positioning objects in the center of a remote form, Position Assistance uses the center of the current layout breakpoint, not the center of the remote form design window.
When the Position Assistance is enabled, Omnis gives precedence to distribution over alignment, and within alignment it prioritises the top edge, over the center, and the center over the right edge. As soon as a visual guide is displayed for a target, any other targets that would also cause the object to move in the same axis are dropped.
As you move or size objects Omnis displays a visual guide when the object(s) being moved or sized are within +/-2 pixels of a specific alignment or distribution target, e.g. an alignment target is the top edge of another object or objects. When you release the mouse, the objects will snap to the displayed target. Position Assistance is applied to objects dragged from the Component Store, as well as objects being moved or sized within a design window. Position Assistance is provided when moving an object even if the adjacent objects are contained inside a container field.
When sizing objects, assistance is not provided if the objects being sized have more than a single container, that is, the component that is the parent of the objects – this can be more granular than a field, such as for complex grids, there are several containers such as the row and header sections.
Position Assistance is provided within each section of a Complex Grid, that is, the row and header sections of a Complex Grid, and the above behavior for container fields applies to each section independently.
Position Assistance attempts to distribute objects by allowing them to be evenly spaced. The visual guide for distribution is a line drawn between the objects with arrow heads.
The guides are drawn for as many objects as possible, immediately adjacent to the object(s) being moved or sized. Position Assistance works best when objects are already reasonably well arranged, either vertically or horizontally, so for more complex arrangements, with overlapping fields may result in no visual guides being presented.
Position Assistance attempts to align objects by giving them the same top or bottom coordinate, or centered relative to each other. When you try to center objects, you only get visual guides when moving objects, and when the appropriate side of the rectangle representing the objects being moved either fully encloses or is fully enclosed by the appropriate side of the object in which it is being centered. The following illustrate how the Position Assistance is applied for different cases when aligning objects.
![]() |
![]() |
Top alignment | Bottom alignment |
![]() |
![]() |
Left alignment | Right alignment |
Assistance is provided to help you align fields inside a container field, such as a Paged Pane. In addition to the left/right, top/bottom positioning, when you move an object inside and near to the center of a container, a line across either the vertical or horizontal center of the container is drawn and the object will snap to the line.
When positioning objects inside a Paged Pane (or any container), Position Assistance is only provided for the controls within the Paged Pane itself, so objects outside the Paged Pane are not included in the current object grouping. Similarly, if you are positioning objects outside, but near to a Paged Pane, the objects inside the Paged Pane are not included in the current grouping.
The Activity Control provides an animated image to show some activity on the client, for example, during a long list calculation or search operation on the Omnis Server.
There is an example app called JS Activity in the Samples section in the Hub in the Studio Browser showing the different activity controls available and how to set a custom animated Gif; the same app is available in the JavaScript Component Gallery.
The Activity Control has the following custom properties:
Property | Description |
---|---|
$activitystyle | The style of the indicator, a constant as below, or kJSActivityCustomLink to specify your own image |
$customlink | The path of an animated GIF which can be displayed when $activitystyle is set to kJSActivityCustomLink |
The $activitystyle property specifies the style of the control, one of the following constants:
Constant | Description |
---|---|
kJSActivityBar | ![]() |
kJSActivityBlock | ![]() |
kJSActivityCircular | ![]() |
kJSActivityLinear | ![]() |
kJSActivityLinearDots | ![]() |
kJSActivitySmallSpinner | ![]() |
kJSActivityCustomLink | the image in $customlink is used |
The following code assigns a custom link to the activity control:
As an alternative to using the Activity Control you could consider using the showloadingoverlay client command to show a loading indicator (animated image) over a remote form or specific control: see Custom Loading Indicator.
The Background Control allows you to draw various shapes in your remote forms: you assign the shape to the object by setting the $::shape property to one of the kJSBack... constants. It can be assigned one of a number of shapes including: Ellipse/Circle, Rectangle/Square, Rounded rectangle/Square, Triangle, Horizontal Line, Vertical Line, and Image.
If the object is an Image, the image source is specified in $imagepath as a URL relative to the Omnis tree during development or your web server for deployment.
You can assign a solid color or gradient fill to a background component by setting its $backpattern, $forecolor and $backcolor. You can also assign the stroke (border) thickness and color by setting $strokewidth and $bordercolor.
There is a sample app called JS Background in the JavaScript Component Gallery, and under the Samples option in the Hub in the Studio Browser showing the various background shapes.
The Background Control has the $animation and $attr properties which allow various animations or effects to be assigned to the object, such as fading the object in or out, or for $attr various attributes of the object to be changed. The $animation and $attr properties must be assigned at runtime and accept a string containing various parameters depending on the function or attribute.
There is an example app called JS Animations in the Samples section in the Hub in the Studio Browser showing how can use animations to move and fade objects to create a richer UI; the same app is available in the JavaScript Component Gallery.
Apart from the scale attribute, the browser must support the Raphael JavaScript library to allow animations and attribute changes (more details about the parameters you can use are available from http://raphaeljs.com).
The $animation property follows the general format:
The functions available in $animation are:
scale
increases and decreases the size of the object
alpha
changes the transparency of the object
rotate
rotates the object
For example:
fades the object to alpha value 0 over 500 milliseconds using a ‘slow, faster, slow’ easing method (see below) and when complete calls evAnimComplete with a parameter "complete_context".
You can use the complete event to chain the next animation, therefore to pulse an object you could use:
You could use the event handling method:
The following ease transition effects or “eases” are supported for animations:
= | linear and default if not specified |
> | fast then slowing |
< | slow then faster |
<> | slow, faster, slow |
bounce | object bounces |
elastic | object stretches |
backIn | object backs in |
backOut | object backs out |
The $attr property allows you to change various attributes of the object, such as their transparency. For example, you can assign an alpha gradient to an object using the following method:
Omnis Studio provides two chart controls: a BarChart Control and a PieChart Control. The data to be represented in both these controls is contained in a list variable which is assigned to the $dataname property of the control.
There is a sample app for both the JS Bar chart and JS Pie chart in the JavaScript Component Gallery, and under the Samples option in the Hub in the Studio Browser.
There are various properties (on the Appearance tab in the Property Manager) that allow you to control the appearance of a Bar or Pie chart. The bars and segments use a set of default colors, but you can specify your own colors at runtime.
For Bar charts you can set $chartdirection to vertical (the default) or horizontal bars, the style of the bar ends as the $barends property (kJSBarEndSharp is shown below), and you can display data values when the end user’s mouse hovers over the bar by setting $showvalue to True (the default).
Specific properties for Pie charts are described under the PieChart Control section.
To draw a simple bar or pie chart, the list variable assigned to the $dataname property of the chart component needs to contain at least two columns. The first column contains the value for the data point, and the second column contains the label or name for the data point. For example, to construct a simple bar chart showing a list of figures for sales agents, you could use the following method:
With the $showvalue property enabled (a value is displayed when the end user passes the pointer over each bar), the method produces the following chart.
When $showvalue=kTrue, the popup label will use $backcolor for the text and $textcolor for the background of the label so that it can be seen against the background of the control.
There are a number of properties in the Bar Chart to allow you to add a main title, as well as titles for the x and y axis. In addition, there are properties to show (the default) or hide the x and y axis details or units.
$maintitle | The main title for the chart |
$xtitle | title for the x axis |
$ytitle | title for the y axis |
$showxaxis | if kTrue the chart shows x-axis details |
$showyaxis | if kTrue the chart shows y-axis details |
The $textcolor and $axiscolor properties allow you to set the color for text and axis, including theme colors; $textcolor applies to the color of the title, labels, axis text, and legend in the chart, where applicable.
The $axiscolor property for a Bar chart applies to the color of the both axes lines, and the unit lines which run across the bar chart.
When set to kColorDefault, both properties will set their color dynamically according to the color of $backcolor.
You can specify your own colors for the bars or segments in a Bar or Pie chart using the runtime-only property $colorlist, rather than using the default colors. You need to create a list of strings representing CSS colors and assign the list to the $colorlist property, for example:
The accepted color formats are: Hex Code RGB, Decimal Code RGB, HSL, or Color Name, and the formats can be mixed throughout the list as in the example above.
If there are not enough colors available in the color list for the number of segments in the chart, then Omnis will repeat the colors in $colorlist. Therefore, if you want to avoid repeating colors, create a color list containing more colors than you will generally need to cater to the number of data points in your chart.
The $colorlist property can contain kJSThemeColor... constants to allow you to match the colors in the current JS theme. Note you cannot use standard Omnis color constants (such as kRed, etc.) in this context, since these are taken as literal text on the JS client.
Bar charts report the evBarClicked event with the bar clicked in the pBar parameter. Similarly, Pie charts report the evSegmentClicked event with the segment clicked reported in pPieSegment.
The Button Control is a basic pushbutton that the end user can click with the pointer or tap on a mobile device to confirm something or initiate a process, such as an OK or Cancel button, or a Print or Send button. Many of the sample apps in the JavaScript Component Gallery contain buttons, including plain text buttons or ones with icons.
The text is specified in $text as a single line of plain text, unless $textishtml is set to true and the text is treated as HTML; see below. $align sets the alignment of the text inside the button and is centered by default.
The button can display an icon, specified in the $iconid property, which can be an SVG or PNG image file from an Icon set chosen from the Select Icon dialog; the ID can be an icon name or a URL pointing to an image file in the ‘html/icons’ folder. See earlier in this chapter about JS Component Icons and specifically SVG Icons.
The Button has the following additional text and appearance properties:
Property | Description |
---|---|
$buttonbackiconid | The icon id of background image for the button. To use the default system button, set $buttonbackiconid to zero and $buttoncolor to kColorDefault |
$buttoncolor | The color of the button. To use the default system button, set $buttonbackiconid to zero and $buttoncolor to kColorDefault |
$borderwidth | The border width in pixels (the default is 0 or no border) |
$bordercolor | Sets the border color when $borderwidth is set >0 |
$textbeforeicon | If true, and the control has both text and an icon, and the text is displayed to the left of the icon |
$::vertical | If true, the text and icon are arranged vertically |
$textishtml | Specifies that the text entered in $text is treated as HTML |
&isflat | If true, the button has a flat appearance |
The flat style of a button is controlled using the $isflat property. The style for all new buttons (and buttons in converted libraries) is flat (from Studio 10.2 onwards), so $isflat is set to true. In addition, if the value of $buttonborderradius in converted libraries is set to 0, it will now be changed to the new default of 4; any other value will be retained on conversion.
When $isflat is disabled a button has a small drop shadow and when the button has the focus a larger difused drop shadow is displayed around the button.
The appearance for flat buttons when they are disabled ($active = kfalse) is as follows: if $isflat is kTrue (the default), the button back color will become transparent (if it isn't already) and the text color will take on the disabledText color. If $isflat is kFalse, the button back color will take on the disabled color and the button text color will take on the disabledText color.
In addition, if $bordercolor for buttons is set to kColorDefault the color will match $textcolor. When disabled ($active = kFalse), the border will match the disabled text color to maintain a consistent disabled appearance.
When set to kTrue the $textishtml property specifies that the text for the button (entered in $text) is treated as HTML, therefore any HTML can be used to style the text. For example, you can insert a line break by setting this property to kTrue, and using <br> in $text for the button wherever a line break is required.
The $textishtml property also allows other styling of the button text using various character and color attributes. Note that design mode does not render the HTML (the raw HTML code is displayed), and if you use attributes in the HTML they must be enclosed in single quotes.
When a Button is clicked an evClick event is triggered which you can handle in the event handling method behind the button.
The sample apps in the Applets section in the Hub have an About window which is loaded into a subform and displayed using an animation; see the Animations section for the About button code. The Close button on the About windows simply closes the About form by sending a message to the main remote form to run a method; it has the following code:
In this case, $cwind is a reference to the main parent form which contains a method called $closeAbout which contains code to fade out the About form and reset various buttons on the main form.
The Checkbox Control can represent On / Off or Yes / No values and is typically used to allow the end user to turn an option on or off, or accept or decline a preference. Several of the sample apps in the JavaScript Component Gallery feature check boxes, such as the Map example.
The variable you specify in the $dataname property of a Checkbox should be a Number or Boolean variable. The $text property specifies the label text for the Checkbox. The $checkboxcolor property specifies the color for the Checkbox (and check boxes when they appear in Lists, Data grids & Tree lists).
When a Checkbox is clicked an evClick event is triggered with the current value reported in the pNewVal parameter.
There is an example app called JS Radio and Checkbox in the Samples section in the Hub in the Studio Browser to show how you can use a check box (and a Radiogroup); the same app is in the JavaScript Component Gallery. The example uses a series of check boxes and a radio button group to filter a list of people based on their gender and age group. The group of controls on the remote form could look like this (the following screen shows the ‘professional’ JS Theme in use):
The $dataname for each of the check boxes is iAgeRange1, iAgeRange2, and iAgeRange3 respectively. These are all Boolean variables defined in the remote form, and the $dataname of the Radio button group is iFilter, which is defined as a Short integer. Each separate check box and the Radio group has a simple event method, which is:
which will call the ‘filter’ class method when any of these objects is clicked. The filter method filters the contents of the list called iList based on the selection of the check boxes and radio buttons, and has the following code:
Note the ‘Smart list’ capability has to be enabled on the iList variable to allow the built-in filtering using the $filter method; this is done in the $construct method of the form in the example, using the following code:
The ComboBox control is a combination of a data field and a dropdown list from which the end user can make a selection or enter their own value into the field. There is an example app in the Samples section in the Hub in the Studio Browser (called JS Droplist, Combo, Popup); the same app is available in the JavaScript Component Gallery. The following screen shows a Combo Box using the Soft JS Theme.
The variable for the data field part is specified in the $dataname property. You can specify a default list of options in the $defaulttext property, which is a comma-separated list of options, or build the list dynamically (with $::listname, see below). When $defaulttext is specified, $defaultline specifies the list line which is selected when the form is opened (set to 1 by default). The $::listheight property specifies the height of the droplist. The Combo Box has the $negallowed property which means it can display negative numbers.
Rather than using a default list specified in $defaulttext, you can assign the name of a list variable to the $::listname property to assign the contents of the list to the droplist part of the combo box; $listcolumn specifies which column of the list variable is used to populate the droplist part of the combo box.
When the list in a ComboBox is clicked an evClick is generated with the selected list line reported in the pLineNumber parameter.
The Combo box control has the $::contenttip property which is a text string which is displayed in the edit field part of the combo box when it is empty to help the user understand what content should be entered into the field. For example, for a Last name field you could enter ‘Enter your last name’ into $::contenttip to prompt the end user for their last name.
Combo boxes have the $autocorrect and $autocapitalize properties, which when enabled means that any text entered into the edit field section of the control is corrected for spelling and capitalization automatically.
The maintenance screen in the Webshop sample app allows the user to enter new products or delete existing ones: specifically, the data in the Webshop app contains food and drink items, but it could be any type of products. When the user enters a new product, they can select the product type from a Combo control; this allows the user to select from a list of given product types or enter a new one.
The $dataname of the combo control is set to iDataRow.product_group, and the $::listname is iGroupList. The evAfter event is enabled in the $events property of the control. In the $construct method of the form, the iDataRow row variable is defined from the T_Products table class, as follows:
The last line of code triggers all the field specific $construct methods which in this case includes the Combo box control; the code defines the iGroupList from the product_group column in the T_Products table class, performs a select on the data, and fetches all the data back into the iGroupList variable.
When the user selects an item in the list or enters a new item into the entry part of the combo box, an evAfter event is triggered and the $event method behind the combo control is called, as follows:
The newItem method is placed behind the Combo box control itself and contains the following code:
A Complex Grid can display multiple rows and columns of data taken from a list variable specified in the $dataname property of the control. You can use a $construct method behind the grid control itself to build the list data to populate the fields in the complex grid. To create a complex grid, you can place other controls in the row and header sections of the grid control, including standard entry fields, droplists, buttons, and check boxes: these controls are duplicated for every row in the grid, displaying each row of data from the data list. The $dataname of each component you place in the grid must correspond to a column in your list variable supplying the data to the grid. A complex grid is a container field having its own $objs group containing the objects inside the grid control.
There is an example app called JS Complex Grid in the Samples section in the Hub in the Studio Browser; the same app is available in the JavaScript Component Gallery.
In addition, there is a Webshop app that uses complex grids in the Applets section in the Hub in the Studio Browser which is described later in this section.
You can place event methods behind the embedded controls to react to user input and clicks within individual fields/cells in the grid. For example, you can have a button in each row of the grid which when clicked triggers an evClick event which runs the $event method for the button that performs an action based on the row clicked.
The Complex Grid itself can have evClick & evDoubleClick events. When clicking on the background of a complex grid row, or a control within the grid which does not have a click event enabled, the evClick or evDoubleClick will be fired. Both of these events receive pLineNumber parameters indicating the line number which was clicked. If no line was clicked (the end user has clicked on empty space), pLineNumber will be 0.
Every field or object in a Complex grid has the $gridsection property which tells you the section the object is in, while $gridcolumn which tells you its column. The $gridsection property is shown in the Notation Inspector so you can inspect its value for an object in a grid section at runtime.
The Complex Grid control has the $pagesize property that allows you to display the lines in the grid as separate pages: see the List Control section for more details.
The complex grid has the properties $vscroll and $hscroll to allow you to scroll a grid dynamically. The $vscroll property takes the row number in the grid to scroll to. The $hscroll property takes the absolute horizontal pixel position to scroll to in relation to the left edge of the grid control, that is, the grid will not scroll by a specified amount, rather the grid will scroll to the absolute position in the grid specified by $hscroll.
You can use the property $vscrolltips to display a scroll tip when a complex grid scrolls vertically. If $vscrolltips is kTrue, the default scroll tip is the contents of column 1 of the list for the first fully displayed row. To override this default scroll tip, implement a client-executed method for the complex grid object, called $getscrolltip. $getscrolltip accepts a single parameter (the row number for which the scroll tip is required), and returns the scroll tip text.
A complex grid can include a scrollable footer section similar to the existing scrolling header section. To enable a scrollable horizontal footer, you need to set $showhorzfooter to true. The complex grid has the following properties to control the appearance of the footer:
$horzfooterheight
The height of the grid horizontal footer
$horzfooterfillcolor
The fill color for the grid horizontal footer
$horzfooterborder
The border style for the grid horizontal footer
$horzfooterlinestyle
The line style for the grid horizontal footer
The $rowdividerlinestyle is assignable at runtime and by $fieldstyle. As $rowdividerlinestyle is a custom field in a $fieldstyle it gets assigned at runtime, and is treated like any other runtime property change, therefore it is assignable at runtime. Note that $rowdividerlinestyle changes just the border between each row in a Complex grid, unless $rowborder is set to kJSborderPlain, in which case it also effects the border around the client, i.e. the section of the complex grid which contains the rows.
The $extraspace property can be used to add extra space to the line content in the grid. If $extraspace is zero, the height of each row is the default height of the row content. If $extraspace is greater than zero, the height of each row is the font height + $extraspace.
The end user can drag data from a remote form field and drop it onto a cell in the grid. Complex grids have the evCanDrop and evDrop events, and the $dropmode property to enable drop support. The pDropRow event parameter is available for evCanDrop, evWillDrop and evDrop events, and reports the row of the complex grid on which the drop is to occur (zero if the control does not belong to a complex grid).
It is possible to drop data onto a single control in the grid (a cell) in any row in the grid, as long as it has its $dropmode enabled. If not, the complex grid itself will receive the drop.
You can format individual cells in a complex grid by applying “exceptions” to those cells: you can then apply different formatting to those cells. For example:
or using indirection:
You can attempt to set an exception for any property, although in practice this may not be satisfactory for some properties. Appearance properties, and button text for example should however all work as expected.
You can set exceptions in both server and client executed code.
In addition, the method $clearexceptions() can be used to clear exceptions. For example (Products is a complex grid object):
You can execute $clearexceptions() in both server and client executed code.
Existing users should note: Prior to the implementation of exceptions, objects in the row section could lose property values set at runtime, when updating the grid data. This issue has been resolved as part of the exception implementation.
A complex grid cannot contain another complex grid as a member, in any section. A complex grid cannot contain a subform in the row section. These restrictions apply to controls that would be direct members of the section, or indirect members that are children of a paged pane. Omnis enforces this by preventing you from dropping these controls into the relevant section(s).
Note: the $add() method for remote form class objects has not been updated to enforce this restriction, therefore using $add() to place controls in a section which does not support them could lead to undesirable results.
The Webshop sample app, available in the Hub in the Studio Browser, uses a Complex grid in the main product remote form to display a list of products. Individual fields for the picture, name, description, price/size of the product are added to the first line of the complex grid; when the form is opened on the client and the data is loaded into the grid, these fields and are repeated for each row in the data list (one row per product).
The $dataname of the complex grid is set to iProductList which is built from a table class T_Products which is linked to a schema class sProducts. A $construct method is placed behind the complex grid that builds the list needed for the complex grid data.
When the form is opened, the $construct method is run and the product list is built from the database, while the data itself is displayed in the various fields embedded in the complex grid with each product shown on a separate line in the complex grid.
There are three order buttons placed in the row of the complex grid; they are repeated for each product in the list and allow the end user to order different sizes of product, such as a small, medium, or large drink or pizza. Each of the buttons has a simple method behind it that passes a number to the process_order class method; the first button sends value 1, the second button value 2, and the third button value 3.
See the Data Grid section for the process_order method which updates the iOrderList and the Orders data grid accordingly.
The Data Grid is a powerful and versatile control that can display character and numeric data in a grid like structure, much like a table or spreadsheet format, allowing you to create compact, data-rich UIs for your web and mobile applications.
There is an example app called JS Data Grid in the Samples section in the Hub in the Studio Browser (the same app is available in the JavaScript Component Gallery), showing how to use Data grids, including how to use custom cell formatting; the following screen shows the Vintage JS Theme in use.
In addition, the Webshop example under the Applets section in the Studio Browser uses a data grid which is described later in this section.
The content for a data grid is supplied from a list variable specified in the $dataname property. The number of columns in your grid would normally correspond to the number of columns in your data list, while the number of columns in the grid object itself in set by $designcols. For each column in the grid (under the Column Tab in the Property Manager) you need to assign $columndatacol to map the grid column to a column in your data list: you can use the column name or number in $columndatacol.
The $hasheader property specifies whether or not the grid has a main header, while $columnheaderheight is the height in pixels of the column header; if set to 0 (the default) the header height will be the same as $rowheight. The $headertext property specifies the text for the header and $::boldheader lets you specify a bold header. The $columnnames property lets you specify the heading text for each column in the grid (a comma separated list of names), which do not have to be the same names as the column names in your data list variable. You can use \n in the text for $columnnames to create a line break.
The $currentcolumn property is the current grid column for which properties are being displayed under the Column tab in the Property Manager. The $movecolumn property allows you to move a column to the specified position in the grid during design mode.
The end user can enter data into the cells of the grid if $enterable is enabled, and as the end user tabs the grid can grow by adding more lines to accommodate more data if $extendable is enabled. If $autoedit is true, and a cell is editable, it will automatically go into edit mode when it is selected (and $hcell or $vcell are set).
The height of the rows in a data grid adjusts to fit the height of the font size specified in $fontsize, unless you specify a fixed height in pixels in $::rowheight. In addition, the height of the header area is adjusted automatically according to the font, but you can fix the height in $::headerheight.
Along with the standard evClick and evDoubleClick events the Data Grid reports a number of events which you can detect in an event handling method behind the grid control.
evClick and evDoubleClick (pHorzCell, pVertCell, pDataColumnName)
sent after the data grid has been clicked or double-clicked
evCellChanged (pHorzCell, pVertCell, pDataColumnName)
sent when the current cell has changed, e.g. when navigating between cells with the arrow keys or clicking a cell that isn't the current cell.
pHorzCell - The column number of the new current cell.
pVertCell - The row number of the new current cell.
pDataColumnName - the data list column name (or number) when the event is triggered
evCellValueChanged (pHorzCell, pVertCell, pDataColumnName)
sent when the user has changed the value of a cell.
pHorzCell - The column number of the cell in the grid that has changed (not the column of the data list belonging to the data grid)
pVertCell - The row number of the cell in the grid that has changed.
pDataColumnName - the data list column name (or number) when the event is triggered
evColumnsResized (pColumnWidths)
sent when the user has resized a column.
pColumnWidths - a comma separated list of the new column widths
The pDataColumnName event parameter contains the data list column name (or number) when the event is triggered. This is useful when columns in the data list do not map directly to the columns of the form data grid (that is, if $columndatacol is used to set the column order. If the list column does not have a name, the parameter contains 'C1', 'C2', etc, so it can be used notationally. The value of the cell can be obtained with: iDataList.[pVertCell].[pDataColumnName].
The Data Grid control has the $pagesize property that allows you to display the lines in the grid as separate pages: see the List Pager section in the List Control for more details.
The $::columnwidths property allows you to set up the widths of the columns, which is a comma separated list of integer values representing each column width in pixels. In order for the data grid to cater for multiple screen sizes, the $columnwidthsarepercentage property allows you to switch to using a percentage in the $::columnwidths property. If true, the column widths in the data grid specify a percentage of the width of the control rather than a specific number of pixels. This affects the properties $columnwidth, $::columnwidths, and $columnminwidth.
You can add a Footer Row to a Data Grid which would allow you to display column totals, for example, or any other data. The $hasfooter property enables the footer row for the data grid, which is a fixed, non-scrolling row at the bottom of the grid. For numeric columns, the total for each column is shown in the footer row automatically.
The $hasfooter property enables the footer row for a Data grid. You can set the properties of the footer row on the Footer tab in the Property Manager using the following properties:
Property | Description |
---|---|
$footerbackalpha | The footer background alpha |
$footerbackcolor | The footer background color |
$footerdateformat | The footer date format |
$footerdateformatcustom | The footer custom date format |
$footerfontstyle | The footer text style |
$footerheight | The footer height |
$footerjst | The footer text justification |
$footerlabel | The default label shown in each footer cell; there is an option to pass in a placeholder |
$footernumberformat | The footer number format |
$footertextcolor | The footer text color |
$footertype | Footer type, a kJSDataGridFooterType… constant: kJSDataGridFooterTypeTotal (the default), kJSDataGridFooterTypeMean (average), kJSDataGridFooterTypeMedian, kJSDataGridFooterTypeFooterColumnValue, kJSDataGridFooterTypeCustom, kJSDataGridFooterTypeNone |
$footerzeroshownempty | If true, show as empty for zero values |
The following are properties for a column in the footer row, shown under the Column tab in the Property Manager. You can set $currentcolumn (a design property) or click on a column in design mode to set the properties for each footer column.
Property | Description |
---|---|
$footercolumnbackalpha | The footer column background alpha |
$footercolumnbackcolor | The footer column background color |
$footercolumndateformat | The footer column date format |
$footercolumndateformatcustom | The footer column custom data format |
$footercolumnfontstyle | The footer column font style |
$footercolumnhidden | If true, the column is hidden |
$footercolumnjst | The footer column text justification |
$footercolumnlabel | The default label shown in the footer cell |
$footercolumnnumberformat | The footer column number format |
$footercolumntextcolor | The footer column text color |
$footercolumntype | The default is to use setting in $footertype, otherwise an individual column can be set to a kJSDataGridFooterType… constant; see $footertype above |
$footercolumnvalue | If the $footercolumntype is set to kJSDataGridFooterTypeFooterColumnValue, it will use the value in $footercolumnvalue property, with the $footercolumnlabel prefix, if used. Otherwise, this property could be read (on the client) for any footer type |
$footercolumnzeroshownempty | If true, the footer column is shown as empty for zero value |
If a List Pager is used or a filter is applied to the list, the automatic totals are for only the data that is currently displayed; specifically for a list pager, the column totals are for the current page only.
When $footertype is set to kJSDataGridFooterTypeCustom, you can use the $updatefooterrow() client method to update the contents of the footer row. The method is called to notify of the footer data changing/requiring a change for every footer column type except kJSDataGridFooterTypeNone (as there is no footer data to be displayed). It is also called on initialization, and whenever any of the data in the grid changes.
Where applicable, a column’s $footercolumnvalue property will be updated before calling into $updatefooterrow() so that this value can be read and used elsewhere, i.e. when the footer type is kJSDataGridFooterType(Total/Mean/Median).
The pColumn parameter is the column number in the data grid list variable (assigned to $dataname), ignoring the display order. If Character data is returned, it will be displayed as-is, and will ignore $footerlabel. If Number data or a Date is returned, it will be displayed with the $footerlabel and formatted according to $footercolumnnumberformat or $footercolumndateformat.
The evFooterClick event is triggered if the end user clicks a cell in the footer row, passing the column number clicked.
The evFooterUpdated event is triggered when a footer or multiple footers have changed. pUpdatedColumns is a list of column numbers that have been updated. The event is triggered after footers have updated so you can receive the value of $footercolumnvalue if required.
You can apply your own formatting to individual cells in a Data Grid. For user-defined Data Grids (where $userdefined is set to true) and where a column has its columnmode set to kJSDataGridModeCustomFormat, you can customize the HTML used to layout or format an individual cell in the grid.
When the grid is rendered (this occurs on demand e.g. when scrolling to make new data visible), it calls the object client method:
which you implement to return html for the formatted cell contents. This HTML can, within reason, be anything you like: you can also just return a text string. To assist this, there are two new calls you can make:
styledtohtml(text)
the styledtohtml(text) function returns the HTML representing the text string containing embedded styles inserted using style() function. This is a built-in function, under the General tab of the Catalog, which must be run in a client-executed method in the JavaScript Client only.
$addcolorcss(cClassName,iRgbColor,iAlpha)
is a method of the data grid object (as such it can only be executed in client-executed methods). Call this in $init to add your own background color class to use with the html returned by kJSDataGridModeCustomFormat.This class takes browser specific issues with transparency into account.
For example, you can use the following method:
in $init, and then do the following in $formatcell:
Using transparency in the CSS background allows the selection color to show through the formatted cell.
There is an example app called Data Grid Formatting in the Samples section in the Hub in the Studio Browser to show how you can use the grid formatting; the same app is available in the JavaScript Component Gallery.
You can add a filter to a data grid by enabling the $hasfilerarea property. When true, the grid has a filter area which can be opened by clicking on a ‘spyglass’ button in the data grid header; the search filter will be applied to the current column (the Product column in the screen shown below). The end user can type into the filter entry box to filter the contents displayed in the column. The following image shows the filter enabled for column 1:
The other properties to set up the filter include:
$filtercol
The grid column to which the filter will apply; this can be changed at runtime in a client method, see below
$filterareaheight
The height of the filter area (when $hasfilerarea is enabled); if zero, the height is calculated automatically
$filterlabel
The text label for the filter entry field
$filtervalue
The name of an instance variable that contains the value used for filtering
$multifilters
enables a filter for all the columns in the data grid; see below
The following code is the $event method for a data grid, set to execute on the client:
You can implement the $filtergrid control method on a data grid, which will be called whenever the user types text into the filter box for a single filter enabled grid (if enabled); this control method does not apply when $multifilters is enabled.
The $filtergrid data grid method should be set to execute on the client.
The $filtergrid method receives two parameters: ColumnData & FilterString, the data in the filtered column for the row in question and the current filter string.
You can return true to say that the row should be included, or false to exclude it. If you return null (or nothing), the default handling will be applied to determine if the row should be shown.
The $openfilter client-executed method can be called from $init to allow you to open the filter area in the grid when the form is opened.
$openfilter([bOpen])
opens or closes the filter area if the grid has one, and returns kTrue if the operation was completed. bOpen: Use kTrue to open the filter area or kFalse to close it. Defaults to kTrue if unspecified.
In addition to being able to set a single filter for any column, you can enable a filter for all the columns in the grid by enabling the $multifilters property (and in this case $filtercol is ignored). When $multifilters is enabled, a default filter is added to each column in the grid (when the spyglass is clicked).
The filter has a number of operators to allow the end user to select the search type; the list of operators in the filter menu is determined by the data type of the column. When a search type is selected, a search field is displayed allowing the end user to add a search string; for date columns a date picker is also displayed.
The end user can use various keys to navigate the filter menus.
Tab or Shift Tab will jump to the next or previous column filters.
Space / Return on a filter type button will reveal the context menu.
Up/Down arrows to move up and down the filter menu items.
Escape closes the filter menu, returning to filter button.
Space / Return on a filter menu item will select the item.
By default a column will show a full set of filter types based on the column data type. You can override this and only show a subset, or remove the filter from the column altogether. You can do this using a client method called $multifiltermenu(pCol), which is called before a popup filter menu is shown for a column. You can assign the filter types for each column using the pCol parameter; the filter types can be summed for multiple filter types, for example:
If you assign any filter types that are not supported by the column data type, the filter types will be ignored. You can use the following filter type constants:
Constant | Description |
---|---|
kJSDataGridFilterContains | Include contains (case insensitive) |
kJSDataGridFilterDefault | Include all filter types for the column data type |
kJSDataGridFilterEmpty | Include must be empty |
kJSDataGridFilterEquals | Include equals (case insensitive) |
kJSDataGridFilterHidden | Hide the column filter at runtime |
kJSDataGridFilterLessThan | Include less than |
kJSDataGridFilterLessThanEqual | Include less than or equal |
kJSDataGridFilterMoreThan | Include more than |
kJSDataGridFilterMoreThanEqual | Include more than or equal |
kJSDataGridFilterNotContains | Include does not contain (case insensitive) |
kJSDataGridFilterNotEmpty | Include must not be empty |
kJSDataGridFilterNotEquals | Include does not equal (case insensitive) |
The filter menu name and filter text signs can be localized (e.g. == for equals) and are stored in the Omnis omnisloc.js. The menu name and sign is separated with a “:” colon character and both parts are required.
You can set or read the filters in a Data grid dynamically in your code using the $::filters property. The evFilterChanged event reports when data grid filters change.
The $::filters property (runtime only) allows you to manage the current filters for a data grid. When reading the property, the property returns a list in the same format as pFilters in evFilterUpdated (see below). Setting the property should be done using a list in the same format, that is, a single column list containing rows of data to change the filter values. The only difference for setting the filter is that only three columns are required in each row, either colNumber or colName can be supplied. If both are supplied, colName will take precedence over colNumber in the case that they reference different columns. The columns in the row can be in any order, but their names must match the format (i.e. colNumber/colName, filterType and value).
The evFilterUpdated event is fired every time the filter in the data grid changes. The event is fired for both types of filter ($multifilter can be kTrue or kFalse). It receives one parameter, pFilters, which contains a single column list of rows. Each row contains four columns:
colNumber or colName: The list column number or name.
filterType: The filter type, a kJSDataGridFilter… constant.
value: The value for the filter. The data type of this should be determined by the column data type.
When $multifilter is kFalse, pFilters is in the same format, but will only contain one row entry.
The following example filters the data grid by product and price:
The $setlineheight property allows you to center text vertically in the rows in the data grid. If true, the grid sets the line height so that text is vertically centered in each row (the default is kFalse).
You can create your own formatting for column headers by adding a client-side method called $formatheader which takes two parameters:
Parameter 1: the text for the column header
Parameter 2: the design grid column number (1-n)
The return value is HTML to use for the header, for example, for a bold header:
For red text:
For right justified text (using float so that sort indicators still appear):
You can reassign the column name to force a call to recalculate the HTML for the column header, even if the text has not changed.
You can add a dropdown list or “picklist” to one of the columns in your data grid to allow the end user to select a value from a list of preset values. You must create another list containing the list of preset values and specify its name in the $columnpicklist property for the column in which you want to add the picklist. The datatype of the column in your main data list variable corresponding to the picklist column must be an integer, and $columnmode for the grid column itself must be set to kJSDataGridModeDropList. The integer value stored in this column will correspond to the line number of the selected line in the picklist.
For example, if you want to list a product in your main grid field that has only four possible colors, you could create a sublist containing those color values and assign this sublist to a column in your grid field corresponding to an integer column in your main data list: this would allow the end user to choose a color from a preset list of colors.
The $rowcsscol property allows you to specify CSS styles for a row in a data grid. The $rowcsscol property specifies the column number in the $dataname list for specifying custom CSS class names to apply to individual rows. Multiple class names can be assigned with a space separated list.
The CSS rules for classes can be added to user.css: it may be necessary to use !important to override existing styles. For example, in user.css:
When you set $columnmode to kJSDataGridModeFormatted, the mode acts like kJSDataGridModeAuto, in that the data grid automatically handles the data based on its type. However, the grid formats the data using the properties $columndateformat, $columndateformatcustom, and $columnnumberformat, rather than the $js...format... properties.
You can use an integer column data type to represent a checkbox. To do this set $columnmode to kJSDataGridModeFormatted and set the $columnnumberformat to “bool”. This will cause integer data to be treated as Boolean, where non-zero means true, and zero means false. If the end user updates the grid using the check box, 1 will be stored in the list for true, and zero for false.
The properties $hilitefocusedcell and $cellhilitecolor allow you to highlight the cell that has the focus.
$hilitefocusedcell
If true, the focused cell will be outlined in the color specified by $cellhilitecolor
$cellhilitecolor
The color of the focused cell's outline, provided $hilitefocusedcell is kTrue
JavaScript Data Grids have $vscroll and $hscroll properties which allow you to scroll a grid vertically or horizontally at runtime in the client browser; note these properties are write-only meaning that you cannot return their values at runtime.
The vertical scroll value assigned using $vscroll is the position of the scroll bar according to row number in the control. The horizontal scroll value assigned using $hscroll is the designed grid column number for a data grid.
The property $tabthroughcells allows you to change the action of the tab key while the focus is on a data grid. If set to kTrue (default is kFalse), tabbing from a cell which is not being edited selects the next cell, or Shift+tab selects the previous cell. In addition, setting $hcell or $vcell triggers edit mode if $autoedit=kTrue.
Datagrids have the $autocorrect and $autocapitalize properties which means that text entered into the cells of a data grid are corrected for spelling and capitalization automatically.
The $validate method allows you to validate the data entered into any cell in the grid. If present, the method is called when an edit is made to a grid cell, with the parameters pRow, pCol, pNewValue being passed to the method. The method returns true to indicate that the change is valid, depending on the validation code you add to the method, otherwise the value in the cell will revert to the previous value.
Data entered in grid columns with the numeric data type will be validated automatically, as it is entered. When the end user tries to enter invalid data into the grid column field, such as an alphabetic character, the data is rejected, and the field is highlighted momentarily to indicate an error (the default action is to show a red border).
When leaving the entry field, the value is normalized, that is, integer data is constrained to the valid range or for other numbers it is rounded to the correct number of decimal places; also, leading zeroes are removed, and so on.
When a Data grid has $enterable & $extendable enabled, the user can add a new row by entering data into the empty 'extendable' row at the bottom, and the remainder of the columns in that row are given default values.
However, if you want to override these defaults, you can now implement a method named $initextendrow on the data grid control. This method should return a row with column values set to the appropriate defaults you wish to use. The order and the data type of the columns must match the order and types of the columns of the list defining the Datagrid and specified in $dataname.
Data Grid columns have the property $columnallownulldateinput to allow a null value to be added to a row of data when the end user tabs out of the last line of the grid to create a new line automatically.
If $columnallownulldateinput is true, and the datatype of the column is Date, cells in the column will default to a value of null when added through the UI. Additionally, if this property is enabled, the end user can change a date to be null by pressing Backspace or Delete while the cell has focus.
If false (the default), the behaviour is unchanged from previous versions. Note it is not possible for the end user to input null values into the grid, via the popup date picker, for example.
The Data Grid uses the appropriate Date Picker according to the constant specified in $dateformat or $columndateformat. If this is set to kJSFormatCustom, then $dateformatcustom or $customdateformatcustom is used as above. If set to kJSFormatNone, then it will attempt to use the data subtype applied to the dataname of the column to determine which picker to use.
Data Grids have the $datepickermode and $datepickerpopupstyle properties, as well as $columndatepickermode and $columndatepickerpopupstyle. The latter two work in the same way, but on the given column when $userdefined = true. The following shows $datepickermode set to kJSDatePickerModeCalendar.
The properties $editdatetext and $columnallownulldateinput allow end users to enter a date manually via the keyboard rather than using the date picker. When set to true, $editdatetext (and $columneditdatetext when $userdefined=kTrue), allows keyboard entry of a date/time. If a date that cannot be parsed is entered, it will revert to the previously stored date, unless $columnallownulldateinput=kTrue, in which case the field data will become null.
Note this has no effect on the date picker popup control, so if you don’t want to use the picker you need to apply the following css rule to hide the picker:
The end user can copy data from selected rows. Data grids return the copied rows as tab-separated values. You can add a client executed method named "$clipboardcopy" to the control to handle the clipboard content. The method can return character data or a list. If it is a list, column 1 must be the MIME type and column 2 must be the content.
For example:
The $frozencolumns property allows you to fix or “freeze” a number of columns to the left of the grid, so they do not scroll when the other columns in the grid are scrolled horizontally. The property takes a number value from 1 upwards corresponding to the first column on the left of the grid. For example, you could specify a value of 1 to create row headings that are fixed to the left of the grid.
The following properties allow you to justify content in data grid column headers.
$headerjst
A kJSDataGridJst… constant that sets the alignment of the data grid header
$columnheadersjst
A kJSDataGridJst… constant that sets the alignment of all the column headers; overrides $columnheaderjst
$columnheaderjst
A kJSDataGridJst… constant that sets the alignment of all the current column’s header; $columnheadersjst must be set to kJSDataGridJstDefault
The kJSDataGridModeColorPicker column type displays a color picker in the data grid cell allowing the end user to select a color. The end user can click into the color palette on the picker to select a color, or the entry field accepts colors in the hex (the default), rgb or color name formats. You can navigate the color picker from the keyboard without the picker losing the focus.
A numeric color value is returned from the color picker, or a color function can be used to set the color of the column, such as truergb(kDarkGreen), or rgb(255,0,0).
For example, to set the colors for the first 3 lines in the second column, use the code:
You can specify the text for the OK and Cancel buttons on the color picker using $colorpickeroktext and $colorpickercanceltext.
You can localize the strings for the color entry field for the aria-label and aria-describedby accessibility properties, "ctl_dgrd_color_input" and "ctl_dgrd_color_input_desc" respectively.
Data grid columns with type Number have the property $columnzeroshownempty which specifies that values of zero are shown empty rather than displaying a 0 digit.
The $columnhidden property allows you to hide the specified column at runtime. The default is false, meaning the column is visible.
The Webshop sample app, available under the Applets section in the Hub, uses a data grid to display a list of products that have been ordered in the main product jsShop remote form. The data grid control is called ‘orderGrid’ and is seen here in design mode:
The $dataname of the data grid is set to iOrderList which is defined from a table class T_qOrders which is linked to a query class qOrders. When the product form is opened, the $construct method behind the data grid defines the list from the table class.
When the end user clicks the ‘Order Now’ button in the product window, the data for the selected product and size/type is passed to the process_order method (as value 1, 2, or 3), which inserts the data into the list (after a check to see if the user has already ordered the same product) and the list is redrawn. The process_order method is as follows:
The Apps Gallery on the Omnis website has a further example showing how you can use the Data grid component.
The Date Picker Control allows the end user to select a single date, a date range, and/or a time, rather than having to enter a date or time from the keyboard; in this case, the UI is better and issues with formatting a date or time are avoided. There is a sample app called JS Date Picker in the Hub in the Studio Browser, and the same app is available in the JavaScript Component Gallery.
You can assign a Date/Time instance variable to the $dataname property to load the date/time selected by the user, or you can assign a two column instance row variable to contain the date/time and time zone offset of the client in the respective columns (see below for info on the time zone offset).
The $datestyle property specifies the style or date/time content of the date picker control, which can be a combination of date & time, date only, time only, or a calendar view, as specified by a kJSDatePickerStyle… constant:
Constant | Description |
kJSDatePickerStyleDate | a date display only |
kJSDatePickerStyleDateTime | a date and time are displayed (right below) |
kJSDatePickerStyleTime | a time display only |
kJSDatePickerStyleCalendar | a calendar is displayed (left) |
kJSDatePickerStyleCustom | a custom format, see below |
The color of the Date Picker is specified with $datefacecolor while $datefacealpha sets the transparency (value 0-255).
There is an example app in the Samples section in the Hub in the Studio Browser showing how you can use the Date picker to allow the end user to select a date; in addition, the Holidays example app under the Applets option in the Hub uses the Date picker, which is described later in this section.
In addition to the $datestyle property, you can use the $datepickermode and $datepickerpopupstyle properties to control the mode and popup style of the date picker (also applies to data grid cells and columns).
$datepickermode
controls the type of picker to be displayed, one of the following constants:
kJSDatePickerModeAuto: Date picker type is assigned automatically based on $dateformat
kJSDatePickerModeCalendar: calendar type is displayed
kJSDatePickerModePicker: a picker type is displayed
$datepickerpopupstyle
controls how the popup is displayed, one of the following constants:
kJSDatePickerPopupStyleAuto: Popup style is determined by device type
kJSDatePickerPopupStyleInline: Popup style will always be displayed adjacent to the control
kJSDatePickerPopupStyleModal: Popup style will always be displayed modal
(Note that Internet Explorer does not correctly display the modal type, and so falls back to inline on these clients.)
The inline style picker will position itself underneath the parent control, but from the right so it is closer to the icon which opens it. If there is not enough space beneath the parent control, the picker will be placed above, where space permits.
The Date Picker control can be switched to display a calendar style date picker, by setting $datestyle to kJSDatePickerStyleCalendar. There are a number of properties that apply to the control when the date style is set to calendar.
When $datestyle is set to kJSDatePickerStyleCalendar desktop browsers will display the calendar as expected. On mobile devices however, even when $datestyle is set to kJSDatePickerStyleCalendar, a calendar will be replaced with a date picker (same as kJSDatePickerStyleDate), since a picker style date selector is the preferred style on mobile devices. This can be overridden by setting the property $datestyleusepickeronmobile to kFalse.
The $datestylecustom property can be used in conjunction with setting $datestyle to kJSDatePickerStyleCustom to set the style or format of the date shown. You can enter a string of characters to represent the columns required as per the Omnis date/time format strings, for example, "mdy" to specify Month, Day, Year columns in that order.
In addition, you can specify a grouped column by enclosing the date characters in parenthesis, for example, "(wdm)" will specify a single coumn containing Weekday, Day, Month. Note: this column will always alter the day by one by increasing or decreasing it, so it only makes sense to use this type of column if it includes a day or weekday. Time elements entered into a grouped column will be ignored. Repeated characters are ignored and only one group can be used (further groups are ignored). Groups take precedence over individual columns, therefore "d(wdm)y" will be treated as "(wdm)y".
Date pickers (other than custom) pick up the locale of the client and display the picker in their standard format. For example, the date picker will display Day, Month, Year in the UK, and Month, Day, Year in the USA (assuming their location settings are set correctly).
When specified, the properties $rangeselection and $rangeenddataname allow the end user to select a date range, that is, a start date and an end date. The first being a boolean to put the calendar into range selection mode. When true, the end user can select a range of dates by selecting one date after another. The $rangeenddataname property is the name of an instance variable to store the end of the data range and should be of type Date. The variable in $dataname will always hold the start date in range selection mode.
A boolean parameter, pInRangeSelection, will be passed as true with evDateClick when the end user has selected the first date, and false once they have selected the second. If $rangeselection is kFalse, this parameter is not passed, and therefore will return NULL if tested on evDateClick.
The evDateRangeChange fires every time a date range selection has been completed (and $rangeselection is kTrue). This passes two parameters: pStartDate and pEndDate. This means you can obtain a date range without using instance variables if you just need to react to the date range selected. evDateChange does not fire when $rangeselection is kTrue.
The $currdaycolor property applies to inside the current day indicator ring and not the whole cell. This ensures the type of cell is still understood by the end user. E.g. When $todayscolor is different to $daycolor, the end user can still see that it is today, even when they have selected it as the current day.
The following events are generated when the end user clicks on a date picker and/or selects a date: you can create an event handling method on the control allowing you to load the selected date.
evDateChange
Sent to the control when the current date is changed (not fired when $rangeselection is kTrue)
evDateClick
Sent to the control when the user clicks on a date; only applicable to Calendar type date pickers.
evDateDClick
Sent to the control when the end user double clicks on a date (not fired when $rangeselection is kTrue)
evDateRangeChange
Sent to the control when a date range has changed (only fired when $rangeselection is kTrue)
In the Holidays sample app uses the Date picker control set to kJSDatePickerStyleCalendar to allow users to select the dates for the holiday applications. The jsUserForm in the Holidays app has two buttons to allow the end user to select a “From” date or “To” date to specify the Begin and End dates for their holiday request. The “From” button has the following code:
The openCalendar class method moves the calendarPane into view on the main form and has the following code:
If you examine the Holidays app to look at the Date picker note that it is on a page pane field called calendarPane located on the jsUserForm. The $left property for the calendarPane is set to 990, to hide it from view, therefore you’ll need to select it using the Field List (right-click the remote form, select Field List and check the calendarPane) and set its $left property to 200 in the Property Manager in order to see it.
The $dataname of the Date picker control itself is set to iCalendarDate, an instance variable of type Date Time and subtype ‘D m y’; when the end user selects a date this variable is set to the selected date automatically.
The Date picker has a simple event method to detect when the end user double-clicks on a date cell; it has the following code:
The closeCalendar class method passes the date from iCalendarDate into either the iFromDate or iToDate variable defined in the form; it has the following code:
The final two lines of the method move the calendarPane off to the right and enables the fields on the Name pane.
You can return the time zone offset of a date value when it is passed back from the client by using a two column row variable in $dataname; the first column should be defined as a Date Time variable and the second of type Number. If the server passes a new value to the client, then only the first column is significant and should specify the new date to be sent to the client.
When evDateChange signals that there has been a change on the client then the updated date is passed back to the server in the first column of the row variable as a UTC/GMT date value and the time zone offset of that value in the client's current time zone is passed back in the second column. The time zone offset is the number of minutes from UTC/GMT, e.g. GMT+2 the time zone offset is 120. This can be used to calculate the date in the time zone of the client.
If time zone offset information is not required, $dataname can be specified as a Date Time instance variable only.
The following strings are available in the JS localization string table to allow you to localize strings for the Date Picker. Note that some of the strings are now arrays of strings to simplify localization (e.g. for months, days of the week, etc).
The following are specific to the date picker control:
The following strings are available for controls that refer to dates, including the date picker:
The following example applies Spanish text to the Calendar:
See the Localization chapter in the Creaing Web & Mobile Apps manual for more information about setting the strings in the jOmnisStrings object.
The Device Control allows you to access features on a mobile device, such as getting the location of the end user’s device using GPS, retrieving the contacts information from the device, or returning images from either the camera or photo library on the device. Depending on the type of application you are creating, some or all these features may be useful to enhance the interactivity and functionality of your app for end users when they run your app on a mobile device, such as a phone or tablet.
The Device control itself is invisible and to enable access to the device functionality you need to add the Device Control to your remote form and assign an action to the $action property of the control at runtime using methods.
Important Note: in all but a few specific cases, the actions enabled via the Device Control only work in an application that is running within one of the JavaScript Wrappers or Omnis App Manager on a mobile device. The exceptions to this are the Email, Call, and SMS actions which will attempt to work if the app is running in a standard web browser, but it’s not guarenteed the actions will always work as expected.
Therefore, you will need to compile your app as a standalone mobile app using the JavaScript Wrappers (for iOS or Android), and test your app in a simulator or directly on a mobile device by running the native app, for the majority of the actions in the Device control to work. Alternatively, on iOS you can use the Omnis App Manager to test your mobile app and the functions of the Device Control, prior to compiling it into a standalone app using the iOS wrapper.
There is a Tech note describing how you can use the Device control and a device’s camera to return the info from a barcode or QR code: see TNJC0013 “Reading a barcode or QR code in a mobile app”; this demonstrates how you use the Device control and the Omnis App Manager to test your app.
The Device control supports several hardware functions, some of which may not be available on specific devices or mobile operating systems. You should test your app thoroughly on the specific devices you wish to support with each of the device functions that you want end users to access.
For some of the hardware features, Omnis can detect if they are not present on the current mobile device running the app. For example, if a device does not have a hardware camera, then the action kJSDeviceActionTakePhoto will report an evPhotoFailed message.
Note the Device control is invisible, therefore some of the visual properties normally associated with JavaScript components may not be relevant, such as $alpha; the following properties are available.
Property | Description |
$action | The “action” for the Device control which specifies which function on the client mobile device is accessed; this is assigned as a kJSDevice… constant: see below |
$communicationaddress | Character value determining the phone number when the Make Call and Send SMS device actions are used (for SMS only, can be a list of phone numbers), or email address when the Send Email device action is used. Can only be assigned at runtime. |
$communicationdata | Character data to be sent as the message body when the Send SMS or Send Email device actions are used. Can only be assigned at runtime. |
$communicationsubject | Character data to be sent as the subject when the Send Email device action is used. Can only be assigned at runtime. |
$dataname | The name of a List instance variable for the Device control. It will be populated with contact details when using the Get Contacts device action. |
$deviceimage | Contains a Character/Binary instance variable name used for holding the image returned from the device. The image will be in base64 format. |
$imageaspect | Sets the aspect ratio of the image, a floating number, indicating width divided by height. A value of 0 no aspect ratio will be enforced, a value of 1 enforces a square image |
$imagejpeglevel | The JPEG quality of images returned (0-100). 100 being max quality, 0 being max compression. |
$imagemegapixel | A float value indicating the maximum Megapixel resolution of images returned. 0 means no limit. |
$imagesizemenu | If true, a dialog will be opened when using the device image actions, to allow the user to pick a size for the image, respecting $imagemegapixel. |
$soundname | Name of the sound sample to be played when the Beep device action is called. |
$contact… | The $contact… properties determine whether particular pieces of contact information are returned when using the Get Contacts device action, e.g. disabling $contactphotos can significantly reduce the time taken to fetch contacts. |
There are several properties that are only relevant when the device action is set to kJSDeviceActionGetContacts which allows you to obtain information from the contacts database on the device. By setting these properties you can control what information is returned from the Contacts data on the device. For example, if $contactname is set to kTrue the contact request will include name info, and so on.
The following list summarizes the actions available, and the constant needed for the $action property:
kJSDeviceActionBeep – Beep Device
forces the device to play the default beep
kJSDeviceActionGetBarcode – Get a Barcode or QR code
returns the output from Barcode/QR-code scanning function on the device (if available); the output is usually a string which can be a URL
kJSDeviceActionGetContacts – Get contact info
returns contact information from the device; note there are other properties to determine the content or extent of the contact information returned
kJSDeviceActionGetGps – Get the device location
returns the location data using the GPS function on the device
kJSDeviceActionGetImage – Get an Image
returns an image from the device’s image gallery
kJSDeviceActionGetUniqueID – Get Unique ID
returns the unique ID of the device
kJSDeviceActionMakeCall – Make a Phone Call
forces the device to make a phone call (if available)
kJSDeviceActionSendEmail | kJSDeviceActionSendSms – Send an Email or SMS
forces the device to send an Email or SMS / text message (if available)
kJSDeviceActionTakePhoto – Take a Photo
forces the device to take a photo (if a camera is available)
kJSDeviceActionVibrate – Vibrate the Device
forces the device to vibrate (if available)
The basic method to assign an action to the Device control is as follows:
Event | Description | ||||
---|---|---|---|---|---|
evBarcodeFailed | Sent when no Barcode could be obtained from the device.
|
||||
evBarcodeReturned | Sent to the device control when a Barcode is ready for processing.
|
||||
evContactsFailed | Sent when no contacts could be obtained from the device.
|
||||
evContactsReturned | Sent to the device control when contacts info is ready for processing.
|
||||
evGpsReturned | Sent to the device control when Location Data is ready for processing.
|
||||
evImageFailed | Sent when the device failed to return an image.
|
||||
evImageReturned | Sent to the device control when an image is ready for processing.
|
||||
evPhotoFailed | Sent when the device failed to take a photo.
|
||||
evPhotoReturned | Sent when an image is returned from camera ready for processing.
|
||||
evUniqueIDReturned | Sent when a unique ID is returned from the device.
|
||||
Standard | evExecuteContextMenu evOpenContextMenu |
To make the device play a given sound sample, you need to assign the constant kJSDeviceActionBeep to the $action property. This is one-way communication with the device which will result in the device playing a sound sample. To specify which sound to play, you need to set the $soundname property to the name of the sound sample to be played which must be compiled into the wrapper application. The wrapper contains a default sound called “notify”.
You can return a Barcode or QR code by assigning the constant kJSDeviceActionGetBarcode to the $action property. If the action is successful an evBarcodeReturned event is sent to the Device Control and the barcode data is returned in the pDeviceBarcode event parameter; the barcode data is usually a string containing Alphanumeric characters, such as a product number or name, or in the case of a QR code it could be a website URL.
The event method for the Device Control could be:
There is a Tech note describing how you can return the info from a barcode or QR code using the Device control and the Omnis App Manager to test the Device control: see TNJC0013 “Reading a barcode or QR code in a mobile app”.
To make the device vibrate you need to assign the constant kJSDeviceActionVibrate to the $action property. This is one way communication with the device which will result in the device vibrating for a short period of time.
To receive location (GPS) data from the device you need to assign the constant kJSDeviceActionGetGps to the $action property. The evGpsReturned event is sent when the location data has successfully been returned. The event parameter pDeviceGps will contain the returned data which is formatted as a string containing longitude and latitude data separated by a colon “:”. If the device fails to obtain location data or the device does not support location tracking, the returned data will be a longitude and latitude of zero, i.e. “0.0:0.0”.
To take a photo with the device (if a camera is present) or to return an image from the device’s gallery the kJSDeviceActionTakePhoto or kJSDeviceActionGetImage constants need to be assigned to the $action property. The $deviceimage property of the Device component needs to be assigned to an Instance Variable of type Binary or Character to hold the incoming image data from the device. If the device is successful in returning an image, the event evPhotoReturned or evImageReturned will be called to indicate that an image was returned, whereupon the instance variable specified in $deviceimage will be populated with the base64 encoded image data. In the event of the device failing to return an image or the user cancels the request, the event evPhotoFailed or evImageFailed will be sent.
In this case the instance variable iImage is a Binary variable. The $deviceimage property is set to iImage. There is another Binary variable called ipic which is associated to a picture component. By copying the returned image in iImage into the picture component variable you can display the image returned from the device.
In addition to the TakePhoto action, the device control has the client-executed method, $takephoto(iWidth, iHeight) which provides a shorthand way of taking a photo with specific dimensions.
The $imageaspect allows you to specify the aspect ratio of a photo; it only affects images taken with the TakePhoto device action, not the GetImage action. This functionality is only available in the iOS and Android wrappers - version 3.1.0 & later; also note the minimum Android version is now API21 (5.0, Lollipop).
The $imageaspect property takes a floating number, indicating width divided by height. If set to 0, no aspect ratio will be enforced, and the standard camera application will be used for taking photos. If greater than zero, a custom camera view within the app will be used, which shows the preview stream in the specified aspect ratio, and an image of the specified aspect will be returned. A value of 1 will enforce a square image.
The $imageaspect property can be used in conjunction with $imagemegapixel to take an image of specific dimensions, that is:
$imageaspect = targetWidth / targetHeight
$imagemegapixel = (targetWidth * targetHeight) / 1,000,000
To obtain information from the contacts database on the device the kJSDeviceActionGetContacts constant must be assigned to the $action property. To accommodate the contact database the $dataname property needs to be assigned to an Instance Variable of type List. The properties starting with $contact... determine which contact fields will be obtained from the device: setting these properties to true or false will determine if that specific field is returned from the device.
The evContactsReturned event is triggered when the contact database has been returned, and in the case of the device failing to obtain the contact database the evContactsFailed event is triggered.
displayName: The name of this Contact, suitable for display to end-users (String).
name: A row containing all components of a contact’s name.
formatted: The complete name of the contact (String).
familyName: The contact’s family name (String).
givenName: The contact’s given/first name (String).
middleName: The contact’s middle name (String).
honorificPrefix: The contact’s prefix (example Mr. or Dr.) (String).
honorificSuffix: The contact’s suffix (example Esq.) (String).
nickname: A casual name to address the contact by (String).
phoneNumbers: A list of all the contact's phone numbers.
type: A string that tells you what type of phone number this is
(example: 'home') (String).
value: The phone number (String).
pref: Set to true if this is the user's preferred value (Boolean).
emails: A list of all the contact's email addresses.
type: A string that tells you what type of email this is (example: 'home') (String).
value: The email address (String).
pref: Set to true if this is the user's preferred value (Boolean).
addresses: A list of all the contact's addresses.
pref: Set to true if this is the user's preferred value (Boolean).
type: A string that tells you what type of address this is (example: 'home') (String).
formatted: The full address formatted for display (String).
streetAddress: The full street address (String).
locality: The city or locality (String).
region: The state or region (String).
postalCode: The zip code or postal code (String).
country: The country name (String).
ims: A list of all the contact's IM addresses.
type: A string that tells you what type of IM this is (example: 'home') (String).
value: The IM username (String).
pref: Set to true if this is the user's preferred value (Boolean).
organizations: A list of all the contact's organizations.
pref: Set to true if this is the user's preferred value (Boolean).
type: A string that tells you what type of organization this is
(example: ‘work’) (String).
name: The name of the organization (String).
department: The department the contact works for (String).
title: The contacts title at the organization (String).
birthday: The birthday of the contact (Character).
note: A note about the contact (String).
photos: A list of the contact's photos. In general, there will be only one row.
type: A string that tells you what type of field this is (example: 'home') (String).
value: The photo data, encoded as base64. These are small, thumbnail photos.
(String).
pref: Set to true if this is the user's preferred value (Boolean).
categories: A list of all the contacts user defined categories.
type: A string that tells you what type of category this is
(example: 'home') (String).
value: The value of the field (such as a phone number or email address) (String).
pref: Set to true if this is the user's preferred value (Boolean).
urls: A list of web pages associated with the contact.
type: A string that tells you what type of web page this is
(example: 'home') (String).
value: The website URL (String).
pref: Set to true if this is the user's preferred value (Boolean).
To make a phone call from the device the kJSDeviceActionMakeCall constant is used. Before assigning this action the phone number for the call should be specified in the $communicationaddress property.
To send an SMS (text message) or Email from the device the kJSDeviceActionSendSMS or kJSDeviceActionSendEmail constant is used. Before assigning this action the phone number or list of numbers (for the SMS action) or the email address (for Email) should be specified in the $communicationaddress property. The message body of the SMS or email can be specified in $communicationdata. The subject of the email can be specified in $communicationsubject.
You can send a SMS to multiple recipients by assigning a comma-separated list of phone numbers to $communicationaddress. For example:
You can return the unique ID of the device running your standalone app using the kJSDeviceActionGetUniqueID action.
The ID is unique to each JS wrapper installation and changes when the app is re-installed.
If successful, the action triggers the evUniqueIDReturned event with pDeviceUniqueID containing the ID. You can use the $event method of the device control to return the ID:
Some of the Device actions (those listed below) may work in your application when running in a standard desktop web browser, that is, outside a wrapper. However, the results of running any of these actions in a web browser are very unpredictable, mainly due to the great variation among different web browsers and operating systems, therefore we do not recommend or support apps using these actions in a web browser. If you do use them however, you should test these actions thoroughly.
You can use the Call, SMS, and Email actions in an application running in a browser, and not in a wrapper, and the web browser on the client will attempt to execute the relevant action (this only applies to these actions: all other actions have to be executed inside the wrapper). For example, if you run the Email action in a web browser it will attempt to initiate an email in the email program on the client.
When run outside the wrapper the Vibrate action is not currently supported on iOS Safari, and hence other iOS browsers, as they all have to based on Apple's WebKit.
The Location action only works over HTTPS in recent browsers.
The Droplist Control displays a dropdown list from which the end user can make a selection; the contents of the list can be supplied from a default list or a list variable which can be built dynamically. There is an example app in the Samples section in the Hub in the Studio Browser (called JS Droplist, Combo, Popup), and the same app is available in the JavaScript Component Gallery. The following screen shows the Vintage JS Theme in use.
You can specify a default list of options in the $defaulttext property, which is a comma-separated list of options; $defaultline is the default line (set to 1) which is selected when the form is opened (only when $defaulttext is used). Alternatively, you can assign the name of a list instance variable to $dataname to populate the list; $listcolumn specifies which column of the list variable is used to display the list. The $::listheight property specifies the height of the droplist.
When a line in the droplist is selected an evClick is generated with the selected list line reported in pLineNumber.
The Droplist and Combo Box controls have the property $horzpadding to allow you to add extra horizontal padding, in pixels, to the text in the list part of the control. This property has also been added to Combo boxes.
The $extraspace property can be used to add extra space to the line content in the list. If $extraspace is zero, the height of each row is the default height of the row content. If $extraspace is greater than zero, the height of each row is the font height + $extraspace.
The $seldataname property allows you to specify the name of an instance variable, which will be populated automatically with the selected value from the droplist.
The jsUserForm in the Holidays sample app uses a droplist to allow users to select an employee to view their holiday leave requests. The $dataname of the empList Droplist control is set to iEmployeeList which is built via the $construct method when the form is opened.
The droplist control contains a $event method which is triggered when the user selects a line in the list; the code in the event method redraws the holiday list for the selected employee:
The buildHolidayList class method builds the list of holiday requests for the selected employee and redraws the form.
The JavaScript Edit Control is a standard Single Line Edit field which you can use to display data or allow the end user to enter data into a Remote Form, such as fields on a Contact form. In most cases, you would add a text label to each Edit control on the form, to identify its purpose, or you can add a ‘content tip’ ($::contenttip) to each edit control to help the end user fill out the form.
Many of the example apps under the Samples option in the Hub in the Studio Browser use Edit controls, as well as the apps in the JavaScript Component Gallery, including the JS Input Border and Button Styles example app. You can examine these apps and code to see how edit controls can be used.
The Edit control can handle all types of character or numeric data stored in the instance variable specified in $dataname: the type of data the edit control can handle will depend on the data type of the instance or column variable assigned to the control. To create an Edit control, you need to drag the Edit control from the Component Store and drop it onto your remote form. You can enter a suitable name in the $name property in the Property Manager, and then you can assign a variable in the $dataname property, that is, it must be an instance variable for a remote form edit control. You can enter the name of an existing variable, or you can enter a new variable name in the $dataname property in the Property Manager, then press Return and the New Variable Name dialog will open allowing you to define the new instance variable; in this case the instance variable is added to the current remote form class (visible in the Method Editor under the Instance tab in the Variables pane).
If you use one of the wizards to create a remote form, the edit controls are added to the form and the required variables are assigned to their $dataname properties automatically.
When the $issingleline property is kTrue (the default), the edit control only allow data entry on a single line, otherwise when kFalse the field can be extended downward to allow data to be entered on multiple lines.
The Edit control has the $::contenttip property which is a text string which is displayed in the edit field when it is empty and before the end user has entered any text. Using content tips may help the user understand what content should be entered into fields in the forms in your application. For example, for a Last name field you could enter ‘Enter your last name’ into $::contenttip to prompt the end user for their last name. As soon as the end user starts to type something into the field the content tip will disappear.
When kTrue, the $ispassword property ensures a place-holder character is displayed when the end user enters something in the field (only applies when $issingleline is kTrue).
The style of the text or font of an Edit control is controlled by the $fieldstyle property under the Appearance tab in the Property Manager. The field styles are set up in the #STYLES system table in the library and are available for many control types. You can set the $fieldstyle to <None> and assign your own font and style properties under the Text tab, including the $align, $font, $fontsize, $fontstyle, and $textcolor properties.
The $effect property lets you set the type of border for the edit control and its value is one of the kJSborder… constants. The kJSborderDefault setting means the control has the default border type as specified by the current client operating system and browser type. For some clients the border may change when the state of the control changes.
The $borderradius property lets you add rounded corners to the edit control. A single value specifies the radius for all four corners, but you can specify a different value for each corner by specifying four-pixel values separated by – (hyphen), in the order topleft, topright, bottomright, bottomleft. If bottomleft is omitted, the topright value is used. If bottomright is omitted, the topleft value is used. If topright is omitted, the topleft value is used.
The property $horzpadding allows you to add extra horizontal padding, in pixels, inside the control; when applied this property adds padding on the left and right of the text within the edit control.
Existing users should note: when a library is converted to Studio 10.2, the $horzpadding property for all JS Edit controls will be set to 4 automatically if they were previously set to 0, which is the default for all new Edit controls; if $horzpadding is set to any other value it is not changed. After conversion, you can change the value of $horzpadding.
The $vertpadding property allows you to add vertical padding above and below the text inside the control’s border; the property only applies when $issingleline=kFalse as single line edit controls are vertically centered.
The $linkedobject property allows you to link a list control to the edit control to create a special type of list called a “Linked List” which updates itself automatically as the user types into the edit control: see the List Control section for more information.
The Edit Control reports the evBefore and evAfter events, so you can detect when the focus is about to enter or leave a field in the $event method and process the event accordingly: note evAfter is only reported if the data in the control has changed. You must enable any of the events for the Edit control in its $events property before any of the events are reported.
In addition, the evKeyPress event is reported allowing you, amongst other things, to create a “Linked List”: see the Linked Lists section.
Many iOS and Android devices have different software keypad layouts which are displayed depending on the type of data required, that is, the keypad content and layout adapts to the content required. For example, if numeric content is required, a numeric keypad is displayed. The $inputtype property allows you to specify which keypad is displayed on touch devices depending on what type of content you wish the end user to enter into the edit control. This property only applies to touch devices and in this case $inputtypetouchonly is set to kTrue by default, and it only applies if $ispassword is false (if true the default keypad is shown).
$inputtypetouchonly
When true (the default for touch devices) the specified $inputtype is applied on touch devices, otherwise it is ignored
$inputtype
The HTML input type used by the edit field. The browser may give this special handling, e.g. by popping up a specific software keypad. (The property is ignored if $ispassword is enabled.) The input type is specified using a constant:
kJSInputTypeDefault: the standard Qwerty keypad (in most cases)
kJSInputTypeNumber: the standard Qwerty keypad flipped to numbers
kJSInputTypeTelephone: the telephone number keypad
kJSInputTypeEmail: the Qwerty keypad plus the @ and dot keys
kJSInputTypeUrl: the Qwerty keypad plus dot, forward-slash, and ‘.com’ keys
kJSInputTypeDate: shows a date picker; see below
If $negallowed is true, the 'number' type is not selected as this does not guarantee the presence of a minus key. You should note that a touch device's virtual keyboard is more likely to use a numeric keyboard if $negallowed is false.
The constant kJSInputTypeDate can be assigned to the $inputtype property to allow the end user to select a date using the Date Picker. When $inputtype is set to kJSInputTypeDate, and $inputtypetouchonly is set to false, a date/time picker will be used to pick the value for the Edit control. $dataname must be set when using kJSInputTypeDate and other input types such as kJSInputTypeNumber.
The format of the date picker should be calculated from $dateformat ($dateformatcustom if $dateformat == kJSFormatCustom). If $dateformat is kJSFormatNone, then the control attempts to fall back to the dataname subtype.
You can control the format of the data entered into an Edit control by defining an input mask using the $inputmask property. If the user enters an invalid character, the control will briefly become highlighted and the input will be rejected. For edit fields of character type, the data variable will contain mask characters. For number/integer fields, the data is the unmasked number value.
The #JSMASKS system table stores the input masks for JS Edit controls for the library, which are also accessible in the $javascriptinputmasks notation group.
There are a number of differences between the existing Masked entry field on the thick client and input masks for JS Edit controls:
On the thick client, the user must complete the masked entry field before focus can leave the field. This is not the case with JS masked edit fields - fields can be left partially filled.
JS input masks do not support any of the 'control characters' which can be used on the thick client.
The JS edit control does not have a $formatstring property (like the thick client masked entry field).
The JS edit control has two unique properties: $inputmaskguide and $maskvaluevalid.
JS input masks can be changed dynamically as the user types using the $processmask client method.
There is visual feedback when entering invalid characters in a masked JS edit field.
Incompatible input types are prevented from being used with input masks. For example, the kJSInputTypeNumber and kJSInputTypeEmail values of $inputtypes are incompatible with input masks. If $inputtype is one of these values, and $inputmask is set, the input element will use the text type (effectively kJSInputTypeDefault).
The value of $inputmask may contain a combination of fixed and special characters. Note that underscores cannot be used as these are used as placeholders.
Special character | Description |
---|---|
# | Any digit |
@ | Any character |
a | Any letter |
A | Any uppercase letter |
n | Alphanumeric |
N | Alphanumeric, uppercase |
“ABC" | Any character from list |
“A-D" | Any character from A to D inclusive |
\ | (back slash) Escape character (next character is displayed literally, use to escape special mask characters, double quotes or backslash) |
The $inputmaskguide boolean property controls whether or not a guide is shown. If true, placeholder and non-placeholder mask characters are always displayed. If false, placeholder characters are hidden, and mask characters are only shown when the user reaches them as they type. The property is false by default.
The $maskvaluevalid property is a boolean, read only, runtime only property. A value of kTrue indicates that the field is completed, and therefore valid.
A client method named $processmask can optionally be added to an edit control. This allows the mask to be changed as the user types. The method is called any time the value in the field changes, and receives a parameter pInput which contains the user input. Note that the user input parameter could contain anything as the event is sent before mask validation occurs (the mask needs to be updated before it can validate input). As a general use case, $processmask could be used to create the effect of optional characters.
You can specify multiple date formats in the $dateformatcustom property for entry fields in a remote form, which allows end users to input a date using one of a number of possible formats, rather than being limited to a single date format. The multiple date formats can be entered into $dateformatcustom separated using “|” (the pipe character), for example:
When parsing data entered by the user, the client uses each format in order, until one successfully matches the user input. The client uses the first format in the list to format the data for display.
Entry fields (and data grids) validate numeric data as it is entered, for JavaScript remote form variables with a numeric data type. When the end user tries to enter invalid data into the field, such as an alphabetic character, the data is rejected, i.e. it cannot be entered into the field, and the field is highlighted momentarily to indicate an error (the default action is to show a red border).
When leaving the entry field, the value is normalized: so for integer data it is constrained to the valid range or for other numbers it is rounded to the correct number of decimal places; also, leading zeroes are removed, and so on.
The $negallowed property for Edit controls allows for the display of negative number values. If this is kFalse and the end user tries to enter a negative sign, the sign will be rejected.
When set to kTrue, the $uppercase property forces all character data to be shown in uppercase.
When the $zeroempty property is set to kFalse (the default), a zero character is shown in a numeric type entry field. Otherwise, you can set $zeroempty to kTrue to ensure a numeric edit field is empty when the variable value is zero. You can have greater control over the display of numbers using Input masks.
Text wrapping for the Multiline Edit field is prevented if the $horzscroll property is enabled (kTrue). However, if $autoscroll is true, then text wrapping does occur (since $autoscroll is on by default).
There are a number of shortcut keys defined in the Edit control that allow end users to select text and move the insertion point within the control (the shortcuts also apply to Window class Entry fields).
The shortcut keys are stored in the Omnis preference $keys which can be edited in the Property Manager (click on the Prefs option in the top level of the Studio Browser). The shortcut keys for Edit controls are stored in a configuration file called ‘keys.json’ and located in the Studio folder (this is the same file containing the shortcut keys for the Method Editor). The file is created the first time you edit the shortcuts in the Property Manager and click OK.
Shortcut key | Action |
---|---|
Alt+End | End of Text Alternative |
Alt+Home | Start of Text Alternative |
Ctrl+Alt+DownArrow | Scroll Down |
Ctrl+Alt+LeftArrow | Scroll Left |
Ctrl+Alt+RightArrow | Scroll Right |
Ctrl+Alt+UpArrow | Scroll Up |
Ctrl+DownArrow | Paragraph Down |
Ctrl+End | End of Text |
Ctrl+Home | Start of Text |
Ctrl+LeftArrow | Backwards Word |
Ctrl+RightArrow | Forwards Word |
Ctrl+UpArrow | Paragraph Up |
End | End of Line |
Home | Start of Line |
PageDown | Page Down |
PageUp | Page Up |
You can control the Automatic Correction, Capitalization And Completion of text entered by the end user into an edit control. This functionality is built into the browser whereby text is ‘corrected’ or updated automatically: note that not all browsers support all of these functions, so you should check support in individual browsers on different platforms.
You should note that Auto correction, Auto capitalization and Auto completion (the properties $autocorrect, $autocapitalize & $autocomplete) only work in Omnis when they are enabled on the client Mac computer. Note also that $autocapitalize only applies when using a virtual keyboard on a device.
If true, the $autocorrect property specifies that text entered into a JavaScript Edit control is auto-corrected, as the end user types into the field. Currently this feature is only implemented in Safari and iOS browsers (note some browsers, such as Chrome, will highlight incorrectly spelled words, but not correct them automatically). This property defaults to kTrue for backwards compatibility.
The $autocapitalize property controls whether or not text typed into an edit field is capitalized, as appropriate, automatically. Possible values include:
kJSAutoCapitalizeSentences
Automatically capitalize the first character of new sentences (default and previous behaviour)
kJSAutoCapitalizeWords
Automatically capitalize the first character of each word
kJSAutoCapitalizeNone
No automatic capitalization
The $autocomplete property controls whether or not text is completed automatically. If true, the browser will attempt to complete text based on content previously entered into this type of field (e.g. name type fields will display a list of names based on the first letter typed): the browser will display a list of suggested text for the end user to select from. There may be many possible values for some types of field, which will be based on values previously entered into any website for a field with the same 'autocomplete' value, e.g. 'email'.
The $setselection method allows you to select a range of characters within the Edit control; note the method only works on the client.
$setselection(iFirstSel[,iLastsel]))
Sets the focus on and selection range of the content in an Edit control. If iLastSel is omitted selection will occur to the end of the edit field. Returns the selected text.
$setselection has two parameters, both Integer, iFirstSel and iLastSel to set position of the characters to be selected within the edit control. iLastSel selects up to, but not including, the character specified, and if omitted the content in the edit field is selected to the end. The method returns the content selected.
You can also use $cinst.$setcurfield(vNameOrIdentOrItemref [,bSelect=kFalse]) to put the focus in the specified field, and if bSelect is kTrue and the client supports it, the contents is selected. This can be used on the client or in a server method; see Remote Form Methods for more info.
You can enter text into an edit field using the built-in Dictation feature on macOS, which tries to convert audible speech into meaningful text. To allow dictation to occur the focus must be in the edit field, which must itself be editable, i.e. not disabled, and dictation must be enabled on the client computer. Dictation is available in Single- and Multi-line edit fields, the edit part of Combo boxes, and edit fields in Complex grids in remote forms (and window classes), that is, wherever text input is required.
Support for Dictation is turned on in Omnis by default, but you can change it in the config.json file. There is a “useDictation" item in a “macOS" section of the config.json file, which is set to true to enable dictation; note you have to quit Omnis to change the config.json file, and any change will be effective when you restart Omnis.
To enter dictation mode, place the cursor in the edit field and select the Start Dictation option from the Edit menu on macOS, or press the Function (Fn) key twice. This will open the dictation popup (usually in the center of the screen, depending on space) and put the computer in listening mode. Dictation can be stopped or cancelled by clicking on Done in the popup, or using the Stop Dictation menu option.
There are two levels of dictation provided by macOS: Standard or Enhanced. These can be enabled from System Preferences->Keyboard->Dictation, or on older systems System Preferences->Dictation & Speech.
Standard dictation (the default) requires an internet connection and provides speech to text translation using Apple’s servers. On older systems, the text is not translated until the Done button is pressed on the popup. On newer systems text is translated and placed into the field while the end user is speaking. Dictation will end automatically when text is entered from the keyboard or the field loses the focus.
Enhanced dictation requires the enhanced dictation engine to be downloaded, which is approximately 500MB for each language pack. This will then provide local machine based translation. Features of enhanced dictation are live feedback and offline support. With live feedback the text is rewritten while speaking. Enhanced dictation also provides spoken dictation commands such as “Select All”, “Cut that”, “Move left”, and so on. When enhanced dictation has been started it is possible to change the currently focused edit field and move the popup to the new field and continue to dictate. It is also possible to type and dictate at the same time.
Text in tooltips will wrap if it contains a carriage return character or other wrapping characters when the text width of the tip would exceed a third of the screen width. In previous versions, tooltips only used CR to line wrap when the width of the tip was greater than half the screen width.
In addition, the CR character is no longer displayed. However, any other control characters (characters less than space, or the character 0x7f) are displayed using the Unicode control character page.
This change also applies to tooltips for window class controls.
The File Control allows end users to upload or download files inside a remote form: from Studio 10 the control allows multiple files to be uploaded. The control itself is invisible and to enable the upload or download functions, you need to assign an action at runtime, to the $action property. The Upload and Download actions are represented by the constants kJSFileActionUpload and kJSFileActionDownload.
There is an example app called JS File Upload/Download in the Samples section in the Hub in the Studio Browser showing how you can upload and download files, and the same app is available in the JavaScript Component Gallery. In addition, the Contacts example app, under the Applets option in the Hub, uses the file control to upload a contact photo.
When in Upload mode the File control opens a standard Upload dialog to allow the end user to select a local file or files to upload. There are various properties to allow you to change the text and error messages on the Upload dialog, including $choosefilesbuttontext that allows you to specify the text on the ‘Choose Files’ button.
For downloads, the File control can provide a standard hyperlink pointing to the file to be downloaded, or you can assign a row variable to the $dataname of the control containing the binary data of the file to download, or a list for multiple file downloads. The download function is supported for mobile devices, and if the browser can interpret the contents of the file it is shown in a new browser window or tab.
Note that if a Timer control is present on the page, timer events will not occur while a file upload dialog is open, or while file download is in progress.
Support for the Upload or Download function on mobile devices depends very much on the device itself and the mobile operating system. Therefore, if you intend to include an upload or download function in your app, you should test your app thoroughly on all devices you wish to support. With this in mind, we are aware of the following limitations or issues regarding different mobile operating systems.
Upload does not work on iOS because the input element to select a file does not become enabled since iOS does not support it. Download works via the hyperlink because mobile Safari has been implemented to support hyperlinks. However, the other download mechanism does not work: on iOS for example, the download actually transfers the data to the client, but then the browser does not carry out any action with the data, so the downloaded file is lost.
To enable the upload function, you must set the $dataname property of the File component to a two-column row variable: Column1 should be of type List, and column2 should be of type Character ($dataname should be set before the upload action if triggered). The value assigned to column2 should be the name of a task variable of Binary type which will receive the binary data when the upload is complete. Column1 will receive MIME header list information when the upload is complete.
To trigger the upload dialog, you need to assign kJSFileActionUpload to the $action property. This action opens a file upload dialog which has two formats: one for up to date browsers, and the other for browsers which do not support XMLHttpRequest2, i.e. Internet Explorer and Opera. When a file has uploaded an evFileUploaded event is generated and the List and Binary task variable assigned to $dataname are populated. When the dialog closes the control generates evFileUploadDialogClosed.
The $maxfileuploadsize specifies the maximum size in bytes of a file to be uploaded to the server. Zero means no limit. Some clients (IE and Opera) cannot enforce this limit. See example below for details on how to upload a file.
While the Upload dialog is open, you can close it by assigning kJSFileActionCloseUpload to the $action property (note this does not generate evFileUploadDialogClosed).
On the upload dialog the file name is displayed above the progress bar, to the left, the percentage is shown above to the right, and file upload size information shown below as before. File sizes displayed to the user are in shown in the appropriate unit so when 1000 bytes is exceeded it changes to kB, 1000 kB changes to MB and 1000 MB changes to GB.
The $uploadtypes property allows you to filter the file types that can be uploaded. The property accepts a comma-separated list of file extensions or MIME types, for example, the string '.png, .jpg, .jpeg' would allow PNG or JPG files, or 'image/*' to allow any image files.
The File control allows multiple files to be selected for uploading by setting $allowmultiple to kTrue. It is not supported by some browsers, just like $maxfileuploadsize (IE9 and below, Opera).
The properties $maxbatchuploadsize and $maxbatchuploadsizeerrortext work similarly to $maxfileuploadsize to impose a limit of the total amount of data to be uploaded. This works independently of $maxfileuploadsize so you can impose a limit on single or multiple file uploads. In addition, $uploadedprogresstextbatch has been added to show the progress of the batch of files, and works similarly to $uploadprogresstext.
Error messages shown when file sizes are exceeded, for single or batches of files, give the user feedback on what the size limits are and lists the offending files exceeding the limit.
Multiple file upload dialogs display the same information for each single file, while another progress bar shows progress through the batch of files, including how many files have uploaded out of the total.
All the text and labels in the File control can be translated via the jOmnisStrings object in the JavaScript client. See the main Localization section for more info.
In its simplest form, the File control can provide a hyperlink to allow the user to download a file located on the internet. In this case, you would set the $visible property of the control set to kTrue, set $hyperlinkurl to the URL of the file, and $hyperlinktext to the text for the hyperlink. The URL does not have to be a file download URL, it can be any file on the internet and will open in a new browser window or tab. The File control will display the download as a standard hyperlink on the remote form.
You can also use the File control to download a file from a binary file or one stored in your database. To enable this functionality, you need to assign kJSFileActionDownload to the $action property. To download a single file, the $dataname property of the File control is set to a row variable, with Column1 as the file name, Column2 the media type (e.g. text/plain;charset=utf8), Column3 the name of a remote task variable which should be a binary containing the file data or character containing a file path, and Column4 is an 'Identifier' column (Character type) containing a name for the file.
You can specify a list in $dataname, instead of a row, to provide a list of files to be downloaded. The definition of this list is identical to the row, with each line on the line representing each file to be downloaded. The fourth 'Identifier' column can contain a unique name for each file.
The File control has an event, evDownloadSent, which indicates if the download was successful, and identifies the file that was downloaded. The event receives two parameters:
pSuccess
Whether or not the download was successsfully sent.
pIdentifier
The value of the Identifier column (the fourth column, if provided) in the download list/row which was assigned to $dataname to initiate the download which has now been sent.
The evDownloadSent event will be triggered when the server has sent all of the data for a file to the client. Note that Omnis sends the data in a single chunk, so the client may still be processing the data at this point. However, at the point that the event is fired, the server has sent all of the data, and the task variable containing the binary data (or file path) can now be re-used.
A File control is used in the jsContacts form in the Contacts sample app to allow end users to upload a photo of their contacts. The File control is placed somewhere on the form, its $dataname is set to iFileRow, an instance row variable, and the evFileUploaded and evFileUploadDialogClosed events are enabled in the $events property of the control. The iFileRow variable is setup in the $construct method of the form, as follows:
MimeList is a local list variable, and tData is a task variable of type Binary – it’s important to note that the second column of iFileRow is of type Character, and is set to the Name of the binary task variable. Elsewhere on the form is a picture control to display the photo, its $dataname is iPicture, and a button to allow the end user to select an image file and initiate the upload process. The code for the button is:
This assigns the kJSFileActionUpload action to the fileControl object which opens the Browse/Upload dialog. The File control has an $event method which detects when a file has been uploaded and the upload dialog has been closed:
When an image is selected by the end user and the file is uploaded the image data is loaded into the tData task variable, as defined in the second column of the iFileRow row variable, which is then transferred to the iPicture variable assigned to the picture field on the form. The Save button saves the contact record including the image file uploaded by the user.
The HTML Object lets you display an HTML page or fragment in a remote form, such as an HTML link or formatted paragraph. The $html property contains the HTML content for the control. There is an example app called JS HTML in the Samples section in the Hub in the Studio Browser, and the same app is available in the JavaScript Component Gallery.
The HTML content for the control must start with an element declaration such as <div...> or <style>. The $wraptext property is set to true by default meaning that the content in the control will wrap (set it to kFalse to stop wrapping): this property sets white-space for the control to 'normal' if true, and 'no-wrap' if false.
The HTML control has a property, $showruntimepreview, which defaults to kTrue, which ensures the HTML is rendered in the remote form rather than showing the HTML code text. If $showruntimepreview is false, the HTML code text is shown, but it cannot be scrolled inside the control in the design window.
Note: This technique using $ctrlname to add custom controls to a remote form is deprecated. You should instead use JSON-defined controls: see the JSON Components chapter.
You can use a custom JavaScript control on a remote form by embedding it in an HTML Object. To do this, the JavaScript file defining the custom control must be placed in the html/scripts folder and referenced in the HTML file containing your remote form (this can be added to the jsctempl.htm file or the specific HTML page containing your remote form). The name of the custom control class (as defined in its JavaScript file) must then be added to the $ctrlname property of the HTML Object.
If you want your custom control to inherit the HTML control's specific functionality (such as the use of $html and its placeholders feature), your custom control must inherit from ctrl_html, rather than ctrl_base (and do not override this.superclass, instead use a different variable to reference the ctrl_html immediate parent class).
The example library (in the Samples section in the Hub in the Studio Browser) shows how you can use HTML to format text using tages and styles, and embed the content into a Remote form.
The same app contains a more complex example showing how you can format HTML for an email. In addition to the HTML example app, there are also two examples in the Samples section in the Hub (and in the Component Gallery) to display a Twitter button and a Twitter Timeline that use the HTML component to embed the necessary HTML into a remote form.
The following HTML is used to create the initial Twitter button:
You can use the Text: or Sta: command to build up the HTML content. The following method constructs some HTML and assigns it to $html of an HTML control called HTML.
You can embed any of the standard HTML tags into the $html property, including links, styles, and tables. The following text could be added to an HTML control which is placed next to a check box control on a remote form to allow end users to popup a window containing competition rules that are stored in a static html page:
The HTML Control reports the evBefore and evAfter events, as well as evClick and evDoubleClick.
You can inherit the effects and font attributes that you set for the HTML object in the Property Manager in design mode by inserting various placeholders in the $html property. The placeholders take the format %<letter>, for example, insert %f to inherit the font specified in $font, or %t to inherit the text color set in $textcolor. Most of the placeholders should be inserted into an html element using the style tag, while others are attributes and can be inserted directly into an HTML element.
Placeholder | Type | Description | Property or desc |
%b | attribute | back color and alpha | $backcolor and $alpha |
%f | style | font | $font |
%z | style | font size | $fontsize |
%s | style | font style | $fontstyle |
%j | style | font align | $align |
%t | style | text color | $textcolor |
%e | attribute | effect | $effect |
%p | style | position | coordinates of omnisobject |
%v | style | vert scroll | $vertscroll must be kTrue |
%h | style | horz scroll | $horzscroll must be kTrue |
For example, you can set $html to <div %e></div> and the text in the control will take on the effect from $effect (or $linestyle or $bordercolor, as these are effect properties).
To use the font specified in the HTML object in a paragraph in your HTML insert: <div><p style="%f">SOME TEXT</p></div>. For example, the following HTML produces some text rendered in plain or default HTML paragraph style and second paragraph of text that uses the font setting specified in $font in the HTML object, which in this case is set to “Verdana,Arial,Helvetica,Sans-serif”:
If the HTML object appears in a Paged Pane or Subform (i.e. inside any container field), you will need to add the “white-space:normal” parameter to the <div> tag containing your Html to allow the text to wrap correctly inside the object. For example, the following <div> tag will contain text etc within a 300px width:
The Hyperlink Control allows you to present a list of options to the end user, where each option in the list is displayed as a web-style hyperlink; each link option corresponds to a line in the underlying list variable used to populate the list. If the whole list does not fit inside the control, the list will “pop up” when the end user passes the mouse over the control. The $extraspace property specifies extra spacing between links. The Hyperlink control is used in the Studio Browser and is very similar to the JavaScript version of the control.
The options or list contents in the Hyperlink control are based on the contents of a list variable specified in $dataname. The first column in the list should be the text displayed for each option listed in the control, unless $listcolumn is specified which is the column of the list variable used to populate the control. Subsequent columns in the list can be used to specify other values.
When the end user clicks on the list an evClick is triggered with the selected line reported in pLineNumber. You can use the value of pLineNumber in your event method to trigger an action. You can create an empty line by putting ”-“ (hyphen) in the first column.
If $isvertical is kTrue the list pops up vertically, and if $shouldunderline is kTrue the links are underlined. The $selectedtextcolor property specifies the color of the text when the mouse is over it.
There is an example library called JS Hyperlink in the Samples section in the Hub in the Studio Browser showing how you can build a dynamic hierarchical list using the Hyperlink control; the same app is available in the JavaScript Component Gallery.
The following method is the $event() method for the Hyperlink control:
The Label Object lets you add standard text labels to your remote form. The text for the label is entered into the $text property in the Property Manager, or you can double-click on the text for the label to edit it. Alternatively, you can assign some text to the $text property in your code.
The font and alignment of the label is setup under the Text tab in the Property Manager. You can use the style() function to style parts of the text assigned to $text, for example:
Styled text is only supported if $textishtml is false. When set to true, the $textishtml property means the text in $text is interpreted as HTML, so in this case you can use any HTML tags and styling to format the text. For example:
Labels have the $dataname property which means you can assign the text from a variable. In this case, the value in $dataname overrides the value in the $text property, and actually sets $text. You can assign a Date variable to $dataname, in which case the label takes its display format from #FDT, #FD, or #FT depending on whether the variable has a date/time component.
The standard List Control allows you to display a single column list on your remote form allowing end users to select a particular line; the following screen shows a simple product list using the ‘ice’ JS Theme in use.
If the $ischecklist property is kTrue in the standard List control, each list line has a checkbox which allows the end user to select or de-select the line, which is useful for multi-select lists or checklists.
There are several example apps showing different types of list control in the Samples section in the Hub in the Studio Browser (see JS List, JS Linked List, JS List Pager), and the same apps are available in the JavaScript Component Gallery.
For lists with many columns, you may prefer to use a Data Grid Control, or for a more compact single-column list you can use a Droplist Control. If you want to include an icon next to the text in each list line you can use a Tree List Control by including your data and icon references at the top-level of the list data without using any child data. For a further alternative to the standard List box, you can use the Native List to display list data but with a native appearance on each OS.
The contents of a standard List is taken from the instance variable (of List type) specified in the $dataname of the control. In this case, the first column of the list contents is used to populate the list control; you can specify an alternative column for the data in $listcolumn. You can build the list using an instance variable of List type in the $construct method of the remote form so it is available to all instances; the list can be built from your database or from a number of static values.
The JS List example app in the Hub uses a simple check list ($ischecklist = kTrue) and a standard List control; the check list is built in the $construct method of the form, as follows:
The example app provides a button to merge the selected lines in the check list into the other list. The code behind the button is:
See the ‘Programming Lists’ chapter in the Omnis Programming manual for more information about using list variables in your code.
You can control the color for selected lines by setting $selectedlinecolor; use kColorDefault for the default selected line color for the client OS, or the current JS theme. The $evenrowcolor property sets the background color of even numbered rows displayed in the list; kColorDefault means use the same color as the odd numbered rows ($backcolor).
When the user selects a line the evClick event is reported with the pLineNumber parameter reporting the selected line number. You can also set the evDoubleClick event for a list control to detect when the end user double clicks on a list line. List events will retuen the pLineNumber parameter containing the number of the line clicked, and you can use this in your event method behind the list to trigger an action.
A double-click event is sent to a List control if the Enter or Space key is pressed while the focus is in the List and if evDoubleClick is enabled on the list. Otherwise, if the control has an evClick event enabled, Enter/Space sends an evClick. If the control does not have the evClick or evDoubleClick enabled, then Enter triggers the okkeyobject (if there is one), as long as the state of the list has not changed, i.e. the current line has not changed, and no checkbox has been toggled.
You need to prefix the column name with $ref for a search to work in a client method. For example:
The JavaScript Client does not support smart lists in client executed methods, insofar as if you change the list in some way on the client, it will no longer be a smart list when the updated data is sent from the client back to the server. Smart lists work as expected in server executed methods.
Lists have the $vscroll and $hscroll properties which allow you to scroll a list vertically or horizontally at runtime in the client browser; note these properties are write-only meaning that you cannot return their values at runtime. The vertical or horizontal scroll value assigned using $vscroll or $hscroll is the row number for a list.
The $keyboardchangesline property determines whether or not the the current line in the list changes when the end user navigates the list using the keyboard; the property is available in the standard JS List, Native lists, Tree lists, and Data grids, and only takes effect when $multipleselect is kTrue. This allows multiple rows to be selected while also having the keyboard change the current line. To enable users to select non-adjacent lines with the keyboard, $keyboardchangesline can be set to kFalse.
When the list only allows a single line to be selected ($multipleselect is kFalse), navigating the list with the keyboard always uses a focus line and the user has to manually select a current line with the Space or Enter key, at which point evClick is fired.
You can link a List control to an Edit control to create a “Linked List”, so that when the end user types into the edit field the contents of the list is updated dynamically. There is an example app called JS Linked List in the Samples section in the Hub in the Studio Browser to show the use of a Linked list; the same app is available in the JavaScript Component Gallery.
The combination of an Edit control with key presses enabled and a List control allow you to create a dynamic list that has the ability to update in response to what the end user types into the edit box. A Linked List is in effect like a Combo box, but with the extra ability to update itself as the user types. To enable this feature, edit controls can detect certain key presses and can be linked to a list control, while for lists themselves there is a property to display selected lines only.
The Edit Control has the $linkedobject property which is the name of a list control on the current remote form used to display suggestions to the user if the Edit control enables the evKeyPress event. You need to add the code to populate the list in response to evKeyPress, based on the current value of the instance variable specified for the Edit control.
When the end user types into the Edit control, the linked list will appear automatically. It is not necessary to process any events for the list control, since the dynamic list behavior is determined automatically by being linked in this way. Therefore, you would expect the following to happen when end users are using a dynamic linked list:
Clicking on a line in the open list will set the edit control to the value of the clicked line.
Pressing up or down arrow when the focus is on the list control will set the value of the edit control to the new current line of the list.
Pressing the down or up arrow when the edit control has the focus and when the list is not visible will open the list, set the edit control value to the selected line in the list, and move focus to the list.
Typing into the edit control when the list is closed will open the list and keep focus on the edit control.
All the following will close the list: pressing return when the list has focus; pressing escape, or clicking away from the list or the edit control.
The list property $selectedlinesonly specifies that only the selected lines in a list will be displayed (this only applies when $ischecklist is false), which in the context of Linked lists allows you to filter the content of a list that is linked to an Edit control. You should optimize the $event method for the edit control in the following way:
Make the $event method for the Edit control execute on the client.
On evKeyPress, if the list of suggestions is empty (or no longer suitable for the data), call a server method to build the list (with lines selected based on the value of the edit control).
In subsequent evKeyPress events that can use the pre-built list, perform a list $search to change the selected lines to the ones which are suitable for the new value of the edit control.
In this way, the list of suggestions is cached on the client, and updates simply by changing the selected lines with a search in your code.
When $selectedlinesonly is true, the processing involving the usual click events and so on all use the line number of the data in the list, not the lines displayed in the list.
Note that if you use the $evenrowcolor property when $selectedlinesonly is true, the even row color applies to the numbers obtained by counting the displayed lines, rather than using the line numbers of the data in the list.
Edit controls have an event called evKeyPress; the Key press detection was added to support Linked Lists, but it could be used by itself for other purposes. The evKeyPress event has a single event parameter, pKeyList, which is a three column list containing the keys entered since the last evKeyPress event (or since typing started) with a row for each key in the order the keys were pressed.
Each key in the list is either a data character or one of a limited set of system keys (note that not all keyboard keys are supported, such as function keys are not supported). Transitions in shift state, ctrl state, and so on, do not result in a key in the list, so if the user types Shift+a, the character in the list will be A. The supported system keys are:
Backspace
Tab
Escape
Insert and Delete
Up, Down, Left, and Right arrow key
Page Up and Page Down
Home and End
Return
The columns in the list are as follows:
Colum 1: If the key is a system key, column 1 is the keyboard constant value representing the key, such as kEscape. Otherwise column 1 is #NULL.
Colum 2: If the key is a data key, column 2 is the character data for the key. Otherwise column 1 is #NULL.
Colum 3: Is the sum of the following keyboard modifier constants, representing the state of these modifiers at the point the key was added to the list: kJSModShift, kJSModCtrl, kJSModAltOrOption, kJSModCmd.
In addition, there are some properties which control when evKeyPress events are generated. The Omnis preference $keyeventdelay is the minimum number of milliseconds (0-2000) between evKeyPress events. The first evKeyPress will also be delayed for this duration. This allows you to throttle keyboard events in the case where they will be executed on the server, and therefore reduce the load on the server. If true, the preference $systemkeys specifies that evKeyPress events include system keys which do not change the value of the data. If false, only system keys such as backspace are included as they potentially change the data.
While the user is typing, the edit control in the user interface remains enabled (unlike normal event processing where the entire user interface is usually disabled). The value of the instance variable associated with the edit control reflects the current content of the entry field when evKeyPress is generated.
The following method is the $event() method for the Edit field linked to a list of names (from the example app in the Hub):
The $pagesize property allows you to display the lines in a list or data grid as separate pages, to improve the user experience when navigating lists or grids with a large number of lines; the default value is zero which means no list pager is displayed. The $pagesize property is available for the JS List, Data Grid, Complex Grid, and Native List (when not using grouped lists). There is an example app showing the List pager for all these list types in the Samples section in the Hub in the Studio Browser.
When assigned an integer value, the $pagesize property forces the contents of the list or grid to be sub-divided into a number of scrollable pages, and a set of page number buttons (as well as forward and back buttons) are displayed under the list or grid box, which allows the end user to “page through” each group of lines in the list or grid.
The value assigned to $pagesize specifies the number of list lines displayed in each page, and therefore the total number of lines in the list, divided by the value of $pagesize determines the number of pages in the list or grid field, as well as the number of buttons displayed in the pager panel. The $pagerpage property allows you to set the page to be displayed, with the first page as the default.
Note that setting $pagesize does not reduce the amount of data sent to or fetched from the server – the full list data is sent to the client, and the setting of $pagesize is only used for displaying the list or grid with the pager element.
The appearance of the pager, such as the color of the buttons, numbers, and arrows, cannot be controlled using standard component properties. However, if you wish to customize the appearance of the pager, you can do so by overriding the associated CSS classes. These classes are named ‘omnis-pager<-xxx>’ and are listed in the core.css file. Note that this file is minified, so you may want to use a prettifier tool to make it more human-legible. Do not edit the classes in core.css, rather you should override the classes by adding your own version in the user.css file found in the html\css folder in your Omnis development tree.
The Map Control allows you to place a Google Map® on your remote form; this provides many of the functions available in a Google map as provided by the Google Maps API, such as placing your own markers or customizing the markers.
There is an example app called JS Map in the Samples section in the Hub in the Studio Browser showing the full capability of the Map control; the same app is available in the JavaScript Component Gallery which you can view online, to see many of its capabilities, but you will need a Google API key to run the example app in development mode.
In order to use the Map control, you need to register with Google Cloud Platform to obtain a Map API key, which can be entered in the $apikey property of the Omnis Map control; the Map control will not work without the API key. Specifically, you need to:
Create and activate a Google Cloud Platform account (a free trial is available with credits)
In the console under Credentials, create a new API key; copy this API key and add it to the $apikey property of the Omnis Map control in your remote form
Under APIs, navigate to Map APIs and enable the “Maps JavaScript API”. In addition, if you want to use the Geocode function, you need to enable “Geocoding API” (there are other APIs which you may be able to use).
Important Note: By signing up to Google Maps API via the Google Cloud Platform and using Google Maps in your deployed Omnis application, you and your end users must agree to the general “Terms of Use” for Google Maps: there is a link to these Terms of use on the map displayed in the Map control. Omnis Software cannot be held responsible for any third-party products or services and will not be liable for any damage or loss resulting from your use of the Google Maps content or the products.
Apart from the $apikey property, there is no further configuration needed to display a basic Google map in your remote form, however, to make the map really useful you will probably want to display specific locations, add markers on the map, or allow end users to interact with the map: all of these are possible with the JS Map control and are described below.
The $latlong property allows you to specify the center location of the map as “latitude:longitude”, for example, a value of 40.749305:-73.985775 will center the map on New York. If you do not set $latlong initially (by setting the property in the Property Manager in design mode or in the $construct method of the form), the map will open at some unspecified location, usually the default location setup in Google on the client device.
The $::zoom property lets you set the zoom level of the map: the range is 0 to 21, with zero showing the largest area (the whole world) and 21 the smallest possible area. The default zoom level is 8 which shows a reasonable amount of detail for the current center location of the map.
The Map component supports Google Geocoding which allows you to convert a street address into a geographic coordinate like latitude and longitude, which you can use to place a marker on a map, or center the map.
To use the Geocoding function you need to access the Geocoding API which itself requires a separate API Key, in addition to the Maps API key, which you can obtain from Google.
A Search button has been added to the JS Map example available in the Hub to show how you can convert a street address to a latitude:longitude coordinate which can be applied to the $latlong map property. Note the example app places the Geocoding API key in the $userinfo property which is then sent to Google.
Alternatively, you can find the latitude:longitude coordinate manually. To do this, Right-click somewhere on a standard browser-based Google map (not the Omnis map control), select the ‘What’s here’ option and the latitude:longitude value of that position is shown on the popup. You need to replace the comma with a colon to be used as a parameter in Omnis, e.g. 52.223460:1.492379.
The $maptype property lets you set the type of map – this can be set to a constant: kJSMapTypeRoad (default), kJSMapTypeSatellite, kJSMapTypeHybrid, and kJSMapTypeTerrain. The end user can change the map type using the map type control shown on the map, assuming the $maptypecontrol property is enabled.
The other standard map controls, including the pan control, scale control, and the street view control are enabled using the properties $pancontrol, $scalecontrol, and $streetviewcontrol, respectively (these are all enabled by default): note you can only change these properties at runtime if the map control itself is enabled ($enable = kTrue).
The zoom control can be further controlled by setting the $zoomcontrol property: it can be set to kJSMapZoomOff, kJSMapZoomDefault (the default), kJSMapZoomSmall, and kJSMapZoomLarge. The latter two settings correspond to a simple Plus|Minus button (Small) or the same button with a vertical slider control (Large) for finer adjustment of the map zoom level.
You can place a marker or set of markers on the map by assigning a row or list containing marker information to the $mapmarkers property. For each marker you must define the latitude and longitude of the marker location in the first column of the setup list in the format latitude:longitude (e.g. “40.749305:-73.985775”), and in subsequent columns you can specify the marker title (shown when you hover over the marker), the tag or title for the popup (shown when you click on the marker), and html content for the popup. An optional fifth parameter can specify an icon for the marker to replace the default map marker (see below). If the third and fourth columns are empty for any marker defined in the list, the marker will not popup when clicked. (See the Events section about how to add markers via user clicks.)
The following code adds markers to a map indicating the Empire State Building and Central Park in New York, it then centers the map on the Empire State Building, and sets a zoom level of 12 which shows a reasonable level of detail in this case:
The marker list assigned to $mapmarkers can have an optional fifth column which you can use to specify the icon URL for an image for the map marker. An empty string in this column (or a missing column altogether) means that the marker will use the default marker icon. The value for the marker icon is an icon URL which you set using the iconurl() function. Since the marker image has to be set for each row in your list you can specify a different image for each marker in the marker list, but if you want the same image for each map marker you still have to set the marker image for every row in your marker list.
You can assign an alternative marker icon or symbol, including map markers from the Google maps API, by adding a sixth column to the marker list: in this case the fifth column should be omitted.
The definition for the markers list in the JavaScript Map control can be:
where iMarkerCustom is a new string column (column 6) specifying a custom marker. When a marker is defined in the marker list, and the iMarkerIcon (column 5) is empty, iMarkerCustom can be included with the following attributes, separated with a ‘|’ character (you only need to specify the attributes required). An example custom string would be:
Or to draw a five-pointed star marker:
Or to draw a circle marker:
Where the custom marker parameters are defined as:
path can either be a map symbol, or an SVG notation path, as defined below
fillColor the color used to fill the marker object, an html css color name or value e.g. #FF0000
fillOpacity the opacity of the fill color, a value from 0 to 1, e.g. 0.5 is 50% transparent fill
scale a scaling factor for the object
strokeColor the color used to outline the object, an html css color name or value e.g. #FF0000
strokeWeight the thickness of the stroke line
anchor allows you to set the anchor position or offset the shape. By default, shapes are aligned to the top left of the marker relative to its lat:long
Marker Symbol – prefixed google.maps.SymbolPath. | Description | |
---|---|---|
CIRCLE | A circle. | ![]() |
BACKWARD_CLOSED_ARROW | A backward-pointing arrow that is closed on all sides. | ![]() |
FORWARD_CLOSED_ARROW | A forward-pointing arrow that is closed on all sides. | ![]() |
BACKWARD_OPEN_ARROW | A backward-pointing arrow that is open on one side. | ![]() |
FORWARD_OPEN_ARROW | A forward-pointing arrow that is open on one side. | ![]() |
For example:
The Map example app includes the use of markers and polygons, and is available in the JavaScript Component Gallery. The following image shows the location of the European Omnis offices using the “Backward-pointing Closed Arrow”.
The map control has a property $fitmaptomarkers that can be assigned value 1 at runtime to force the map to zoom in or out to allow all the map markers to be shown.
In addition to icons and standard map markers, you can add polygon objects or irregular shapes to maps in the JavaScript Map control. The $mappolys property specifes the data name of a list which contains the definition of each polygon or shape as follows:
iPolyLatLong the latitude:longitude values for each of the the points of the polygon, so a triangle would have 3 points: the lat:long settings are separated with the ‘|’ character, e.g. 25.774,-80.190|18.466,-66.118|32.321,-64.757|25.774,-80.190
iPolyStroke the color used to outline the polygon, which is an html css color name or value e.g. #FF0000
iPolyOpacity the opacity of the stroke color, a value from 0 to 1, e.g. 0.5 is 50% transparent
iPolyWeight the thickness of the stroke line
iPolyFill the fill color of the polygon object, an html css color name or value e.g. #FF0000
iPolyFillOpacity the opacity of the fill color, a value from 0 to 1, e.g. 0.5 is 50% transparent
iPolyTag the tag name or label for the polygon, which is sent to the evPolygonClicked event method in pPoly
For example, the following code draws the Bermuda Triangle on the map (see the JS Map example app):
The evPolygonClicked event with the parameter pPoly is called when a polygon on the map is clicked, and pPoly will be set to the polygon tag as defined in the list.
There are various events available in the map control to allow you to detect when and where the map was clicked (evMapClicked, reports latitude and longitude of the click), when the map is dragged by the end user (evMapMoved, reports the latitude and longitude of the new center location), when the map is zoomed using the zoom control (evMapZoomed), or when a map marker is clicked (evMarkerClicked). None of these events are enabled by default, so you have to enable them in the $events property for the control using the Property Manager.
The following $event method could be placed behind a map control to detect when the map is clicked, or when a marker is clicked (assuming a marker has been added), or if the map is moved or zoomed. The add_markers Boolean variable is linked to a checkbox on the window to allow the end user to enable or disable the ability to add markers. When the map is clicked, the evMapClicked event reports the position in pLatlong, and a marker definition is added to the map_markers list. The message variable is assigned to a field on the form to show either the new center of the map, the new zoom level, or which marker has been clicked.
The Native List control appears in the ‘JavaScript Native Components’ group in the Component Store, and it provides a list control that looks familiar on different platforms. You can customize the accessories in the list by adding your own HTML content and CSS styling, and therefore provide a very rich UI in a single list format.
In keeping with this philosophy, the JS Native List exposes many appearance properties to allow you to customize the list how you wish. If you leave any of the values as kColorDefault, they will revert to the platform-specific default.
The native list has been designed along the same lines as the iTableView component of iOS forms. The list can either be a standard flat list or a grouped list, using nested lists.
To increase efficiency, the list only draws the displayed rows, along with several more in a buffer zone around them, at any one time. This provides smooth scrolling, and means that the size of the list has very little impact on performance. As a side-effect of this, when scrolling quickly, you will see that the rows may not be rendered immediately.
There is an example app called JS Native List in the Samples section in the Hub in the Studio Browser showing how you can customize the accessories in a native list; the same app is available in the JavaScript Component Gallery.
The structure of the List instance variable used for the $dataname of the native List control differs based on how you wish the list to display.
The Data tab in the Property Manager allows you to assign column numbers for each row part, i.e. $text1col allows you to specify which column in your list contains the the data to display as the main text of the row. If you do not wish to make use of a particular row part, leave its column set to 0.
You need to define and populate your list in accordance with the column numbers you have set in the Data tab of the Property Manager. The content of these columns should be as follows:
text1col: This should be Character data, to display as the main text for the row.
text2col: This should be Character data, to display as the secondary text for the row.
imagecol: This should be Character data - a URL to an image to display.
The image will be scaled to fit the size of the row’s image (customized using $imageheight & $imagewidth).
The URL can make use of Omnis’ support for pixel-density-aware image selection by passing the URL in the format: “<URL to 1x image>;<Name of 1.5x image>;<Name of 2x image>” (where all 3 images are in the same location). This means that on a Retina device it will use the 2x image, but on a standard display device it will use the 1x image. As the image is scaled anyway, you could just always use the 2x image, but this method reduces unnecessary bandwidth usage and processing of larger images
accessorytypecol: This should be a kJSNativeListAccessoryType… integer value. It determines the type of accessory to display on the right edge of the row.
Use kJSNativeListAccessoryTypeNone for no accessory
accessoryvaluecol: Contains the current value of the row’s accessory.
This is currently only used by the Checklist accessory, to represent the checkbox’s state
accessorycontentcol: This should be Character data, and should describe the content for some accesssory types. The Accessory types which make use of this are:
Button: For rows with a button accessory, the content should be the text for the button.
Custom: For rows with a custom accessory, this should be HTML to describe the contents of your custom accessory.
CustomWithEvent: see below.
You can add your own custom row accessories by setting the accessorycontentcol list column to kJSNativeListAccessoryTypeCustom or kJSNativeListAccessoryTypeCustomWithEvent.
kJSNativeListAccessoryTypeCustomWithEvent works in the same way as kJSNativeListAccessoryTypeCustom but will trigger a different click event when you click on the accessory (evClick will be called with pWhat equal to kJSNativeListPartAccessory instead of kJSNativeListPartRow).
When accessorycontentcol is set to a custom accessory, its value should be the HTML content of your custom accessory, encapsulated within a single parent element.
You can set your accessory to a particular size (rather than fill the available space in the row) by providing width & height values in the style tag of your top-level HTML element.
If a size is defined in this way, the native list control will attempt to center the accessory. If this does not work, you may also need to set "position: absolute;" in your style tag. For example:
If you wish your Native List control to display its data as a Grouped list, you need to change the structure of the list assigned to $dataname. The main list should comprise two columns:
Column 1: Should be defined as being of type “List”, and each row should contain a list structured as defined above (adhering to the columns specified in the Datatab of the property inspector). All of the rows defined in this sub-list become part of a single group.
Column 2: A Character column, defining the name of the group.
The Native List component has many properties to allow you to customize its appearance. Most of these are self-explanatory and/or are described by their Property Manager tooltips. The following may need futher explanation:
$rowdisplaystyle: Determines how the row is displayed. Value should be a kJSNativeListDisplayXXX constant. Current values allow you to change between displaying the two text fields in a vertical or horizontal fashion.
If you wish to change the default appearance of the Native list for a particular platform, or wish to change something which is not exposed as a property, it is recommended that you extend any relevant CSS styles in your user.css file.
When extending the CSS used by any controls in Omnis, there is the possibility that you may change how a control appears or behaves (especially if you alter sizes), so you do so at your own risk.
The Native Slider control appears in the ‘JavaScript Native Components’group in the Component Store, and it works, for the most part, in the same way as the standard JavaScript Slider component but has a more familiar appearance when running on different platforms. There is an example app called JS Native Slider in the Samples section in the Hub in the Studio Browser, and the same app is available in the JavaScript Component Gallery.
The current value of the slider is reported in the property $val according to where the slider is positioned. You can specify the range for the slider in the $::min and $::max properties. The $usessteps property is a Boolean determining whether or not the slider should snap to discrete step values specified in $step.
The Slider reports three events: evStartSlider (when the control is starting to track), evEndSlider (when the control has finished tracking), and evNewValue (when the value has changed). You can detect these events in the $event method for the component. These events all pass the current value of the Slider in the pSliderValue parameter. As the user drags the Slider thumb the evNewValue event is triggered and pSliderValue is sent to the $event method for the Slider.
If you do use evNewValue, you should mark your $event method as client-executed and consider enabling the $usessteps property and setting $step to limit the number of events being triggered as the user moves the slider. Alternatively, you could use the evEndSlider event to report the final value since for most purposes this will be the value selected by the user.
The Native Switch control appears in the ‘JavaScript Native Components’group in the Component Store, and it works, for the most part, in the same way as the standard JavaScript Switch component but has a more familiar appearance when running on different platforms. There is an example app called JS Native Switch in the Samples section in the Hub in the Studio Browser, and the same app is available in the JavaScript Component Gallery.
![]() |
![]() |
---|---|
iOS | Android |
The Switch has a $dataname property, to which you can assign a Boolean instance variable. This will be kept up to date with the state of the switch, as the end user clicks or taps on the control.
The Switch has $justifyhoriz and $justifyvert properties. For some platforms (e.g. iOS) the switch maintains a specific aspect ratio. These properties determine how the switch is positioned inside the control in these circumstances.
The text displayed on the Native Switch is controlled by two members in the built-in strings object jOmnisStrings in the JavaScript Client. You can use the members "switch_on" and "switch_off" to replace the default text with your own text, for example, if you wish to provide different language equivalents to the default text.
Information about how to change or localise these strings can be found in this manual, under "Localizing Built-in Strings".
If you wish to override the base text, you could use the following code in a separate JavaScript file loaded in your form's html file after omjsclnt.js:
The Navigation Bar Control (or Nav Bar) provides a standard navigation bar which end users can use to navigate to different parts of your application. There is an example app called JS Nav Bar in the Samples section in the Hub in the Studio Browser, and the same app is available in the JavaScript Component Gallery. ; the following screen shows the example Nav Bar using the ‘sky’ theme.
The Navigation Bar has a main title in the middle of the control, and it can have a left and/or right button which respond(s) to user clicks; see above, Page 2 is displayed, with ‘back’ and ‘forward’ buttons displayed on the left and right, respectively.
The Nav bar can be linked to a Paged Pane via the $linkedobject property to allow you to display different panes in your form in response to clicks in the Nav bar. Actions for the Nav bar can be stacked up using the $push property: see the example below.
The Nav Bar has a number of properties for setting the color, fonts and style of the bar and buttons ($button.. properties), together with the following properties:
Property | Description |
---|---|
$disableanimation | Disables the animation when moving between pages. This property can only be set in design mode (not at runtime using the notation) |
$initiallefticonid | If this is not zero, and $initiallefttext is empty, the first navigation bar item has a button on the left hand side, displaying this icon |
$initiallefttext | If this is not empty, the first navigation bar item has a button on the left hand side, displaying this text |
$initialrighticonid | The icon for the initial navigation bar button on the right |
$initialrighttext | The text for the initial navigation bar button on the right |
$initialtitle | The initial title displayed on the navigation bar |
$lefthidden | If true, the left hand (back) button is hidden for the current navigation bar stack item |
$linkedobject | The name a paged pane on the current remote form, used in conjunction with the $push property |
$push | At runtime, allows you to assign a 2-6 column row to the paged pane referenced in $linkedobject: col1 is the page number of the paged pane, col2 is the title for pushed item, col3 is the text for right button (pass empty for no right button), col4 is the or icon id for the image for right button, and col5 can be non-zero to hide the left button, col6 is the text for left or ’Back’ button (pass empty to display the title of the previous pane by default). The path to the icon referenced in col4 must be obtained in a server method using the iconurl(icon-id) function since icon ids cannot be resolved on the client |
$pop | Removes a specified number of items off the navigation stack: see below |
$righticonid | If this is not zero, and $righttext is empty, the current navigation bar item has a button on the right hand side, displaying this icon |
$righttext | If this is not empty, the current navigation bar item has a button on the right hand side, displaying this text |
$::title | The title for the current navigation bar stack item |
Setting $disableanimation to kTrue disables the animation when moving between pages: this property was added to fix a problem when using the built-in VoiceOver screen reader on an iPad in conjunction with a Nav Bar linked to Page Pane: the problem is avoided by disabling the animation effect on the Nav Bar.
You can use the $pop property to “pop” or remove a specified number of items off the navigation stack: it is analogous to clicking on the left or back button, since it allows you to step back in the navigation stack a specified number of times.
The $pop property can only be assigned at runtime. If you try to pop more items off the stack than exist, it will pop everything except the first item. If you assign to $pop, note that the evUserChangedPage event of a linked paged pane will not be triggered.
In addition, you can set the text or title for the left (back) button for a navbar. If provided, the 6th col in the row assigned to $push allows you to specify the left button text. This can be set to an empty string to default to the previous page's title.
The Nav Bar reports evClickInitialLeftButton when the initial left button has been clicked, and evClickRightButton when the right button has been clicked.
The events evPushFinished and evPopFinished are triggered when the push or pop animations complete. Both events have one event parameter which is the associated page number that has been pushed or popped.
The following Navigation Bar has a main title and a button on the right which is used to display some information on the second pane of a paged pane.
The Nav Bar is placed across the top of the form and its various properties under the General and Appearance tabs in the Property Manager are set, as follows:
$events | set to receive evClickRightButton events |
$linkedobject | set to pPane, the name of the paged pane |
$push | can only be assigned at runtime; see below |
$initialtitle | set to “Main Page” |
$initialrighticonid | set to 1794, the id of an icon in Omnispic |
$initialrighttext | set to “Info” |
The $event method for the Nav Bar ($name = oNav) traps a user click on the right button, and has the following event code:
The $doPush method is a class method in the remote form and has the following parameters, variables, and code.
The effect of assigning to the $push property is to change the pane number in the paged pane specified in the $linkedobject property which, in this case, displays some information for the end user on the second pane. Assigning to $push adds a left or ‘Back’ button to the navbar which the end user can use to go back to the previous pane; the default text for this button is the name of the previous pane, or you can pass your own text in the 6th column of the row passed to $push.
The Navigation Menu Object (or Nav Menu) allows you to build interactive cascading menus within your remote forms, providing a navigation method similar to that found on many websites. Such menus typically comprise a number of hot text links, which cause further menus to open below the top level. In addition, each menu option can have an image as a background or link. The nav menu can also operate as a breadcrumb, with a hierarchical set of text links, similar to the folder selection mechanism found in Windows Explorer.
The Nav Menu control has been implemented for both the JavaScript client (remote form class) and the fat client (window class), and the two controls have almost identical properties, with the same look and feel. Unless otherwise stated, the descriptions here apply to both the JavaScript Client and fat client types of control.
There is an example app called JS Navigation Menu in the Samples section in the Hub in the Studio Browser, and the same app is available in the JavaScript Component Gallery.
The Navigation Menu control uses a list specified by $dataname to define its content. The list should have seven columns with each line of the list corresponding to a single entry in the menu. The columns in the list are defined as follows:
Column | Type | Description |
---|---|---|
Type | Integer | The menu entry type, a kNavMenuType… constant. See below. |
Text | Char | The text for the menu entry. This can include styles embedded using the style() function, and embedded kCr characters in order to split the text over multiple lines. |
Desc | Char | Optional text describing the menu entry. This can include styles embedded using the style() function, and embedded kCr characters in order to split the description over multiple lines. |
Flags | Integer | Sum of one or more constants that indicate how the menu entry behaves. See table below. |
Ident | Integer | A unique integer value that identifies the menu entry. Note that the control does not enforce uniqueness. |
Tag | Char | A unique string value that identifies the menu entry. Note that the control does not enforce uniqueness. In fact, developers may choose to just use the tag or just use the ident, or make the combination of tag and ident unique. |
Info | Row | A row that contains further information required for the menu entry. Not used for all entry types. E.g. contains the content for a cascaded menu, see kNavMenuTypeCascade. |
The flags column can be zero, or a sum of one or more of the following flag values and specifies how the menu entry behaves:
Flag | Description |
---|---|
kNavMenuFlag HorizontalLayout |
Only applies to the first line of a menu (or cascaded menu) list. If not set, entries are laid out vertically; if set, entries are laid out horizontally. |
kNavMenuFlag EndOfRowOrColumn |
If set, the menu entry for this line is the last entry in the current row or column in the layout for the menu (row or column depends on whether layout is horizontal or vertical respectively) |
kNavMenuFlag Disabled |
If set, the menu entry is disabled. This means it will not accept clicks, and it will not hot-track. |
kNavMenuFlag Breadcrumb |
Only applies to line 1 of the $dataname menu list. If set, the menu is a breadcrumb control, and for the $dataname list, kNavMenuFlagHorizontalLayout is turned on and kNavMenuFlagEndOfRowOrColumn is ignored. |
kNavMenuFlag BreadcrumbSeparator |
If set and kNavMenuFlagBreadcrumb is set and applies to line 1, the entry draws the breadcrumb separator. Note that the control uses the description text color ($descriptiontextcolor ) as the color of the separator. |
The first column of your data list sets the type of menu control, using one of the following kNavMenuType... constants:
kNavMenuTypeHeading
Used as a heading to group other menu entries. Typically, this would be a disabled entry, but it can accept clicks if desired. The info column is not used for this type.
kNavMenuTypeEntry
A normal menu entry, typically used to accept a click and generate an event.
kNavMenuTypeImage
A menu (or cascaded menu) list can only have a single image entry (others are ignored). You use the info column to provide an image that will be displayed as a background of the menu, and which will also accept clicks. The control will place the image at the “end” of the menu, irrespective of where the entry is placed in the list. The info column for an image entry is a row with the following columns. Note that only the icon column is mandatory.
Column | Type | Description |
---|---|---|
Icon | Character or Integer | For the JavaScript Client, the character URL of the image, generated by calling iconurl(iconid). For the fat client, the integer icon id of the image. |
Horizontal offset | Integer | You can adjust the horizontal position of the image in the menu by supplying a value here. Defaults to zero. |
Vertical offset | Integer | You can adjust the vertical position of the image in the menu by supplying a value here. Defaults to zero. |
kNavMenuTypeCascade
An entry representing another menu which cascades from the entry when either the mouse is over the entry, or when the entry is clicked (this depends on the $openwhenmouseover property described below). Note that the control supports a cascade nesting depth of 15.
The info column for a cascaded menu entry is a row with the following columns (note: when you understand how the properties and events for the control work, you will see that the info row does not always need to be fully specified for a cascaded menu - in many cases only column 1 is required, and in fact, in some cases, the info row is not required at all for a cascaded menu):
Column | Type | Description |
---|---|---|
List | List | A menu list defining the entries in the cascaded menu. |
Cascade flags | Integer | Zero, or a sum of kNavMenuCascadeFlag… flags, see below. Defaults to $defaultcascadeflags. |
Open side | Integer | The side from which the cascaded menu will open. Either kNavMenuSideLeft, kMenuSideRight, kMenuSideBottom or kMenuSideTop. Defaults to $defaultcascadeopenside. |
Border edges | Integer | A sum of kNavMenuSide… constants that specifies the edges of the cascaded menu that are to have a border. Defaults to $defaultcascadeborderedges. |
Border color | Integer | The color of the border of the cascaded menu. Defaults to $defaultcascadebordercolor. For the JavaScript Client control, you must set this column to the result of truergb(color) if the color you are using is a color constant. |
Border width | Integer | The width of the border of the cascaded menu (1-16). Defaults to $defaultcascadeborderwidth. |
Background color | Integer | The background color of the cascaded menu. Defaults to $defaultcascadebackcolor. For the JavaScript Client control, you must set this column to the result of truergb(color) if the color you are using is a color constant. |
Background alpha or foreground color | Integer | For the JavaScript Client, the background alpha value for the cascaded menu (0-255). Defaults to $defaultcascadebackalpha. For the fat client, the foreground color of the cascaded menu. Defaults to $defaultcascadeforecolor. |
Background pattern | Integer | Only applies to the fat client. The background pattern of the cascaded menu. One of the standard pattern constants. Defaults to $defaultcascadebackpattern. |
Cascade Flags
The cascade flags are as follows:
Flag | Description |
---|---|
KNavMenuCascadeFlag UseEventToPopulate |
If set, the control sends evLoadCascade in order to populate the cascaded menu |
KNavMenuCascadeFlag UseEventWhenRequired |
If set, and kNavMenuCascadeFlagUseEventToPopulate is also set, only send evLoadCascade when data is required again for some reason,rather than each time the menu opens |
KNavMenuCascadeFlag OpenOnParentEdge |
If set,the cascaded menu opens on the relevant edge of the parent menu, rather than opening on the relevant edge of the parent entry. |
KNavMenuCascadeFlag Expand |
If set, and kNavMenuCascadeFlagOpenOnParentEdge is also set, the cascaded menu expands if necessary to the width or height of the parent. |
KNavMenuCascadeFlag UseDefault |
If set, use the default cascaded menu flags for the control ($defaultcascadeflags) and ignore any other flags. This allows you to use default cascade flags, and then override other properties using the info row. |
In addition to the standard control properties, the Nav Menu control has the following properties:
Property | Description |
---|---|
$borderedges | A sum of kNavMenuSide… constants that specifies the edges of the control that are to have a border. |
$borderwidth | The width of the border of the control (1-16). |
$closeboxiconid | The icon id of the close box for cascaded menus (only relevant when $openwhenmouseover is kFalse, and the control is not in breadcrumb mode). Note that when $openwhenmouseover is kFalse, on a non-touch device, menus still close automatically when the mouse leaves the control or its open cascaded menus. If you do not want a close box, set this to zero. On a touch device you can close all open cascaded menus by touching an area away from the control and its open cascaded menus. |
$defaultcascade… | Default properties for cascaded menus (see the description of the info row for cascaded menus). These eliminate the need to repeat this information for every cascaded menu. |
$horizontalcascadeiconid | The id of the icon used to represent an entry that cascades to the left or right. |
$horizontalspacing | Horizontal spacing used when laying out entries. |
$hotcloseboxiconid | The icon id of the close box for cascaded menus, used when $openwhenmouseover is kFalse, and the mouse is over the close box. |
$verticalcascadeiconid | The id of the icon used to represent an entry that cascades to the top or bottom. |
$verticalspacing | Vertical spacing used when laying out entries. |
$font… properties | Used to control the font and colour of entry text: $font, $fontsize, $fontstyle, $textcolor, $hotfontstyle, $hottextcolor |
$descriptionfont… properties | Used to control the font and colour of description text: $descriptionfont, $descriptionfontsize, $descriptionfontstyle, $descriptiontextcolor |
$headingfont… properties | Used to control the font and colour of heading text: $headingfont, $headingfontsize, $headingfontstyle, $headingtextcolor, $hotheadingfontstyle, $hotheadingtextcolor |
$openwhenmouseover | If true, cascaded menus open when the mouse is over the relevant part of the control. Otherwise, the user needs to click in order to open a cascaded menu. On a mobile device, the value of this property is ignored and treated as kFalse, because there is no mouse. |
When an entry is selected in the Nav Menu an event is triggered, one of the the following events:
Event | Description |
---|---|
evLoadCascade | The control sends this event when it needs to populate a cascaded menu (i.e. kNavMenuCascadeFlagUseEventToPopulate is set for the menu). The application code processing this event builds a list for the cascaded menu, and assigns it to the runtime-only property $cascadecontents. |
evMenuEntryClicked | The control sends this event when the user clicks on a menu entry. |
evEmptySpaceClicked | The user has clicked in empty space to the right or bottom of the menu (generated for top-level menu page only). |
evLoadCascade and evMenuEntryClicked have 2 event parameters, pLineIdent and pLineTag, which are the ident and tag of the menu list line for which the event was generated. These events and their parameters can be trapped in the $event method for the control.
If the initial menu (set with the list content in $dataname) is too wide to fit the control, the control uses scroll arrows at the left and right to allow its content to be scrolled – ideally you should fit your content to the width of the control, so no scroll arrows are required. The scroll arrows are displayed in this case to support the breadcrumb mode which uses a single row of entries for the initial page.
On a touch device, the scroll arrows are not displayed but you can scroll the control horizontally by touch-dragging. The scroll arrows are the same ones used for the tab control which are specified in core.css (img.ctrl-arrow-left-dis & img.ctrl-arrow-right-dis) and the images folder, so you can change their appearance if required. Note that the core.css file is minified, so you may want to use a prettifier tool to make it more human-legible. Do not edit the classes in core.css, rather you should override the classes by adding your own version in the user.css file found in the html\css folder in your Omnis development tree.
The following methods define the Nav Menu for a fictional online shop (they are contained in an object class and called via an object variable in the remote form). An example containing a similar Nav menu is available in the JavaScript Components Gallery on the Omnis website, and in the Hub.
First the content list for the Nav Menu is defined (with seven columns), then the second-level items are created, in this case the shop departments, and the top-level for the menu is added. The list built here is added to the list specified in $dataname for the Nav Menu object in a remote form.
The defineMenuList method is a generic method to define the list of the menu content:
The $events property for the Nav Menu object has two events specified: evLoadCascade and evMenuEntryClicked. The menu object itself has the following event method:
The $shopLoadCascade method builds the content for the cascaded menu:
The menu will look something like this:
The Page Control links to a Paged pane on a remote form and allows the end user to change the current page in the linked paged pane by swiping over the page control or clicking for non-touch screens. The Page control also gives the end user a visual clue as to the current selected pane in the linked page pane object, since the highlighted dot in the control changes to reflect the current page in the linked paged pane.
There is an example app called JS Page control in the Samples section in the Hub in the Studio Browser, and the same app is available in the JavaScript Component Gallery.
The paged pane linked to the Page control is specified in the $linkedobject property. In this case, when the page control is clicked or swiped the linked paged pane control will select the next available pane automatically.
Property | Description |
---|---|
$::currentpage | the current page number |
$linkedobject | the name of a paged pane object on the current remote form that links to the iPage control |
$::pagecount | the number of pages |
$pageindicatorcolor | the color for the current page indicator |
$currentpageindicatorcolor | the color for all the pages except the current page indicator |
When the page indicator changes in the Page control an evPageChanged is triggered containing the number of the new page in pValue.
The Paged Pane provides a very convenient method to show a number of fields or controls grouped together on separate panes, or to break down an entry form into more manageable parts whereby each pane contains a small number of fields. The JS Page Control example app in the Samples section in the Hub in the Studio Browser uses the Paged Pane; the same app is available in the JavaScript Component Gallery.
The $pagecount property specifies the number of panes, and $currentpage specifies the current pane. In design mode, you have to set $currentpage to the number of the pane you wish to add fields to, or you can right-click the background of the paged pane and select the number of the pane you want to edit. You can set $effect to select different border effects for the control (a kJSborder... constant).
You can link a paged pane to a Navigation Bar, Page Control, or Tab Bar control so when the nav bar, page or tab changes the current pane of the paged pane changes accordingly. To link a paged pane to one of these controls, set the $linkedobject property of the Nav bar, Page control or Tab bar to the name of the paged pane.
By setting $scrolltochangepage to kTrue the pages are laid out horizontally, and the end user can change the current page by scrolling horizontally (for touch devices the end user can change panes by tapping on the current pane).
An evUserChangedPage event is triggered when the pane changes and the new page number reported in pPageNumber.
When a Paged Pane is linked to a Nav bar or Tab bar control, the evUserChangedPage event is triggered when the nav button or tab is clicked to change the pane.
The $borderradius property lets you add rounded corners to the Paged pane. The radius can be specified by a single value, so all corners are the same radius, or up to four hyphen-separated pixel values, in the order topleft, topright, bottomright, bottomleft, e.g. 4-4-0-0 to add rounded corners to just the top of the paged pane. If the bottomleft value is omitted the topright value is used. If bottomright is omitted the topleft value is used. If topright is omitted the topleft value is used.
Note: If a border radius is set, the rounded corners are not drawn in design mode: they are only rendered when the app is run on the client. The rounded corners are not drawn in design mode to allow the full use of the available space within the page pane control while designing the form.
The Page Pane control has a $dataname property which you can use to set the value of $currentpage. When the form is opened or redrawn the numeric value of $dataname is used to set the current page. If $dataname is empty or returns an invalid page number, the control uses the page number in $currentpage.
You can use a page pane in a complex grid. You can set the value of $currentpage by assigning a column in the complex grid list to $dataname of the page pane. Therefore each row in the complex grid could display a different page in the page pane control.
In this case, controls within the page pane control will also get their data from the complex grid control, if their $dataname refers to a column in the list used to build the complex grid.
There is no Group box JS component, but you can create one “on the fly” using the $makegroupbox() method to change a Paged pane into something that simulates the behavior and appearance of a group box.
The method PagePaneName.$makegroupbox(cLabel[,cFont,cFontSize,cTextColor]) converts a Paged pane into a Group box with the specified label, as well as the optional CSS font, font size, and text color. The method must be executed on the client, and can be called from $init in the remote form.
If enabled, the $animatetransitions property ensures that the transition between pages is animated when the current page is changed. The property cannot be changed at runtime (the same as $scrolltochangepage).
If used in conjunction with $scrolltochangepage, when the user stops scrolling, the pane will smoothly animate into position, rather than jumping instantly.
The animation time is set to 500ms, which should be fine for most purposes, but if you wish to change this, you can use JavaScript to change the Paged Pane control's (or its prototype's) ANIMATION_TIME property.
Page panes have a default CSS classname ‘omnis-pagedpane-page’. This allows you to apply CSS styling or behavior to each page of the paged pane control.
In addition, a CSS rule (-webkit-overflow-scrolling: touch;) enables momentum scrolling on iOS, i.e. for touch iOS devices, scrolling slows down before stopping.
The Picture Control allows you to display an image in your form: you can display an image file in a folder, an image from a database, or an icon, depending on the combination of settings of $dataname, $mediatype and $iconid. If $mediatype is empty (and $iconid is zero), the $dataname of the Picture control is a URL to the image to be displayed, relative to your html page containing the JavaScript Client. If $mediatype is specified, then $dataname is the name of a binary instance variable containing the image data: in this case, $mediatype can be set to one of the standard image types, e.g. image/png, image/jpeg or image/gif. Alternatively, $iconid can be set to a URL referencing an image file in the ‘html/icons’ folder, overriding the $dataname and $mediatype properties. For backwards compatibility, the picture control can display an icon in an icon data file (Omnispic) or #ICONS by setting $iconid to a numeric icon ID.
There is an example app called JS Picture in the Samples section in the Hub in the Studio Browser, and the same app is available in the JavaScript Component Gallery.
The $picturealign property specifies where the picture will be positioned in the control and is a kPAL... constant. The $noscale property determines whether or not the images displayed in the control are scaled. The $keepaspectratio property determines whether or not the images displayed in the control keep their aspect ratio when scaled: if true, and $noscale is false, the aspect ratio of pictures is maintained when they are scaled.
The property $keepaspectratiomode controls how the image in the Picture control is scaled and positioned when $keepaspectratio is true and $noscale is false. The value of $keepaspectratiomode is a kKAR... constant with the possible values:
kKARtopLeft
The image is scaled to fit the control and anchored at the top-left corner. This is the default value (and maintains compatibility with existing libraries)
kKARcenter
The image is scaled to fit the control and centered, so background may be visible at the top and bottom or the left and right of the image, depending on the shape of the image control and the orientation of the image
kKARfill
The image is scaled to fill the control and centered, so no margin (background) is shown. This can result in the image being cropped at the top and bottom, or the left and right, depending on the shape of the image control and the orientation of the image
In the Webshop sample app, the product images are shown in a Picture control embedded in the Complex grid control on the main jsShop remote form. In this case, $mediatype is set to JPG and the $dataname of the control is iProductList.product_picture which holds the image data for each product.
See the description for the Bar and Pie Chart Control section for information about defining the list variable structure for pie and bar charts, plus chart events, as well as information about setting the bar/segment colors for charts, including the use of theme colors and the $colorlist runtime property to set the segment colors.
Each value in a Pie chart is shown as a segment, and its angle indicates a percentage of the total of all the values in your list, that is, the angle in degrees is calculated as the proportion of the individual value when compared to the total of all values in the list.
There is an example app JS Pie Chart in the Samples section in the Hub in the Studio Browser showing you how to set up a Pie chart using a simple list of data, and the same app is available in the JavaScript Component Gallery.
There are a number of properties in the Pie Chart component to allow you to add a legend title and have some control over the appearance and positioning of the legend.
Property | Description |
---|---|
$maintitle | The legend title |
$legendnames | If true the legend shows the value names ( column 2 ) and not values ( column 1 ). The list data structure is same as bar chart |
$legendcolumns | The number of columns the legend is split into |
$legendpos | Changes the position of the legend: can be above, below, left or right of the pie, or use kJSPieLegendOff to hide the legend |
$flyout | Enables the pie segments to move or “fly out” when the end user’s pointer hovers over the segment (kFalse by default) |
The following pie chart has $legendnames = kTrue, $legendcolumns = 2 and $flyout = kTrue.
Two positioning constants are available for the $legendpos property (which in practice are only appropriate for mobile devices), whereby as the device is rotated and the screen orientation changes, the legend is repositioned automatically either “before” (left or above) the pie or “after” (right or below) the pie. The constant values are:
kJSPieLegendAutoBefore | the legend is placed before the pie chart, either above or to the left of the chart |
kJSPieLegendAutoAfter | the legend is placed after the pie chart, either below or to the right of the chart |
The Popup Menu Control is a menu that pops up when the user clicks on the header of the control, or when $hotwhenmouseover is true the menu will pop up when the end user’s pointer hovers over the control. The contents of the popup menu can be:
a list variable specified in $::listname
a remote menu class specified in the $::menuname property, or
When specifying one of these properties, the other property must be empty; the properties are on the Data tab in the Property Manager.
There are two example apps that use the Popup menu in the Samples section in the Hub in the Studio Browser: the first is named JS Droplist, Combo, Popup and uses a popup built from the list; the second uses a Remote menu to display a popup menu. The same apps are available in the JavaScript Component Gallery; the following screen shows the ‘red night’ JS Theme in use.
When using a list variable to populate a Popup menu, the data in the column specified in $coltext is used for the menu options. The $colenabled property is the column name for the menu line enabled state, and $colcommandid is the column name holding the menu line command id.
You can add an icon to the popup menu by setting $iconid to the ID of an icon in an icon file or #ICONS. You can place the icon before or after the menu title by setting $textbeforeicon.
The menu will normally popup when the user clicks on the control, but you can make the menu popup when the end user’s pointer passes over the control (it is “hot”) by setting $hotwhenmouseover to kTrue.
You can control the position of the popup by setting $menupos to one of the constants: kJSPopMenuPosBottom, kJSPopMenuPosRight, or kJSPopMenuPosTop.
When the menu is clicked the evClick event is triggered with the selected line reported in pLinenumber. You can use the following $event method to trap the line number:
You can use an HTML <select> tag for the user interface by setting $usehtmlselect to kTrue.
The $menulineheight remote form property allows you to set the line height for all the menus in a remote form, including Popup menus and any Context menus for the form, as well as menus belonging to Tab strip and Splitbutton controls.
For pre-Studio 10.2 converted applications, the value of $menulineheight will be zero, meaning the font size will determine the line height, as previous versions. For new applications, this will be a touch-friendly value to give enough space for each menu option.
The Progress Bar Control lets you display a progress bar in your remote form, to indicate the progress of some process in your application; this could be a static value, or a value that changes dynamically. There is an example app called JS Progress in the Samples section in the Hub in the Studio Browser, and the same app is available in the JavaScript Component Gallery.
The current value of the progress bar is reported in the $::value property which is a value between 0 and the value of $max inclusive. The color of the bar representing the completed amount can be set in $progresscolor, which only applies when the standard HTML5 progress control is not available. The following screen is when $usesystemappearance is kTrue on Windows:
The $sendcarryon property provides a mechanism to send an evCarryOn event to the progress control. To generate an evCarryOn event, assign kTrue to $sendcarryon. The event processing code for evCarryOn can assign $sendcarryon to kTrue again, to generate the next evCarryOn.
You can add a Cancel button to your form to allow the end user to break a long process, but the Cancel button itself must be named in the $alwaysenabledobject remote form property so it remains enabled during the long process.
When set to true (the default), the $usesystemappearance forces the progress control to use the <progress> HTML5 element (if it’s supported by the browser). If $usesystemappearance is set to false, the progress control uses two <div> elements, and the following additional properties apply: $secondarycolor sets the color of the stripes of the progress bar, and $progressanimation (true by default) animates the progress bar. The following progress bar has $usesystemappearance set to false (and using the ‘red night’ JS Theme):
The following example code (from the example app in the Hub) assumes the progress control has been added to a remote form and a button is used to initiate some process and send a carryon event to the progress itself; note the ‘lockui’ client command is used to stop any clicks on the UI once the progress is initiated (except for the Cancel button). The initial values for $::value and $::max of the progress control are 0 and 100 respectively. The following code could be behind a button:
The evCarryOn event is sent to the progress bar which has the following event method:
A RadioGroup Control presents a number of mutually exclusive buttons that can be either on or off: selecting one of the radio buttons deselects all other buttons in that group. The variable you assign to a radio group should be numeric (e.g. Integer). Its value is within the range $minvalue and $maxvalue inclusive and directly corresponds to which button in the group is selected, that is, the first button selects the first value in the range, the second button the second value, and so on. The labels for the buttons are assigned in $text which is a comma-separated list (e.g. All,Female,Male). The Radio group has the following properties:
Property | Description |
---|---|
$dataname | a numeric variable |
$::horizontal | If true, the radio column order is horizontal |
$columncount | The number of columns shown for the radio group |
$minvalue | The minimum value for the radio group |
$maxvalue | The maximum value for the radio group |
$text | Comma-separated list of labels assigned to the buttons |
$radiobuttoncolor | The color for the Radio group control |
When a button in the group is clicked the evClick event is reported with pNewValue containing the value of the selected button.
The JS Radio and Checkbox example app in the Samples section in the Hub in the Studio Browser uses a Radiogroup to select Gender, and the same app is available in the JavaScript Component Gallery; the following screen shows the ‘health’ JS Theme in use.
The Webshop app uses a Radiogroup control to allow the end user to select a group or category of products to be shown in the main product list. (To examine this control and its properties and methods, open the webshop library and the jsShop remote form.) The $minvalue and $maxvalue of the radiogroup are set to 0 and 8, respectively (although the groups are generated dynamically in the form), and the numeric variable iRadioGroup with an initial value of 1 is assigned to $dataname. When the form is opened, the $construct() method behind the radiogroup calls a $build method.
The $build method generates a list of product groups from the database, which is then concatenated into a single comma-separated list and assigned to the $text property of the radiogroup.
When the form is opened the main product list is built using a method behind the product list itself (also called $build) and the list initially contains the Appetizers only. A group of radio buttons is created, each item representing a different group or category of food or drink; the initial value of the radiogroup is set to 1 selecting the first item in the group.
When the end user clicks on the radiogroup, to select another product type, the click is detected in the $event method in the radiogroup control, the number of the radio button clicked is passed in pNewVal, and the product list is rebuilt based on the selected product group; note a Where clause is created based on the selected group and sent to the $build method behind the main productList control.
The Rich Text Editor Control (jsrich) can be used instead of a regular Edit or Multi-line edit field, which adds the ability for end users to edit the text using a text editor UI and to apply “rich” formatting such as bold, italic, and simple bullets.
There is an example app called JS Rich Text Editor in the Samples section in the Hub in the Studio Browser, and the same app is available in the JavaScript Component Gallery.
The Rich text editor control uses the Quill open source text editor which relies on modern browser technologies and, as such, some older mobile operating systems (iOS < 6.0 & Android < 4.0) may have compatibility issues. The control is based on Quill 1.0, which allows Code Blocks with syntax highlighting, Undo/redo shortcut keys, Sub/Superscript, In/Outdent, Block Quotes, Image uploads, content tips, and so on.
The text data for the control is stored in the instance variable assigned to $dataname: see below for properties to format the data content. You can allow text editing in the control by setting $showcontrols to kTrue where upon the text content in the field will become editable: on mobile devices this places the cursor in the field and opens the soft keypad ready for typing. The text editing controls in the field will appear at the top of the control and will allow the end user to format the text, including bold, italic, underline, and so on. The text data in the control is HTML markup and can include formatted text such as ordered (numbered) and unordered lists (bullets). End users can also insert images using the Paste option.
The control dynamically loads the necessary JavaScript & CSS files when it is used. There are some files in the Studio tree to support the text editor:
When deploying to a web server, you must make sure to also copy these files over.
Together with the standard component properties, the Rich Text Editor Control has the following properties:
Property | Description |
---|---|
$dataname | The name of an instance variable to store the HTML formatted text, or a column in an instance row variable |
$dataformat | Controls the format of the document data stored in $dataname for the control, a constant: kJSRichTextDataFormatJSON, kJSRichTextDataFormatHTML, or kJSRichTextDataFormatPlain |
$showcontrols | Set this to kTrue to switch the control to edit mode and to display text editing toolbar controls |
$plaintextname | Specifies the name of a variable that automatically receives the plain text equivalent of the data stored in the variable named in $dataname (just the plain text without any HTML formatting); this property is optional |
$contenttip | Allows you to specify some text to be displayed in the editor when it has no content |
$removedtoolbaritems | A bitmask of kJSRichText… values, allowing you to specify toolbar items to hide in your Rich Text Editor instance |
You can specify the default value of the font, size and text color shown in the editor’s controls by assigning values to the component’s text properties, as follows:
$font
maps directly to the editor’s font droplist and will set the default value accordingly.
$textcolor
will attempt to set the default text color to one of the colors in the toolbar’s color palette. If there is not an exact match, it will add the color as another tile in the palette.
$fontsize
will set the default font size to the closest match. Set to 13 for the ‘Normal’ font size as default.
The $dataformat property controls the format of the document data stored in $dataname for the control. It can be one of the following constants:
kJSRichTextDataFormatJSON
The document data will be stored in the $dataname as JSON, as a Quill 'Delta' object. This is the best option for restoring the data later, as it preserves all formatting.
When setting the data, you can assign JSON (Delta), HTML or plain text: this should be detected and converted as necessary.
kJSRichTextDataFormatHTML
The document data will be stored in the $dataname as HTML. This may lose some minor formatting. This format is suitable to use if you are going to use the data elsewhere in your code, but not for storing the document data and restoring into the Rich Text Editor.
When setting the data, you can assign HTML only.
kJSRichTextDataFormatPlain
The document data will be stored in the $dataname as Plain text. This will lose most formatting.
When setting the data, you can assign Plain Text only.
The $dataformat property can be changed in your code to populate the $dataname with data of the specified format. Note that if you do this in a server-executed method, the $dataname won't be updated until the client next contacts the server.
The $appenddata(cData, bNewLine) and $prependdata(cData, bNewLine) methods allow you to append or prepend data to the content in $dataname. If you pass bNewLine as kTrue, the data will be added on a separate line. These methods can only be executed on the client.
The data format of the passed data depends on the value of the $dataformat property. If $dataformat is JSON, the data could be sent as plain text, HTML or JSON (a Quill Delta object).
The updated Rich Text Editor allows you to insert Code Blocks. These allow you to insert syntax-highlighted code. The syntax highlighting is achieved using highlight.js and by default includes highlight support for several popular languages.
If the language(s) you require is/are not supported out of the box, you can create a ‘Custom Package’ on the highlight.js download page, and replace the highlight.pack.js in your tree/web server with the one you download.
Similarly, if you want to change the code block’s appearance, you can take any of the theme css files from your highlight.js download, rename it highlight-theme.css and replace the supplied file with your own.
End users can drag data from a Rich Text Editor and drop it elsewhere in the form, or users can drag data and drop it into the Rich Text Editor; in the latter case the evDrop event is generated in the control. If some text is selected and dragged out of the Rich Text Editor, then only the selected text is dropped at the cursor position.
End users can also drag external content and drop it onto the Rich Text Editor, e.g. text or an image from another browser pane or a different application, but in this special case the evDrop event is not generated in the control.
There are various strings in the Rich Text Edit control that can be localized in the string table for the remote form containing the control. You must use the following string table ids to replace the default text for the controls in the text editor.
rt_backgroundcolor | rt_insertorderedlist | rt_print |
rt_blockquote | rt_insertunorderedlist | rt_removeformat |
rt_bold | rt_italic | rt_strikethrough |
rt_clearformat | rt_justifycenter | rt_subscript |
rt_codeblock | rt_justifyfull | rt_superscript |
rt_decrease_indent | rt_justifyleft | rt_textalign |
rt_image | rt_justifyright | rt_textcolor |
rt_increase_indent | rt_link | rt_underline |
rt_indent | rt_outdent | rt_video |
rt_fontsize | rt_fontfamily | rt_sansserif |
rt_serif | rt_monospace |
End users can print the contents of the editor control using a print button on the editor's toolbar, which when clicked opens a window for printing. The $printcontents lets you print the contents.
$printcontents(cTitle)
Opens a new window to print the editor's current contents. cTitle is the title of the document to print.
You enable the new print button by setting $removedtoolbaritems to kJSRichTextPrint. In addition, the Omnis string table item with ID: rt_print lets you edit the tooltip of the button.
The Segmented Control displays a number of segments or buttons that you can use for navigation (like a tab bar or toolbar) within your web or mobile app, or you can use it with only two segments to create a switch. You can assign an icon and text to each segment and you can detect which segment has been clicked in the $event method of the control.
The Segmented control provides a series of ‘segments’ or buttons arranged horizontally, each of which can contain an icon and/or text. You can optionally show the selected segment in a highlighted state, by setting $showselectedsegment to kTrue, which is useful if you are using the segmented control as a navigation control. You can further show the current segment by the setting the color of the current segment indicator in the $focusedsegmentindicatorcolor property.
You can use the segmented control as a toolbar, docking it to the top or bottom of its container by setting its $edgefloat property to one of the kEFposn… values, such as kEFposnMenuBar or kEFposnTopToolBar.
There is an example app called JS Segmented Control in the Samples section in the Hub in the Studio Browser, showing how you can use the Segmented control as a toolbar and switch (the second image below); the same app is available in the JavaScript Component Gallery. The following images show the ‘professional’ JS Theme in use.
The Segmented control has the following properties, together with the standard properties for a JavaScript control.
Property | Description |
---|---|
$currentsegment | The number (1 - $segmentcount) of the current segment (this specifies the segment affected by segment specific properties). This can also be changed in a design view by clicking on a segment of the design component. The current segment will be shown with a red outline while the component is selected. |
$hidedisabledsegments | Hides any disabled segments |
$movesegment | Lets you move a segment (in design mode only) |
$segmentcount | The number of segments (must be at least one). |
$segmentenabled | If true, the segment is enabled and generates a click event when the user presses it. |
$segmenticonid | The icon displayed on the current segment. Set to 0 for no icon; |
$segmenttext | The text displayed on the current segment. |
$displaystyle | A kJSSegmentStyle… controls whether the text is above or below the icon |
$showselectedsegment | If true, the currently selected segment will be shown in a highlighted state. See $selectedcolor & $selectedtextcolor. If false, the highlighted appearance will still be shown while segments are being clicked, to give the user feedback of the click. |
$focusedsegmentindicatorcolor | Specifies the color of the current segment indicator |
$segmentbordercolor | The colour that applies to borders / dividers of segments |
$segmentborderradius | Single value border radius that applies to segments. If $segmentspacing is zero, this applies to only the outer edges of the outer segments. Otherwise, it applies to all segments |
$segmenteffect | Determines whether borders / dividers are applied to segments, either kBorderNone or kBorderPlain |
$segmentenabled | Set to kFalse to disable a segment |
$segmentspacing | the space between the segments in pixels. The behavior can be affected by $segmentwidth (see below). If zero, dividers are drawn between segments. Otherwise, borders are drawn around the segments |
$segmentwidth | The width applied to all the segments in pixels. By default, this is zero, in which case the width of the segments is determined by the total width of the control and $segmentspacing. If this value is small enough, the segments will be centred in the control |
$selectedsegment | The number (0 - $segmentcount) of the currently selected segment. If 0 no segment will be selected. |
$selectedcolor | The background color of the currently selected segment, or of the segment currently being clicked. |
$selectedtextcolor | The text color of the currently selected segment, or of the segment currently being clicked. |
$bordercolor | Controls the color of the segment divider lines, as well as the control’s border. |
$backcolor | Controls the background color of the segments. |
If $segmentwidth and $segmentspacing are set so that the segments extend beyond the width of the control, the overflowing content will be scrollable. However, if $segmentwidth is zero (the default), the segments will always fit inside the container.
In the extreme case where $segmentspacing is very high, as long as $segmentwidth is zero, the spacing will be limited to prevent the segments becoming too small or the content overflowing.
You can set $segmentenabled for a segment to false to disable it. The property $hidedisabledsegments allows you to hide any segments that have been disabled.
The $movesegment property lets you move a segment: you need to set it to a number corresponding to the new position (the property works in the same way as the Data Grid's $movecolumn property).
An evClick event is generated when one of the segments is clicked and the pClickedSegment event parameter returns the number of the segment clicked.
The Slider Control provides a graphical slider component to set the value of a variable, such as a volume control, or to control the value of another component in your form. You can change the thumb icon if required. As an alternative, you can use the Native Slider to control variable numeric values.
There is an example app called JS Slider in the Samples section in the Hub in the Studio Browser, and the same app is available in the JavaScript Component Gallery.
The current value of the slider is reported in the property $val according to where the slider is positioned. You can specify the range for the slider in the $min and $max properties, while $step is the size of each step the slider takes between the min and max values. The slider also has these properties:
Property | Description |
---|---|
$vertical | If true, the slider is a vertical slider |
$sliderhorziconid | The id of the icon to use for a horizontal slider handle |
$sliderverticonid | The id of the icon to use for a vertical slider handle |
$horzmargin | The horizontal drawing margin |
$vertmargin | The vertical drawing margin |
The Slider reports three events: evStartSlider (when the control is starting to track), evEndSlider (when the control has finished tracking), and evNewValue (when the value has changed). You can detect these events in the $event method for the component. These events all pass the current value of the Slider in the pSliderValue parameter. As the user drags the Slider thumb the evNewValue event is triggered and pSliderValue is sent to the $event method for the Slider.
To use the values of the slider in your remote form you can trap the slider events in the $event method of the slider control (which must execute on the client), and transfer the current values to instance variables in your form, as follows:
The Split Button Control combines a standard button with a dropdown menu, allowing you to provide multiple, alternate actions grouped together in a single button control. The Split Button is like the Send button in gmail as it provides two options in one control: a default Send option on the button and a Schedule send option via the menu.
The component is available for JavaScript remote forms as well as window classes, but there are some additional properties for the JavaScript control (the window version is an external component that must be loaded via the Component Store).
The menu for the control is specified in the $menuname property and must be a Remote Menu class for the JavaScript component, or a menu class for the Window class control.
The following example Split button has a Print option and a printer icon on the main button part, and it has options for printing to a Preview, PDF or File specified in a Remote menu class, specified in the $menuname property of the button control. In this case, a single click on the button would activate the Print to printer option, while clicking on the down arrow provides the other options (the images uses the ‘professional’ JS Theme).
The following properties are available for both the JS Remote form and Window class controls.
Property | Description |
---|---|
$hotbackcolor | The background color of the control when hovered |
$activebackcolor | The background color of the control while pressed; active color is generated automatically if $activebackcolor is kColorDefault |
$buttonborderradius | The radius in pixels of the corners |
$borderwidth | The width (0-7) of the edges drawn as the border of the control |
$arrowside | The position of the dropdown button on the control |
$textbeforeicon | If true, and the control has both text and an icon, the text is drawn before the icon |
$vertical | If true, the text and icon are arranged vertically |
$menuname | The name of the menu class, a Remote Menu class for the JS control, or a Menu class for the Window control |
The following properties are available for the JavaScript control only.
Property | Description |
---|---|
$menubackcolor | The background color of menu lines |
$menuhotbackcolor | The background color of menu lines when hovered |
$menutextcolor | The text color of menu lines |
$menuhottextcolor | The text color of menu lines when hovered |
$menudisabledtextcolor | The text color of disabled menu lines |
An evClick event is triggered when the main button area is pressed. In addition, for the JavaScript client only, the evOpenContextMenu and evExecuteContextMenu events are generated when the menu is pressed, and in this case, the pControlMenu event parameter is kTrue (when a Context menu is opened pControlMenu will be kFalse), and the pCommandID parameter contains the command ID of the selected menu line, e.g. 1002 for line 2.
There is an example app called JS Split Button in the Hub in the Studio Browser, and the same app is available in the JavaScript Component Gallery. The example library contains a JS remote form and remote menu class (plus a window class and menu to show the thick client split button). The following image shows the JS Split button example using the ‘default’ theme.
The $event method behind the split button control traps the evClick and evCCC events corresponding to clicks on the button or the menu part of the control.
The pCommandID parameter is passed to the menuClicked method which contains the command ID for the selected menu line ($commandid is a menu line property which stores IDs 1001, 1002, etc for successive menu lines).
The Subform control allows you to place another remote form class inside the main remote form. The concept of the subform is similar to embedding an iframe into an HTML page where you can embed another page or form or inside the main page. You could, for example, create a single “main” form and a number of other remote forms loaded at runtime into a subform control, to create a powerful and interactive web application with many subforms or frames. For example, the JavaScript Component Gallery app on the Omnis website is implemented using a main gallery form and each example component is loaded in a separate form as a subform.
When you have placed the subform control on your remote form, you specify the initial remote form to appear in the subform in the $classname property. Alternatively, you can switch subforms at runtime by assigning a new remote form name to $classname to switch the current form displayed in the subform control, as follows:
Note: you can also create a group of subforms dynamically in your code using a Subform Set, which is described in the JavaScript Remote Forms chapter.
There are a few example apps showing how you can use subforms or subform sets in the Samples section of the Hub in the Studio Browser (called JS Subform, JS Subform Set, JS Subform Set Panels), and the same apps are available in the JavaScript Component Gallery.
If the remote form class inside the subform field has only one field, you can override its dataname using the $dataname property for the subform field. For example, your subform class may contain a single headed list field that takes its data from a specific list variable. However, you can change the list assigned to the headed list by setting the subform field’s $dataname property to the name of another list. You could do this in the $construct() method of the subform field.
Opening a remote form containing a subform field or any number of subform objects creates an instance of each form, which belong to the same task as the parent remote form instance. Omnis calls the $construct() methods of all the subform classes first in tabbing order, then the $construct() method of the parent form instance. The reverse happens on closing the parent form, with the subforms being destructed after the parent form instance.
You can send parameters to the subform’s $construct() method by including a comma-separated list of parameter values in the $parameters property when you create the subform field. The $parameters property can only be assigned in the remote form editor, and it has no effect at runtime. If you attempt to set it at runtime in your code, the error "$parameters cannot be assigned at runtime" will be displayed on the client.
When changing subform instances you can send parameters to the new target subform instance. To do this you can assign a comma-separated list of values to the $userinfo property of a subform and this can be parsed and sent as parameters to the client-executed $init method in the new subform instance. Each token in the comma-separated list will be a separate parameter, and can be a quoted string (including spaces and commas) or a numeric value. For example, when changing subform:
In the $init method in the new subform jsSubform1, three parameters will be populated: p1: "Davy Jones", p2: 123, p3: 0.
The $loadfinished client-executed method allows you to check when all subforms of a form have been loaded. The method is called after all the subforms that belong to the parent remote form instance have finished loading and their $init methods have been called.
The $multipleclasses property tells Omnis to keep a set of remote form instances open for use in the subform object, rather than constructing a new instance each time the subform class is changed. When you assign a new remote form name to $classname at runtime, the new remote form is downloaded to the client and displayed in the client’s browser. If the $multipleclasses property is enabled, the previous remote form is cached and hidden on the client, otherwise the remote form instance is destroyed. If any previous remote forms have been cached in this way using $multipleclasses, you can switch back to them instantaneously, otherwise they have to be reloaded each time you assign to $classname of the subform object.
It is not required that all subforms within the inheritance hierarchy of a set of Remote forms have the same layout breakpoints. In other words, a subform can have different layout breakpoints to its superclass.
A subform control has the $subinst property (object) which is the instance contained within the subform control. You can use this property to get a reference to the instance in a subform object and therefore change properties within the instance. If the subform property $multipleclasses is set to kTrue, you must use $subinst(cClassName) to get a reference for the appropriate instance. For example, where a subform control has a single subform class the following code will return a reference to the form instance in the subform:
or when you may have assigned multiple classes to the subform control ($multipleclasses is set to kTrue):
Note that the item returned will be null if the instance does not exist.
You can use $cinst.$container to obtain the instance containing a subform instance, where in the current context $cinst is a subform. The $container property returns the object containing the referenced object. This notation will work in server methods (for all clients) , and client-side methods for the JavaScript Client only. For examples:
The Holidays sample app (in the Applets section of the Hub in the Studio Browser) uses a subform to display either the User or Admin form. When the main jsHolidays remote form is loaded, its $construct() method calls a class method to setup the initial subform to be shown which, in this case, is the User form. In addition, there are buttons on the main Holidays form to allow the end user to switch forms; for example, the code behind the User button is:
The setSubForm method has the following code to switch forms:
The Switch Control is like a check box insofar as it represents an On / Off value (1 or zero), but it can display alternative images for the On or Off states. When the end user clicks the switch the value of the control’s variable alternates between 1 and zero, so the control is useful for representing preferences which can be Enabled or Disabled, or items that can be turned On and Off, like a switch.
The variable you specify in the $dataname property should be a Number or Boolean variable. The $switchon and $switchoff properties let you specify an icon ID for the images to be used when the switch is either On or Off. The properties $justifyhoriz and $justifyvert allow you to justify the contents in the control horizontally or vertically.
The $switchcolor property specifies the color for the Switch control when it is switched on (set to value 1), assuming no on/off icons have been set.
Alternatively, you can use the Native Switch component to display on/off values.
There is an example app called JS Switch in the Samples section of the Hub in the Studio Browser, showing the Switch control with a range of different ON/ OFF images; the same app is available in the JavaScript Component Gallery.
The Tab Control or ‘Tab bar’ allows the end user to select a tab which can correspond to a specific option in your application; the tab control can also be linked to a Paged Pane by setting $linkedobject. The $tabcount property specifies the number of tabs; it can be set to zero in design mode, and the number of tabs assigned at runtime using the notation. The $currenttab property specifies which tab is highlighted and its value will change as the end user selects a tab: assigning a new value to this property at runtime will change the highlighted tab; the following screen shows the Tab control using the ‘health’ JS Theme.
In design mode, you can specify the properties for a particular tab by making it the “selected tab” in the $selectedtab property, under the “Tab” tab in the Property Manager. The text for a tab is specified in the $tabtext property: you can add a line break by inserting //. The size of the tab (i.e. the width for horizontal tabs) is determined by the width of the text on the tab. However, you can set $fixedtabsize to kTrue to fix the size of the tabs, and set $maxfixedtabsize to set the tab width or height. You can hide or show a tab using the $tabvisible property, and you can disable or enable a tab using $tabenabled; for example, you can set these properties for individual tabs to kFalse in design mode and at runtime set these properties to kTrue to show and enable the tabs.
There are many properties under the Appearance tab in the Property Manager to control the general appearance of the Tab Control and the tabs themselves. The tabs have angular corners by default, but you can round the corners by setting $tabborderradius. You can create a vertical aligned set of tabs by setting the $side property: you can orient the tabs on the left or right. The $tabsjst property determines the position of the tabs within the control. The $currenttabindicatorcolor property specifies the color of the current tab indicator.
The $tabbackstyle property controls the style or color of the background of the tabs and is a kJSTabsBackStyle… constant: kJSTabsBackStyleDefault shows a default appearance for the current platform, kJSTabsBackStyleColor shows a flat background color specified in $tabbackcolor, and kJSTabsBackStyleImage displays an image specified in $tabbackiconid.
There is an example app called JS Tab bar in the Samples section in the Hub in the Studio Browser showing how you can link a tab control to a paged pane, as well as using a tab control to display a menu; the same app is available in the JavaScript Component Gallery.
By default, the tabs display text only, but you can add an icon to the tabs by selecting the position of the text and icon by setting $tablayout. For example, you can set $tablayout to kJSTabsLayoutIconLeft to add an icon to the left of the tab text, and then set $tabiconsize to set the width of the space allowed for the icons.
In design mode, you can move or re-order the tabs in the control by entering a number into the $movetab property; in effect, the number of the selected tab will become the number you entered, and the other tabs are shuffled along. This is useful if you have setup multiple tabs and need to move a tab easily without having to redefine each tab again.
The Tab Control can be linked to a Paged Pane by setting $linkedobject to the name of a Paged Pane control, so when different tabs are clicked, the pane in the linked Paged Pane is changed automatically. Assigning a new value to the $currenttab tab property of the Tab control at runtime will also change the current pane in the linked Paged Pane control.
The base edge of the tab control does not normally have a border, and when the tabs are linked to a paged pane the tab control updates the paged pane border so that there is the appearance of a gap below the current tab. If you want to add a border under the tabs you need to set $baseedgewidth to 1 or more.
The Tab Control can also be linked to a Remote Menu class; clicking on a tab will trigger the corresponding line in the menu. To implement this, the $trackmenus property must be kTrue, and the $tabmenu property set to the name of a remote menu class for the selected tab (the tab with number $selectedtab). If assigned at runtime, the menu instance must already be present on the client (via a $tabmenu or $contextmenu property in the class data when the form was loaded).
You can control the color of the menu lines and text using the $tabmenu… properties under the Appearance and Text tabs in the Property Manager, or in your code for the control.
When the end user clicks on a tab the value of $currenttab will change and an evTabSelected event is triggered, with the new tab number reported in pTabNumber. This event needs to be enabled in the $events property for the control to be reported.
The $canclickselectedtab property can be enabled so a click on the selected tab generates evTabSelected (provided that evTabSelected is specified in $events). This allows you to detect a click on the currently selected tab (which was not possible in previous versions).
The Contacts sample app users a Tab control in the main jsContacts remote form to allow the end user to switch from viewing a list of contacts to a form showing details of individual contacts. In this case, the Tab control is linked to a page pane which displays the contact list or contact details view. The $linkedobject property of the contactTabStrip control is set to ‘pagePane’ (the name of the page pane) and the $tabtext for each tab is defined as ‘Contacts’ and ‘Details’ respectively. In addition, the evTabSelected event is enabled in the $events property of the Tab control. The code for the Tab control $event method is:
If the Details tab is clicked, the second tab, the second pane in the page pane is displayed and the details for the currently selected contact are loaded using the loadRecord class method.
The Timer Control is an invisible component that triggers an evTimer event after a specified time while $running is set to kTrue. You can specify a $timervalue, which is interpreted as an interval in seconds or milliseconds according to $useseconds, which should be set to kTrue for seconds or kFalse for milliseconds (the default).
There is an example app called JS Timer in the Samples section in the Hub in the Studio Browser, and the same app is available in the JavaScript Component Gallery.
In the Webshop sample app (available under the Applets section in the Hub), it would be possible to use a Timer control to rebuild the Orders list periodically; in this case, you could use the Timer object to run a method at a given interval to rebuild the Orders list in the jsShopOwner remote form. In reality, the Orders list is rebuilt every time a new order is placed, but a Timer object could be used to regulate the rebuilding of the Orders list.
To implement a Timer in the Webshop app, you would need to enable the evTimer event in the $events property of the Timer control. The $useseconds property is set to kTrue and $timervalue is set to 2 (to give an interval of 2 seconds). The $construct() method of the Orders list (a data grid) includes a line of code to start the timer:
The $build() method behind the Orders list builds the list when the form is opened, but when used with the Timer object it can be used to rebuild the list as well. The $event method for the Timer object is run every 2 seconds, and has the following code:
The timer component contains a Worker Object. This has the advantage over the other timer objects in that it can be used with remote tasks in the multi-threaded server. It has the following properties:
$timervalue and $useseconds
These work as for the current timer objects
$repeat
If true, then after calling $starttimer() the timer will fire until $stoptimer() is called or the object is deleted;otherwise the timer will fire at most once for each call to $starttimer().A change to $repeat is ignored until the timer is started again
The timer component supports the methods $starttimer() and $stoptimer(). Just like $repeat, changes to $useseconds or $timervalue do not take effect if the timer is already running.
When the timer fires (or the timer is cancelled), Omnis calls the $completed or $cancelled method in the object, just like other worker objects. This occurs in the context of the task that owns the object, and interrupts any code running for that task (after a complete method command has executed).
The Toolbar Control allows you to add a series of buttons and an optional menu at the top of a remote form that the end user can click on or tap to perform an action. Each toolbar button can be assigned an icon and text, as well as a different action. When a button is clicked, the item number is reported to the event handling method allowing you to run the appropriate code.
The toolbar is displayed horizontally, by default, but can also be displayed vertically. You can use edgefloat properties to ‘stick’ the toolbar to the top or side of the remote form. It items do not fit on the toolbar they are added to an overflow menu automatically (shown by three vertical dots on the right of the toolbar), or items can be forced to appear on the overflow menu.
A toolbar can have a “side menu”, displayed on the left of the toolbar, by setting $sidemenu to true and adding a list variable name to $dataname containing the menu items. Items in the side menu can have a 'selected' state as well as a 'focused' state. Selecting a line in the side menu sets the current line in the list. The selected line will remain highlighted until another line is selected. When the side menu is opened, the selected line will get the focus.
There is an example app called JS Toolbar in the Samples section in the Hub in the Studio Browser showing a Toolbar with overflow and a side menu; the same app is available in the JavaScript Component Gallery.
The example Toolbar has four items or buttons defined, each with an icon and text, the main title ‘Toolbar’ on the left, and an overflow menu on the right.
Items can be forced to always appear in the overflow, regardless of the width of the main toolbar, shown on the right of the toolbar by the three vertical dots, and shown dropped here:
As the browser window is resized, or the remote form (the app) is displayed on a mobile device, the main toolbar width will shrink, and the button items are added to the overflow menu automatically, as shown (note the icons are not displayed when the item is in the overflow menu):
The following image shows the same Toolbar with the side menu added and in the dropped state:
The following image shows the same Toolbar but using the Themed SVG icons (available in the ‘material’ icon set in Omnis), instead of the PNG image icons, and using the ‘lemonade’ JS Theme:
The custom properties for the Toolbar control are described below. The ‘Item’ tab in the Property Manager contains item specific properties that apply to the $currentitem.
Property | Description |
---|---|
$itemcount | The number of toolbar items/buttons |
$currentitem | Item specific properties are assigned to the current item |
$moveitem | Allows you to move an item in design mode; the current item moves to the position specified by the number entered |
$itemiconid | The icon for the current item (item specific property); note $showitemicons needs to be enabled to display icons |
$itemtext | The text for current item (item specific property); note $showitemtext needs to be enabled to display text |
$itemoverflow | Force the item to be appear in the overflow menu (item specific property) |
$itemenabled | If kTrue (the default) the item is enabled (item specific property); if kFalse the item is greyed and cannot be selected with the pointer or keyboard; applies to items whether they are on the toolbar itself or the overflow menu |
$sidemenu | Add a side menu to the toolbar. The $dataname must be a list containing the menu data |
$dataname | Name of a list variable containing the menu data, to display a menu when $sidemenu is set to true |
$verticaltoolbar | Display the toolbar in a vertical orientation |
$menudirection | A kJSToolbarMenuDirection… constant which sets the direction the menu should open. Different values are available depending on the $verticaltoolbar property: Down or Up for horizontal toolbars, Right or Left for vertical toolbars |
$toolbartitle | The optional title to display on the toolbar; leave this blank for no title |
$titlefontsize | The font size applied to the toolbar title |
$itemwidth | The width of items on the toolbar; without a value items have a variable width and are forced to fit the length of the toolbar |
$displaystyle | A kJSToolbarStyle... constant determining the position of the icon text relative to the icon: either Above, Below, Left of, or Right of the icon |
$showitemicons | If true, any item with an $itemiconid will display an icon on the toolbar |
$showitemtext | If true, any item with $itemtext will display text on the toolbar; when true, $showtooltips is disabled |
$showtooltips | Show tooltips on toolbar items; $showitemtext must be set to false |
$showdividers | If true, dividers will be shown between toolbar items |
$dividercolor | The color of the dividers between items if $showdividers is true |
$iconcolor | The color of standard icons such as the hamburger icon |
$sidemenucolor | The background color of the side menu |
$overflowcolor | The background color of the overflow menu |
$toolbaractivecolor | The color of toolbar items when clicked |
$toolbarhovercolor | Hover color for toolbar items |
$sidemenuhovercolor | Hover color for side menu items |
$overflowhovercolor | Hover color for overflow items |
$selecteditem | The number of the selected item |
$showselecteditem | If true, the item will have its background color set to $selectedcolor and its text colour set to $selectedtextcolor. |
$selectedcolor | The background color of the selected item |
$selectedtextcolor | The text color of the selected item |
$selectedlinecolor | The color used for the background of the selected line in the side menu |
$toolbarhovertextcolor | Text color of toolbar items when hovered |
$sidemenutextcolor | Text color of side menu items |
$sidemenuhovertextcolor | Text color of side menu items when hovered |
$overflowtextcolor | Text color of overflow menu items |
$overflowhovertextcolor | Text color of overflow menu items when hovered |
Clicking on a toolbar item will make that item selected, and $selecteditem is set to the selected item number. If $showselecteditem is true, the item will have its background color set to $selectedcolor and its text color set to $selectedtextcolor.
The $itemenabled property allows you to disable specific items. When $itemenabled is set to kFalse for an item it is greyed and cannot be selected with the pointer or keyboard. This property applies to items whether they are on the toolbar itself or the overflow menu.
The Toolbar reports two events: evClick reports the toolbar item that was clicked, with pClickedItem returning the item number; and evNavigationClick reports true if an item on the side menu was clicked, with the group number reported in pClickedMenuGroup (zero if the data is ungrouped) and the item number in pClickedMenuItem. You can write event handling code in the $event for the toolbar to trap these events and branch according to the value of pClickedItem or pClickedMenuItem.
To enable the side menu, you need to set $sidemenu to kTrue and specify a list variable name in $dataname containing the contents of the menu. The $dataname can generate either a grouped or an ungrouped menu.
Ungrouped list columns with each row representing an item:
Text (Character): The text of the menu item.
IconPath (Character): A URL of an image to display. The image will be scaled to fit.
Grouped list columns with each row representing a group:
SubList (List): A list with columns matching the ungrouped list above. Contains data for the group.
GroupName (Character): The text displayed on the group header.
Fixed (Boolean): Optional column. If true, the group is always expanded. False by default.
Collapsed (Boolean): Optional column. If true, the group is collapsed by default. False by default.
The TransButton Control is like a standard button, but it can display a different icon and/or background color when the end user’s pointer hovers over the control, or when the button is tapped on touch devices. In all other respects the Transbutton is like a standard push button control, insofar as it generates a single evClick event when the button is clicked which can be used as confirmation or to initiate an action in your code using the $event method. Note the evClick event must be enabled in the $events property for the control for it to be reported.
There is an example app called JS Trans Button in the Samples section in the Hub in the Studio Browser showing how you can use the Trans button, and the same app is available in the JavaScript Component Gallery.
The following image shows the same buttons but using the SVG icons (available in the ‘material’ icon set in Omnis), instead of the PNG image icons:
The Transbutton has several properties prefixed “$hot” that relate to the appearance of the button for the hover action. You can specify two icons for the Transbutton: one to represent the “off” state which is specified in $iconid, and the other to represent the “over” state which is specified in $hoticonid: if no $hoticonid is specified the icon in $iconid is used which will not provide a hover effect. You can also specify a different background color for the hover action in $hotbackcolor, and an alternative border color in $hotbordercolor.
The icons used in $iconid and $hoticonid can be from an icon set, or #ICONS, or an icon datafile. You can use the standard icon sizes (16x16, 32x32, 48x48 and their 2x equivalents for hi-def support), but you can also use non standard sized images as well, but in this case they can only be sourced from an icon set (and the size should be specified in the file name according to the usual naming). The Transbutton will not draw or position icons from standalone pages in #ICONS or icon datafiles (e.g. omnispic.df1) correctly in the client, since the client cannot determine the icon size from its URL.
You can set $vertical to true to center the button’s content vertically: $align also affects the placement of the icon when $vertical is true.
You can specify a label for the button using the $text property which is a single line of plain text. When set to kTrue the $textishtml property specifies that the text in $text is treated as HTML, and therefore any HTML, including character and color attributes, can be used to style the text. For example, you can insert a line break by setting $textishtml to kTrue, and using <br> in $text for the button wherever a line break is required.
The HTML needs to be valid for it to be rendered in the form, including when used as the contents of a <p> element; so for example, you cannot use a <p> element inside another <p> element.
The Tree List Control (or Tree Control) provides a graphical way of displaying a list of items in a hierarchical format. Each node can have a check box or its own icon. The $dataname property for a tree list is the name of a list variable containing the content (data) and structure of tree list. The list can contain the entire data for a tree list when the form is opened, or the content can be built as nodes are expanded when a tree list is in “dynamic” mode.
There are two example apps in the Samples section in the Hub in the Studio Browser showing how you can create a Tree list with check boxes (left) and a Dynamic tree structure (right); the same apps are available in the JavaScript Component Gallery. The following images show the ‘vintage’ JS Theme in use.
Tree lists have the following properties:
Property | Description |
---|---|
$checkbox | If true, and $multipleselect is also true, the tree control has check boxes that can be used to select nodes |
$currentnodeident | The current node ident for Dynamic tree lists only: see below |
$datamode | Controls how the list content is used to structure the tree list, a constant: kJSTreeFlatList, kJSTreeFlatListWithTags, kJSTreeFlatListOld, kJSTreeFlatListOldWithTags |
$evenrowcolor | Specifies the color to be used for every even row in the list of nodes. The kColorDefault setting means use the same color as odd numbered rows ($backcolor). |
$extraspace | Adds extra space in between the lines in the list; it is the number of pixels added to the normal font height of a row in the list, or zero for no extra space |
$iconurlprefix | All icons used in the tree (as a result of $showicons being true) must come from a single icon directory; the default is _icons/omnispic/ |
$lineborder | If true, a row border is added between each node |
$linebordercolor | Specifies the color of the line when $lineborder is true; it uses the value of $bordercolor when set to kColorDefault |
$multipleselect | If kTrue allows the end user to select more than one line; should be enabled for tree lists with $checkbox enabled |
$nodeaction | Performs an action on the tree node, only for Dynamic mode: see below |
$nodedata | List for tree node when building dynamically: see below |
$showicons | If true, the tree control shows node icons from location in $iconurlprefix |
$showlines | If true, the tree control displays dotted lines connecting nodes |
$twostate | If true, and the tree control has checkboxes (see $checkbox), selection of each node is independent |
The format or mode of the data is set in the $datamode property which controls how the list content is used to structure the contents of the tree list. There are several different data modes to format a tree list, as well as the Dynamic mode, represented by the following constants:
kJSTreeFlatList
The first N columns represent a node in a tree of depth N. The last 5 columns are node properties: iconid,ident(int),expanded(bool),textcolor(zero means $textcolor),tooltip
kJSTreeFlatListWithTags
The first N columns represent a node in a tree of depth N. The last 7 columns are node properties: iconid,ident(int),expanded(bool),textcolor(zero means $textcolor), tooltip, tag(char), enterable(bool)
kJSTreeFlatListOld
A list with the same structure as the plug-in client tree kTreeDataFlatList
kJSTreeFlatListOldWithTags
A list compatible with the plug-in client kTreeDataFlatListWithTags
kJSTreeDynamicLoad
the tree list content can be built dynamically; see below
When the user selects a node the evClick event is reported, while a double-click reports an evDoubleClick. In both cases, the id and tag of the selected node is reported in the pNodeIdent and pNodeTag parameters. Note you cannot get click or double-click events for nodes which are enterable, as the click puts them into edit mode.
For enterable nodes, the evRenamed event is reported if the end user has renamed the node. evRenamed has node ident, node tag, old name and new name as event parameters.
The evExpandNode event is fired after the user has expanded a node, every time that node is expanded (unlike evLoadNode which is only triggered if the node has no children). This applies to both dynamic and non-dynamic tree lists; see below for dynamic tree lists.
You cannot use $nodedata to load data into the tree list with evExpandNode, it is just a notification and includes the parameters pNodeIdent and pNodeTag. If evLoadNode and evExpandNode are both active, evLoadNode will be fired first, as evExpandNode is fired after the node is expanded.
Tree lists scroll to view the current line in the list, and any parents opened as necessary, whenever the current line changes or the $currentnodeident property is set. In a non-multiple select tree lists, setting either the current line in the list or the $currentnodeident will select the line and scroll to it. This applies to flat list trees only.
In multiple select tree lists, setting the current line will scroll to that line but will not select it. Setting $currentnodeident notationally will set both the current line and select the node. Tree lists without checkboxes will clear any current selection, but tree lists with checkboxes will not. This behavior mimics the user behaviour of clicking a node.
In multiple select tree lists, the $currentnodeident and the current line in the list can reference different nodes; however, in single select tree lists, they will always reference the same nodes.
The content inside a Tree List Control can be built dynamically as the end user expands a node. In previous versions, the entire contents of the tree list had to be built and sent to the client, including the contents for all unexpanded nodes, which for large lists created quite an overhead. Building the tree list data and displaying content in a tree list can be optimized with the ability to build node contents as required, by setting the tree list data mode to “dynamic”; note there is an example app in the Samples section in the Hub in the Studio Browser and in the JS Component online gallery.
To use a Tree Control in dynamic mode you need to set its $datamode property to kJSTreeDynamicLoad. Note that dynamic mode can only be used for ‘single-select’ trees, and attempting to assign kJSTreeDynamicLoad to $datamode will fail if $multipleselect or $checkbox for the tree control is kTrue.
A dynamic tree still requires a list to be identified by $dataname, but the list need only contain the initial content of the tree, that is, the content for the root or parent nodes. After the list content is changed, the tree reloads its content from the list.
Dynamic trees also use lists to set the content of expanded nodes and to add nodes programmatically to the tree. The lists all have the same structure: each list represents an ordered set of nodes with the same parent (or no parent in the case of the $dataname list), and the columns are as follows:
Column 1: Text. The text displayed for the node.
Column 2: Icon. Only used when $showicons is set to kTrue. This is a line number in the list identified by $nodeiconlist, or zero if the node does not have an icon. $nodeiconlist is described below.
Column 3: Ident. A unique positive integer that identifies the node. Cannot be the same as the ident of any other node in the tree. The tree control throws an exception (resulting in a message box displayed on the client) if you try to use a duplicate ident.
Column 4: Tag. A string associated with the node. Any value that is useful to the developer. Need not be unique.
Column 5: Tooltip. The tooltip string for the node, displayed when the user hovers the mouse over the node. Leave empty for no tooltip, although on some browsers nodes may inherit their tooltip from their parent node if the tooltip is empty.
Column 6: Text color. The text color for the node (an integer RGB value). Zero means use the $textcolor of the tree.
Column 7: Flags. Integer flags. A sum of zero or more of the following constants:
kJSTreeFlagEnterable. The node text can be edited (this works with the existing evRenamed event).
kJSTreeFlagHasChildren. The node has children.
kJSTreeFlagExpanded. The node will be immediately expanded. If you set this flag you must supply the child nodes using a node list supplied as the children column.
kJSTreeFlagDiscardOnCollapse. If set, when the user collapses the node, the tree deletes the node contents. This means that the next time the user expands the node, the tree will generate an evLoadNode event; evLoadNode is described later in this document.
Column 8: Children. If the kJSTreeFlagHasChildren is present, you can pre-populate the node content by using a nested list to specify the children. If you do not supply any children using this list, then you can supply them later by using the evLoadNode event (see below). The content of this column is ignored if the kJSTreeFlagHasChildren is not present. You can nest children lists arbitrarily deep (within reason).
$nodeiconlist allows you to specify the icons to be used with the tree. These must be available when the tree is updated from the dataname list. $nodeiconlist must be the name of an instance variable list with at least one column which must be a character column containing icon URLs. You can populate each URL in the node icon list using the iconurl() function, for example:
Dynamic trees have the event evLoadNode which allows you to populate the tree on demand, by only populating node content when a node is expanded. When using the kJSTreeDynamicLoad mode for $datamode, evLoadNode is generated so that you can set the content of the node by setting the $nodedata property which is the name of a list containing the expanded node content. For other settings of $datamode, evLoadNode is generated when the user expands a tree node.
The evLoadNode event has two parameters, pNodeIdent and pNodeTag, corresponding to the node that is being expanded. In the event processing for evLoadNode, you can set the $nodedata property to a node list representing the content of the node (with the above column format); if the event processing fails to set this property, the tree control sets the node content to empty.
The list assigned to $nodedata can specify nested children if desired.
$nodedata is a runtime-only property that can only be set.
Dynamic tree lists support ‘node actions’ to allow you to manipulate the nodes in a Tree List programmatically. For example, you can expand or collapse a node, and you can add, delete or rename nodes. You execute a node action by assigning a row variable to the $nodeaction property of the tree; this is a runtime-only property that can only be set. The supported actions are as follows:
Node Action | Description |
---|---|
kJSTreeActionExpand | row(kJSTreeActionExpand, ident). Expands the node with the specified ident if it is not already expanded |
kJSTreeActionCollapse | row(kJSTreeActionCollapse, ident). Collapses the node with the specified ident if it is not already collapsed |
kJSTreeActionRename | row(kJSTreeActionRename, ident, newname). Renames the node with the specified ident to the new name |
kJSTreeActionDelete | row(kJSTreeActionDelete, ident). Deletes the node with the specified ident (also recursively deletes node children). If the current node is deleted, an evClick event will be generated to inform the application of the new current node |
kJSTreeActionAdd | row(kJSTreeActionAdd, ident, position, nodelist). Adds the nodes in the nodelist to the tree, where ident specifies the parent node of the nodes in nodelist; to add a new root nodes specify ident as zero. The position parameter can be one of: -1 to add the new nodes before any existing children of the node specified by ident 0 to add the new nodes after any existing children of the node specified by ident a child node ident. New nodes are added after the child node with this ident. If no such node exists, the new nodes are added after any existing children |
kJSTreeActionUpdateIcon | row(kJSTreeActionUpdateIcon, ident, newicon) updates the icon of a node. Extra parameter is the line number in the list identified by $nodeiconlist, or zero for no icon |
kJSTreeActionMove | row(kJSTreeActionMove, ident, position) moves the node to a new position, where ident specifies the new parent node; to move to the root, specify ident as zero. The position parameter can be one of: -1 to move before any existing children of the node specified by ident 0 to move after any existing children of the node specified by ident a child node ident. The node is moved after the child node with this ident. If no such node exists, the node is moved after any existing children. |
kJSTreeActionCollapseAndDiscard | row(kJSTreeActionCollapseAndDiscard, ident) collapses the node and discards all child nodes |
kJSTreeActionReload | row(kJSTreeActionReload, ident). Reloads the node, generating an evLoadNode event |
The tree control generates evCollapseNode when the user collapses a node. This applies to all trees, not just dynamic trees.
The property $currentnodeident applies to dynamic trees; in previous versions the current (selected) node was represented by a list line. When the end user clicks on a node, the value of $currentnodeident changes, and the control generates evClick. In addition, the developer can assign $currentnodeident (and read its value in client-executed methods). $currentnodeident is a runtime-only property.
The Video Control allows you to play a video within your remote form. The video can be hosted on YouTube or you can play a video via the HTML5 video support in the browser. There is an example app called JS Video in the Samples section in the Hub in the Studio Browser showing how how you can embed a YouTube video in your remote form; the same app is available in the JavaScript Component Gallery.
The JS Video control has the following properties:
Property | Description |
---|---|
$dataname | If $youtube=kFalse, this is a 2 columned list containing the location and type of the videos to be played: Column 1 is the URL of the video file; Column 2 is the media types If $youtube=kTrue, this is a list containing the IDs of the YouTube videos to be played; only Column 1 of the list is used and contains the ID of the YouTube video |
$showcontrols | If true, the control displays video controls such as the Play and Pause buttons |
$youtube | If true, the control will play a movie from youtube.com; column 1 of the $dataname list is the YouTube video id If false, the control will use HTML5 video to play video files from URLs |
$startposition | The time (in seconds) at which the video should start when played |
$currentposition | (Runtime only) The current time (in seconds) of the current position in the video. Assign to this to ‘seek’ to a particular time |
$duration | (Runtime only) The duration of the current video (in seconds). Read-only (in a client-exec method) |
$poster | A URL to an image to display before the first frame of the video is ready. HTML5 video only ($youtube=kFalse) |
$playing | Whether the video is currently playing. Assign to this in order to play or pause the video. Note that many mobile devices prevent the playing of videos if not in direct response to a user action |
$volume | The volume level of the video player (0-100). Assigning 0 will mute the player |
$playbackrate | The video's playback speed, with 1.0 being default speed. Youtube will round down to the closest supported rate of the particular video |
$requestcaptions | If true, closed captions will be turned on (when available, attempting to use the client's language) for Youtube videos. Note that even if disabled, captions may be enabled through the video controls, or through the user’s account settings in Youtube (if they are signed in) |
Properties relating to the current video player ($currentposition, $duration, $volume) will return -1 if queried before a video is ‘ready’ (see evVideoReady).
If you set the $youtube property to kTrue, the $dataname for the video control should be a list containing YouTube ids: the data in the first column of the first row in the list is used to reference the video on YouTube. Note the YouTube id is not the full URL on youtube.com, but just the id on the end of the URL, e.g. 'Ff-qlTlSkc0'.
If the list assigned to a Youtube video control ($youtube = ktrue) has more than one line, a YouTube playlist will be created, using the video IDs supplied in each line of the list. The videos in the playlist will be played successively.
If $showcontrols is true, the playlist can be accessed via the video controls in the UI. You could notationally skip to the next video by skipping to the end of the current video. For example, using the client-executed method:
If you set $youtube to kFalse, the $dataname should be a 2 column list. The first column should contain URLs to the video files, located somewhere on the internet or the Omnis App Server, and the second column should state the media type. For example:
Not all browsers are able to play all video file types, so you should provide the video in multiple formats and populate the list with the URL to each file and type. When the client connects, the browser will play the first video file it is able to play from the list.
The JS Video control has the following events:
evVideoReady
Sent when the video is ready to be played, and can be interacted with.
evVideoEnded
Sent when the video has finished playing (i.e. it has played to the end).
Both events receive a pVideoURL parameter, describing the currently playing video. For HTML5 videos ($youtube = kFalse), this will be a URL to the video file. For Youtube videos ($youtube = kTrue), this will be the Youtube video ID. These should correspond to a value in the list assigned to the control’s $dataname.
The iCalendar external component (or Calendar Control) allows you to load and manage calendar events: it is a non-visual External Component that you can use in your Remote Forms (or window classes). iCalendar allows you to read, write and modify objects based on the standard iCalendar format, which is supported by many third-party calendar products.
The iCalendar model is based on four object types:
Component: A group containing Properties which represent, for example, an event. Components can contain other Components (sub-components).
Property: Used to communicate information about a Component, such as a description or a location.
Value: Properties have a value associated with them. For example, a DTSTART Property will have a date or datetime value.
Parameter: A modifier for a Property. Properties may have more than one Parameter (or none).
There are two types of objects in the Omnis iCalendar external component:
Document: Represents the entire Document and its children.
Component: Used to access and manipulate iCalendar Components and their associated Properties and Parameters.
To access the iCalendar objects & its methods, you need to create an instance variable in your remote form (or window class), choose Object as its Type, under Subtype drop down the Select object dialog, open the ‘iCalendar Objects’ group and select ‘Document’ object.
iCalendar Documents can be initialised with character data, or built up with the Omnis iCalendar methods.
To load an iCalendar file into a Document object, use FileOps to read in the character data. Then use $initwithdata() to initialise the document.
To output the character data, use $getdata() on the Document or a single Component. To save the data into a file, use FileOps.
The functions $getcomponent() and $getsubcomponent() return a copy of a Component. Therefore, modifying the returned Component will not affect the parent (the Component or Document that the method was called on). In order to update the parent, Component copy will need to be saved back to the parent with $replacerootcomponent() or $replacesubcomponent().
As well as the standard Property types, custom Properties can be added to Components. These must be prefixed with “X-”, e.g. “X-PROPERTY”. By default, the data type of a custom Property is character. When adding a Property to a Component with $addproperty(), the optional iDataType Parameter can be used to override the default data type. Doing so will set the “VALUE” Parameter to the data type associated with the constant. The data type cannot be changed after it has been created.
Like custom Properties, custom Parameters can be applied to Properties. Similarly, they must also have “X-” as a prefix.
When a Document is initialised with $initwithdata(), the character data is parsed. If there are any syntactic or semantic errors in the data, such as a misspelt Property name or a Property without a value, an X-LIC- error Property will be inserted. For example, the following error is caused by misspelling the ATTENDEE Property:
X-LIC-ERROR;X-LIC-ERRORTYPE=PROPERTY-PARSE-ERROR:Parse error in property name: ATENDEE
These values contain multiple parts and are therefore represented as rows. The static $createrow() helper method can be used to build these rows, which can be used to create a new Property or update a value.
Recur
The “RECUR” value type in the iCalendar model denotes a recurring event. It is commonly used with the “RRULE” Property. Its value may contain several parts, separated by semicolons. The parts contain key value pairs separated by the equals sign. The example shows a Recurrence Rule property.
RRULE:FREQ=MONTHLY;BYMONTHDAY=1;UNTIL=19980901T210000Z
A Component’s $propertylist will store an RRULE Property as a rows containing columns relating to each keyword. To create an RRULE Property with $addproperty(), the vValue parameter can take either a character or row argument. To create a recurrence type row, use $createrow(kICalendarRowTypeRecur).
Duration
The “DURATION” value type is represented in a component’s $propertylist as a row. The columns are: IS_NEGATIVE, DAYS, WEEKS, HOURS, MINUTES and SECONDS. To add a Property with a duration type, a row containing these column names can be used. The column values are all Integers, with the exception of IS_NEGATIVE, which is a Boolean. Alternatively, a string can passed. For example, P15DT5H0M20S denotes a duration of 15 days, 5 hours, and 20 seconds. See the RFC 5545 iCalendar specification for details on this format (https://tools.ietf.org/html/rfc5545#section-3.3.6).
Period
“PERIOD” value types have two parts: The first is the start time (date time). The second can either be the end of the period (date time), or a duration. Period is the default value type of the Free/Busy Property. In the $propertylist, period values are displayed as a row containing a START date time and either a DURATION or an END date time.
19970101T180000Z/19970102T070000Z date time “/” date time (Explicit)
19970101T180000Z/PT5H30M date time “/” duration (Start)
Geo
“GEO” Properties hold geographic coordinates, represented as two floats separated by a semicolon. The values are latitude and longitude respectively, e.g. 37.386013;-122.082932.
In the $propertylist of a Component, they are displayed as a row containing a LAT and a LONG column with float values.
$createcomponent()
OmnisICalendar.$createcomponent(iType)
Creates a new iCalendar Component object using one of the kICalendarComponent... constants. Returns an iCalendar component object.
iType: A kICalendarComponent... constant to specify the Component type.
$createrow()
OmnisICalendar.$createrow(iType)
Returns a row which can be used to add or update certain Properties. iType can be one of the kICalendarRowType... constants.
iType: A kICalendarRowType... constant to specify the type of row.
$initwithdata()
$initwithdata(cData)
Initializes the object with the Character contents of an iCalendar file. Returns true if successful.
cData: The character data containing the contents of an iCalendar file.
$getdata()
$getdata() - no parameters
Returns character data representing the Document that can be saved as an iCalendar file.
$getcomponent()
$getcomponent(iComponentId)
Returns a copy of the root Component object with the specified ID.
iComponentId: The ID of the root Component to find.
$addrootcomponent()
$addrootcomponent(oComponent)
Adds a Component to the root of the Document. Returns the ID of the new Component.
oComponent: The Component to be added to the root.
$deleterootcomponent()
$deleterootcomponent(iComponentId)
Removes the Component with the specified ID from the root. Returns true if the Component was deleted.
iComponentId: The ID of the Component to delete.
$replacerootcomponent()
$replacerootcomponent(iComponentId, oComponent)
Replaces the Component at the specified ID with oComponent. Returns true if successful.
iComponentId: The ID of the Component to replace.
oComponent: The new Component.
$componentlist
A list of root-level Component info for the Document. The columns for this list are: ID, Type and TypeName.
$getdata()
$getdata() - no parameters
Returns character data representing the Component and its children, that can be saved as an iCalendar file.
$isvalidcalendar()
$isvalidcalendar() - no parameters
Returns true if the VCALENDAR Component meets the RFC 5546 iCalendar specification standards.
$getsubcomponent()
$getsubcomponent(iComponentId)
Returns a copy of the sub-component object with the specified ID.
iComponentId: The ID of the sub-component to find.
$addsubcomponent()
$addsubcomponent(oComponent)
Adds a sub-component to the Component. Returns the ID of the new Component.
oComponent: The sub-component to be added to the Component.
$deletesubcomponent()
$deletesubcomponent(iComponentId)
Removes the sub-component with the specified ID from the component. Returns true if the sub-component was deleted.
iComponentId: The ID of the Component to delete.
$replacesubcomponent()
$replacesubcomponent(iComponentId, oComponent)
Replaces the Component at the specified ID with oComponent. Returns true if successful.
iComponentId: The ID of the Component to replace.
oComponent: The new Component.
$addproperty()
$addproperty(cName, vValue, [wParameters, iDataType])
Adds a new Property to the Component. Returns the Property ID.
cName: The name of the Property. Must be a valid Property type.
vValue: The value to assign to the Property. The type can be Character, Integer, Date Time, Float, Boolean or Row.
wParameters: A row of Parameters to add to the Property.
iDataType: A kICalendarDataType... constant. Sets the 'VALUE' Parameter which overrides the default data type for the Property. Can be used to specify the type of a custom Property.
$deleteproperty()
$deleteproperty(iPropertyId)
Delete the Property with the specified ID. Returns true if the Property was deleted.
iPropertyId: The ID of the Property to delete.
$setparameter()
$setparameter(iPropertyId, cName, cValue)
Sets the Parameter of the Property. If there is an existing Parameter with the same name, it will be overwritten. Returns true if successful.
iPropertyId: The ID of the Property associated with the Parameter.
cName: The name of the Parameter to set.
cValue: The value to set the Parameter to.
$updateproperty()
$updateproperty(iPropertyId, vValue, [wParameters])
Updates the Property with the specified ID. Providing Parameters will overwrite any existing ones. Returns true if successful.
iPropertyId: The ID of the Property to update.
vValue: The new value to assign to the Property. The type can be Character, Integer, Date Time, Float, Boolean or Row.
wParameters: A row of Parameters to add to the Property.
$deleteparameter()
$deleteparameter(iPropertyId, cName)
Removes the Parameter with the name cParamName from the Property. Returns true if the Parameter was deleted.
iPropertyId: The ID of the Property associated with the Parameter.
cName: The name of the Parameter to delete.
$componentlist
A list of sub-component info for the Component. The columns for this list are: ID, Type and TypeName.
$propertylist
A list of iCalendar Properties held by this Component. The columns for this list are: ID, PropertyName and PropertyValue. The PropertyValue column contains a row for each Property. Each row has a “_VALUE” column containing the Property value (the type of this depends on the Property), and columns for any Parameters that the Property has.
$typename
The type name of the Component.
$typenumber
The type number of the Component.