The Component Store contains over 30 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 open in design mode (assuming the $client property in the remote form is set to kClientJavaScript, which is the default for all new remote forms). In addition, there are a number of alternative controls available under the JavaScript Native Components tab.
You can create your own 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/#section-jsgallery
or you can use the shortcut: tinyurl.com/jsgallery10
Many of the example apps in the 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.
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 manager for recording information about colleagues or friends, a Holidays app for managing annual leave requests, and a Webshop app which has a product catalog and 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.
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, but you can open it, or bring it to the top, from the main Omnis toolbar (CStore button), or by pressing F3. The JavaScript Components tab (group button) should be selected by default, showing the standard JavaScript Components; there are a number of JavaScript Native Components under that tab.
You can Right-click/Cmnd-click on the background of the Component Store and select Large/Small Icons and/or Text to alter the display of the component store, and you can Save the window setup from the same menu to store 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(s): in this case, you may prefer to start adding components on the larger breakpoints (768 or create a new one at 1024 pixels), and then switch to the smaller breakpoint to rearrange and/or resize the components you have added.
To create a JavaScript component, you can:
Drag a component icon from the Component Store and drop onto a JavaScript remote form; the component is added at the default size
Double-click on a component icon in the Component Store to add it to a form; the component is added at the default size
Select the component icon in the Component Store and press Return to add it (same effect as double-clicking)
Select the 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 button icon for radio buttons.
Once you have placed the component on the remote form you can resize or re-position it, and set its properties using the Property Manager (if the Property Manager is hidden, press F6 to open it or bring it to the top). The following screen shot shows the Pie Chart example app, with the JavaScript Pie Chart component selected; the Property Manager (on the right) shows the properties of the current selected object, which could be a class, or in this case, a specific component.
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, or onto a different form. Alternatively, you can hold down the Ctrl key and click and drag a component 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).
The following components are available for JavaScript remote forms under the “JavaScript Components” tab (group button), plus there are a number of “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 | 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 Edit 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 |
Subform | Allows you to insert another remote form class as a subform |
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 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 currently 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 new ‘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.
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.
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_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, 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:
$jscustomformat
a date-time format string using the characters described below. If $jsdisplayformat 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 $clientcommand 'setcustomformat'
$jsdisplayformat
the format used to display 'Date Time' data, a kJSFormat... constant as follows:
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 $jscustomformat |
The following standard date formatting characters are supported for $jscustomformat:
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:
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) |
There is an entry on the Constants tab in the Catalog (F9) called "Date codes (JavaScript Client only)" that lists the formatting characters.
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:
% | print a literal "%" character |
b | print an integer as a binary number |
c | print an integer as the character with that ASCII value |
d | print an integer as a signed decimal number |
D | as above but include thousand separators |
e | print a float as scientific notation |
u | print an integer as an unsigned decimal number |
f | print a float as is |
F | as above but include thousand separators |
o | print an integer as an octal number |
s | print a string as is |
x | print an integer as a hexadecimal number (lower-case) |
X | print 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 pixel offset 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. 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; the style of the error outline is set in the omnis.css style sheet as div.om-error-border
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.
There is a new client command, “clearerrors” to allow you to clear all error text messages for the form.
is 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 and is often useful if you need to select a specific component which is partly obscured or hidden in the form. 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.
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 display a message, initiate 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.
In order 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. 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.
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 allow you to add an icon, such as a Button, to create a better appearance and UI for your apps. Such controls that support icons have the $iconid property which allows you to specify an image to be used for the control. You can use images that are 16x16, 32x32, or 48x48 pixels either at a standard pixel density suitable for displaying on standard monitors, or you can create icon images that are 1.5 and 2 times the size, suitable for displaying on devices with high definition screens such as the latest Apple iPhones or Android Phones, as well as tablets and HD monitors on desktop computers.
You can create icon images in any third-party image editing software and place the image files directly in the Omnis development tree, in the folder named ‘iconsets’ (in previous versions icons sets were stored in ‘html/icons’). The icon image files must be saved using the PNG file type and placed in a sub-folder of the ‘iconsets’ folder in the main Omnis tree (note for existing users: this is not the same icons folder in the root of the Omnis tree which contains the built-in icon datafiles). Each sub-folder represents what is called an Icon Set which is a named collection of icons (which would normally corresponed to a single library). The name of the sub-folder in the icons folder becomes the name of the icon set which is specified in the $iconset property for the library (see below) and will also appear in the icon selection dialog. 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.
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 (separate image files in a folder) which support icon images up to 96x96 pixels (i.e. 2x the largest 48x48 icon size). Icon sets are supported in JavaScript Client remote form classes and on window classes in the thick client – you cannot use Icon sets with the old ‘Web Client’ or the ‘iOS Client’ plug-in (note these plug-ins are not supported in Studio 6.1 or higher).
When Omnis references an Icon ID it will first search for the icon in an icon set, then it will search #ICONS in the current library, then it will search the ‘Studio’ icon set, and then any other icon datafiles, including Omnispic and Userpic.
Each image file within an icon set must conform to the following naming convention:
<text> is the name of image. This string is used in the icon picker dialog when you set an object’s $iconid in the Property Manager.
<id> is the positive integer id to be used as the icon id. It can be in the range 1 to 10000000.
<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. Example file names are:
pencil_1657_16x16.png | Normal state 16x16 icon with ID 1657 for standard resolution devices |
pencil_1657_16x16_2x.png | Normal state 16x16 icon with ID 1657 for HD resolution devices |
check_1658_32x32c_2x.png | Checked state 32x32 icon with ID 1658 for HD resolution devices (see below) |
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).
As a special case you can implement icons for different states in check boxes and radio buttons.
<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
If you are unsure about the icons you need to create and the file naming, you can examine the icons in the ‘iconsets/studioide’ folder – here you will see the different size image files and their naming required for each icon used in the Studio IDE (note you cannot use the icons in this folder without acquiring the proper license). You need to adopt the same naming scheme for your own icon images.
Image File Name | Image Size & Description |
---|---|
catalog_1632_16x16.png | 16x16 pixels; Icon ID 1632 for standard resolution devices |
catalog_1632_16x16_2x.png | 32x32 pixels; Icon ID 1632 for HD resolution devices |
catalog_1632_32x32.png | 32x32 pixels; Icon ID 1632 for standard resolution devices |
catalog_1632_32x32_2x.png | 64x64 pixels; Icon ID 1632 for HD resolution devices |
catalog_1632_48x48.png | 48x48 pixels; Icon ID 1632 for standard resolution devices |
catalog_1632_48x48_2x.png | 96x96 pixels; Icon ID 1632 for HD resolution devices |
You do not have to create an icon 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 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”.. (Existing users should note that this is the equivalent of an ‘Icon Page’ in the existing icon support.)
When you deploy your app to a web server, you need to copy any icon sets used by your forms from /iconsets in your Omnis development tree to the /icons folder at the same location as the .htm file containing your app, that is, <location of .htm file on webserver>/icons: each icon set will appear as a subfolder of the /icons folder and contain all the PNG icon files for your app.
Libraries have a preference called $iconset ($libs.LIB.$prefs.$iconset). This is the name of the icon set to be used when resolving icon ids for the JavaScript client and the thick client in the current library. When using this library, and when looking up an icon for the thick client or JavaScript client, Omnis will search for icons within this icon set before following the current icon search path for the library. In this case icons present in the icon set will take precedence over those in #ICONS, omnispic.df1, etc.
Omnis looks in various icon set folders and icon datafiles when it looks up an icon. If an icon with the same ID is included in another folder, after it has already been found, it is ignored in subsequent folders and an error written to iconsetlog.txt. You should therefore avoid having the same or similar icons or icon sets in multiple folders to avoid any confusion. Omnis looks in the following folders or datafiles in this order:
When using a web server for deploying your application, the icon sets must still 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 tree.
When you set the $iconid of an object using the Property Manager, the icon set for the current library will be shown in the Icon picker dialog ($iconset must be set for the library for the icon set to appear) allowing you to select one of the icons in the set. You can select the icon required and the Icon ID will be assigned to $iconid for the object.
Any errors created while setting the icon ID for JavaScript controls are sent to a file called iconsetlog.txt located in the Studio folder.
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 need to copy your icon sets and images files to the Omnis App Server when you want to deploy your web or mobile app. If the icons are not copied to the Server tree they will appear to be missing from your app.
Note that for standalone apps the icons needed for your mobile app will be bundled in the SCAF. If any icons change on the Omnis App Server they will be updated on the client when the standalone application files are updated.
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.
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 a new constant pDropId 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 available in the Samples section in the Hub in the Studio Browser, and in the JS Component Gallery on the Omnis website: www.omnis.net
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.
In addition, the list, tree 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 (note that pDropId is new for Studio 8.0):
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 | (new for Studio 8.0) 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 new 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 new client commands described in the later section about processing files. |
evCanDrop, evWillDrop and evDrop for the thick client have a new event parameter, pDropId. 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 Omnis JavaScript remote forms using Page panes and by assigning the appropriate value to a new $landmark property for each pane: the options for the new property 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 $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 the form in design mode, starting at 1 and increasing by 1 for each control (note the $order values do not change if you 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 value of other controls on the form will shuffle automatically.
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. Once 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.
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”.
Some of the Remote form class controls (and Window class controls) support alpha colors, meaning that you can set the transparency for the color of the control. The color selection dialog in the Property Manager displays an alpha selection slider if a selected control supports alpha colors (the alpha slider is hidden for controls that do not support alpha).
The controls that support alpha colors include the Line, Oval, Rect and RoundRect background objects for windows.
The rgba() function can be used to set the RGB color and alpha setting for controls. The syntax is rgba(red,green,blue,alpha) with each parameter being an integer value in the range 0-255, where an alpha value of 255 means completely transparent. For example, to set the color of a window background object, in this case 50% transparent red:
In addition, the color selection palette for the controls that support the use of a color palette or a popup color palette, including the colorpalette control, push buttons, and toolbars, include the new alpha selection slider.
When assigned a color with no alpha the palette will automatically hide the alpha slider. If the control is assigned an alpha value, the palette will display the new alpha slider.
For example, where colorbutton is a push button with $buttonmode set as kBMcolorpicker:
The Omnis external component interface has been updated so external components can support alpha colors. The example WASH control has been updated to demonstrate this.
The Export & Import Library to JSON options have been updated to support alpha color values for controls.
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.
As part of the work to make the JavaScript Client meet Accessibility guidelines in Studio 10, a new $active property has been added to all JavaScript controls; the $active property is set to kTrue for all new controls, except the Label Control which has $active set to 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.
Existing users should see the What’s New in Studio 10 doc/pdf for further details about the new $active property and how it relates to the existing $enabled property.
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. To do this, you need to create a new remote form, copy any components you want to customize from the JSFormComponents form, and add them to your own form. This might be useful if you always want to create edit controls or buttons with certain properties (e.g. colors or fonts)
You will need to edit the Component Store library (comps.lbs) to change the contents of the Component Store. To open the Component Store library, right click on the background of the Component Store itself and select ‘Show Component Library in 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 remote form class to the Component Store library; note that the name of the new remote form will be used as the tab name in the Component Store toolbar. 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).
With your new remote form open, open the JSFormComponents remote form next to it. Drag any JavaScript controls you want to customize from JSFormComponents into your 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.
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. It has the following custom properties:
Property | Description |
---|---|
$activitystyle | The style of the indicator, one of the following constants: kJSActivityBar: a moving bar kJSActivityBlock: a moving block kJSActivitySmallSpinner: a small rotating spinner kJSActivityCustomLink: the image in $customlink is used |
$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, either a Bar, Block, a small Spinner, or a custom Gif specified in $customlink.
The following code assigns a custom link to the activity control:
There is an example app 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 JS Component gallery on the Omnis website at: www.omnis.net.
Alternatively, you could consider using the showloadingoverlay client command to show a loading indicator (animated image) over a remote form or specific component.
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.
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 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 JS Component gallery on the Omnis website at: www.omnis.net.
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 Bar Chart and a Pie Chart. 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 Bar and Pie charts in the JavaScript Apps Gallery on the Omnis website (www.omnis.net), 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 and 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 Pie Chart 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.
For Pie charts, each value is shown as a percentage of the total of all the values in your list, that is, the size of each segment (angle) is calculated as the proportion of the individual value when compared to the total of all values in the list.
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 hide or show 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 |
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.
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 to confirm something or initiate a process, such as an OK or Cancel button, or a Send button.
The button can display an icon, specified in the $iconid property (a URL pointing to an image file in the ‘html/icons’ folder), and/or a single line of plain text specified in $text. The Button has the following custom 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 |
$textbeforeicon | If true, and the control has both text and an icon, and the text is displayed to the left of the icon |
$textishtml | Specifies that the text entered in $text is treated as HTML |
$::vertical | If true, the text and icon are arranged vertically |
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 new 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.
For example, 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. 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.
When a Checkbox is clicked an evClick event is triggered with the current value reported in the pNewVal parameter.
There is an example app 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 JS Component gallery on the Omnis website at: www.omnis.net. 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 $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, and in the JS Component gallery on the Omins website: www.omnis.net.
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 a Complex Grid example app in the Samples section in the Hub in the Studio Browser, plus there is a Webshop app that uses complex grids in the Applets section; the webshop app 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.
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 in the Samples section in the Hub in the Studio Browser, showing how to use Data grids, including how to use custom cell formatting: in addition, the Webshop example under the Applets section 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 $headertext 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.
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 the grid can grow by adding more lines to accommodate more data if $extendable is enabled. The height of the rows in a data grid adjusts to fit the data automatically, unless you specify a height in pixels in $::rowheight.
The Data 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 about the List Pager.
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 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.
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 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 JS Component gallery on the Omnis website at: www.omnis.net.
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
The following code is the $event method for a data grid, set to execute on the client:
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 (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 determine the search type. 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.
You can implement a control method on a data grid, which will be called whenever the user types text into the data grid's filter (if enabled). The method should be named $filtergrid and 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 $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.
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.
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.
The properties $editdatetext and $columnallownulldateinput allow end users to enter a date manually via the keyboard rather than having to use 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 evCellValueChanged event reports when the user has changed the value of a cell, while there has been a small change to the existing evCellChanged event.
evCellValueChanged (pHorzCell, pVertCell)
sent when the user has changed the value of a cell.
pHorzCell - The column number of the cell that has changed.
pVertCell - The row number of the cell that has changed.
evCellChanged (pHorzCell, pVertCell)
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.
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. A numeric color value is returned from the picker, or a color functions 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 third column, use the code:
You can specify the text for the OK and Cancel buttons on the color picker using $colorpickeroktext and $colorpickercanceltext.
An entry field has been added to the color picker which accepts colors in the hex (the default), rgb or color name formats. Localisable strings have been added 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. In addition, end users should be able to navigate the color picker from the keyboard without the picker losing the focus.
Data grid columns with type Number have a 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 date and/or time by clicking on the up or down arrows for each part of the date or time; from Studio 10.0.1 a date range can be selected, see below. 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).
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.
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 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) |
kJSDatePickerStyleCustomr | a custom format, see below |
The color of the Date Picker is specified with $datefacecolor while $datefacealpha sets the transparency (value 0-255).
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. However on mobile devices, 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 access to mobile device features 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 of 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 smartphone or tablet computer.
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. Therefore, you will need to compile your app into a wrapper, and test it 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; or test it in the App Manager. The only 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: see those actions later in this section.
The Device control supports a number of hardware functions, some of which may not be available on particular devices. 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.
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, 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. |
$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 a number of 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
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)
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)
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.
|
||||
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:
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.
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 (for the SMS) or the Email address 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.
Some of the Device actions (those listed below) may work in your application when running in a normal 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.
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 $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, such as in a Contact form; in this case you would normally add a label to each edit or entry field on the form, or you can add a ‘content tip’ ($::contenttip) to each edit control to help the end user.
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 variable assigned to the control. When kTrue (the default), $issingleline makes the edit control only allow data entry on a single line, otherwise when kFalse the field can be extended downward to allow data entry on multiple lines. 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 $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 List Control section for more information about linked lists.
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. It can be set to up to four-pixel values separated by -, 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.
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
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.
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 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 uppercase for character data.
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.
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 capitalise the first character of new sentences (default and previous behaviour)
kJSAutoCapitalizeWords
Automatically capitalise 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.
$setselection(iFirstSel[,iLastsel]))
Sets the focus on and selection range of the content in the 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 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" option in a new “macOS" member in config.json, 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 in the Samples section in the Hub in the Studio Browser showing how you can upload and download files; in addition, the Contacts example app uses the file control, which is described below.
When in Upload mode the File control opens a standard Upload dialog to allow the end user to select a local file to upload. There are various properties to allow you to change the text and error messages on the Upload dialog.
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. The $html property contains the HTML content for the control. The HTML content for the control must start with an element declaration such as <div...> or <style>. The $ctrlname is the name of the control. 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.
There is an example app in the Samples section in the Hub in the Studio Browser, and the same app is available in the JS Component gallery on the Omnis website at: www.omnis.net.
There are also two examples in the Samples section in the Hub 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 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 (that is, 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 showing how you can build a dynamic hierarchical list using the Hyperlink control in the Samples section in the Hub in the Studio Browser; in addition, the same app is in the JS Component gallery on the Omnis website at: www.omnis.net
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.
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 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.
If $ischecklist 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.
There are a number of example apps showing different types of list control in the Samples section in the Hub in the Studio Browser; in addition, the same apps are available in the JS Component gallery on the Omnis website at: www.omnis.net.
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 via 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 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:
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. 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.
Data Grids have $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 pixel offset for a list.
When set to true, the $keyboardchangesline property means that navigating the list with the keyboard also sets the current line, so when the list is not in a multiple select state, there is not a separate focused line. The evClick event is fired when the current line changes. This property is available in standard Lists, Native lists, Tree lists, and Data grids.
When set to false, 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 in the Samples section in the Hub in the Studio Browser to show the use of a Linked list; in addition, the same app is in the JS Component gallery on the Omnis website at: www.omnis.net
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 omnis.css file. Do not edit the classes in omnis.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 and as provided by their API. There is an example app in the Samples section in the Hub in the Studio Browser showing the full capability of the Map control; in addition, the same app is in the JS Component gallery on the Omnis website at: www.omnis.net
In order to use the Map control, you need to register with Google to obtain a map API key, which can be entered in the $apikey property of the control; the Map control will not work without the API key. Specifically, you need to obtain a Google “Maps JavaScript API” key (previously called a Browser API key). In addition, if you want to use the Geocode function you need to obtain a separate “Geocoding API” key.
Important Note: By signing up to Google Maps and using the 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 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 user interaction 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 JS Map example app has been updated and includes some of the new markers and polygons, and can viewed or downloaded via the Omnis website (www.omnis.net) from 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 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 in the JS Component gallery on the Omnis website at: www.omnis.net.
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 a value of 0 for no accessory. A kJSNativeListAccessoryTypeNone constant will be added in the future.
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 alter the default appearance for a particular platform, or wish to change something which is not exposed as a property, you would need to do so using CSS. This is only recommended if you have experience of customizing CSS.
The classes used (when defaulting to platform-specific appearances) are defined in native_list.css.
Rather than altering these classes here, it is recommended that you extend them in your user.css file, to prevent you needing to make these changes each time you update Omnis.
As always, when editing the CSS used by Omnis’ controls, 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 in the Samples section in the Hub in the Studio Browser.
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 in the Samples section in the Hub in the Studio Browser.
![]() |
![]() |
---|---|
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 in the Samples section in the Hub in the Studio Browser.
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. 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 control (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 in the Samples section in the Hub in the Studio Browser.
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 omnis.css and the images folder, so you can change their appearance if required.
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 in the Samples section in the Hub in the Studio Browser.
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 |
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 fields or controls on separate panes, or to break down an entry form into more manageable parts whereby each pane contains a small number of fields. 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 one); in this case, an evUserChangedPage is triggered with the new page number reported in pPageNumber.
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.
A Group box component is not available in the JavaScript client components, but you can create one “on the fly” using a new method called $makegroupbox() 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]) must be executed on the client, and converts a Paged pane to a Group box with the specified label, as well as the optional CSS font, font size, and text color. This method 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.
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 Chart Control 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.
There is an example app in the Samples section in the Hub in the Studio Browser showing you how to set up a Pie chart, and the same app is available in the JS Component gallery on the Omnis website at: www.omnis.net
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.
$maintitle | The legend title |
$showlegendnames | 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 |
$flyout | Enables the pie segments to move or “fly out” when the end user’s mouse hovers over the segment (kTrue by default) |
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 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 JS Component gallery on the Omnis website at: www.omnis.net
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 Progress Bar control lets you display a progress bar in your remote form, to show the progress of some process in your application. 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 $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 (as long as it’s supported by the browser). If $usesystemappearance is set to false, the progress control is built with 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 example 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:
This example is in the Samples section in the Hub in the Studio Browser, and in the JS Component gallery on the Omnis website at: www.omnis.net.
A Radio Group 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. 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. 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 |
The evClick event is reported with pNewValue containing the value selected.
Note that the Check box example app in the Samples section in the Hub in the Studio Browser also uses a Radiogroup (to select Gender in this case), and the same app is available in the JS Component gallery on the Omnis website at: www.omnis.net
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 showing how you can use the Rich text editor in the Samples section in the Hub in the Studio Browser, and the same app is available in the JS Component gallery on the Omnis website at: www.omnis.net
The Rich text editor control uses the Quill open source text editor which relies on modern browser technologies and, as such, some older mobile OS's (iOS < 6.0 & Android < 4.0) may have compatibility issues. For Studio 8.0.2 the control is based on Quill 1.0, which brings several new features and bug fixes, including 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 several 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. Quill 1.0 only supports IE 11+. When running on earlier IE versions, the control will fall back to Quill 0.2 - this is what the ‘-legacy’ files above are used for.
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_bold | rt_subscript | rt_italic |
---|---|---|
rt_superscript | rt_underline | rt_strikethrough |
rt_justifyleft | rt_removeformat | rt_justifycenter |
rt_indent | rt_justifyright | rt_outdent |
rt_justifyfull | rt_textcolor | rt_insertorderedlist |
rt_backgroundcolor | rt_insertunorderedlist | rt_decrease_indent |
rt_increase_indent | rt_video | rt_blockquote |
rt_codeblock | rt_clearformat |
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 as a toolbar within your web and mobile apps; 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.
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, which is useful if you are using the segmented control as a navigation control.
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.
There is an example app 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 JS Component gallery on the Omnis website at: www.omnis.net.
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. |
$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 new 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 with an optional custom thumb icon that the user can drag to control its numeric setting, which can be used to set the value of another component in your form, such as a volume control. As an alternative, you can use the Native Slider to control variable numeric values.
There is an example app in the Samples section in the Hub in the Studio Browser, and the same app is available in the JS Component gallery on the Omnis website at: www.omnis.net.
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 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 form or 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. The JavaScript Component Gallery app on the Omnis website, for example, 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.
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:
There are further subform examples in the Samples section in the Hub in the Studio Browser, and the same apps are available in the JS Component gallery on the Omnis website at: www.omnis.net.
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 $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 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.
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 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. Alternatively, you can use the Native Switch to display on/off values.
The variable you specify in the $dataname property should be a Number or Boolean variable. The $switchon and $switchoff properties let you specify the icon IDs 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.
There is an example library showing the Switch control with a range of different ON/ OFF images in the Samples section in the Hub in the Studio Browser, and the same app is in the JavaScript Apps Gallery on the Omnis website at: www.omnis.net.
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 lets you specify 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.
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.
There is an example app called ‘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 JS Component gallery on the Omnis website at: www.omnis.net.
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 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 in the Samples section in the Hub in the Studio Browser, and the same app is available in the JS Component gallery on the Omnis website at: www.omnis.net.
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 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 JS Component gallery on the Omnis website at: www.omnis.net. 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 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 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 JS Component gallery on the Omnis website at: www.omnis.net
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 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 $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.
The Tree List 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 JS Component gallery on the Omnis website at: www.omnis.net
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.
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 “on the fly” as required (note there is an example app in the Hub and JS Component 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.
As in previous versions, a dynamic tree still requires a list 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 a new tree property, $nodedata, 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 trees 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 modes. You execute a node action by assigning a row variable to the $nodeaction property of the tree. The supported actions are as follows:
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.
$nodeaction is a runtime-only property that can only be set.
The tree control now generates evCollapseNode when the user collapses a node. This applies to all trees, not just dynamic trees.
The current (selected) node in the tree is no longer represented by a list line. Instead, there is a new property, $currentnodeident that applies to dynamic trees. When the user changes $currentnodeident (by clicking on a node), 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. 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 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 object 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 & 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.