Omnis Webdev
Omnis Webdev
Omnis Webdev
Mobile Apps
Using the Omnis JavaScript Client
TigerLogic Corporation
Sept 2013
28-092013-01
The software this document describes is furnished under a license agreement. The software may be
used or copied only in accordance with the terms of the agreement. Names of persons, corporations, or
products used in the tutorials and examples of this manual are fictitious. No part of this publication may
be reproduced, transmitted, stored in a retrieval system or translated into any language in any form by
any means without the written permission of TigerLogic.
© TigerLogic Corporation, and its licensors 2013. All rights reserved.
Portions © Copyright Microsoft Corporation.
Regular expressions Copyright (c) 1986,1993,1995 University of Toronto.
© 1999-2013 The Apache Software Foundation. All rights reserved.
This product includes software developed by the Apache Software Foundation
(http://www.apache.org/).
OMNIS® and Omnis Studio® are registered trademarks of TigerLogic Corporation.
Microsoft, MS, MS-DOS, Visual Basic, Windows, Windows 95, Win32, Win32s are registered
trademarks, and Windows NT, Visual C++ are trademarks of Microsoft Corporation in the US and other
countries.
SAP, R/3, mySAP, mySAP.com, xApps, xApp, and other SAP products and services mentioned herein
as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and
in several other countries all over the world.
IBM, DB2, and INFORMIX are registered trademarks of International Business Machines Corporation.
ICU is Copyright © 1995-2003 International Business Machines Corporation and others.
UNIX is a registered trademark in the US and other countries exclusively licensed by X/Open Company
Ltd.
Sun, Sun Microsystems, the Sun Logo, Solaris, Java, and Catalyst are trademarks or registered
trademarks of Sun Microsystems Inc.
J2SE is Copyright (c) 2003 Sun Microsystems Inc under a licence agreement to be found at:
http://java.sun.com/j2se/1.4.2/docs/relnotes/license.html
MySQL is a registered trademark of MySQL AB in the United States, the European Union and other
countries (www.mysql.com).
ORACLE is a registered trademark and SQL*NET is a trademark of Oracle Corporation.
SYBASE, Net-Library, Open Client, DB-Library and CT-Library are registered trademarks of Sybase
Inc.
Acrobat is a trademark of Adobe Systems, Inc.
Apple, the Apple logo, AppleTalk, and Macintosh are registered trademarks and MacOS, Power
Macintosh and PowerPC are trademarks of Apple Computer, Inc.
HP-UX is a trademark of Hewlett Packard.
OSF/Motif is a trademark of the Open Software Foundation.
CodeWarrior is a trademark of Metrowerks, Inc.
This software is based in part on ChartDirector, copyright Advanced Software Engineering
(www.advsofteng.com).
This software is based in part on the work of the Independent JPEG Group.
This software is based in part of the work of the FreeType Team.
Other products mentioned are trademarks or registered trademarks of their corporations.
Table of Contents
Table of Contents
ABOUT THIS MANUAL.....................................................6
CHAPTER 1—TUTORIAL.................................................7
STARTING OMNIS.....................................................................8
CREATING A LIBRARY .............................................................9
CREATING A DATABASE SESSION ..........................................11
OPENING A DATABASE SESSION ............................................13
VIEWING YOUR TABLES .........................................................14
VIEWING YOUR DATA ............................................................15
MAKING A SCHEMA ...............................................................16
EDITING A SCHEMA ...............................................................17
CREATING A DESKTOP FORM .................................................18
EDITING A DESKTOP FORM ....................................................21
TESTING A DESKTOP FORM AND INSERTING DATA ................25
CREATING A WEB FORM........................................................28
ADDING FIELDS TO A WEB FORM ..........................................30
ADDING CODE AND FURTHER FIELDS TO A FORM ..................32
ADDING A PICTURE AND A BUTTON TO A FORM ....................37
ADDING A REMOTE TASK ......................................................41
TESTING YOUR WEB FORM....................................................42
TESTING YOUR FORM ON A MOBILE DEVICE .........................44
SUMMARY .............................................................................46
TUTORIAL LIBRARIES ............................................................46
WELCOME WINDOW ..............................................................47
CHAPTER 2—JAVASCRIPT REMOTE FORMS.........48
CREATING JAVASCRIPT REMOTE FORMS ...............................48
REMOTE TASKS .....................................................................55
REMOTE FORM PROPERTIES ..................................................63
REMOTE FORM INSTANCES AND METHODS ...........................67
CLIENT COMMANDS ..............................................................70
REMOTE FORM EVENTS.........................................................73
CLIENT METHODS..................................................................76
TESTING JAVASCRIPT REMOTE FORMS ..................................81
REMOTE MENUS ....................................................................85
SUBFORM SETS ......................................................................87
RESIZABLE FORMS AND COMPONENTS ..................................93
RUNNING JAVASCRIPT IN THE CLIENT ...................................95
STYLED TEXT ........................................................................97
3
Table of Contents
ANIMATIONS..........................................................................98
TIME ZONES AND DATES .......................................................99
PDF PRINTING .....................................................................100
CHAPTER 3—JAVASCRIPT COMPONENTS ...........108
JAVASCRIPT COMPONENT PROPERTIES................................110
JAVASCRIPT COMPONENT EVENTS ......................................115
JAVASCRIPT COMPONENT ICONS .........................................116
ACTIVITY CONTROL ............................................................120
BACKGROUND CONTROL .....................................................120
BAR AND PIE CHART CONTROL ...........................................122
BUTTON CONTROL ..............................................................124
CHECKBOX CONTROL ..........................................................125
COMBO BOX ........................................................................126
COMPLEX GRID ...................................................................128
DATA GRID CONTROL .........................................................130
DATE PICKER CONTROL ......................................................135
DEVICE CONTROL................................................................137
DROPLIST CONTROL ............................................................145
EDIT CONTROL ....................................................................146
FILE CONTROL .....................................................................148
HTML OBJECT....................................................................150
HYPERLINK CONTROL .........................................................153
LABEL OBJECT ....................................................................153
LIST CONTROL.....................................................................154
MAP CONTROL ....................................................................158
NAVIGATION BAR CONTROL................................................161
PAGE CONTROL ...................................................................163
PAGED PANE .......................................................................163
PICTURE CONTROL ..............................................................164
PIE CHART CONTROL...........................................................165
POPUP MENU CONTROL.......................................................165
PROGRESS BAR CONTROL ...................................................166
RADIOGROUP CONTROL ......................................................167
RICH TEXT EDITOR CONTROL .............................................169
SLIDER CONTROL ................................................................170
SUBFORM ............................................................................171
SWITCH CONTROL ...............................................................173
TAB CONTROL .....................................................................174
TIMER CONTROL .................................................................176
TRANS BUTTON CONTROL...................................................176
TREE CONTROL ...................................................................177
VIDEO CONTROL .................................................................182
4
Table of Contents
5
About This Manual
6
Starting Omnis
Chapter 1—Tutorial
The first section of this tutorial shows you how to create an Omnis application to browse a
picture database on your desktop computer. The database is a library of sample client
designs for a fictional design company including TV program idents, Album artworks, and
book jackets. You could, however, use the application to store any type of picture data, such
as a library of your digital photos. To use the application for your own data, you need to
work through the tutorial to create the application and then create and logon to your own
database, or you could use the library in the final folder, located inside the welcome/tutorial
folder.
Further sections of the tutorial show you how to view the same picture database in a web
browser and/or a mobile device such as a tablet or smartphone. (Note that some editions of
Omnis Studio may not allow you to develop web or mobile applications, but you will be
able to complete the first part of the tutorial.)
The first part of the tutorial will take about an hour to complete.
7
Chapter 1—Tutorial
Context Menus
Many of the tools in Omnis have context menus that provide options that speed up
development and navigation (to show a context menu click the Right mouse button on the
tool under Windows, or Ctrl-click on the tool under OS X).
Starting Omnis
To create an Omnis Studio application, you use the Development version. Once your
application exists, you normally use it in conjunction with the Runtime or Server version of
Omnis Studio. The Development version has all the browsers and debugging facilities that
you need to help you build an application, but also allows you to test your application in
runtime mode as you build it and without having to compile your app. During this tutorial,
you will be using the Development version.
When you start Omnis Studio, the Integrated Development Environment (IDE) will appear
and the Studio Browser is opened.
If you cannot see the Studio Browser then press the compass icon on the main Omnis Studio
toolbar, or press the F2/Cmnd-2. If any Omnis libraries are currently open, they will appear
under the Libraries node in the Folders tree list in the Browser. If you cannot see the tree
list in the Browser, press the Folders button on the Studio Browser window toolbar.
8
Creating a Library
Creating a Library
The starting point for your Omnis application is an Omnis library. A library stores all the
windows (forms), menus, reports, and other classes in your application. To create a library:
Press F2/Cmnd-2 or click on the Studio Browser to bring it to the top, then click on
the Libraries branch in the Folders tree list and select the New Library option to the
right of the Folders tree list in the Browser.
Starting from the folder where Omnis Studio is installed (under Windows Vista this may be
in your Local folder):
Navigate to the welcome/tutorial folder.
Under Windows XP the welcome\tutorial folder is in the main Omnis product tree in
Program Files, but under Windows Vista the welcome\tutorial folder is located in your
Local folder (note that you may need to enable hidden folders in the Windows File Manager
to access the AppData folder). The path under Windows Vista will be something like:
C:\Users\<your-name>\AppData\Local\TigerLogic\OS5x\welcome\tutorial
In the New Library dialog, type the name pics.lbs, including the extension .LBS, and
click on OK/Save.
9
Chapter 1—Tutorial
When you create or open a library it appears in the Studio Browser. To view the contents of
a library you expand the Libraries branch of the Folders tree list and click on the library
name.
An alternative way to expand a branch in the Folders tree list is to double-click the library.
The classes that belong to the selected library are listed to the right of the Folders tree list in
the Browser list. Using the View menu on the Browser window toolbar you can change the
display to Large Icons, Small Icons or Details.
Note that the list displaying the contents of your library initially contains a Startup Task
that initializes the library when it starts up and a folder containing some System Classes
(inside the folder) that are required to configure a library.
10
Creating a Database Session
The Modify Session window contains all the information needed to connect to your
database. (Not all the fields on the session template are needed for all databases.)
Type PicSess in the Session Name box, select SQLite from the DBMS Vendor list,
select SQLITEDAM from the Data Access Module list; in this case, the DB Version is
not required.
Now you need to connect this session template to the SQLite database supplied in the
welcome\tutorial folder. On the Modify Session window the Host Name box needs to
contain the path to the SQLite database file that you wish to use.
Click the Select Data File button (as shown below) to the far right of the Host Name
box.
11
Chapter 1—Tutorial
The SQLite database file is called 'pics.db' and is located in the welcome\tutorial folder on
your system.
When you have located the pics.db database file on your system, click OK and the path
to this file appears in the Host Name box.
Note that there is also a New Data File button on the Modify Session window that you can
use to create a new empty SQLite database, but for this tutorial you will use the existing
database file, as above.
Now press the OK button to save the session template.
You will see your new PICSESS session template appear in the list of available session
templates.
12
Opening a Database Session
Click the SQL Browser option in the Folders tree list of the Studio Browser to exit the
Session Manager.
You should see your PICSESS session template displayed in the list of sessions.
Select the PICSESS option to open the session.
The PICSESS session appears under the SQL Browser branch of the Folders tree list and
the Tables and Views icons on the right. (Different databases may contain different
database objects.)
13
Chapter 1—Tutorial
Note that if you quit and restart Omnis Studio then you will need to reopen your database
connection/session, as above, to continue this tutorial.
To view the column structure and indexes in the MyPictures table, double-click the
MyPictures table in the Browser list.
14
Viewing your Data
Expand the Interactive SQL window, resize the Pic_Image column (drag the line in
the table header), and scroll down to view the data.
Note the Interactive SQL tool has entered the SQL needed to view the whole of the
MyPictures table (SELECT * FROM MyPictures), but you can use this tool to return
whatever data you like by entering your own SQL statements and clicking on the Run
button. For example, you could add an 'Order By Pic_Category' clause to sort the data on
Pic_Category; in this case the Books would appear at the top.
When you have viewed the data, close the Interactive SQL window.
Now you have used the SQL Browser in the Development version of Omnis Studio to create
the PicSess session and to explore the tables and data in the database, you need to provide a
way for your library to access the data in the database, using that session information.
To allow your library to access the data in the MyPictures table you must first create a
schema class in your library that defines the column structure of the table.
15
Chapter 1—Tutorial
Making a Schema
Make sure that the Libraries branch of the Folders tree list is expanded so that you can see
your library PICS in the tree list.
Then make sure that the SQL Browser branch of the Folders tree list is expanded so that
you can see Tables under your session PicSess in the tree list.
Click on the Tables branch of the Folders tree list to select it. (You will see the table
MyPictures listed in the Browser list.)
Drag the MyPictures table from the list of tables and drop it on the PICS library in the
Folders tree list to create a schema class.
You should see a new schema class called MyPictures appear in the Browser list.
16
Editing a Schema
This schema was created by Omnis to match the definition of the database table when you
dropped the MyPictures table on the PICS library.
Editing a Schema
To edit the schema class:
Double-click the MyPictures schema in the Browser list to open the schema editor.
Alternatively, click the MyPictures schema class and then select the Modify option.
The 'Server table or view' box at the top of the schema editor contains the name of the
database table MyPictures that is related to this schema. Each of the entries in the schema
contains the name and Omnis data type of one of the columns in the table. Note the data
type is the equivalent Omnis data type to that of the column defined in the SQLite database
table.
To ensure that certain kinds of queries execute in the most efficient manner it is
recommended that one column in each table should be designated as the Primary Key. It is
important that the value of the primary key column in each row is unique because it is used
to identify a particular row when it is to be updated or deleted. In other words only one row
in each table should contain a particular value in the primary key column.
Locate the Pic_ID row (it should be row 5) in the schema class and make sure the value
of the Primary Key property is set to kTrue. (As you use Omnis Studio, you will meet
many constants like kTrue, all of which by convention start with the letter "k".)
When you have finished modifying a class in Omnis you can simply close the editor
window to save it, or you can use the Save option from the File menu, or press
Ctrl/Cmnd-S.
17
Chapter 1—Tutorial
Now click the Window... option on the left of the Browser list to display the available
window class wizards.
At the bottom of the Browser window type the class name PicsWindow and press the
Create button.
The radio buttons on the Omnis Class Wizard are to select the style of form to create. Select
the first radio button that reads "One field per column based on schema or query class".
18
Creating a Desktop Form
Note that if different text is displayed next to the first radio button, you have selected the
wrong type of wizard so you should press the Cancel button on the wizard window and
choose the SQL Form Wizard.
Press the Next button to move on to the stage where you will choose the data structure
to be used to create the form.
Note that if at this point you get the message "There are no file classes available for
selection. Please create a file class in your library and try again", you have selected the
wrong type of wizard so you should press the OK button and choose the SQL Form
Wizard.
Click the check box to select the MyPictures schema and press the Next button to
move on to the stage where you will choose the database connection that will be used to
access the data.
Note that if at this point you get the message "There are no SQL sessions available for
selection. Please use the SQL Object Browser to open a session and try again", you need to
cancel the wizards and open a database connection, as described earlier.
19
Chapter 1—Tutorial
Click the checkbox to select the PICSESS database session and press the Next button
to move on to the stage where you will choose a GUI theme for your form.
Select the Plain Blue theme from the list on the left of the Omnis Class Wizard
window.
Press Next to move on to the final stage where the form will actually be created.
Note that at any time prior to pressing the Finish button you can press the Previous button
to go back and review or change a selection.
20
Editing a Desktop Form
Note the Component Store (bottom left) and Property Manager (right) are opened
automatically. The Component Store contains objects that you can add to your forms and
other classes, while the Property Manager lets you view and modify the values of
properties of selected objects. At this stage you do not need to use these tools.
21
Chapter 1—Tutorial
Assuming you have the PicsWindow open in design mode, double-click on the Insert
button.
The Omnis Method Editor will open and the $event method behind the Insert button will be
highlighted.
This method will be executed when you click on the button; in this case the method inserts
the current values in the iSqlRow variable into the database, and it's before this line you
need to make a small addition.
Click on the second line of code 'Do iSqlRow.$insert() Returns lReturnFlag' and press
Ctrl-I/Cmnd-I to insert an empty line above.
With the empty line selected, press "c" or "ca" to locate the Calculate command.
22
Editing a Desktop Form
Click in the Field name box (or tab to it) and enter iSqlRow.Pic_ID
Click in the Calculation box (or tab to it), enter #NULL and then press Return to
complete the line of code.
23
Chapter 1—Tutorial
The Pic_ID column in the SQLite database we are using is an INTEGER data type with a
Primary Key, known as an INTEGER PRIMARY KEY, which will store a unique integer
value automatically. The trick is to insert the value of Pic_ID as NULL and SQLite will
insert the next available numeric value; in effect the value of Pic_ID is incremented by 1
automatically and the new value is inserted. If you delete a data record the value of Pic_ID
in that record is never reused; SQLite will always use a new unique value.
#NULL is a so-called "hash variable", a built-in Omnis constant, and represents a NULL
value. The line of code you added to the Insert button ensures that whatever value is entered
into the field in the open window, just before the row of data is inserted, the value of Pic_ID
is set to NULL.
Your method should now look like the following.
When you have finished editing the method, close the Method Editor.
24
Testing a Desktop Form and Inserting Data
This will create a window instance on the screen. The window is opened on top of the
design window. Note that when you press Ctrl/Cmnd-T to test your form you must first
make sure that the design window for PicsWindow is the top window and not some other
Omnis window such as the Component Store or Property Manager.
Press the Next button on the open window to see the first row of data in the MyPictures
table.
25
Chapter 1—Tutorial
If you are not sure if your form is open, read the text on the window title bar. If it says
"Window PICS.PicsWindow", your form is in design mode and you need to press
Ctrl/Cmnd-T to test it.
If you don't see any data in your form, check that the database session is open (note if you
have closed and reopened Omnis, then resumed the tutorial, you will need to open the
database session again, as described in an earlier section in this tutorial).
Press the Next button again to see the second row in the MyPictures table. You may
like to try out the other buttons on the form.
When you are developing a form you can press Ctrl/Cmnd-T at any time in order to switch
between the design mode and open mode, and back to design mode again.
To insert data (a record), first enter some data into the fields or as follows:
Pic_Category Book
Pic_Name Science in Chaos
Pic_Image [insert '11bookchaos.png' from the tutorial folder using the Paste
from File option, available from the Edit menu (press Alt under
Vista to view the Edit menu). You will need to change the
filetype to PNG]
Pic_Desc Cover art for Bob Zurich’s latest science book
Pic_ID leave this field blank; a new unique value of Pic_ID will be
inserted for you automatically
Pic_URL images\tutorial\11bookchaos.png
(this is not required for the desktop window but you will need this
information when you create a remote form for viewing the data in
your browser).
Click the Insert button to save the record.
26
Testing a Desktop Form and Inserting Data
Important note: Your form must be in open mode to test it and edit/enter data.
Close the pics window and the design window.
27
Chapter 1—Tutorial
Click on the New Class option in the Studio Browser and then the RemoteForm
option.
The new Remote Form will appear in the Studio Browser; name the new class
PicsWebform.
28
Creating a Web Form
The Component Store will open at the bottom of the Omnis window containing 30 or so
ready-made JavaScript based components which you can drag and drop onto your form.
Note you can Right-click/Ctrl-click on the background on the Component Store and select
the Text option to show the text labels for the components, as shown, which may help you
identify the different component types.
29
Chapter 1—Tutorial
Drag the Edit Control from the Component Store and drop it onto your form
somewhere near the top.
An edit field is placed on your form and assigned a default name, but you can change it
using the Property Manager.
Press F6/Cmnd-6 to bring the Property Manager to the top and locate the name
property in the list of properties.
Click in the cell next to the property name and enter Pic_Name.
30
Adding Fields to a Web Form
Next you need to add a dataname to the field to associate the field with a column in your
database.
31
Chapter 1—Tutorial
Double-click somewhere on the background of the form (not on a field) to open the
Omnis Method Editor for the form.
Select all the lines of code in the $construct method and Copy them (press Ctrl/Cmnd-
C).
Making sure the $construct method is selected, click in the right pane and paste the
code you copied; you should now see the following:
32
Adding Code and Further Fields to a Form
The code is added to the $construct method and note that the iSqlRow row variable has also
been added to your class (as well as the local variable lSessionName). The $construct
method will be executed when the remote form is opened (in this case in the client browser),
so you can use it to initialize the form and perform many other functions.
The three lines of code starting ‘Do iSqlRow…’ in the $construct method (highlighted
above) do the following:
1. The first line defines the row variable based on the Schema class in your library
(using the $definefromsqlclass method), which itself links to the table in your
SQLite database.
2. The next line of code creates a session object based on the session template called
PICSESS you created previously in this tutorial (using the $sessionobject
property).
3. The third line of code performs a SELECT on your database which creates a
results set of data (using the $select method).
The other code in the $construct method is for managing errors.
Close the Method Editor
Click on the Pic_Name field in your PicsWebform to select it, then press F6/Cmnd-6 to
open the Property Manager or bring it to the front.
Locate the dataname property in the Property Manager and enter iSqlRow.Pic_Name;
this is a column in the iSqlRow variable that is linked to the Pic_Name column in the
MyPictures table in the database.
33
Chapter 1—Tutorial
You need to create some other fields in the form, but rather than creating them from scratch
you can copy the Pic_Name field and change the properties of each field.
Click on the Pic_Name field and press Ctrl/Cmnd-C to copy the field.
With the new field selected press F6/Cmnd-6 to open the Property Manager and change
the following properties:
dataname = iSqlRow.Pic_Category
name = Pic_Category
Make the Pic_Category field narrower and move it so it's level with the Pic_Name
field.
34
Adding Code and Further Fields to a Form
Select the Pic_Category field, copy and paste it onto the form, and change the
properties of the new field using the Property Manger (F6/Cmnd-6) as follows:
dataname = iSqlRow.Pic_Desc
name = Pic_Desc
issingleline = kFalse (so the field will allow multiple lines of text)
Make the Pic_Desc field a little larger and place it under the Pic_Category field.
Move the Pic_ID field and place it under the Pic_Desc field.
35
Chapter 1—Tutorial
36
Adding a Picture and a Button to a Form
Make the new Picture field deeper by dragging its bottom border.
Make sure the new field is selected, and press F6/Cmnd-6 to open the Property
Manager.
37
Chapter 1—Tutorial
The Pic_URL column contains the location of each picture referenced in the SQLite
database. (Note the actual image files are located in the html\images\tutorial folder in the
main Omnis folder.)
Next you need to create a button in your form to allow the end user to load each data record,
that is, each row in the database.
Locate the Button Control in the Component Store and drag it onto your form.
With the button selected, press F6/Cmnd-6 to open the Property Manager and change
its properties as follows:
name = Next
text = Next
38
Adding a Picture and a Button to a Form
You need to add some code to the button, but you can copy this from the Next button on the
PicsWindow you created previously in this tutorial.
Press F2/Cmnd-2 to bring the Studio Browser to the top.
Double-click the PicsWindow, then double-click on the Next button to open the
Method Editor.
Note that the code for the Next button is placed inside the $event method for the button
(highlighted in red below). The class contains two row variables, iSqlRow, which you've
seen already in the form code, and iOldRow; these variables are needed to load or "fetch"
each successive row of data from the database (result set). When you copy the code from
this method these variables will be copied as well automatically.
Select all the lines of code and copy them using Ctrl/Cmnd-C.
39
Chapter 1—Tutorial
Double-click on the Next button to open the Method Editor for the button.
Note the Method Editor has selected the $event method for the Next button on your form.
This method will contain the code that will be executed when the end user clicks on the
button.
Select the first line of code (On evClick) and paste the code from the clipboard.
Your Method Editor should look the same as the following (note Omnis added the iOldRow
variable):
You can delete the last line of code (Do $cwind.$redraw) since it will have no effect; to
do this, select the line and press Ctrl/Cmnd-X.
40
Adding a Remote Task
Click on New Class, then RemoteTask and name the new class PicsRemoteTask
Press F6/Cmnd-6 to open the Property Manager and add the name PicsRemoteTask to
the designtaskname property of the remote form
Now your library has a remote task you can test your remote form.
41
Chapter 1—Tutorial
Your remote form should open in your default web browser. Omnis Studio creates an
HTML page for you automatically containing the JavaScript client; in this case the page is
called 'PicsWebform.htm' and is placed in the html folder inside the main Omnis Studio
development folder (which is inside your ‘C:\Users\<username>\AppData\Local’ folder
under Windows Vista or later). This page displays your remote form by connecting to your
development version of Omnis Studio and the Pics library you have created; you can view
the source for the test HTML page in your browser to see the embedded JavaScript client
object.
42
Testing your Web Form
In your browser, click on the Next button and each data record should be displayed.
If the data is not displayed this may be because your database session is not open; this may
be because you have closed Omnis and returned to the tutorial at a later time. If you need to
open the database session, click on the SQL Browser, click on the Open Session option,
then click on PicSess. Return to your PicWebform in design mode, press Ctrl-T to open it in
your browser and try clicking the Next button again.
43
Chapter 1—Tutorial
Click on the background of the form and press F6 to open the Property Manager.
The remote form will adjust its size automatically and the window frame will change. The
same fields (and methods) are used for this screen layout (different size and orientation), but
you can resize and reposition the fields if necessary to fit the current screensize; in this case
you don't need to move the fields at all since our form has only a few fields.
44
Testing your Form on a Mobile Device
You can change the value of the height and width properties of the form, and move and
resize your fields as much as you like, and Omnis will store these values for each different
value of screensize. The dotted grey area shown beyond the remote form background
(defined by the height and width values) will not be displayed in the browser, it shows the
visible area available for your form and each screensize and orientation.
Next set the screensize property to kSSZjs320x480Landscape.
The screen will adjust its size again and the window border will change to show a mobile
device; the device image around the remote form is for display purposes only. You may
want to resize and reposition the fields to fit the form area. To remove the scroll bars, you
can set the height of the form to 300 (allowing 20 pixels for the mobile menubar) and the
width to 480.
If you change the screensize property to kSSZjs320x480Portrait you may need to set the
width property to 500 or so to enable the horizontal scrollbar on the form to allow you to
scroll across to move the fields into the visible area of the form. When you have positioned
the fields for Portrait layout you can set the width to 320 and the height to 460 (allowing
20 pixels for the mobile menubar).
To test your remote form on a mobile device or any other computer, assuming those devices
are within the same local network (LAN/WLAN), you can enter the test URL into the web
browser on your device but replace the Localhost IP address (127.0.0.1) with the IP address
of your computer itself, that is, the computer running Omnis Studio and your library. (On a
PC, you can use the ‘ipconfig’ command in the Command prompt to find your IP address,
while on OS X you can use ‘ifconfig’ in a Terminal window.)
45
Chapter 1—Tutorial
First you'll need to open the form in your desktop browser to find out the test URL.
Click on the background of your PicsWebform and press Ctrl/Cmnd-T to test the form
(remember, if the data does not display when you click Next, close the browser, go to
the SQL Browser and open the PicSess session, and reopen the form using
CtrlCmnd-T).
Open the web browser on your mobile device or tablet computer and enter the same
URL displayed in your desktop browser, but replacing the local host IP with the IP
address of your development computer; it will be something like the following (the port
number and IP shown in red will be different, otherwise the URL should have the same
format):
http://194.131.70.184:52357/jschtml/PicsWebform.htm
When you submit the test URL on your mobile device the PicsWebform remote form will
open, but this time Omnis detects that the form is on a mobile device and displays the
correct screen size, layout and orientation. Note it is possible to adjust the fields on your
form for several different screen sizes and orientations (including Landscape and Portrait)
and the correct layout will be chosen automatically depending on the device. If a layout for
the current device is not found then the nearest screen size or layout specified in the form is
used.
Summary
This tutorial does not cover the process of deploying your application to the web, but
hopefully it has given you an insight into how quick and easy it is to create and test remote
forms in a web or mobile app. For more information about deploying your web application,
refer to the Deploying your Web & Mobile Apps chapter.
Tutorial Libraries
There is a library called ‘pics.lbs’ in the final folder, located inside the welcome/tutorial
folder, that contains all the classes created in this tutorial, plus there is some code in the
Startup_Task to open the database session automatically: you might like to open this library
and examine the classes and their methods.
In addition, there is a second library called ‘pics2.lbs’ in the tutorial folder that has some
extra classes including a Query class, Report class, and Menu class that enhance the
Desktop aspects of the application.
46
Welcome Window
Welcome Window
The Welcome window opens when you first start Omnis Studio and contains a set of sample
apps that use the JavaScript Client. The Welcome window can also be opened by clicking
on the New Users button on the main Omnis menu bar.
The sample web apps in the Welcome window cover a range of business and home uses and
include the following:
Memo allows you to create quick post-it like notes using subform sets
Contacts manager for recording information about colleagues or friends
Todo app for handling tasks in the office or home,
Holidays app for managing annual leave requests,
Timesheets app for recording time-based tasks,
Guestbook app for recording feedback from your website visitors,
Webshop app which has a product catalog and shopping cart.
We urge you to examine these apps and in particular try out the JavaScript forms that they
all use and examine the code behind each form: you can try the apps in your desktop
browser or in the web browser on your mobile device.
47
Chapter 2—JavaScript Remote Forms
Chapter 2—JavaScript
Remote Forms
To create web or mobile app in Omnis you need to create a Remote Form class using the
ready-made JavaScript Components available in the Component Store in design mode. At
any stage during the design process you can test a JavaScript remote form using the “Test
Form” option (press Ctrl/Cmnd-T or Right-click on the form) and the Remote form will
open in the web browser on your development computer. The remote form and the
components you have added to the form are embedded into a simple HTML file in the
JavaScript Client object and are rendered in the browser using JavaScript and CSS.
In order to test or open a remote form, your Omnis library also needs to have a Remote Task
class which will handle the remote form instance and any current connections to web or
mobile clients. JavaScript remote forms and remote tasks are discussed in this chapter,
while the individual JavaScript components are described in the next chapter.
48
Creating JavaScript Remote Forms
49
Chapter 2—JavaScript Remote Forms
Click on the Remote Form option to launch the remote form wizard
The SQL JavaScript Form wizard will be selected by default; next you need to name
the new class, such as PicsWebform, and then click on Create
When you create a remote form in your library you also need to create a Remote Task: this
is required at runtime since it handles all the remote form instances running in the client
browser, and without it you will not be able to test or run your remote form.
50
Creating JavaScript Remote Forms
Select ‘Create New Remote Task’, then select ‘Plain Remote Task’ from the list of
remote task templates, enter a name for your new task, such as PicsRemoteTask, and
finally click on Next
For the next stage of the wizard you can select the type of remote form created, based on a
schema class or (query class) in your library.
The Parent / Child option requires two schema classes linked in a parent/child relationship.
Accept the default form type, that is ‘One field per column based on schema or query
class’ and click on Next
51
Chapter 2—JavaScript Remote Forms
For this stage of the wizard you can select the SQL class to be linked to your remote form:
this will either be a Schema class or Query class, the latter is a type of data class that lets
you combine one or more schema classes or individual columns from one or more schemas.
Note that you can expand the tree list to display all the columns in your schema class which
would allow you to select individual columns to be added to your remote form. If you check
the schema name in the list, all the columns in that schema will be selected.
Check the box next to the MyPictures schema class and click on Next
The MyPictures schema class will be in the Pics library if you have followed the appropriate
sections in the tutorial: if a schema class is not displayed you will have to cancel the wizard
and create one.
The next stage of the wizard lets you select an open database session.
Check the box next to the PICSESS session
The PICSESS session will be in the SQL Browser if you have followed the appropriate
sections in the tutorial, or if you are using the pics.lbs in the ‘final’ folder, the session
52
Creating JavaScript Remote Forms
should be opened for you automatically. If a session is not displayed in the wizard you will
have to cancel the wizard and open a session in the Studio Browser.
To complete the wizard click on Finish
When the wizard is completed your remote form will be opened in Omnis in design mode.
The Property Manager will appear on the right side of the Omnis window, and the
Component Store will open at the bottom of your screen.
53
Chapter 2—JavaScript Remote Forms
JavaScript Components
When you edit a remote form (assuming the $client property is set to kClientJavaScript), the
Component Store contains a set of components for the JavaScript Client.
To display the Component Store as above you can Right-click on the background of the
window and select the Text option to show text labels, and then you may need to enlarge
the window to display all the components. You can Right-click on the Component Store and
select the Save Window Setup option to store the layout of the window.
See the JavaScript Components chapter for more information and example code for each
component.
Copying Components
In design mode, you can copy a component on one form and paste it onto either the same
form or a different form using the Copy/Paste menu options or Ctrl-C/Ctrl-V keyboard
options. Alternatively, you can hold down the Ctrl key, then click on and drag a component
to make a copy of the component in the new location. You can also drag a component from
one remote form and drop it onto another form to make a copy of a component, but only if
both the forms are set to the same screen size (i.e. the setting of $screensize is the same for
both forms).
54
Remote Tasks
Remote Tasks
In order to test or run your remote form in a browser, your library should contain a Remote
Task and the $designtaskname property of your remote form should be set to the name of a
remote task in the current library. When you create a new remote form from the Studio
Browser, and if your library contains a single remote task, the $designtaskname property
will be set to the name of that remote task automatically. If your library does not contain a
remote task, you will have to create one manually and set the $designtaskname property of
your remote form to the name of the new remote task. If your library has multiple remote
tasks, and you create a new remote form from the Studio Browser, the $designtaskname
property will not be set, so again you will have to assign this manually before you can set
the form.
Select the wizard you want, name the new class and click on Create
55
Chapter 2—JavaScript Remote Forms
$enablesenddata Property
The remote task property $enablesenddata should be set to kFalse for all tasks controlling
JavaScript remote forms since the $senddata() method is not implemented for JavaScript
remote forms.
56
Remote Tasks
is connecting (and specified in the $designtaskname property of the remote form). Once the
remote task class has been instantiated, next the Remote form instance is created. The
$construct method of first the Remote task and then the Remote form are run, so these
methods can include any code you want to run prior to opening the form (in the task
construct method) or when the form is opened.
Column Description
OmnisLibrary <OmnisLibrayName>
OmnisClass <RemoteFormName>
param1, 2, .. 9 Up to 9 pre-defined custom parameters called param1, param2, etc,
which you can add to the JavaScript Client object in your HTML
page; you can add custom parameters prefixed with “data-“ to send
further values to the task or form construct method
OmnisPlatform JSU, the JavaScript Client
JSscreenWidth The screen width of the client, e.g. 1280 for desktop PC
JSscreenHeight The screen height of the client, e.g. 1024 for desktop PC
JSscreenSize The initial setting of $screensize for the client, e.g. kSSZDesktop
userAgent The navigator.userAgent of the client, which usually contains the
browser type and version
appName The navigator.appName of the client, i.e. the browser application
name, such as “Microsoft Internet Explorer” or “Netscape”
Flags Currently indicates if the client supports animation: 1 means the
browser does support animation, zero means that it does not
JStimezoneOffset offset from UTC in seconds, e.g. “120” for clients on UTC+2
ClientLocale the Locale language setting of the client, e.g. “en_GB” for clients
in the UK, or “en_US” for America
The appName and userAgent columns return properties of the client browser and therefore
allow you to determine which browser and version the client is using, such as whether it is a
desktop or mobile browser.
57
Chapter 2—JavaScript Remote Forms
58
Remote Tasks
Changing Forms
The remote task instance has a method, $changeform(), which enables you to replace the
form currently in use on the client, with another form in the same library. $changeform() has
a single argument, which is the new remote form name. When it executes, the current form
instance destructs, and the client constructs an instance of the new form to display in the
user’s browser. You can use task variables in the remote task instance to pass information
between the destructed remote form instance, and the new remote form instance.
There are some restrictions to note:
$changeform() cannot be used in the $construct() or $destruct() method of a remote
form instance or remote task instance. If used, Omnis generates a runtime error.
Multiple calls to $openform() (described later) or $changeform() during the processing
of a single event will result in only the last call to $openform() or $changeform()
having any affect.
One scenario for using $changeform() is where the end user is required to log onto your
web application, whereby the initial “logon” form prompts the user for a name and
password, and the application changes to another form when the user has successfully
submitted a valid name and password.
Multiple Forms
You can open more than one form within a single client connection, that is, within a single
remote task instance. At any one time, only one of these multiple instances is visible, and
the forms must be from the same library.
There are two methods of a remote task instance which you can use to manage multiple
forms: $openform() and $closeform(). Like $changeform(), both these methods take a single
argument, the remote form name.
If the form passed to $openform() already has a remote form instance open in the context of
the remote task instance, it becomes the visible form for the remote task. Otherwise, Omnis
constructs a new instance of the remote form in the remote task, and makes the new remote
form instance the visible form.
The $closeform() method closes (destructs) the remote form instance for the named form,
without closing the task instance or any other forms that may be open within the task. It is
possible to close the last remaining remote form instance, but this is not recommended,
since the end user will be presented with a blank screen. If the referenced form is not
visible, the client observes no affect; otherwise, the most recently visible open remote form
instance becomes visible.
59
Chapter 2—JavaScript Remote Forms
60
Remote Tasks
$reqmaxbytessent
The largest block in bytes sent to the client for all requests. Updates prior to evIdle
message.
$reqcurbytesreceived
The number of bytes received from the client for the current request. Updated prior to
evBusy message for the current request.
$reqcurbytessent
The number of bytes sent to the client for the current request. Updated prior to evIdle
message.
Timeouts
You can control how long someone is connected to the Omnis App Server and how long a
single client connection can remain idle, using the following properties.
$maxtime
the maximum time in minutes that a client is allowed to stay connected; the default
value is 0 which means the client can stay connected indefinitely.
$timeout
the maximum time in minutes that a client is allowed to stay idle; the default value is 0
which means the client is allowed to stay idle indefinitely.
Client Connections
Remote tasks have some properties that tell you about the current client connection.
$clientaddress
the TCP/IP address of the current client. Note that this may not be the exact TCP/IP
address of the client machine, due to the possible presence of proxy servers and
firewalls between the client machine and the web server.
$connectionid
the id of the current client connection; ids are allocated dynamically by the Omnis
Server and numbers are not reused unless the server is restarted.
$connectiontime
the time and date the client connected to the Omnis Server, i.e. the time the current task
instance was instantiated.
$lastresponse
the time and date the client last accessed the remote task instance on the Omnis Server.
Secure Sockets
You can use secure sockets (HTTPS) if you have installed an SSL certificate on your web
server. The JavaScript Client will use a secure connection to connect the client to the web
server if you prefix the URL or IP_address in the data-webserverurl parameter with
61
Chapter 2—JavaScript Remote Forms
“https://”. In addition, remote tasks have the $issecure property that lets you turn secure
mode on and off dynamically, by assigning to the property for the current task at runtime.
62
Remote Form Properties
There are a number of default screen sizes available in the $screensize property, which
include the following (note other sizes can be added: see below):
kSSZDesktop
for remote forms running in a web browser on a laptop or desktop based PC or Mac
computer; in effect the screen size is unspecified and the $height and $width of the
form in design mode is used to size the form in the browser
kSSZjs320x480Portrait or kSSZjs320x480Landscape
For mobile devices with screens 320 x 480 px (at 96dpi) in Portrait/ Landscape
orientation
63
Chapter 2—JavaScript Remote Forms
kSSZjs768x1024Portrait or kSSZjs768x1024Landscape
For mobile devices with screens 768 x 1024 px (at 96dpi) in Portrait/ Landscape
orientation
Designing forms for different devices
When you create the remote form, you can place the objects on the form, for example, on
the desktop layout. Then when you are ready to design the layout for other devices you can
change the setting of $screensize, and reposition the same objects for each screen size and
orientation. In other words, each screen size/layout uses the same set of objects (and
methods) and the single remote form class stores the position of the fields for each screen
size/orientation setting.
Typically you would design the layout of a single remote form for a number of different
devices or screen sizes, and then use the floating edge, scaling and centering properties to
position and size the form on devices which have sizes relatively close to those that are
stored in the form.
When opening (constructing) a remote form, the JavaScript Client uses the most appropriate
screen size and orientation stored with the form, for the screen size and orientation of the
current device. If the user swaps from portrait to landscape, or back again, the JavaScript
Client repositions the controls automatically, using the coordinates the new orientation
stored in the remote form (assuming you have added a layout for each orientation). If for
example, the user switches to landscape orientation, and you haven’t added a layout for this
orientation to the form, the portrait layout is used by default.
64
Remote Form Properties
a 5" HD display which is 1080 x 1920 physical pixels at 441 ppi resolution, equating to
CSS pixel dimensions of 360x640.
Thers is a new library preference, $designedscreensizes, which is a comma-separated list of
screen size constants for JavaScript Client based remote forms in the library (note this is a
library wide preference, not a remote form property). To enab le the new screen sizes, you
need to check the kSSZjs345x345 and kSSZjs360x640Portrait options under the Prefs tab
in the Property Manager for the current library: note that by enabling the ‘Portrait’ option
you enable the equivalent landscape layout for the given size. The screen sizes enabled in
the new library preference will be used to populate the $screensize property in the Property
Manager and will be available for all remote forms in the library.
If you change $designedscreensizes, the size and position information for sizes or layouts
no longer in the list of designed sizes will not be lost: the designed layouts will remain
stored with the remote form in the library.
Implementing new screen sizes
The omnisobject containing the JavaScript client in the HTML page has a new attribute,
‘data-dss’, which contains the designed screen sizes for the library. If you use forms from
more than one library in a single client instance, each library must have the same set of
$designedscreensizes. If not, a runtime error will occur when trying to use a form from
another library.
If you change the screen sizes supported in the $designedscreensizes library preference, all
the HTML files for all remote forms in your library need to be rebuilt to reflect the new set
of screen sizes: this is done automatically when you test a remote form since the HTML file
is rebuilt every time you test a remote form.
Note there is a new jsctempl.htm template file to accommodate the new screen sizes and
ongoing support for any new sizes.
Requesting new screen sizes
Developers can now request a new screen size or form factor for inclusion in Omnis Studio,
although we will reserve the right to decide whether or not any suggested screen size is
appropriate for Omnis. Between major releases, we will make new sizes available by
supplying new screen size configuration files on request. An updated ‘ssz.cfg’ file will be
provided and can be placed in the ‘studio’ folder in the Omnis tree, and a new ‘ssz.js’ file
which should be placed in the ‘scripts’ folder. Then for the next major release the new or
updated screen sizes will become available for all developers with an updated set of files.
65
Chapter 2—JavaScript Remote Forms
form. If you specify a negative value, and a subform is created from the remote form class,
the field specified in $startfield becomes the current enterable field on the form.
The relative values of the $order property for each field or control in your remote form
determines the tabbing order of the controls in the form. For inherited forms, the
$inheritedorder property determines the tabbing order for the first inherited field: zero
means maintain the designed order from the base class through to this class.
Gradients
To create a gradient for the background of a JavaScript remote form, you can select a
gradient fill pattern for $backpattern and control the start and end colors for the gradient by
setting $forecolor and $backcolor.
66
Remote Form Instances and Methods
67
Chapter 2—JavaScript Remote Forms
initiated (depends on the OS); if bSelect=kTrue, and if supported by the control, all of
its content will be selected; executing $setcurfield(‘’) will remove the focus from the
current field; you can specify the field by name, ident, or item reference
$showmessage()
$showmessage(cMessage[,cTitle]) displays an OK message on the client machine using
the specified cMessage and cTitle
$showurl()
$showurl(cURL[,cFrame,cWindowProperties]) opens the URL in a new window or
frame on the client machine; cURL specifies the URL of the HTML page; cFrame
specifies the HTML frame name; if cFrame is empty, the page is displayed in a new
window, otherwise it is displayed in the specified frame of the current window.
The final optional parameter for the $showurl() method, cWindowProperties, is ignored if
cFrame is not empty. Otherwise, it has the same format as the JavaScript argument to
‘window.open’, for example, "toolbar=0,menubar=1" specifies that the browser window
will have a menubar, but not a toolbar. The keywords are all boolean (0 or 1) except for the
width, height, top and left, which are numbers in pixel units. Possible keywords are:
Keyword Description
toolbar specifies if the browser window has a toolbar
status specifies if the browser window has a status bar
menubar specifies if the browser window has a menu bar
scrollbars specifies if the browser window has scrollbars
resizable specifies if the browser window is resizable
location specifies whether the browser window has a location bar
directories specifies whether the browser window displays Web directories
width width of browser window
height height of browser window
top top coordinate of browser window
left left coordinate of browser window
68
Remote Form Instances and Methods
Client Messages
The $showmessage() method allows you to display a message on the client machine. This
method only applies to remote tasks that are associated with remote forms, that is, the
method does not work for remote tasks that handle HTML forms or “ultra-thin” clients.
Only one message can be shown in response to a single event. Executing $showmessage()
more than once in response to the same event will result in a single Ok message with the
text and title of the last call to $showmessage being shown. Alternatively, you can use the
OK message command provided it is executed on the client; in this case the command uses
a standard browser alert() or confirm() dialog.
69
Chapter 2—JavaScript Remote Forms
Client Commands
The $clientcommand() remote form method allows you to execute various commands on the
client device, including ones that open various type of message boxes; the suitability of
certain commands will depend on the current client device (e.g. some of the commands may
not be available for certain mobile devices), so these commands should be thoroughly
tested, as appropriate, for all devices you wish to support. The $clientcommand() method
may be very useful since the JavaScript does not support client-side scripting,
i.e. component methods cannot be executed on the client (as in the Omnis Web Client plug-
in).
The $clientcommand() method must be executed on the Omnis Server in a remote form
instance, and requires various parameters dependent on the command sent to the client. It
has the following general syntax:
Do $cinst.$clientcommand(cCommand,wRow)
where $cinst is the current remote form instance, cCommand is the name of the command to
be executed on the client, and the wRow is a row variable containing any number of
parameters to be passed to the client.
The client commands that open a message box allow you to enter the message text in the
first parameter. You can create a line break in the message text using //.
70
Client Commands
Yes/No Messages
The “yesnomessage” command opens a Yes/No message box in which Yes is the default
button.
Do $cinst.$clientcommand("yesnomessage",row-variable)
Where row-variable is row(message text, title text, name of public form server method
called on yes, name of public form server method called on no, name of public form server
method called on cancel (leave empty for no cancel button)).
For example, in the Webshop sample app a Yes/No message is generated using the
$clientcommand method when a user clicks on a product size/type that is not available:
Do $cinst.$clientcommand('yesnomessage',row(con('Would you like
to order >',iProductList.product_size_1,'< instead?'),'Not
available','$orderYes'))
No/Yes Messages
The “noyesmessage” command opens a No/Yes message box in which No is the default
button.
Do $cinst.$clientcommand("noyesmessage",row-variable)
Where row-variable is row(message text, title text, name of public form server method
called on yes, name of public form server method called on no, name of public form server
method called on cancel (leave empty for no cancel button)).
Ok/Cancel Messages
The “okcancelmessage” command opens an OK/Cancel message box in which OK is the
default button.
Do $cinst.$clientcommand("okcancelmessage",row-variable)
Where row-variable is row(message text, title text, name of public form server method
called on ok, name of public form server method called on cancel (leave empty for no
cancel button)).
71
Chapter 2—JavaScript Remote Forms
Playing Sounds
The system bell
The “soundbell” command plays the default system sound on the client.
Do $cinst.$clientcommand("soundbell",row-variable)
In this case, row() is empty.
Play a sound file
The “playsound” command plays a sound on the client.
Do $cinst.$clientcommand("playsound",row-variable)
Where row-variable is row(name of sound file from html sounds folder).
Date Format
The “setcustomformat” command allows you to set the date format used on the client when
$customformat is empty (defaults to D m y).
Do $cinst.$clientcommand("setcustomformat",row-variable)
Where row-variable is row(date format). See the Date and Time Formatting section for
more details about setting the data format on the client.
Client Preferences
The following commands allow you to save and load end-user data on the client, such as
user preferences. You could use these commands to store and load usernames and/or
passwords to allow the end user to log onto your application.
Saving preferences
The “savepreference” command saves a value (as a character string) as a named preference
on the client.
Do $cinst.$clientcommand("savepreference",row-variable)
Where row-variable is row(preference name, preference value).
Loading preferences
The “loadpreference” command loads a named preference value from the client preferences
into an instance variable.
Do $cinst.$clientcommand("loadpreference",row-variable)
Where row-variable is row(preference name, instance variable name (e.g. a quoted string
containing the name of the variable)). The preference name is initially empty.
72
Remote Form Events
Subform Sets
There are a number of client commands that allow you to create and manage subform sets:
see the Subform Sets section for more information.
PDF Printing
The “showpdf” and “assignpdf” client commands allow you to print and display PDF files
in the client browser: see the PDF Printing section for more information.
73
Chapter 2—JavaScript Remote Forms
evSubFormToTop
An existing remote form, contained in a subform that has $multipleclasses set to kTrue,
is about to become visible on the client, with the parameter pEventCode
evOpenContextMenu and evExecuteContextMenu
JavaScript remote forms report the context menu events: see the Context Menus section
The evFormToTop and evSubFormToTop events are discussed in the Multiple Forms
section, while evAnimationsComplete is discussed in the Animations section.
Event Parameters
When an event is triggered, a number of event parameters are sent from the client to the
event handling method. The first of these parameters is always the name of the event that
occurred, and all subsequent parameters are specific to the event and describe the event in
more detail. For example, a click on a list passes the click event in the first parameter
(pEventCode=evClick) and the list line clicked in the second parameter (pLineNumber).
Form Orientation
When the orientation of a remote form changes (e.g. when the end user rotates their mobile
device), Omnis sends an evScreenOrientationChanged event to the top remote form. This
allows the remote form to adjust the coordinates of any dynamically added objects. In
addition, evFormToTop also receives the pScreenSize event parameter, allowing other
forms to make adjustments if necessary when they come to the top.
74
Remote Form Events
Event Methods
You can trap and respond to events generated in a remote form in the $event() method in
the form. You have to add a method called $event to the Class methods for the form to
create an event handler. Like other event methods you can use the On event command to
trap specific remote form events. The following $event method responds to the
evScreenOrientationChanged event and sets the iScreensize variable to the correct screen
size.
On evScreenOrientationChanged
Switch pScreenSize
Case 3
Calculate iScreensize as kSSZjs320x480Portrait
Case 4
Calculate iScreensize as kSSZjs320x480Landscape
Case 9
Calculate iScreensize as kSSZjs768x1024Portrait
Case 10
Calculate iScreensize as kSSZjs768x1024Landscape
Default
Calculate iScreensize as kSSZDesktop
End Switch
Do method setupSizes
75
Chapter 2—JavaScript Remote Forms
Client Methods
You can run certain methods on the client, such as event handling methods, instead of
running them on the Omnis App Server. When such Client Methods are called in your
application, runtime execution does not pass back to the Omnis App Server, rather the
method is executed entirely in the end-user’s browser within the JavaScript Client. Enabling
certain methods to execute on the client can speed up your application by cutting down on
network traffic, while from a design point of view, this capability may allow you to add
more interactivity into the user interface of your web or mobile app.
Any methods in your JavaScript remote forms that are enabled to execute on the client are
converted to JavaScript files. These JavaScript files are run in the browser when the method
is called on the client. When a client browser opens a JavaScript remote form, the Omnis
App Server generates a JavaScript file containing the client methods for the remote form
(the generation of this file only occurs once unless the remote form class is modified, in
which case it will regenerate the file). This file is added to the html/formscripts folder in the
Omnis tree inside a subfolder named after the library. Each remote form containing client
methods has a separate JavaScript script file.
When you deploy and run your web or mobile app on the Omnis App Server, these
JavaScript script files are generated at the same location as in the development version, the
first time the client calls the client-side method. For the deployed app, the JavaScript files
are in minified form, and therefore are smaller and will run faster since all the comments are
stripped out.
$init method
You can create a client-side method with the name $init in your remote form which the
client calls after the form and the client scripts file have been loaded. This allows you to do
any final initialisation of the remote form, especially when the remote form is running in
serverless client mode.
76
Client Methods
stage), but the number of commands and functions available to use will be limited to those
shown in the Method Editor. The type of Local and Parameter variables you can create will
also be restricted: see Data Types below.
The Omnis Help (F1) indicates whether or not a command or function can be executed on
the JavaScript client: please note that some commands or functions could be executed in the
Web Client plug-in but may not now be executable in the JavaScript client which only allow
a smaller subset of commands and functions to be run on the client.
Binary functions
The Binary functions cannot be used in JavaScript client methods since JavaScript does not
support binary data particularly well.
Text blocks
You can use the text block commands (Begin text block, Text:, End text block, Get text
block) in JavaScript client methods to build up a block of text, e.g. to generate styled text
(see the Styled Text section).
The Omnis flag
You can use the flag() function in your code to return the status of #F, the Omnis flag,
which can be true or false, depending on the result of executing a method or Omnis
command.
Object properties in client methods
While some properties can only be assigned in Server methods, you can read the current
value of many more remote form properties and component properties in Client executed
methods. So for example, you cannot change the size and position of an object in a client
method (by setting $top, $left, $width, and $height), but you can return the current values
for an object in a client method, e.g. $cobj.$width returns the width of the object.
77
Chapter 2—JavaScript Remote Forms
custom method called $mymethod from within in a client method in the current remote form
instance, you must use Do method $cinst.$mymethod(), or you can use Do
$cinst.$mymethod().
Further restrictions
Field reference parameters are not supported, since JavaScript methods use call by
value.
Date Time local variables and parameters do not have a subtype in client methods.
Date Time, List and Row variables are represented by a JavaScript object on the client,
whereas the other data types are the native JavaScript types (number, string and
Boolean).
When you change a method from client to server execution, or back again, the data type of
Local variables and Parameters changes to the most logical supported value for client or
server execution (restoring the original type when changing from client to server execution
if the type on the client is Var).
78
Client Methods
The client-side method can only call one server method like this – if it makes a second call,
the client throws an exception.
If the client code needs to handle the return value from the server method, then you must
implement a client-side method in the remote form with the name <method name>_return,
for example, to receive the return value from a server method called $test, implement a
client-side method $test_return. The _return method must have a single parameter, which is
the return value from the server method. A typical action of the _return method might be to
update a progress control, and then issue another call to the server. This allows a time-
consuming operation to execute while showing its progress.
Field Validation
A web or mobile form may include several mandatory fields. You can use a client-side
method behind the Submit button (called Add in the example app) to check that the fields
contain some data – this is the code for the email field:
; $event method behind Submit button – it is enabled to execute on
the client
On evClick
If pos('@',iEmail)=0
Do $cinst.$objs.EmailLabel.$textcolor.$assign(kRed)
Calculate lCurField as 'Email'
Else
Do $cinst.$objs.EmailLabel.$textcolor.$assign(kBlack)
End If
; check other fields…
The code checks whether or not the Email field contains an ‘@’ and if not the field label is
colored red and the cursor is placed in the Email field – if the Email field contains data the
method moves onto the next field. All the other fields on the form are checked for any
content and handled in a similar way: the password field is checked for a minimum number
of characters, as follows:
If len(iPassword)<6
Do $cinst.$objs.PasswordLabel.$textcolor.$assign(kRed)
Calculate lCurField as 'Password'
Else
Do $cinst.$objs.PasswordLabel.$textcolor.$assign(kBlack)
End If
79
Chapter 2—JavaScript Remote Forms
80
Testing JavaScript Remote forms
The Do inherited command is evaluated at the point at which the script file is generated by
the server. This means you can only use Do inherited from within the actual method you
have overridden. This differs from the other clients, in that they allow you do call Do
inherited from a private method called from an inherited public method, and then the call to
Do inherited calls the overridden public method.
81
Chapter 2—JavaScript Remote Forms
The URL for the test HTML page will be something like the following:
http://127.0.0.1:51452/jschtml/<remoteformname>.htm
The test URL contains the IP address of your Localhost (127.0.0.1), the port number of
your copy of Omnis Studio, a reference to the test JavaScript Client HTML folder, and the
name of the HTML file. The port number during testing will be the port number specified in
the $serverport Omnis preference, or if this is empty (the default) a port number is selected
randomly from the available ports on your computer.
If you try to open or navigate to the test URL from your browser history it may not work: in
this case such a URL may not have the correct port setting since the port number is assigned
dynamically during testing if the $serverport property is empty and therefore may be
different from one session to another. In addition, you cannot open or test your remote form
by opening the test HTML in the template folder: again your browser will not have the
correct URL to load the test HTML file.
Omnis Studio and your library must be open and running to test your remote form. So if
you open the test HTML file from your file system, and Omnis and your library are not
open, then your remote form will not be displayed and your web or mobile app will not run.
82
Testing JavaScript Remote forms
Trace Log
The tracelog() function allows you send debugging and other messages to the Omnis trace
log from within client methods executed in the JavaScript Client: this will allow you to
debug client methods. The tracelog(string) function writes the string to the Omnis trace log,
or does nothing if debugging is disabled using the library property $nodebug. It returns true
if the string was successfully written to the trace log.
Alternatively, in JavaScript client-executed methods you can use the Send to trace log
command which sends the text to the JavaScript console.
Error reporting
When an error is encountered in your code in the JavaScript client Omnis populates the
#ERRCODE and #ERRTEXT global variables with the appropriate error code and message
text. You can read the value of these variables in client executed methods using the
following functions:
errcode()
returns #ERRCODE, a numeric variable containing the error number generated by a
method
errtext()
returns #ERRTEXT, a string variable containing the error text generated by a method
83
Chapter 2—JavaScript Remote Forms
http://194.131.70.184:51452/jschtml/jsMain.htm
You can use the ipconfig command to find the IP address of your development computer,
via the Command prompt on a PC or the Terminal on a Mac.
You can test a mobile remote form in a wrapper application using the Test Form Mobile
(Ctrl-M) option, assuming a wrapper application is setup and enabled: if a wrapper is not
setup you can test your mobile forms in a web browser during development, as above. See
the Deployment section for details about setting up a wrapper application.
Remote Forms
When I open my blank remote form in design mode I don’t see any JavaScript
components in the Component Store.
You need to set the $client property of the remote form to kClientJavaScript to use the new
84
Remote Menus
JavaScript components. When you use the New Class>>Remote Form option in the Studio
Browser, the client property should be set to kClientJavaScript for you automatically. (Note
you cannot switch an existing Web Client based remote form to the JavaScript Client, but
there is a migration tool available in the Studio Browser to help you move to the new
client.)
Events
I have placed an event method behind my button (or any other event-driven object)
but nothing happens when I click it while testing the form in a browser.
You must specify which events are to be triggered by the object or remote form in the
$events property of the object or form. So for a button, the evClick event must be checked
in the $events property of the button. Events for some objects are checked by default but
you may like to examine the state of each event in the $events property and make sure the
events you need are enabled.
Remote Menus
The Remote Menu class allows you to add various types of menu to remote forms and
individual controls. A remote menu can be opened as a Popup Menu control, added to a Tab
Control, or as a Context menu for the form itself or individual control (popup menus and tab
menus are described in the Components chapter).
85
Chapter 2—JavaScript Remote Forms
Context Menus
A context menu is a menu that can be opened by the end user by right-clicking on the
background of a form, or within the border of a form control. You can implement context
menus for remote forms or individual form controls by setting the $contextmenu property of
the form or control to the name of a Remote menu class. Each line in a remote menu has the
$commandid property, so when the user selects a line in the menu this ID can be used to
trigger a specific action in your code. When a line in a remote menu is selected, an
evExecuteContextMenu event is reported to the form or field with event parameters
containing the Command ID of the selected line, and for fields, a reference to the field
which was clicked on.
Remote forms and controls have the $disabledefaultcontextmenu property to disable default
menus from opening when the end user right-clicks the form or object: the default menu for
the edit control could be the clipboard menu. If true, the default context menu for the object
will not be generated in response to a context click ($clib.$disabledefaultcontextmenu and
$cobj.$disabledefaultcontextmenu must both be false for the default menu to be generated).
86
Subform Sets
Subform Sets
You can open a special kind of subform or group of subforms that behave rather like
separate windows in the JavaScript Client. The subforms in a subform set are different to
standard subforms (which are embedded in a Subform control, and described in the
Components chapter) in that they have a title bar and resizable borders, and the end user can
move or resize them within the “main” remote form running on the client. Such dynamic
subforms within a subform set will allow you to create highly flexible user interfaces in your
apps, by allowing a high degree of interactivity for the end user.
The new subforms or group of subforms are opened as part of a new client object called a
Subform Set (SFS), which is created at runtime in the JavaScript Client and allows you to
manage the group of subforms. The new subforms are opened in the client at runtime within
the main JavaScript remote form, or they can be opened within the context of a single page
in a paged pane. Each separate subform in the Subform Set is a standard Remote form class
that you have previously created in your library, which is referenced and added to the
Subform Set.
87
Chapter 2—JavaScript Remote Forms
88
Subform Sets
Column 2: classname: The name of the Omnis remote form class for the subform.
Column 3: params: Literal parameters to be passed to the $construct of the subform e.g.
‘Test’,200.
Column 4: title: The title of the subform - text displayed in the title bar of the subform.
Column 5: left: The left coordinate of the subform (for Desktop browsers, or portrait if
a mobile device). The constant kSFScenter centers the form horizontally in its parent.
Column 6: top: The top coordinate of the subform (for Desktop browsers, or portrait if
a mobile device). The constant kSFScenter centers the form vertically in its parent.
Column 7: width: The width of the subform. If the forms in the set are resizable, then
the form cannot be made narrower than the minimum of this width and the width
designed for the remote form class.
Column 8: height: The height of the subform. If the forms in the set are resizable, then
the form cannot be made taller than the minimum of this height and the height designed
for the remote form class.
If the subforms are to be displayed on a mobile device, Columns 9-12 are landscape
left, top, width and height respectively. If these are omitted, the landscape values
default to the portrait values.
subformset_remove
The subformset_remove command removes a set of subforms. All subforms in the set will
be destructed and removed from their parent.
Do $cinst.$clientcommand("subformset_remove",row-variable)
subformset_formadd
The subformset_formadd command add a form to an existing subform set.
Do $cinst.$clientcommand("subformset_formadd",row-variable)
Where row-variable is row(setname, uniqueID, classname, params, title, left, top, width,
height, modal)
The row variable parameter are as follows:
setname: a string which is the name of the set to which the subform is to be added.
uniqueID: an integer which must uniquely identify this subform in the set.
classname: the name of the Omnis remote form class for the subform.
params: literal parameters to be passed to the $construct of the subform e.g. ‘Test’,200.
title: the title of the subform - text displayed in the title bar of the subform.
89
Chapter 2—JavaScript Remote Forms
left: the left coordinate of the subform (for Desktop browsers, or portrait if a mobile
device). The constant kSFScenter centers the form horizontally in its parent.
top: the top coordinate of the subform (for Desktop browsers, or portrait if a mobile
device). The constant kSFScenter centers the form vertically in its parent.
width: the width of the subform. If the forms in the set are resizable, then the form cannot
be made narrower than the minimum of this width and the width designed for the remote
form class.
height: the height of the subform. If the forms in the set are resizable, then the form cannot
be made taller than the minimum of this height and the height designed for the remote form
class.
modal: zero if the subform is non-modal, or 1 if the subform is fully modal, and prevents
the use of any other form or subform in the remote task’s user interface.
If the subforms are to be displayed on a mobile device, the next four columns are landscape
left, top, width and height respectively. If these are omitted, the landscape values default to
the portrait values.
The parameters above, starting with uniqueID, are identical to those in the formlist (for the
subformset_add command), except the modal indicator is present between the two sets of
coordinates.
subformset_formremove
The subformset_formremove command removes a subform from an existing set and
destructs it (removing it from its parent).
Do $cinst.$clientcommand("subformset_formremove",row-variable)
subformset_formtofront
The subformset_formtofront command brings a subform in a set to the top of the stacking
order, and gives it the focus. You must use this command to display a subform that has
previously been minimized.
Do $cinst.$clientcommand("subformset_formtofront",row-variable)
90
Subform Sets
uniqueID: an integer which identifies the subform in the set to be brought to the front.
91
Chapter 2—JavaScript Remote Forms
Example
The following code creates a subform set containing two subforms.
; setupSubformSet method which could be called from £construct
; Create vars: iFormList (List), iID, iClassName, iParams, iTitle,
iLeft, iTop, iWidth, iHeight
; jsSub1 and jsSub2 are remote forms in the library
Do iFormList.$define(
iID,iClassName,iParams,iTitle,iLeft,iTop,iWidth,iHeight)
Do iFormList.$add(1,"jsSub1",,"subform1",10,10,200,200)
Do iFormList.$add(2,"jsSub2",,"subform2",220,10,400,200)
Do lRow.$define(lSetName,lParent,lFlags,lOrderVar,iFormList)
Do lRow.$assigncols(
"SubformSet",,kSFSflagCloseButton+kSFSflagMaxButton+
kSFSflagMinButton+kSFSflagResize,,iFormList)
Do $cinst.$clientcommand("subformset_add",lRow)
The code creates the subforms in the main remote form within the browser:
The Memo sample app available in the Welcome screen uses subform sets.
Subform Styles
The Omnis style sheet Omnis.css contains CSS classes that specify the appearance of the
subform frame of the members of subform sets, as well as the images for the maximize and
minimize buttons. You can modify these classes to give the subform frames your own style.
Open Omnis.css and search for “subform” to locate the styles.
Subform Titles
You can use $cinst.$title to change the title text for a member of a subform set.
92
Resizable Forms and Components
Subform References
You can obtain a reference to any subform instance within a subform set using the
$sfsmember root notation. For example:
$root.$sfsmember(cSetname,iUniqueID)
returns an item reference to the remote form instance for the subform set member with the
specified unique ID in the named subform set in the current remote task. This notation can
be used in server and client methods.
93
Chapter 2—JavaScript Remote Forms
fit the browser window; it will not resize to a size smaller than the designed size in the
remote form class
kJSformResizeModeFull
The form resizes itself to fit the browser window, regardless of aspect ratio; it will not
resize to a size smaller than the designed size in the remote form class
You can assign $width and $height of the remote form at runtime, however this may conflict
with $resizemode, so you should only assign these properties when $resizemode is
kJSformResizeModeNone.
Component Resizing
The “floating edge” ($edgefloat) capabilities for JavaScript components allow you to resize
them at runtime, so when a remote form is resized in the end user’s browser its components
will resize automatically, if their $edgefloat property has been set as appropriate. Note that
like the form resizing, this behavior only applies when the remote form is being displayed in
a standard browser window on a desktop computer or laptop, not a browser on a mobile
device.
In previous versions, the $edgefloat property only applied to resizing components in design
mode, but the setting of $edgefloat for each component is applied at runtime when the form
is resized on the client. 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 form
is resized. See the Omnis Help (F1) for a list of all possible settings of $edgefloat.
You can store a different setting of the $edgefloat property for each component, for each
different screen size ($screensize), which means you can set different $edgefloat properties
for web and mobile browsers. When setting $edgefloat in the Property Manager in design
mode, you can set the value of $edgefloat for all $screensize values 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 $resizemode property of the form causes the form to resize
When the component is in a resizable subform in a subform set and the subform is
resized
94
Running JavaScript in the Client
95
Chapter 2—JavaScript Remote Forms
command. To extend the alert() example above, you could embed a JavaScript function in
your HTML page, like this:
<html>
<head>
<script type="text/javascript">
function show_alert()
{
alert("Hello World");
}
</script>
</head>
<body>
<!-- body including the omnisobject containing your form -->
</body>
</html>
And call this function from your Omnis code using the JavaScript: command as follows:
JavaScript: show_alert();
Another example could include using the JavaScript: command to “push” events to Google
Analytics to track certain actions or events in your application. To do this you would need
to add the standard Web Analytics code provided by Google into your HTML page
(containing your remote form) and call the gaq.push() function with the correct parameters
from within your Omnis code.
96
Styled Text
Styled Text
You can insert various text styles in some of the JavaScript components wherever text is
displayed. For example, you can insert colors, font styles, and images into the text within
the list control, the droplist control, the data grid control, and the hyperlink control.
Text styles can be inserted using the style() function, in both server and client methods. The
style() function inserts a style-character represented by an Omnis constant into a calculation
or a text block. The styles that can be used include some of the existing constants (listed
under ‘Text Escapes’ in the Omnis Catalog) and a few new ones, prefixed kEscJs...,
introduced for the JavaScript Client. The following style constants can be used:
Style Description
kEscColor In a client-side method, the color parameter must be a numeric literal or
constant.
kEscStyle In a client-side method, the style parameter must be a numeric literal or
constant.
kEscBmp In a client-side method, the icon id parameter must be either a numeric
literal, or the sum of a numeric literal and an icon size constant e.g.
1710+k48x48
kEscJsNewline No additional parameters are required. Inserts a <br> line break tag. See *
kEscJsClose No additional parameters are required. Closes the current open style
information (inserted by kEscColor or kEscStyle) in the styled text and
reverts to the original color and text style. Note - kEscColor and
kEscStyle insert a <span> tag to style the text. kEscJsClose closes the
<span> tag.
kEscJsHtml Inserts raw HTML (the second parameter to style()).
97
Chapter 2—JavaScript Remote Forms
* There is also a new function br() which can be used as short-hand to insert a new line.
The br() function and kEscJsNewline can only be used with styled text for the JavaScript
client.
The following example code produces a list line which looks like this from the styled text
data in iChar:
Animations
JavaScript remote forms have the methods $beginanimations() and $commitanimations()
which allow you to control animations for some controls.
$beginanimations(iDuration[,iCurve=kJSAnimationCurveEaseInOut])
after calling this, assignments to some control properties are animated for iDuration
(milliseconds) by executing $commitanimations()
iCurve values are:
kJSAnimationCurveEaseInOut (the default), kJSAnimationCurveEaseIn,
kJSAnimationCurveEaseOut, kJSAnimationCurveEase and kJSAnimationCurveLinear
The animated properties are: left, top, width, height, alpha, backcolor, backalpha, textcolor,
fontsize, bordercolor, linestyle, buttoncolor (the latter is for pushbutton only).
If you set the same property for an object more than once, the first property change is
animated, and then the last property change is animated when the first completes. Property
98
Time Zones and Dates
changes between the first and last are ignored. The evAnimationsComplete event (for
remote forms) is generated after the last property change(s) have completed. This allows
you to reverse the effect of an animation (which is the equivalent to the autoreverse/repeat
options available on iOS).
The sample apps in the Welcome window contain an About form which is loaded into a
subform on the main sample app form. Animations are used to display the About subform,
which initially has the $alpha value of zero (fully transparent) and is increased to 255 during
the animation, as follows:
; method behind About button
On evClick
Switch iScreensize
; set aboutSubForm size for different devices
Etc.
End Switch
Do $cinst.$objs.aboutSubForm.$classname.$assign("jsAbout")
Do $cinst.$objs.aboutSubForm.$visible.$assign(kTrue)
Do $cinst.$beginanimations(500,kJSAnimationCurveEaseIn)
Do $cinst.$objs.aboutSubForm.$alpha.$assign(255)
Do $cinst.$commitanimations()
99
Chapter 2—JavaScript Remote Forms
Local Time
The $jslocaltime task property allows you to switch to Local time rather than UTC. If true,
the JavaScript Client and the Omnis App Server exchange date-time values in local time
rather than UTC time. $jslocaltime must be set in design mode: it cannot be assigned at
runtime.
Date Calculations
The dadd() function can be used in client executed methods to adds a number of “date
parts” to the given date. The sybtax of the function is:
dadd(datepart,number,date)
The datepart parameter determines what is added to the specified date and is one of a
number of constants: kYear, kMonth, kWeek, kQuarter, kDay, kHour, kMinute, kSecond,
kCentiSecond. The number is interpreted as the number of date or time parts or units
specified by a datepart constant. The number argument must be an integer when specifying
datepart as kYear, kMonth, kWeek, kQuarter, or kCentiSecond (the fractional part of a
number is ignored). You can use fractions for the other date parts.
PDF Printing
There is a printing device (external component) to allow you to print a report from Omnis
Studio to a PDF file and display it in the JavaScript Client in the end-user’s web or mobile
browser. There are two client commands (used with $clientcommand) to allow you handle
PDF reports in the JavaScript Client (if the end user’s device supports PDF). See the Omnis
Programming manual for more information about creating report classes to format your
PDF reports.
The PDF Device is available for Windows and OS X. Various supporting files are located
in the ‘python’ folder within the main Omnis Studio folder, and the PDF component itself is
in the ‘xcomp’ folder: these files need to be present in the Omnis App Server when you
deploy your web or mobile app.
100
PDF Printing
Fonts
The PDF device will only work with Reports that use TrueType fonts, and using other fonts
may cause an error during PDF generation. Specifically only fonts contained in “.ttf”, “.ttc”
or “.dfont” files can be used. Therefore you must choose TrueType fonts for your report if
you intend to print using the new PDF device.
Ensure that all fonts used in your PDF reports are in the specified locations within the
rl_config.py file stated under the 'T1SearchPath' section within the rl_config.py file which
can be found in the following folder:
omnis\python\App\Lib\site-packages\reportlab
Any installed font that is used in your report and not in one of these locations will result in
an error message when attempting to print to the PDF Device.
101
Chapter 2—JavaScript Remote Forms
bTemp A Boolean: kFalse means a temporary file will not be used. kTrue means
the next report sent to PDF by the current task instance will be written to a
temporary file in the folder “omnispdf/temp” in the data part of the Omnis
Studio tree. Note that after the next report has been sent to PDF, the stored
value of bTemp will revert to kFalse.
iTimeout An integer: Only used when bTemp is kTrue. If omitted defaults to 10. The
time in minutes for which the next PDF file generated by the current task
will remain on disk. When the time expires, the Omnis PDF device
automatically deletes the file. Note that Omnis automatically deletes any
files left behind in omnispdf/temp when it starts up.
102
PDF Printing
Each task instance (including remote tasks) stores its own information set up using
$settemp. This allows $settemp to be used in one thread on the Omnis Server without
affecting other threads/clients.
$setdocinfo()
The $setdocinfo function lets you specify the author, title and subject properties for the PDF
documents generated by the current task. The author, title and subject parameters are all
strings, and the function returns kTrue for success.
Do Omnis PDF Device.$setdocinfo(cAuthor,cTitle,cSubject) Returns bOK
$encrypt()
The $encrypt function sets encryption (security) properties for the PDF documents
generated by the current task, and the function returns kTrue for success. The full syntax is:
Do Omnis PDF Device.$encrypt(
cUserPassword
[,cOwnerPassword='',
bCanPrint=kTrue,
bCanModify=kFalse,
bCanCopy=kTrue,
bCanAnnotate=kFalse]) Returns bOK
The parameters are as follows:
cUserPassword A character string: The user password for the document. If this is set
to empty then none of the other arguments apply and the document
will not be encrypted; otherwise the document will be encrypted and
the user password and other properties specified by this function will
be applied to it.
cOwnerPassword A character string: The owner password for the document. The default
is no password is assigned.
bCanPrint A Boolean: Specifies if the user can print the PDF document. The
default is kTrue.
bCanModify A Boolean: Specifies if the user can modify the PDF document. The
default is kFalse.
bCanCopy A Boolean: Specifies if the user can copy from the PDF document.
The default is kTrue.
bCanAnnotate A Boolean: Specifies if the user can annotate the PDF document. The
default is kFalse.
103
Chapter 2—JavaScript Remote Forms
showpdf
The showpdf client command opens the specified PDF in a new window or tab. There is no
control over whether the PDF is opened in a new window or tab: typically this depends on
the end-user browser settings, including their setting for popups.
Do $cinst.$clientcommand("showpdf",row-variable)
assignpdf
The assignpdf client command opens the specified PDF in a PDF viewer control in the
current remote form instance. The PDF must be assigned to an HTML control in the remote
form which tries to open the PDF file using the PDF viewer installed in the end user’s
browser.
104
PDF Printing
Do $cinst.$clientcommand("assignpdf",row-variable)
105
Chapter 2—JavaScript Remote Forms
If iSaveCopy
Quit method lSaveLocation
Else
Quit method lID
End If
106
PDF Printing
107
Chapter 3—JavaScript Components
Chapter 3—JavaScript
Components
The Component Store contains over 30 ready-made components for the JavaScript Client
which you can drag and drop onto a JavaScript remote form. The components are displayed
under the “JavaScript Components” tab in the Component Store (assuming the $client
property is set to kClientJavaScript, which is the default for all new remote forms).
Component Description
Activity Control Animated image to display during Omnis Server activity
Background Control Object you can set to Rectangle, Line, Triangle, or Image
Bar Chart 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
108
PDF Printing
Component Description
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)
Navigation Bar Control Navigation with touch selection
Page Control Allows selection of page pane using touch
Paged Pane Can contain fields on multiple panes
Picture Control Standard field for displaying images
Pie Chart Control Displays a pie chart based on a list of values
Popup Menu Control A menu that pops up when clicked
Progress Bar Control Shows progress of server process or calculation
RadioGroup Control Displays a group of radio buttons for exclusive selection
Rich Text Editor Control Text field that allows end user to edit text
Slider Control Slider component for setting values
Subform Allows you to insert another remote form 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
Tree Control List for displaying hierarchical data or list of options
TransButton Control Button with hover over effects
Video Control Plays a YouTube or Flowplayer video
109
Chapter 3—JavaScript Components
110
JavaScript Component Properties
provided to allow you to create standalone custom apps for iOS and Android. See the
Standalone Mobile Apps section for more details.
kJSFormatNone No format
kJSFormatTime Default time format for client locale
kJSFormatShortDate Default short date format for client locale
kJSFormatShortDateTime Default short date and time format for client locale
kJSFormatMediumDate Default medium date format for client locale
kJSFormatMediumDateTime Default medium date and time format for client locale
kJSFormatLongDate Default long date format for client locale
kJSFormatLongDateTime Default long date and time format for client locale
kJSFormatFullDate Default full date format for client locale
kJSFormatFullDateTime Default full date and time format for client locale
kJSFormatCustom Use the custom format in $dateformatcustom
111
Chapter 3—JavaScript Components
There is a new entry on the Constants tab in the Catalog (F9) called "Date codes (JavaScript
Client only)" that lists the formatting characters.
Date functions
Omnis has a set of built-in global variables called hash variables (since their names begin
with #) including a set of date and time variables. There are a number of functions to
provide you with access to the values stored in the hash variables from within client
executed methods in the JavaScript Client. Note that the default value of these variables
may depend on the language version of Omnis Studio you are using.
The date and time related functions use the special date format characters listed under the
‘Date codes’ item on the Constants tab in the Catalog (press F9/Cmnd-9).
fmtshortdate()
fmtshortdate([newformat]) either sets #FD to newformat and returns the previous value
of #FD, a string used to format Short dates; or if no parameter is supplied returns the
current value of #FD (default value is 'D m y')
fmtshorttime()
fmtshorttime([newformat]) either sets #FT to newformat and returns the previous value
of #FT, a string used to format Short times; or if no parameter is supplied returns the
current value of #FT (default value is 'H:N')
fmtdatetime()
fmtdatetime([newformat]) either sets #FDT to newformat and returns the previous
value of #FDT, a string used to format Long date and time values; or if no parameter is
supplied returns the current value of #FDT (default value is 'D m y H:N:S')
fmtdp() (not available in client executed methods)
fmtdp([newdps]) either sets #FDP to newdps and returns the previous value of #FDP, a
112
JavaScript Component Properties
numeric variable which specifies the format used for display or string conversion of a
floating point number; or if no parameter is supplied returns the current value of #FDP
(defaults to 12)
getdatetime()
returns the current system date and time, formatted using #FDT
getticks()
returns the number of ticks elapsed since system boot; a tick is 1/60th of a second. The
value can overflow and restart at zero (for a JavaScript client executed method, the
number of ticks since midnight on 1 Nov 2011).
The JavaScript client uses #FD and #FT for short date and short time instance variables in
client methods; previously it used #FDT when converting short dates and times to character
data.
Number Formatting
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, so for example, the formatting is 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.
113
Chapter 3—JavaScript Components
Autoscrolling
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.
Rounded Borders
All the JavaScript components can have rounded borders by specifying the corner radius in
pixels in the $borderradius property. 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.
114
JavaScript Component Events
Enabling Events
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
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.
115
Chapter 3—JavaScript Components
116
JavaScript Component Icons
117
Chapter 3—JavaScript Components
118
JavaScript Component Icons
Errors
Any errors created while setting the icon ID for objects are sent to a file called
iconsetlog.txt located in the html folder.
Assigning a URL for images
When you set the $iconid of a JavaScript client object 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.
Deploying HD Icons
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.
119
Chapter 3—JavaScript Components
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 ‘html/icons’ folder, applying the correct
image file names. The $iconid property of a control will now reference the external image
file and not the icon datafile image.
Activity Control
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
Background Control
The Background Control allows you to draw various shapes in your remote forms. 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 assign the shape to the object
by setting the $::shape property to one of the kJSBack... constants.
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.
120
Background Control
alpha
changes the transparency of the object
alpha( newvalue, time(milliseconds), ease(optional) ,
complete_context(optional) )
rotate
rotates the object
rotate( newvalue, time(milliseconds), ease(optional) ,
complete_context(optional) )
For example:
Calculate $cinst.$objs.backgroundobject.$animation as
"alpha(0,500,<>,fade_complete)"
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:
Calculate $cinst.$objs.backgroundobject.$animation as
"alpha(0,500,<>,fade_off)"
121
Chapter 3—JavaScript Components
122
Bar and Pie Chart Control
change the position of the legend (by setting $legendpos the legend can be above, below,
left or right of the pie) and allow the pie segments to move or “fly out” when the end user’s
mouse hovers over the segment (enable $flyout).
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.
Events
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.
123
Chapter 3—JavaScript Components
Button Control
The Button Control is a basic pushbutton that the end user can click to confirm or initiate a
process, such as an OK or Cancel 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 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
$::vertical If true, the text and icon are arranged vertically
When a Button is clicked an evClick event is triggered which you can handle in the event
handling method behind the button.
On evClick
Do something…
Example
For example, all the sample apps in the Welcome window 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:
On evClick
Do $cwind.$closeAbout()
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.
See also the Trans button control.
124
Checkbox Control
Checkbox Control
The Checkbox control can represent On / Off or Yes / No values and is typically used to
allow the end user to turn on or off an option. The variable you specify in the $dataname
property of a Checkbox should be a Number or Boolean variable. The $text property
specifies the text for the Checkbox.
When a Checkbox is clicked an evClick event is triggered with the current value reported in
the pNewVal parameter.
For example, you could use 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:
On evClick
Do method filter
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:
125
Chapter 3—JavaScript Components
Do iList.$unfilter(0)
If not(iAgeRange1)
Do iList.$filter(not(iAge<=20))
End If
If not(iAgeRange2)
Do iList.$filter(not(iAge>=21&iAge<=40))
End If
If not(iAgeRange3)
Do iList.$filter(not(iAge>40))
End If
Switch iFilter
Case 1
Do iList.$filter(iGender='F')
Case 2
Do iList.$filter(iGender='M')
End Switch
Note the ‘Smart list’ capability has to be enabled on the iList variable to allow the built-in
filtering using the $filter method. You can enable this using the code:
Do iList.$smartlist.$assign(kTrue)
Combo Box
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. 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 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.
Content Tips
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
126
Combo Box
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.
Example
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:
; $construct of jsMaintenance form
; sets up form sizes, etc, then…
Do iDataRow.$definefromsqlclass($tables.T_Products)
Do $cinst.$objs.$sendall($ref.$construct())
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.
Do iGroupList.$definefromsqlclass(
$tables.T_Products,'product_group')
Do iGroupList.$selectdistinct()
Do iGroupList.$fetch(kFetchAll)
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:
127
Chapter 3—JavaScript Components
On evAfter
Do method newItem
Do $cinst.$setcurfield('product_name') ;; puts the focus in the
product_name field
The newItem method is placed behind the Combo box control itself and contains the
following code:
Do iGroupList.$search(
$ref.product_group=iDataRow.product_group,kTrue,kFalse,
kFalse,kFalse) ;; test iGroupList for group/type entered
If iGroupList.$line=0 ;; if not found in the group list
Do iGroupList.$add().product_group.$assign(
iDataRow.product_group) ;; add a new group to the list
End If
Complex Grid
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 place other controls in the row and header sections of the grid
control, including standard entry fields, droplists, buttons, and checkboxes. 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. In addition, a complex grid is a container field having its own
$objs group containing the objects inside the grid control. The edgefloat properties of the
fields inside a complex grid do not apply when the grid has a horizontal scroll bar.
You can place event methods behind the embedded controls (rather than the grid field) 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 a method that performs an
action based on the row clicked.
Example
The Webshop sample app, available in the Welcome window (open via the New Users
button), 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).
128
Complex Grid
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.
; $construct of complex grid control in jsShop form
Do iProductList.$definefromsqlclass($tables.T_Products)
Calculate whereClause as con('WHERE product_group =
',kSq,'Appetizers',kSq)
Do $cfield.$build(whereClause) ;; calls $build
; $build method also behind complex grid control in jsShop form
Do iProductList.$select(pWhereClause,' ORDER BY product_isfood
desc')
Do iProductList.$fetch(kFetchAll)
When the form is opened, the $construct method is run and the product list is built from
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
129
Chapter 3—JavaScript Components
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.
; ‘Order now’ button method
On evClick
Do method process_order (1)
See the Data Grid section for the process_order method which updates the iOrderList and
the Orders data grid accordingly.
130
Data Grid Control
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.
131
Chapter 3—JavaScript Components
132
Data Grid Control
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.
Grid Scrolling
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.
Example
The Webshop sample app, available in the Welcome window (open via the New Users
button on the main Omnis menubar), uses a data grid to display a list of products that have
been ordered in the main product 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.
; $construct behind the data grid
Do iOrderList.$definefromsqlclass($tables.T_qOrders)
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:
133
Chapter 3—JavaScript Components
134
Date Picker Control
The color of the Date Picker is specified with $datefacecolor while $datefacealpha sets the
transparency (value 0-255).
When the date is changed on the client an evDateChange event is generated, or when in
calendar view an evDateDClick is sent when a date cell is double-clicked.
Example
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
135
Chapter 3—JavaScript Components
specify the Begin and End dates for their holiday request. The “From” button has the
following code:
On evClick
Calculate iUsingCalendar as kTrue
Calculate iSelectFrom as kTrue ;; this is the From button
Do method openCalendar
The openCalendar class method moves the calendarPane into view on the main form and
has the following code:
Do method enableFields (kFalse) ;; enables the calendar pane &
disables the name pane
Do $cinst.$objs.calendarPane.$top.$assign(90)
Do $cinst.$objs.calendarPane.$left.$assign(150)
Do $cinst.$objs.calendarPane.$visible.$assign(kTrue)
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:
On evDateDClick
Do method closeCalendar
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:
If iSelectFrom ;; if the From button
Calculate iFromDate as iCalendarDate
Else ;; it must be the To button
Calculate iToDate as iCalendarDate
End If
Do $cinst.$objs.calendarPane.$left.$assign(1250)
Do method enableFields (kTrue)
136
Device Control
The final two lines of the method move the calendarPane off to the right and enables the
fields on the Name pane.
Device Control
The new 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.
137
Chapter 3—JavaScript Components
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.
Properties
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
The “action” for the Device control which specifies which
$action function on the client mobile device is accessed; this is
assigned as a kJSDevice… constant: see below
$barcodeimage If true, a barcode image will be returned.
Contains contact address details when the Make Call and Send
$communicationaddress
SMS device actions are used.
Contains the data to be sent when the Send SMS device action
$communicationdata
is used.
$dataname The name of an instance variable for the Device control
Contains an instance variable name used for holding the image
$deviceimage
returned from the device.
Name of the sound sample to be played when the Beep device
$soundname
action is called.
Contact properties
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.
138
Device Control
139
Chapter 3—JavaScript Components
Events
Event Description
Sent when no Barcode could be obtained from the device.
evBarcodeFailed Parameters
pEventCode The event code
Sent to the device control when a Barcode is ready for processing.
Parameters
evBarcodeReturned pDeviceBarcode The Barcode data
pEventCode The event code
Sent when no contacts could be obtained from the device.
evContactsFailed Parameters
pEventCode The event code
Sent to the device control when contacts info is ready for processing.
evContactsReturned Parameters
pEventCode The event code
Sent to the device control when Location Data is ready for processing.
Parameters
evGpsReturned pDeviceGps The GPS location
pEventCode The event code
Sent when the device failed to return an image.
evImageFailed Parameters
pEventCode The event code
Sent to the device control when an image is ready for processing.
Parameters
evImageReturned pDevicePhoto Image from Camera
pEventCode The event code
Sent when the device failed to take a photo.
evPhotoFailed Parameters
pEventCode The event code
Sent when an image is returned from camera ready for processing.
Parameters
evPhotoReturned pDevicePhoto Image from Camera
pEventCode The event code
Standard evExecuteContextMenu evOpenContextMenu
140
Device Control
Do iProducts.$loadcols()
Calculate iAmount as 1
If iProdName='Other'
Calculate iProdName as pDeviceBarcode ;; show the value of
the barcode
End If
141
Chapter 3—JavaScript Components
142
Device Control
On evPhotoReturned
Calculate iPic as iImage
143
Chapter 3—JavaScript Components
value: The value of the field (such as a phone number or email address) (String).
pref: Set to true if this ContactField contains 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 field 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 ContactField contains the user's preferred value (Boolean).
addresses: a list of all the contact's addresses.
pref: Set to true if this ContactAddress contains the user's preferred
value (Boolean).
type: A string that tells you what type of field 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 field 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 ContactField contains the user's preferred value (Boolean).
organizations: a list of all the contact's organizations.
pref: Set to true if this Contact organization contains the user's preferred
value (Boolean).
type: A string that tells you what type of field this is (example: 'home') (String).
name: The name of the organization (String).
department: The department the contract 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.
type: A string that tells you what type of field 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 ContactField contains 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 field 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 ContactField contains the user's preferred value (Boolean).
urls: a list of web pages associated to the contact.
type: A string that tells you what type of field this is (example: 'home') (String).
144
Droplist Control
value: The value of the field (such as a phone number or email address) (String).
pref: Set to true if this ContactField contains the user's preferred value (Boolean).
Droplist Control
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.
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 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.
Example
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
145
Chapter 3—JavaScript Components
control is set to iEmployeeList which is built via the $construct method when the form is
opened.
; buildEmpList class method in the jsUserForm
Do iEmployeeList.$definefromsqlclass('sEmployee') ;; the schema
Do iEmployeeList.$sessionobject.$assign(iSQLObjRef)
Do iEmployeeList.$select()
Do iEmployeeList.$fetch(kFetchAll)
Do iEmployeeList.$cols.$add(iEmpFullName)
Calculate lTotal as iEmployeeList.$linecount
For lNum from 1 to iEmployeeList.$linecount step 1
Calculate iEmpFullName as con(
iEmployeeList.[lNum].FirstName,kSp,
iEmployeeList.[lNum].LastName)
Do iEmployeeList.[lNum].$assigncols(,,,,,iEmpFullName)
End For
Do iEmployeeList.$line.$assign(1)
Calculate iName as iEmployeeList.iEmpFullName
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:
On evClick
Do method buildHolidayList
Calculate iName as iEmployeeList.[pLineNumber].iEmpFullName
Do $cinst.$objs.pagePane.$objs.holidayList.$redraw()
Do $cinst.$objs.pagePane.$objs.empName.$redraw()
The buildHolidayList class method builds the list of holiday requests for the selected
employee and redraws the form.
Edit Control
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. The Edit control can handle all types of
character data stored in the instance variable specified in $dataname. 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 $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.
146
Edit Control
If bottomleft is omitted the topright value is used. If bottomright is omitted the topleft value
is used. If topright is omitted the topleft value is used.
The $effect property lets you set the type of border for the edit control and 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 $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.
Content Tips
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.
Events
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. 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. Note that
147
Chapter 3—JavaScript Components
you must enable any of the events for the Edit control in its $events property before any of
the events are reported.
File Control
The File Control allows end users to upload or download files. 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.
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. 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.
Uploading Files
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
148
File Control
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).
Downloading Files
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. In this case, $dataname of the control must be a row variable, with
Column1 as the file name, Column2 the media type (e.g. text/plain;charset=utf8), and
Column3 the name of a remote task variable which should be a binary containing the file
data or character containing a file path.
Example
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:
Do iFileRow.$define(MimeList,"Binary Variable")
Calculate iFileRow.C2 as "tData"
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
149
Chapter 3—JavaScript Components
$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:
On evClick
Do $cinst.$objs.fileControl.$action.$assign(kJSFileActionUpload)
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:
On evFileUploaded
Calculate iPicture as tData
; transfer the pic data to iPicture
On evFileUploadDialogClosed
Do method setPicBtnTitle (kHavePic) ;; changes the button text
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.
HTML Object
The HTML Object lets you display an HTML page or fragment on the remote form. The
$html property contains the HTML content for the control. This must start with an element
declaration such as <div...> or <style>. The $ctrlname is the name of the control.
The following method constructs some HTML and assigns it to the HTML control called
HTML.
; lHTML is a local var of Character type
Begin statement
; ===== Styles =====
Sta: <style>
Sta: p {color: #00F; margin: 0 2em; padding: 1em; background-color:
#fff; border: #DDD solid 2px;}
Sta: h1, h2 { color: #666; margin-left: 0.5em;}
Sta: img {margin: 5px 0 5px 50px;}
Sta: </style>
150
HTML Object
Events
The HTML Control reports the evBefore and evAfter events, as well as evClick and
evDoubleClick.
151
Chapter 3—JavaScript Components
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).
The %d placeholder inserts “outline:none;” when disable system focus for the control is
true, thereby disabling the focus around the control. This placeholder has to be placed in the
<div> tag for the control, e.g. <div style="%d">.
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”:
<div><p>PLAIN TEXT</p><p style="%f”>STYLED TEXT</p></div>
Produces the following:
152
Hyperlink Control
Hyperlink Control
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 options in the Hyperlink list are based on the contents of a list variable (which requires
a different format to the existing web client Hyplinks component). The first column in the
list specified in $dataname is 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.
When the end user clicks on the list an evClick is triggered with the line number 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.
Example
There is an example library showing how you can build a dynamic hierarchical list using the
Hyperlink control in the new JavaScript Component gallery on the Omnis website at:
www.tigerlogic.com/omnis
Label Object
The Label object lets you add standard labels to the fields on your remote form. The text for
the label is entered into the $text property. The font and alignment of the label is setup
under the Text tab in the Property Manager.
The Label object also has the $dataname property which means its text can be populated
dynamically. If $dataname is set, its value overrides the value in the $text property, and
153
Chapter 3—JavaScript Components
actually sets $text, so if you read $text when using a label with a data name, the value of
$text will become the content of the variable in $dataname.
List Control
The standard List control allows you to display a single column list on your form allowing
end users to select a particular line. For lists with many columns you may prefer to use a
data grid, or for a more compact single-column list you can use a droplist. 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.
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 build the list via the $construct method of the remote
form; the list can be built from your database or from a number of static values, as follows:
Do iListvar.$define(iCol) ;; defines the list
Do iListvar.$add("Value1") ;; add the values
Do iListvar.$add("Value2")
Do iListvar.$add("Value3")
Do iListvar.$line.$assign(1) ;; selects the first line
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).
If $ischecklist is kTrue each list line has a checkbox which allows the end user to select or
de-select the line.
When the user selects a line the evClick event is reported with the pLineNumber parameter
reporting the selected line number. You can use the value of pLineNumber in your event
method behind the list to trigger an action.
See the ‘Programming Lists’ chapter in the Omnis Programming manual for more
information about using list variables in your code.
154
List Control
List Scrolling
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.
Linked Lists
You can link a List control to an Edit control to create a “Linked List” that can be updated
as the end user types into your remote form. 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.
155
Chapter 3—JavaScript Components
156
List Control
the instance variable associated with the edit control reflects the current content of the entry
field when evKeyPress is generated.
157
Chapter 3—JavaScript Components
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.
Map Control
The Map Control allows you to place a Google map on your remote form. In order to use
the Map control, you should register with Google to obtain a map API key, which can be
entered in the $apikey property of the control.
Important Note: By signing up to Google Maps and using the maps in your deployed
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.
TigerLogic 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, but 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 Map control and are described below.
158
Map Control
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.
Map Markers
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. 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:
; create vars map_markers (List), marker_latlong, marker_title,
marker_tag, marker_html (Chars)
Do map_markers.$define(
marker_latlong,marker_title,marker_tag,marker_html)
Do map_markers.$add(
"40.749305:-73.985775","Empire State Building","Empire State
Building","<div id='content'><h3 id='firstHeading'>Empire State
Building</h3><div id='bodyContent'><p><b><img src='http://nyc-
architecture.com/MID/esb1.jpg'></b></p></div></div>")
Do map_markers.$add(
"40.766225:-73.972514","Central Park","NY Central Park","<div
id='content'><h3 id='firstHeading'>Central Park</h3><div
id='bodyContent'><p><b>Central Park Info</b></p></div></div>")
Do $cinst.$objs.map.$mapmarkers.$assign("map_markers")
Do $cinst.$objs.map.$latlong.$assign("40.749305:-73.985775")
Do $cinst.$objs.map.$::zoom.$assign(12)
159
Chapter 3—JavaScript Components
Events
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.
; $event method for map control
; define vars map_markers (List), marker_latlong, marker_title,
marker_tag, marker_html, message (Chars), add_markers (Bool),
marker_no (Long int = 0)
On evMapClicked
If add_markers ;; linked to checkbox on window
Calculate marker_no as marker_no+1
Do map_markers.$define(
marker_latlong,marker_title,marker_tag,marker_html)
Do map_markers.$add(
pLatlong,con("Marker ",marker_no),
con("Marker ",marker_no),con("This is marker ",marker_no))
Do $cinst.$objs.map.$mapmarkers.$assign("map_markers")
End If
Calculate message as con(
pick(add_markers,"Map clicked here: ",
"Marker added here: "),pLatlong)
On evMapMoved
Calculate message as con("Center is now: ",pNewCenter)
On evMapZoomed
Calculate message as con("New zoom level: ",pNewZoom)
On evMarkerClicked
Calculate message as con("Marker clicked: ",pMarker)
160
Navigation Bar Control
Property Description
$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 is 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-5 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
$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
Events
The Nav Bar reports evClickInitialLeftButton when the initial left button has been clicked,
and evClickRightButton when the right button has been clicked.
161
Chapter 3—JavaScript Components
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.
Example
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:
The $event() method for the Nav Bar ($name = oNav) traps a user click on the right button,
and has the following event code:
On evClickRightButton
Do $cinst.$doPush(2,'Info','','','')
The $doPush method is a class method in the remote form and has the following
parameters, variables, and code.
; PaneNo (Short Int)
; Title, RightBtnText, RightBtnIcon, NoLeftBtn (all Character)
; lRow is local var of type Row
Do lRow.$define(
'New class','Title','text for right btn',
'icon for right btn','no left btn')
Do lRow.$assigncols(
PaneNo,Title,RightBtnText,RightBtnIcon,NoLeftBtn)
Do $cinst.$objs.oNav.$push.$assign(lRow)
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.
162
Page Control
Page Control
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 paged pane linked to the Page control is specified in the
$linkedobject property. In this case, when the page control is clicked the linked paged pane
control will select the next available pane automatically.
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.
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.
Paged Pane
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. It can be set to
up to four pixel values separated by -, in the order topleft, topright, bottomright, bottomleft.
163
Chapter 3—JavaScript Components
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.
Using $dataname
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.
Picture Control
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.
$picturealign is a kPAL... constant which, together with $horzscroll and $vertscroll,
identifies where the picture will be positioned in the control. If true, $noscale ensures the
images displayed in the control are not scaled.
Example
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.
164
Pie Chart Control
165
Chapter 3—JavaScript Components
Example
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. The
initial values for $::value and $::max of the progress control are 0 and 100 respectively. The
following code could be behind a button:
On evClick
;; initiate some process and
Calculate iCancelled as kFalse
Calculate iValue as 1
Do $cinst.$objs.ProgressBar.$sendcarryon.$assign(kTrue)
The evCarryOn event is sent to the progress bar which has the following event method:
On evCarryOn
If not(iCancelled)
Calculate iValue as iValue+1
Do $cinst.$objs.ProgressBar.$::value.$assign(iValue)
If iValue<100
Do $cinst.$objs.ProgressBar.$sendcarryon.$assign(kTrue)
End If
End If
166
RadioGroup Control
RadioGroup Control
Radio Groups present 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.
Example
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.
; radiogroup control is called ‘filter’ containing
; $construct method which is run when the form opens
Do iGroupList.$definefromsqlclass($tables.T_qGroups)
Do $cfield.$build()
167
Chapter 3—JavaScript Components
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.
; $build method behind the radiogroup
Do iGroupList.$selectdistinct()
Do iGroupList.$fetch(kFetchAll)
For iGroupList.$line from 1 to iGroupList.$linecount() step 1 ;;
loop through the list
Calculate text as con(
text,mid($prefs.$separators,3,1),iGroupList.product_group)
;; uses the localized separator (possibly semicolon)
End For
Calculate text as mid(text,2,len(text))
Do $cfield.$minvalue.$assign(1)
Do $cfield.$maxvalue.$assign(iGroupList.$linecount())
; $maxvalue of radiogroup is set to the number of groups in list
Do $cfield.$text.$assign(text)
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.
; $event method for Radiogroup
On evClick
Calculate whereClause as con(
'WHERE product_group =
',kSq,iGroupList.[pNewVal].product_group,kSq)
Do $cinst.$objs.productList.$build(whereClause)
168
Rich Text Editor Control
Property Description
The name of an instance variable to store the text, or a column in an
$dataname
instance row variable
$showcontrols Set to kTrue to show the Rich text editing toolbar
169
Chapter 3—JavaScript Components
Slider Control
The Slider control provides a graphical thumb component that the user can drag to control
the numeric setting of another component in your form, such as a volume control. 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 and transfer the current values to instance variables in
your form, as follows:
On evStartSlider
Calculate iStartValue as pSliderValue
On evEndSlider
Calculate iEndValue as pSliderValue
On evNewValue
Calculate iNewValue as pSliderValue
170
Subform
Subform
The Subform control allows you to place another remote form 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 layers.
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 to $classname to switch the
current form displayed in the subform control, as follows:
; oSub is the name of the Subform control on the main Remote form
Calculate $cinst.$objs.oSub.$classname as NewFormName
Note you can also create subforms dynamically in a Subform Set which are described in the
Remote Forms chapter.
Example
The Holidays sample app 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:
; $event method for User button on jsHolidays
On evClick
Do method setSubForm (kUserForm)
Calculate iAdminBtnState as kTrue
Calculate iUserBtnState as kFalse
Do $cinst.$objs.adminBtn.$enabled.$assign(kTrue)
Do $cobj.$enabled.$assign(kFalse)
The setSubForm method has the following code to switch forms:
If pOption=kAdminForm ;; test if Admin or User
Do $cinst.$objs.subForm.$classname.$assign("jsAdminForm")
Else
Do $cinst.$objs.subForm.$classname.$assign("jsUserForm")
End If
171
Chapter 3—JavaScript Components
172
Switch Control
Switch Control
The Switch control is like a check box insofar as it represents an On / Off value (1 or zero);
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. 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.
Example
There is an example library showing the Switch control with a range of different ON/ OFF
images in the new JavaScript Apps Gallery on the Omnis website at:
www.tigerlogic.com/omnis
173
Chapter 3—JavaScript Components
Tab Control
The Tab Control allows the end user to select a tab which can correspond to a specific
option in your application. 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.
Tab Icons
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.
Reordering Tabs
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.
174
Tab 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.
Tab Menus
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. The $tabmenu property is 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.
Events
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.
Example
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:
; $event method for Tab control
On evTabSelected
If pTabNumber=2
Do method loadRecord (iContactList.$line)
Do $cinst.$objs.saveBtn.$enabled.$assign(kTrue)
Else If pTabNumber=1
Calculate iNewContact as kFalse
Do $cinst.$objs.saveBtn.$enabled.$assign(kFalse)
End If
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.
175
Chapter 3—JavaScript Components
Timer Control
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).
Example
In the Webshop sample app it would be possible to use the 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 using the 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 enabled 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:
; $construct method for Orders list/data grid
Do iOrderList.$definefromsqlclass($tables.T_qOrders)
Do $cinst.$objs.timer.$running.$assign(kTrue) ;; possible using
a timer object
Do $cfield.$build()
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:
On evTimer
Do $cinst.$objs.dataGrid.$build()
176
Tree Control
which is specified in $hoticonid – if no $hoticonid is specified the $iconid is used. You can
also specify a different background color for the hover action in $hotbackcolor, and an
alternative border color in $hotbordercolor.
Tree Control
The Tree Control provides a graphical way of displaying a list of items in a hierarchical
format. Each node can have a check box or its own icon. The $dataname property for a tree
list is the name of a list variable containing the content (data) and structure of tree list. The
list can contain the entire data for a tree list when the form is opened in the client, or when a
tree list is in “dynamic” mode the content can be built as nodes are expanded by the end
user. Tree lists have the following additional 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
$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/
$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
By default the rows in a tree list are spaced automatically, based on the font size of the
control, but $extraspace allows you to add extra space in between the lines in the list. The
$extraspace property is the number of pixels added to the normal font height of a row in the
list, or zero for no extra space.
177
Chapter 3—JavaScript Components
Tree Events
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.
178
Tree Control
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).
179
Chapter 3—JavaScript Components
$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:
Do iNodeIcons.$define(iNodeIcon)
Do iNodeIcons.$add(iconurl(1710))
Do iNodeIcons.$add(iconurl(1711))
Do iNodeIcons.$add(iconurl(1712))
180
Tree Control
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.
Collapsing a Node
The tree control now generates evCollapseNode when the user collapses a node. This
applies to all trees, not just dynamic trees.
181
Chapter 3—JavaScript Components
Video Control
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 through a Flowplayer client.
The Video control allows you to play a video within your remote form. You can play videos
hosted on YouTube, or you can play video files directly accessed by a URL, using the
browser’s HTML5 video playing capabilities. The Video control has the following
properties:
Property Description
$dataname If $youtube=kTrue, this is a list containing YouTube ids; the id of the
video in the first column of the first row is played
If $youtube=kFalse, this is a 2 columned list containing URLs to video
files in Column 1 and media types in column 2
$showcontrols If true, the control displays video controls such as the play and pause
buttons
$flowplayerline If not zero, the line number in the $dataname list of the video content
to be used for the fallback Flowplayer object
$flowplayerurl The URL of the Flowplayer to be used as a fallback when HTML5
video is not available
$youtube If true, the control will play a movie from youtube.com; row 1 of
column 1 of the $dataname list is the YouTube video id
If false, the control will use HTML5 video (or Flash if HTML5 is not
supported) to play video files from URLs
YouTube
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. 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'.
HTML5
If you set $youtube to kFalse, the $dataname should be a 2-columned 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:
182
Video Control
Do iList.$define('VideoURL','VideoType')
Do iList.$add('videos/myVideo.mp4','video/mp4')
Do iList.$add('videos/myVideo.ogv','video/ogg')
Do iList.$add('videos/myVideo.webm','video/webm')
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.
Flowplayer
Not all browsers support HTML5 video so it is possible to play your video using
Flowplayer which uses Flash. To do this, you should point the $flowplayerurl property to a
Flowplayer object, which you can download from flowplayer.org. You then need to set
$flowplayerline to the line in your list of video files defined in $dataname which contains
the video file that can be played in Flowplayer.
183
Chapter 4—Creating Apps using iOS Client
184
Requirements
Requirements
Development Software
You can design remote forms for iOS in the OS X or Windows version of Omnis Studio.
That is, the iOS remote form components are available on both platforms, but you will need
an OS X computer to build your app, and an iOS device to test your app.
To build device and simulator apps, and to run the latest version of Xcode and the SDK
from Apple, you will need OS X 10.6 (Snow Leopard) or above.
You will also need a copy of iTunes to sync your computer with your iOS device.
185
Chapter 4—Creating Apps using iOS Client
Or you can
Click on the Class Wizard option, then Remote Form, and then Templates in the
Studio Browser, then select the NewiOSRemoteForm option
Both these options will create a new remote form with the $client property already set to
kClientiOS, plus the $height and $width of the remote form will be set for the different
values of $screensize.
Or you can create a remote form from scratch:
Create a new remote form using the New Class>>RemoteForm option in the Studio
Browser
Click on the background of the remote form and in the Property Manager set the $client
property to kClientiOS
In addition, for all of the above options, you will need to create a Remote Task:
Create a new remote task using the New Class>>RemoteTask option in the Studio
Browser
Set the $designtaskname property of your remote form to the name of the remote task
you created
When you create or switch a remote form to iOS, the Component Store will display iOS
Components only, under the ‘iOS Components’ group, replacing the standard JavaScript
components, while the remote form design window will display a mobile device image in
186
Creating Remote forms for iOS
the border and the title bar. The iOS components are located in the ioscomp folder in your
Omnis development tree.
The iOS remote form (right) and the Omnis Component Store (left)
showing the twenty or so iOS components
From here on, you will find the layout and visual design of forms for iOS very familiar,
although you set the behavior of components in a different way. You can design your
remote form for iOS in the same way as you would for a standard web-based remote form.
When you open a remote form from the Studio Browser, the Component Store will display
the appropriate components depending on the type of remote form you open, either a remote
form for iOS, or for web browsers, or some other client device.
There are several properties you need to set to specify the behavior, event handling and
other functionality in your iOS remote form; these are listed in the iOS Form Properties and
Methods section below.
187
Chapter 4—Creating Apps using iOS Client
188
Creating Remote forms for iOS
Client-Side Scripting
You can run certain methods in an iOS based remote form containing calculations, switch
statements, event handling, and other programming constructs.
To enable a method to run on the client, you can Right-click/Cmnd-click on the method and
select the 'Execute on Client' option. If a method contains code that cannot be executed on
the client, Omnis will not allow you to set the 'Execute on Client' option. When you have
enabled a method to run on the client, it will be shown in pink in the method editor.
Debugging Methods
You can debug your methods as you are testing your application on the client device by
setting breakpoints in your code. You can right click on a method line and select the
Breakpoint option to set a breakpoint. When you test the application on your client device
and the breakpoint is encountered in your code, method execution is halted at the breakpoint
and the application is temporarily suspended on the device. At this point, you can switch
back to Omnis on your development computer and step through the live code, inspecting
variable values (Right-click on the variable name anywhere in your code and select the
Variable <varname> option), commenting and uncommenting code (using Ctrl-; and Ctrl-‘),
and so on. When execution has completed in the Omnis method editor, the app will resume
operation on the client device.
189
Chapter 4—Creating Apps using iOS Client
To view the pParams row variable in design mode, you can set a breakpoint in the
$construct() method and open/test your remote form. Switch to the Omnis debugger, click
on the Parameters pane in the method editor, right-click the pParams variable and select the
‘Variable pParams…’ option. A small popup window will show the columns in the pParams
row variable.
190
Creating Remote forms for iOS
Device type
For iOS remote forms or associated remote tasks, the ClientInfoIphone parameter contains a
character string reporting the iOS device type. The ClientInfoIphone parameter may be one
of the following values (note other device types may be added in future):
ClientInfoIphone Description
i386 iPhone Simulator
iPhone1,1 iPhone
iPhone1,2 3G iPhone
iPhone2,1 3GS iPhone
iPhone3,1 4 iPhone
iPod1,1 1st Generation iPod
iPod2,1 2nd Generation iPod
iPod3,1 3rd Generation iPod
The following code within the form $construct() could be used to return the current device
type:
Calculate deviceType as pParams.ClientInfoIphone
191
Chapter 4—Creating Apps using iOS Client
The UDID is useful for identifying individual devices or end users, allowing you to store
some information in your app, such as the configuration of a Tabbar as selected by an end
user, against individual UDIDs.
Component Transparency
All iOS components have the $alpha property which specifies the transparency of the
component, with 0 being completely transparent and 255 being opaque; for most controls,
$alpha is set to 255 by default. Some components also have the $backalpha property which
controls the transparency of the background part of the control, rather than the foreground
elements or data in the control.
Component Icons
Several of the iOS components allow you to use icons to enhance the user experience. This
includes standard pushbuttons (iButton control), as well as the navbar, segmented, tabbar,
and toolbar controls, where you can use an icon to represent a single button, segment, or
tab. You can use an icon from any of the Omnis icon datafiles or the #ICONS system table
in your library, although the latter is advised. The icon for a component or button is
specified in its $iconid property. The icon used must support Alpha values to be displayed
in iOS.
Alpha icons
You must use icons with alpha values in components on iOS remote forms; non-Alpha icons
are not supported for iOS components and will not display correctly. Therefore when you
choose an icon for a component, by clicking on its $iconid property, you must choose an
Alpha compatible icon from an Omnis icon datafile or the #ICONS system table in your
library.
Icon pages
If you use an icon in any iOS component, such as a button or toolbar, you must specify the
icon page name for the icon in the $iconpages property of the remote form. If the icon page
is not listed in the $iconpages property, the icons will not be sent to the client and will not
be displayed. So for example, if you have created your own icon page in #ICONS, you must
check its name to the $iconpages property of the remote form.
192
Creating Remote forms for iOS
support Alpha icons are indicated in the Pages list using a small blue “A” icon, as shown
above.
To create a new page, click on “New Icon Page” and make sure you select the “Solid &
Alpha” option. In addition, you must check the boxes for 32x32 and 48x48 if you intend to
add icons for this size.
Importing Images to an Icon file
When importing your own Alpha compatible icons into an Icon Page you must use the
“Paste From File” option to import each Alpha image: you cannot use Copy and Paste from
another image application since the Alpha properties may not be imported successfully
using this method.
To import an Alpha icon, such as a PNG file, place your cursor in the icon field in the Icon
Editor (as above), select Paste from File from the Edit menu, and select the image file you
wish to import. Assign an ID to the icon and save the icon page. Note you can only add an
icon of a particular size if the page supports that size: you can change the icon size support
in the Page Options for a page.
Styles
You can assign styles to iOS components based on the Field Styles defined in your library
in the #STYLES system class. The definition for iOS styles are added under the kiOS
section of the #STYLES system class.
Fonts
There is a new system class #IOSWFONTS to handle fonts on iOS devices. A new column
called iOS has been added to the Window font table to allow you to map fonts used in
desktop, web, and mobile forms, including iOS forms. (Note there is no equivalent font
mapping for reports on mobile devices since Omnis reports do not run on mobile devices.)
193
Chapter 4—Creating Apps using iOS Client
Paged panes
You can use a Paged pane in your iOS apps to simplify the user interface by placing a small
number of fields and controls on separate panes and switching panes as appropriate.
Like the subform, the paged pane is a standard Omnis component and is available in the
‘iOS Components’ group in the Component Store. The paged pane can also be linked to a
navbar or tabbar component via the $linkedobject property in the navigation component.
Client Commands
There are a number of Client Commands you can use in remote forms in the iOS client:
these are executed using the remote form method $clientcommand() which has the general
syntax:
194
Creating Remote forms for iOS
Do $cinst.$clientcommand("commandname",row-variable)
iOS Preferences
The following client commands allow you to save and load end-user data on the client, such
as user preferences.
savepreference
Saves a value (as a character string) as a named preference on the client. You could use this
to store a username or a password for logging onto your app.
Do $cinst.$clientcommand("savepreference",row-variable)
Where row-variable is row(preference name, preference value).
loadpreference
Loads a named preference value from the client preferences into an instance variable.
Do $cinst.$clientcommand("loadpreference",row-variable)
Where row-variable is row(preference name, instance variable name (e.g. a quoted string
containing the name of the variable)).
195
Chapter 4—Creating Apps using iOS Client
196
iOS Form Properties and Methods
Method Description
$beginanimations() $beginanimations(iDuration
[,iCurve=kiOSAnimationCurveEaseInOut, iRepeatCount=0,
bAutoReverse=kFalse]) after calling this method, assignments to
some properties are animated for iDuration milliseconds by
$commitanimations()
$clientcommand() allows you to execute various functions on the iOS client, such as
Yes/No messages and client preferences; see earlier in this chapter
$commitanimations() $commitanimations() animates the relevant property changes that
have occurred after the matching call to $beginanimations()
$redraw() $redraw([bSetcontents=kTrue, bRefresh=kFalse, bBobjs=kFalse,
bExcludeSubForms=kFalse]) redraws remote form; Do
$cinst.$redraw() redraws the form; bSetContents loads the control
data only, bRefresh refreshes the screen, bBobjs redraws
background objects, bExcludeSubForms excludes child controls
which are subforms from bSetcontents (note that they cannot be
excluded from bRefresh due to the way operating system redraws
work)
$senddata() $senddata(iVar1[,iVar2,...]) specifies the instance variables to be
sent to the client after executing an event or $construct on the
server (see remote task class property $enablesenddata for details
of when $senddata applies)
$setcurfield() $setcurfield(vNameOrIdentOrItemref) sets the current field on the
client computer which is useful for data entry forms; when this is
set the focus is placed in the field and on iOS the soft keypad is
initiated; $setcurfield(‘’) removes the focus from the current field
$showmessage() $showmessage(cMessage [,cTitle]) Displays an OK message on the
client computer using the specified cMessage and cTitle
$showurl() $showurl(cURL) Opens the URL in the appropriate application on
the client machine. Note that the Omnis client will immediately
close as a consequence
197
Chapter 4—Creating Apps using iOS Client
method can be placed behind a button to allow the end user to navigate back to the previous
screen; in this case, the app appears to ‘remember’ the last page and uses the $openform()
method to reopen the last form:
On evClick ;; the last form visited is saved in tLastPage
Do $openform(
$ctask.tLastPage,kFormTransTypeFade,kFormTransDirNone)
Note the $openform() method in this case has three parameters: the name of the form to be
opened, as well as the transition type and direction specified using one of the
kFormTransType.. and kFormTransDir.. constants.
See the Omnis Notation Reference manual or the Omnis Help (press F1) for a full
description of the remote task methods.
198
iOS Form Events
Enabling Events
You should remember to enable any events that you wish to report for any individual
component or the remote form itself by enabling the event in the $events property for the
component or form. If an event is not enabled in the $events property, it will not be
reported, even if you have added code to handle the event in the $event method of the
component or form.
To enable an event, select the component or form background, open the Property Manager
(press F6), and click on the $events property to open the event droplist. Select the event you
wish to report from the list of possible events for the component or form.
199
Chapter 4—Creating Apps using iOS Client
iOS Components
There are several new components for remote forms that you can use on iOS devices, and
many of them will be familiar to iPhone/iPad users. When the components are instantiated
on the device itself, the native iOS components are used. The following section lists all the
iOS specific components available for remote forms. In addition, you can use the Paged
Pane and Subform components for iOS forms.
iActivity Control
iActivity provides an animated image to show some activity on the client, for example,
during a long list calculation or search operation. You assign kTrue to the $animating
property to display the animated image. The $hidewhensstopped property controls if the
control is hidden when animation stops.
The following method can be used to display the activity component, which could be called
or triggered by some event in your application.
Do $cinst.$objs.oActivity.$animating.$assign(kTrue)
Events
The iActivity control has no events.
200
iOS Components
iButton Control
The Button field responds to user clicks reported as the evClick event which can be handled
in the $event() method of the button. The button can display an icon, specified in the
$iconid property, and/or a single line of text. If you use an icon for the button, you must
specify the icon page for the icon in the $iconpages property of the remote form. In
addition, the icon must support Alpha.
The $disabledtextcolor property lets you set the color for the button text when the button is
disabled. Setting it to kColorDefault means $textcolor is used.
Events
evClick a user generated click
The following method can be placed behind a button control, which, in this case, allows the
user to switch to another form.
; code behind Scores button
On evClick
Calculate tLastPage as 'rfTitle' ;; Store this page so we can
come back here from the scores page
Do $ctask.$openform(
'rfScoreboard',kFormTransTypeFlipLeft,kFormTransDirFromLeft)
iDateTime Control
The iDateTime component provides a “spinner” field to allow the end user to select dates
and/or times. You can assign a Date/Time instance variable to the $datename property of
the control to load the date/time selected by the user. The $pickerstyle property specifies the
style of the date time picker. The following image shows the default Date/Time picker style
showing the current date.
Events
evClick a user generated click
201
Chapter 4—Creating Apps using iOS Client
You can create an instance variable in your form called iDate with the Subtype ‘Date Time
D m y’ and assign the variable to the $dataname property of the Datetime control. In the
$construct() method of your form you can use the following method to assign today’s date
to the variable.
Calculate iDate as #D
When the form is opened the Datetime control will display today’s date. When the user
selects a different date, the selected date will be held in the iDate variable. For example, you
could ask the end user to select their date of birth and the following code would calculate
the end user’s age this year.
Calculate lAge as ddiff(kYear,iDate,#D)
Do $cinst.$showmessage(con('You are ',lAge,' years old this year.'))
iImageView Control
The iImageView comp can be used to display an image, either a TIFF, JPEG, GIF, PNG,
BMP, ICO, CUR, or XBM image. The control supports the drag and pinch gestures which
allow the end user to zoom into and move the image within the picture control.
The $dataname of the control must be set to a Binary variable containing the image data;
you cannot use an Omnis picture variable. Alternatively, the variable in $dataname can be
an integer which references an icon id to display an icon from one of the Omnis icon
datafiles or #ICONS in your library.
The iImageView control has the following properties:
Property Description
$getimagedata (runtime only) assign a kiImageSource... constant to this property to
instruct the client to prompt the user for an image from the specified
source, and send an evImageSelected event with the image data in
pImageData
$getrawimage (runtime only) assign a kiImageSource... constant to this property to
instruct the client to prompt the user for an image from the specified
source, and use the selected image to set $rawimage
$imagealign specifies where the image will be positioned when $noscale is kTrue and
the image entirely fits in the bounds of the control
$maxzoom The maximum zoom factor that can be applied to the current image by
the pinch gesture (1-16)
$rawimage if set, this raw PNG image is used instead of the databound object
202
iOS Components
Events
evImageSelected Sent to the control when the action requested by assigning
$getimagedata completes; the pImageData parameter contains
the binary image data selected by the user
The following method can be placed behind a toolbar control that allows the end user to
select images from the photo or camera library on their device. The $getimagedata property
must be assigned at runtime and can be used with either kiImageSourcePhotoLibrary or
kiImageSourceCameraRoll to specify the image source.
; oPic is the image control, its dataname is iPic which is a binary
variable
On evClick
Switch pToolbarButton ;; contains the tab number clicked
Case 1
Do $cinst.$objs.oPic.$getimagedata.$assign(
kiImageSourcePhotoLibrary) Returns #F
Case 2
Do $cinst.$objs.oPic.$getimagedata.$assign(
kiImageSourceCameraRoll) Returns #F
End Switch
Do $cinst.$redraw()
The event method behind the image control loads the image held in pImageData and assigns
it to the iPic binary variable behind the image control.
On evImageSelected
Calculate iPic as pImageData
Do $cinst.$redraw()
203
Chapter 4—Creating Apps using iOS Client
iLabel Control
The iLabel control provides a simple text label.
Property Description
$adjustsfontsizetofitwidth if true, and $numberoflines is one, the object reduces the font
size in order to fit the text string into its bounding rectangle -
the property $minimumfontsize specifies the smallest value to
which the font size can be reduced
$linebreakmode a kiOSLineBreakMode... constant that specifies how lines
break when drawing text
$minimumfontsize the smallest value to which the font size can be reduced when
$adjustsfontsizetofitwidth is true and $numberoflines is one
$numberoflines the number of lines to be used to render the text. Zero means
use as many as necessary
Events
The iLabel control has no events.
iMap Control
The iMap control provides a Google map interface to allow the end user to search for
locations or for you to show locations in your app. The end user can drag and pinch the map
image to change location and zoom of the map. Using the map control together with other
controls, such as the table control which could list a number of locations, you can create
very interactive location based Omnis apps.
You can display the map with a specified location, adding your own annotation pins and/or
popup location markers. The iMap control generates a number of events in response to the
end user touching the map or markers.
204
iOS Components
Property Description
$addannotation Adds pin annotations to the map. Assign a list with columns
(nLatitude, nLongitude, cTitle [,cDesc]). nLatitude and
nLongitude are degrees where positive numbers are North and
East, or negative numbers are South and West. cTitle is the title
for the marker with cDesc the optional description
$centermap Centers the map to the location. Assign a row with columns
(nLatitude, nLongitude, nSpan). nLatitude and nLongitude are
degrees where positive numbers are North and East or negative
numbers are South and West. nSpan is the number of degrees of
latitude and longitude to display
$desiredaccuracy A kiMapLocationAccuracy... constant which indicates the level
of accuracy you require for evHeadingChanged and
evLocationChanged events. Greater accuracy requires more time
and power
$enableheadingevents If true, heading events are sent from the device to the server (the
device must support heading events)
$enablelocationevents If true, location events are sent from the device to the server (the
device must support location events)
$headingfilter The minimum angular change (measured in degrees) required to
generate new heading events. Set this to zero to indicate no
filtering of evHeadingChanged events
$locationfilter The minimum distance (measured in meters) the device must
move laterally before another evLocationChanged event is
generated. Set this to zero to indicate no filtering of
evLocationChanged events
$mapcanscroll If true, the map can scroll
$mapcanzoom If true, the map can zoom
$maptype The type of map, a constant: kiMapTypeStandard,
kiMapTypeSatellite or kiMapTypeHybrid
$nexttouchevent If kTrue, the next touch on the map sends an evLocationTouch
event. pLongitude and pLatitude are sent as parameters
$showannotation Assign an annotation number (a 1-based index into the added
annotations) to show the callout bubble for the annotation; the
number usually relates to the order of the list you may have
assigned to $addannotation. If the annotation is not currently
visible, assigning this property has no effect
$showuserlocation If true, the map shows the users location
205
Chapter 4—Creating Apps using iOS Client
Events
The iMap control generates a number of events which you can detect in your event handling
methods for the control. Here is a summary of the events; the next section provides full
details and parameters for each event.
evAnnotationTouched
Sent to the control when an annotation is touched
evLocationChanged
Sent to the control when the location changes or when $enablelocationevents changes
value to kTrue. You can use $locationfilter to restrict the generation of
evLocationChanged events
evHeadingChanged
Sent to the control when the heading changes or when $enableheadingevents changes
value to kTrue. You can use $headingfilter to restrict the generation of
evHeadingChanged events
evLocationOrHeadingError
Sent to the control when an error occurs while trying to get location or heading data
evLocationTouch
Sent to the control when $nexttouchevent is kTrue. After the event $nexttouchevent
will be set to kFalse
206
iOS Components
207
Chapter 4—Creating Apps using iOS Client
208
iOS Components
iMap example
Consider an example app that contains an
iMap control and a table containing a
number of locations, plus a toolbar for
adding markers. The contents of the table
list could be built on the fly or from a
database, which is the case in this example.
The following code samples show how you
can build the location list and show each
location with an annotation pin.
The first task would be to create a database
session, logon to the database and build the
list of locations. In this case the locations
are held in an Omnis database located in the
same folder as the app, and standard SQL
code is used to build the list based on the
Markers table.
; $getAnnotation class method
; Instance var: iAnnList (List)
; oMap is the map control on the form
Do iAnnList.$clear()
Do $cinst.$objs.oMap.$addannotation.$assign('')
Do iStmt.$execdirect('SELECT * FROM Markers') Returns #F
Do iStmt.$fetch(iAnnList,kFetchAll)
Do $cinst.$objs.oMap.$addannotation.$assign(iAnnList)
Do $cinst.$redraw()
209
Chapter 4—Creating Apps using iOS Client
In this example, the iAnnList list variable has the following data.
The list of annotation data is assigned to the map control by assigning it to its
$addannotation property. The data list must contain columns for the Latitude and Longitude
of the locations, a Title for the location marker, and an optional description. In our example
there is a fourth column containing the type of accessory marker to be displayed in the
location list on the form. The Latitude and Longitude parameters are specified as the
number of degrees where positive numbers are North and East, and negative numbers are
South and West.
In this example, the remote form startup code centers the map and displays the second pane
of a paged pane control showing the table of locations. The instance variable iCurrentPos is
a Row based on the schema table in our database (set the subtype of the variable to the
name of the schema class), with the columns Latitude, Longitude, and Span. The value of
iCurrentPos is hard coded in this case and assigned to the $centermap property of the map
control.
Do iCurrentPos.$assigncols(52.3,1.65,4)
Do $cinst.$objs.oMap.$centermap.$assign(iCurrentPos)
Calculate $cinst.$objs.oPane.$currentpage as 2
Do $cinst.$redraw()
210
iOS Components
211
Chapter 4—Creating Apps using iOS Client
On evLocationTouch
Do iAnnList.$add(
pLatitude,pLongitude,iName,
iDesc,kiTableCellAccessoryDisclosureButton)
Do iStmt.$execdirect('INSERT INTO Markers
VALUES(@[pLatitude],@[pLongitude],@[iName],@[iDesc],2)')
Returns #F
Do $cinst.$getAnnotation() ;; builds the annotation list
The evLocationTouch event returns the selected location in the pLatitude and pLongitude
parameters which can be used to add the location to the list and insert the new location into
the database. The $getAnnotation() class method is called to rebuild the annotation list and
redraw the form including the new location marker.
iMultiLineEdit Control
The iMultiLineEdit control is a field for displaying multiple lines of text from the variable
specified in $dataname. The $autocapital property controls the capitalization of entered text,
while $autocorrect specifies if auto correction is used.
See the section on the iSingleLineEdit Control for further information about using edit
fields in remote forms.
Events
evAfter Sent to a field when it ceases to be the target field
evBefore Sent to a field when it becomes the target field
212
iOS Components
iNavigationbar Control
The iNavigationbar component provides a standard iOS navigation bar which end users can
use to navigate to different parts of your application. The navigation bar has a main title in
the middle of the control and can have a left and/or right button which respond to user
clicks.
Property Description
$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
$initiallefttype specifies the type of button displayed on the left hand side of the
first navigation bar item
$initialrighticonid if set to kinavigationbarbuttontypeimage, the first navigation bar
item has a button on the right hand side, displaying this icon
$initialrighttext if set to kinavigationbarbuttontypetext, the first navigation bar item
has a button on the right hand side, displaying this text
$initialrighttype specifies the type of button displayed on the right hand side of the
first navigation bar item
$initialtitle is 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 of a subform or paged pane object on the current remote
form, used in conjunction with the $push property of the navbar. If
you use a subform, $multipleclasses for the subform must be ktrue
$navigationbarstyle specifies the appearance of the navigation bar
$push allows you to assign a 2-4 column row to the object referenced in
$linkedobject, col1 is the page number of a paged pane or classname
of the linked subform, col2 is the title for pushed item, col3 is the
text or icon id for right button (pass empty for no right button), and
col4 can be non-zero to hide the left button
$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
$righttype specifies the type of button displayed on the right hand side of the
current navigation bar item
$tintcolor the color of the navigation bar
213
Chapter 4—Creating Apps using iOS Client
Property Description
$title the title for the current navigation bar stack item
If you use icons in your navbar you must specify the icon page for the icon(s) in the
$iconpages property of the remote form.
Events
evClickInitialLeftButton The initial Left Button has been clicked
evClickRightButton The Right Button has been clicked
Consider the Help form in the Anagrams example application. The Help form has a navbar
which allows the end user to select different help topics. The navbar itself is linked to a
paged pane field which displays the help topics on individual panes. The $linkedobject
property of the navbar specifies the name of the paged pane, in this case, called oPane.
The $construct() method of the Help form builds a list containing information about the
pages of the tab pane, including the arguments needed for the $push property of the navbar.
Do iPageList.$define(Page,Title,Rightbtn,HideLeft)
Do iPageList.$add(1,'Info','Manual Play',1)
Do iPageList.$add(2,'Manual Play','Anagram',0)
Do iPageList.$add(3,'Anagram','',0)
The navbar control itself 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:
The $event() method traps a user click on the button on the navbar, and has the following
event code:
On evClickRightButton
Do $cinst.$pushPage(iPage+1) ;; page number is incremented
and passed to the $pushPage method
214
iOS Components
The $pushPage method is a class method and gets the details for the new page from
iPageList (built in the $construct of the form, as above) and passes the details to the $push
property of the navbar.
; pPage receives the page number
; lRow is local var of Row type
; iPage stores the current page number
Calculate lRow as iPageList.[pPage]
Do $cinst.$objs.oNav.$push.$assign(lRow)
Calculate iPage as pPage
The effect of the $push property is to change the pane number in the paged pane control
specified in the $linkedobject property; in the case of the example app, an initial click by
the end user will display the second pane in the Help form.
iPage Control
The iPage control links to a Paged pane on the remote form and allows the end user to
change the current page in the linked paged pane by flicking or swiping over the page
control. The paged pane to link to the iPage control is specified in the $linkedobject
property.
The iPage 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 (the screenshot shows page 3 selected).
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
Events
evPageChanged The page has changed;
pValue = the new page
215
Chapter 4—Creating Apps using iOS Client
an entry form into more manageable parts whereby each pane contains a small number of
fields.
Several of the other iOS controls can link to a paged pane, by setting the control’s
$linkedobject property to the name of the paged pane. You can link a paged pane to the
iNavigationbar, iPage, and iTabbar controls.
In addition to the standard paged pane properties, you can set $effect to select different
border effects for the control, and by setting $scrolltochangepage to kTrue the end user is
able to can change the current page simply by flicking or wiping horizontally across the
paged pane.
iProgress Control
The iProgress control lets you indicate the progress of an operation such as a complex
search, calculation, or loop. The $progressstyle sets the style of the progress bar. The $min
and $max properties specify the maximum and minimum values for the progress range,
while $val is the current value in the progress range (between $min and $max).
Events
evClick a user generated click
The following method could be placed behind a button to trigger the progress control, but
could equally be triggered by another event in your code.
; the $min and $max of ‘progress’ are set to 0 and 1000
On evClick
For count from 1 to 1000 step 1
Do $cinst.$objs.progress.$val.$assign(count)
End For
Do $cinst.$showmessage('Done!')
216
iOS Components
iSearchBar Control
The iSearchBar component provides an entry field in the search bar style. The text entered
by the user is held in the variable specified in $dataname and can be used as the source for a
search.
Property Description
$autocapital controls the capitalization of text entered
$autocorrect controls how the iOS device corrects the entered text
$contenttip the text displayed in the field when it is empty, to help the user
understand what content should be entered
$dataname the data name of the object
$prompt the text shown above search bar; increase the height of the searchbar
control itself to make the text visible
$searchbarstyle sets the visual style of the searchbar (only applies if $tintcolor is
kColorDefault)
$showsbookmark enables the bookmark icon in the search bar; note you can detect a
click on the bookmark with evBookmarkClick which must be enabled
in the $events property
$showscancel enables the cancel button in the search bar
$tintcolor the color of the search bar
Events
evAfter Sent to a field when it ceases to be the target field
evBefore Sent to a field when it becomes the target field
evBookmarkClick The user has pressed the bookmark button
evClick a user generated click
The following Searchbar control works in conjunction with a Webview control to allow the
end user to browse web pages within your Omnis application. The $dataname of the
searchbar is set to iUrl, a simple Character instance variable.
217
Chapter 4—Creating Apps using iOS Client
The code in the $event() method for the Searchbar assigns the contents of the control held
in iUrl, along with a Webview command constant, to a row variable which is itself assigned
to the $execcommand property of the Webview control.
On evClick
Do lCommand.$define('','')
Calculate lCommand.1 as kiWebViewCommandLoadPage
Calculate lCommand.2 as iUrl ;; the text in the Searchbar
Do $cinst.$objs.oBrowser.$execcommand.$assign(lCommand)
Do $cinst.$setcurfield('')
Do $cinst.$redraw()
218
iOS Components
iSegmented Control
The iSegmented component is similar to the tabbar in so far as it provides a number of
buttons or segments for the user to click. You can detect which segment the user has clicked
on and execute the appropriate code.
Property Description
$currentsegment the number (1 - $segmentcount) of the current segment (this
specifies the segment affected by segment specific properties);
$movesegment moves the segment by assigning a number in the range 1 to
$segmentcount, which changes $currentsegment to the assigned
number (not assignable in class notation)
$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, if $segmenttext is not
empty, $segmenticonid is ignored;
$segmentlist a list containing segment-specific properties, one line per
segment;
$segmentstyle specifies the appearance of the control;
$segmenttext the text displayed on the current segment, if this is not empty,
$segmenticonid is ignored;
$segmentwidth the width of the segment in pixels, otherwise if zero, the control
automatically sizes the segment;
$selectedsegment the number (1 - $segmentcount) of the currently selected
segment, or zero if no segment is selected (only relevant if
$showselectedsegment is kTrue);
$showselectedsegment if true, the control highlights the selected segment
($selectedsegment specifies the highlighted segment);
$tintcolor the color of the control (only applies if $segmentstyle is
kiSegmentStyleBar and $tintcolor is not kColorDefault);
If you use icons in the segmented control you must specify the icon page for the icon(s) in
the $iconpages property of the remote form.
Events
evClick a user generated click;
pSegment = the number of the segment clicked
219
Chapter 4—Creating Apps using iOS Client
The following Segmented control has been configured to work in conjunction with a
Webview control to provide a web browser in a remote form.
See the iWebView section for the example code used behind such a Segmented control.
220
iOS Components
iSingleLineEdit Control
The SingleLine Edit Field is for displaying or receiving a single line of text from the
variable specified in $dataname. In most cases the variable will be character based, but the
single-line edit can display numeric data; see below. Like all remote form fields, the
variable specified in $dataname for the edit field must be an instance variable.
Property Description
$adjustsfontsizetofitwidth if true, the object reduces the font size in order to fit the text
string into its bounding rectangle, while $minimumfontsize is
the smallest value to which the font size can be reduced when
$adjustsfontsizetofitwidth is true
$autocapital controls the capitalization of text entered
$autocorrect controls how the iOS device corrects the entered text
$clearbuttonmode controls when the clear button is displayed in the field which
allows the end user to clear any data in the field; this is one of
the kiOSViewMode… constants
$contenttip the text displayed in the field when it is empty, to help the
user understand what content should be entered
$effect The effect or border style of the edit field; for iOS this is one
of the kiOSBorder… constants
$dataname the data name of the object
$securetextentry if true, each character is hidden which is useful for password
text entry
Events
Single line edit fields do not report any special events other than the standard evAfter,
evBefore, and evClick.
221
Chapter 4—Creating Apps using iOS Client
222
iOS Components
If a numeric variable allows decimal points, such as Number 2dp, the standard keyboard is
opened, but on the numeric page, and will only allow the input of numbers and the decimal
point character (in this case, no other characters can be inserted).
iSlider Control
The Slider is a convenient and intuitive way for the end user to select a value or setting,
such as a numeric value or percentage, since the position of the button corresponds to the
current value of the variable assigned to the control.
The $sliderstyle property sets the style of the slider bar. The $min and $max properties
specify the minimum and maximum values for the slider range, while $val is the current
value in the slider range (between $min and $max). When the end user drags the thumb
button and the slider is changed, the evSliderChanged event is triggered with pValue
containing the current value.
Events
evSliderChanged The slider value has changed;
with pValue = the new value
The following method can be placed behind a slider control to set the $alpha property of an
image field called oPic.
On evSliderChanged
Calculate $cinst.$objs.oPic.$alpha as pValue
iSwitch Control
The Switch component provides an ON / OFF button. The instance variable specified in
$dataname will be set to value=1when the end user pushes the switch on, and set to zero
when the switch is turned off.
Events
evClick a user generated click
223
Chapter 4—Creating Apps using iOS Client
The following method can be placed behind the Switch component to trap whether the
switch is on or off and run some code as appropriate.
On evClick
Switch iSwitch ;; iSwitch (Short int)
Case 1 ;; switch is on
; Do something
Default ;; switch is off
; Do something else
End Switch
iTabbar Control
The Tabbar component allows the user to select a tab which can correspond to a specific
option in your application. You can specify the number of buttons on the tabbar, while for
each button you can use one of the standard types or specify your own. The tabbar can be
linked to a paged pane or subform so when different buttons are clicked the pane or subform
can be changed accordingly. You can also allow the end user to reconfigure or reorder the
buttons in the tabbar.
Property Description
$config the tabbar configuration specified by the user, which allows you to store
the configuration set by the user (using the value of the pConfig event
parameter in the evConfigDone event)
$currentobject the number of the current button in the range 1 - $objectcount; setting
this in design mode allows you to set the button specific properties for
each button
$linkedobject name of a subform or paged pane to link to the tabbar. If this is not
empty, when the user selects an object, it sets $classname or
$currentpage for the linked object to $objectlink instead of generating a
click event
$moveobject moves the button by assigning a number in the range 1 to $objectcount,
which changes $currentobject to the assigned number; this provides a
convenient method for you to move buttons (in design mode only)
$objectbadge the badge text used to mark the item; this can be useful for adding
information to the button to help the user make a selection
$objectcount the number of buttons on the tabbar (this must be at least one)
$objectenabled if true, the button is enabled and generates a click event when pressed
$objectflags a combination of the kiTabbarButtonFlagInitiallyVisible and
kiTabbarButtonFlagAlways constants that control when the tabbar
button is visible in its initial state prior to the user configuring the tabbar
$objecticonid the icon displayed on the current button (only significant if $objecttype
224
iOS Components
Property Description
is kiTabbarButtonTypeUser)
$objectlink When the user selects this object, the object sets $classname or
$currentpage for the object to $objectlink; only significant if
$linkedobject is not empty
$objecttext the text displayed on the current button (only significant if $objecttype is
kiTabbarButtonTypeUser)
$objecttype the type of the button specified by one of the kiTabbarButtonType..
constants; to define your own tabbar button use
kiTabbarButtonTypeUser and set $objecttext and $objecticonid
$openconfig set this to kTrue to open a dialog for the user to customize or reorder the
buttons in the tabbar. On completion, evConfigDone is sent with the new
configuration in pConfig and invisible items in pMoreList. Changes to
screen orientation are disabled while the dialog is displayed
$selectedobject the number (1 - $objectcount) of the currently selected button, or zero if
no button is selected
Events
evClick a user generated click;
pTabbarButton = the number of the tabbar button clicked
evConfigDone pConfig = the new configuration of the tabbar specified by the user
which is a row containing button IDs in the new order
pMoreList = 2 column list; col1 is the icon ID, col2 the text
Button Icons
For most tabbar buttons you can use the standard button types available in $objecttype and
specified using one of the kiTabbarButtonType.. constants. You can however specify your
own tabbar buttons using the kiTabbarButtonTypeUser object type. In this case, the
$objecttext and $objecticonid properties are enabled which allow you to define your own
button, including your own text and icon. Note that you must use icons that include Alpha
properties for tabbar buttons, since the alpha values in the icon image are used to render the
button image, and in this special case, the color values in the image are ignored.
If you use icons from an icon datafile or #ICONS in your tabbar, you must specify the icon
page for the icon(s) in the $iconpages property of the remote form.
Tabbar position and size
In addition to setting the tabbar specific properties, you can set the $edgefloat property of
the control to kEFposnTopToolbar or kEFposnBottomToolbar to position and “fit” the
control to the top or bottom of the form, respectively.
225
Chapter 4—Creating Apps using iOS Client
Most of the standard tabbar buttons require a minimum height to display the icon and text
correctly. In this case, you will find that you cannot resize the height of the tabbar below 49
pixels, although you can set $height of the control if you need to specify a height.
Tabbar configuration
When you create the tabbar control in development mode, the configuration or order of the
tabbar buttons is stored in the object, but at runtime you can allow the end user to change
the order of the buttons. By setting the $openconfig property to kTrue, you can open a
configuration dialog on the client, allowing the end user to drag the buttons to reorder them.
The following method could be placed behind a standard button to open the configuration
dialog:
On evClick
Do $cinst.$objs.oTabBar.$openconfig.$assign(kTrue)
When the end user has finished reordering the tabbar and clicked the Done button, the
evConfigDone event is sent to the tabbar with the new configuration in pConfig, which is a
comma-separated row containing the button numbers in the new order.
You can save the new configuration into the $config of the tabbar using the following
method placed behind the tabbar itself:
On evConfigDone
Calculate $cinst.$objs.oTabBar.$config as pConfig
If you wish to store the new configuration permanently you will need to store the new
values returned in pConfig onto the server, together with the ID of the device, and load it
when the individual client device reconnects. See the Getting App and Device Information
section earlier in this document.
Example Tabbar
Consider the Scoreboard remote form in the Anagrams example application. A tabbar is
used to allow the end user to select which set of scores to display in the scoreboard.
The $objectcount property is set to 7 to display seven tabs, with a text value for each tab
specified in $objecttext; you have to set $currentobject to edit the properties of each tab.
The $objecttype property controls the type or style of each button in the tabbar, and in this
case each tab is set to kiTabbarButtonTypeUser which means the button is user defined.
Many of the other types provide a predetermined button or icon for specific purposes.
226
iOS Components
The tabbar reports an evClick with pTabbarButton containing the number of the clicked tab
which you can use to trigger an action depending on the code in the $event() method for the
control. For example, in the Anagrams example app the tab number is used to return a list of
scores for the selected number of letters.
; contains instance vars iList (list), iPath (Char)
; iSess (Object based on OMSQLSESS), iStmt (Object no subtype)
On evClick
Do iList.$clear()
Do iSess.$logon(iPath,'','','ScoreSess') Returns #F
Calculate lLetters as pTabbarButton+2
; pTabbarButton +2 since the tabbar starts on ‘3 letters’
Do iStmt.$execdirect('Select * From Scores where
Letters=@[lLetters]') Returns #F
Do iStmt.$fetch(iList,kFetchAll)
Do iSess.$logoff()
Do iList.$sort($ref.RealTime,kFalse) Returns #F ;; Sort into
time order although the time is not displayed
Do $cinst.$redraw()
Note that when the data is fetched from the database, in this case an Omnis datafile, the
form needs to be redrawn using the $redraw() method, which is a method of a remote form
instance, referenced using $cinst. See below for details about the table control used on the
scoreboard remote form.
227
Chapter 4—Creating Apps using iOS Client
iTable Control
As well as providing a method for displaying lists of data, the iTable component can be
used for the main interface of your iOS app, since it can provide a hierarchical set of
options, complete with graphical symbols and icons, for users to navigate their way around
your application. Many iOS apps use a Table based interface in preference to the menu &
button based approach found in traditional desktop and web applications.
Property Description
$altcolor1 & $altcolor2 the alternating row colors of the table
$dataname the list variable name for the content of the table
$grouped set to kTrue to enable grouped mode
$iconcolumn the column number of the list column containing the icon id
of the icon to display for each row, or zero if icons are not
required
$label1bold / $label2bold sets label 1 or 2 to bold
$label1column the column number of the list column containing the first text
string to display for each row
$label1size / $label2size the font size of label 1 or 2
$label1textcolor / the text color of label 1 or 2
$label2textcolor
$label2column the column number of the list column containing the second
text string to display for each row, or zero if a second text
string is not required
$rowflagscolumn the column number of the list column containing flags which
control various options for the row, with each flag’s column
value a kiTableCellAccessory... constant, or zero if
accessories are not required
$rowht the default height of a row
$tablestyle the style of the table, a kiTableStyle... constant
If you use icons in the table you must specify the icon page for the icon(s) in the $iconpages
property of the remote form.
The iTable component is able to display both standard “flat” lists and “grouped” lists.
Standard flat lists are defined as you would any other list, containing columns and simple
rows of data. In this case, you assign the flat list to the $dataname of the iTable component
and define how the data is interpreted by setting its various properties, including $tablestyle
to specify how the list determines the structure of the table (one of the kiTableStyle...
constants), $iconcolumn to specify the icon, $label1column and $label2column for column
labels, and $rowflagscolumn.
228
iOS Components
Events
evTableRowAccessoryClicked pRow = a reference to the list row clicked
pSection
evTableRowClicked pRow = a reference to the list row clicked
pSection
Consider the Scoreboard remote form in the Anagrams example application. A table is used
to display the scores for any given number of letters, selected by the user clicking on a
tabbar above the table.
The iTable control itself has no methods behind it and it does not trap events since the data
is built by the end user clicking on the tabbar (see the iTabbar section). However, its visual
appearance has been specified using various General and Appearance properties in the
Property Manager, as follows:
In addition to the General and Appearance properties, you can set the properties of the text
labels and row background displayed in the table under the Text tab in the Property
Manager.
Note you can examine the $construct() method in the rfScoreboard remote form to see how
the table (list) data is built and displayed initially.
229
Chapter 4—Creating Apps using iOS Client
230
iOS Components
iMainList is assigned to $dataname of the table, and its $grouped property is set to kTrue.
iToolbar Control
The iToolbar provides a row of buttons to allow the end user to select an option in your
application. You must specify the properties for the toolbar control itself, and for each
button in turn by setting $currentobject.
Property Description
$events enable evClick to report user clicks
$tintcolor the color of the toolbar
$toolbarstyle specifies the appearance of the toolbar
Property Description
$currentobject the number (1 - $objectcount) of the current button (this specifies the
button affected by button specific properties)
$moveobject moves the button by assigning a number in the range 1 to $objectcount,
which changes $currentobject to the assigned number (not assignable in
class notation)
$objectcount the number of toolbar buttons (this must be at least one)
$objectenabled if true, enables the button and generates a click event when the user
presses it
$objecticonid the icon for the current button (only significant if $objecttype is
kiToolbarButtonTypeImage), the alpha values in the source image are
used to create the image, and opaque values are ignored
$objectselected if true, the object is the currently selected object in the group of
kiToolbarButtonTypeSegmented objects to which it belongs (ignored
unless $objecttype is kiToolbarButtonTypeSegmented)
$objectstyle specifies the style of the button (only significant if $objecttype is
kiToolbarButtonTypeText or kiToolbarButtonTypeImage)
$objecttext the text on the current button (only significant if $objecttype is
kiToolbarButtonTypeText or kiToolbarButtonTypeSegmented)
$objecttype indicates the type of the button
$objectwidth the width of the button in pixels, if zero, the control automatically sizes
the button (ignored unless $objecttype is kiToolbarButtonTypeText,
kiToolbarButtonTypeImage or kiToolbarButtonTypeFixedSpace)
If you use icons in your toolbar you must specify the icon page for the icon(s) in the
$iconpages property of the remote form.
231
Chapter 4—Creating Apps using iOS Client
Events
evClick a user generated click;
pToolbarButton = the number of the toolbar button clicked
The following toolbar has two buttons allowing the end user to select images from their
Photo Albums collection or Saved Photos folder.
The $event() method behind the toolbar can detect which button is clicked using the
pToolbarButton event parameter and act accordingly. For example, a toolbar with 3 buttons
could have the following code:
On evClick
Switch pToolbarButton ;; contains the number of the clicked button
Case 1
; Do this
Case 2
; or do this
Case 3
; or this
End Switch
Do $cinst.$redraw()
232
iOS Components
iWebView Control
The iWebView component allows you to display a web page and/or run some Javascript.
You can load or reload a web page, perform a Forward or Back web command, or run some
Javascript by assigning a 2 column row variable to $execcommand to execute a command.
Column 1of the row variable must contain an integer or a kiWebViewCommand... constant,
while column 2 has info specific to the command, as follows:
When the page has loaded, reloaded, or the Javascript has executed, the control sends the
evResult event which contains the pResult parameter, a 2 column row containing the status
and result of the command executed.
233
Chapter 4—Creating Apps using iOS Client
Events
The evResult event is sent to the iWebView control when the command assigned to
$execcommand finishes executing. The pResult parameter is a row variable, where column
1 contains the value of a kiWebViewStatus... constant (see below), and column 2 contains
either error information or the URL of the page that has been loaded or the result of running
the JavaScript.
The following remote form contains a iWebview control called oBrowser together with a
Searchbar and Segmented control to allow the user to view web pages within your Omnis
application.
234
Creating an Omnis iOS App
There is no specific code behind the oBrowser control, rather the code to load or search for
pages is behind the Segmented or Searchbar controls. The following code is placed in the
$event() method for the Segmented control; the method sets a row variable depending on
which segment was clicked and the contents of the row variable is assigned to the
$execcommand property of the oBrowser Webview control.
; lRow (Row var), Command (Short int), Value (Char)
On evClick
Do lRow.$define(Command,Value)
Calculate lRow.Value as ''
Switch pSegment ;; the segment clicked
Case 1 ;; Back Pressed
Calculate lRow.Command as kiWebViewCommandBack
Case 2 ;; Forward Pressed
Calculate lRow.Command as kiWebViewCommandForward
Case 3 ;; Refresh Pressed
Calculate lRow.Command as kiWebViewCommandReloadPage
Case 4 ;; Home pressed
Calculate lRow.Command as kiWebViewCommandLoadPage
Calculate lRow.Value as 'http://www.tigerlogic.com/omnis'
End Switch
Do $cinst.$objs.oBrowser.$execcommand.$assign(lRow)
Do $cinst.$redraw()
235
Chapter 4—Creating Apps using iOS Client
Configuring Xcode
Go to the Apple website and log into the iOS Developer Program
Download and install the latest Xcode with the iOS SDK (which also provides you with
the iPhone/iPad simulator)
For all builds, whatever the target, you should select “Distribution” as the “Active
Configuration” in the “Overview” droplist.
236
Testing your Omnis iOS app
Connect your iOS device to your computer via a cradle or USB cable, and let it sync
with iTunes
Locate your mobile provisioning profile and drop it onto your device in iTunes
Locate your Omnis.app which you built in the previous section, and drop it onto your
device in iTunes
Then sync your iOS device with iTunes, and your Omnis app will be installed on the
device
Your Omnis iOS app should now be installed on your device, and the app should appear in
the list of apps on your device. However, before you can use it, you must configure the app.
This allows you test your form on your local computer in the usual manner using the Test
Form option or Ctrl-T.
In the ‘IP address:Port’ field enter the IP address of the computer you are using for
development and the $serverport number of your local copy of Omnis Studio in the
format IP Address:Port, e.g: 193.456.82.311:5555
237
Chapter 4—Creating Apps using iOS Client
Note your iOS device needs to be able to connect to a wireless network that can
communicate with this IP address and port
IP address
To obtain the IP address of your development computer under OS X, open the "System
Preferences" dialog, click on "Network" under the “Internet & Network” section, then select
your network (Ethernet, AirPort, etc) and click on the TCP/IP option.
Under Windows, you can run the ipconfig command at the command prompt.
238
Testing your Omnis iOS app
being sent to the server when you pressed the home button, the app will resend it when it
comes back to the foreground.
If you are running an earlier version of iOS or if your device does not allow multi-tasking,
then pressing the home button will terminate the app.
Saved State
When you close the Omnis app on your device, as part of the terminate processing, the app
saves the exact state of the form, its controls and their data in a file on the device. At the
same time, Omnis retains the remote form instance on the Omnis Server (or in your local
copy of Omnis during development). If you then re-open the Omnis app, the form is re-
instated at the same stage as when you closed the app. This “saved state” stores the exact
state of the controls, any data you or the end user has entered, and so on, so when you
restart the client, the form appears exactly as when you closed the app. Remember that the
remote task instance on the server has timeout properties, which could mean that the server
instance has closed when the app eventually reopens.
239
Chapter 4—Creating Apps using iOS Client
240
HTML Forms and Remote Tasks
Chapter 5—Ultra-thin
Omnis
In addition to accessing the Omnis App Server via the JavaScript Client, Omnis Studio lets
you interact with your Omnis application using standard HTML forms. This approach is
often referred to as “Ultra-thin Omnis” since the client’s browser uses standard GET and
POST methods without any other client access layers.
In the Ultra-thin Omnis environment, the HTML form sends parameters and data directly to
the Omnis App Server via the Omnis web server plug-in located in the cgi-bin or scripts
folder. When the ‘Submit’ button in your HTML form is pressed, the Omnis web server
plug-in is executed and passed all the form’s parameters. The Omnis web server plug-in
sends the request to the Omnis App Server, which creates an instance of the specified
Remote Task Class and calls its $construct() method.
241
Chapter 5—Ultra-thin Omnis
242
HTML Forms and Remote Tasks
In the above example, the HTML form uses the “GET” method. You can also use the
“POST” method. The main difference lies in how the data is transmitted to the server, and
this is reflected in cases where the URL generated by the form is displayed in the location
bar of the user’s browser. A “GET” method is equivalent to requesting the URL
/cgi-bin/omnisapi.dll?OmnisClass=…&OmnisLibrary=…&…
243
Chapter 5—Ultra-thin Omnis
Secure Sockets
You can use secure sockets (HTTPS) if you have installed an SSL certificate on your web
server. Omnis will use a secure connection to connect the client to the web server if you
prefix the location of your HTML forms with “https://”. In addition, remote tasks have the
$issecure property that lets you turn secure mode on and off dynamically, by assigning to
the property for the current task at runtime.
244
Using Task Methods to Process Requests
245
Chapter 5—Ultra-thin Omnis
Do iObj.$createDownloadRecord(
lNextSeq,lCustID,lPlatformID,,,,pParams.Code,
pParams.ProductID,pParams.HowDidYouHear)
If len(pParams.Code)
; if they have entered a magazine code, they need an
; email with a serial number
; send user email with the appropriate serial number
Do iEmailObj.$sendEmail(
2,lCustID,lMagazineRow.SerialNumber,,kTrue)
; 4th parm is blank; 5th parm for using downloadcustomer table
Calculate lUrl as 'http://www.omnis.net'
Else
Do iEmailObj.$sendEmail(1,lCustID,,,kTrue)
; 3rd & 4th parm are blank; 5th parm is for using
; downloadcustomer table
Switch pParams.Platform
Case 'Win95'
Calculate lUrl as iWin95download
Break to end of switch
Case 'WinNT'
Calculate lUrl as iWinNTdownload
Break to end of switch
Case 'Ppc'
Calculate lUrl as iPpcdownload
Break to end of switch
Case 'Linux'
Calculate lUrl as iLinuxdownload
Break to end of switch
Case 'OSX'
Calculate lUrl as iMacosxdownload
Break to end of switch
Default
Calculate lUrl as iWin95download
Break to end of switch
End Switch
End If
End If
If not(lCodeFound)
Do $itasks.DOWNLOAD.$getUnsecuredUrl(lServerUrl)
; get the server path
Calculate lUrl as con(
lServerUrl,sys(9),'downloadhtml',sys(9),
lFolder,sys(9),iUrl,'.htm')
End If
246
Returning Content to the Client
If you do not prefix the URL as above, the user’s browser will be redirected to the
URL http://<web server address><url>. For example, if your web server is
www.myhost.com
Quit method “/omnishtml/00000001/myfile.html”
will result in the browser being redirected to
http://www.myhost.com/omnishtml/00000001/myfile.html
If you do generate dynamic HTML files, perhaps by printing reports to HTML, you can use
the oDirClean object to periodically check for expired files, and delete them. The HTML
report task wizard contains an example of how to do this. You should also note that if you
are generating new output for each request, you need to use a different file name or folder
for each request. The oDirClean object provides a mechanism which allows this.
247
Chapter 5—Ultra-thin Omnis
248
Returning Content to the Client
249
Chapter 5—Ultra-thin Omnis
250
Persistent Remote Tasks
that when $construct() runs, there is a column HTTP_<header name> in the row variable
parameter, and its value is the value of the HTTP header. Note that the header value can be
empty if it is either not present, or not available to the Omnis web server plug-in.
evPost events
When an HTML form request arrives at the Omnis App Server, Omnis looks for the
ConnectionID parameter. If there is none, processing proceeds in the usual manner, calling
$construct() for a new remote task instance. If there is a ConnectionID parameter, Omnis
tries to locate the existing remote task instance. If it is no longer present, Omnis returns an
error to the user. Otherwise, Omnis sends an evPost event to the $event() method of the
remote task instance.
evPost works in exactly the same way as $construct(). In other words, there is a parameter
which is a row variable containing the HTML form parameters, HTTP header processing
occurs for the parameters, and the result is one of the three alternatives allowed for the
result of $construct(). The only difference is that the parameters and return value are
handled using event parameters. Event parameter pPostData is a row variable containing the
form parameters from the client, and you use the field reference event parameter
pPostResult to return the result to the client.
After each call to evPost, Omnis calls $canclose, to see if the remote task instance can now
be closed.
251
Chapter 5—Ultra-thin Omnis
252
Direct Client Connections
253
Chapter 5—Ultra-thin Omnis
254
Localization for the JavaScript Client
Chapter 6—Localization
If you are developing applications for an international market, you may want to translate the
text and labels in your web and mobile apps into another language or support multiple
languages. You can use the String Table Editor to create an external file to store alternative
strings for the labels and text in your app to support multiple languages in your JavaScript
remote forms. The external file is stored in Tab Separated Value (TSV) format.
Note that the old way of storing string tables internally (.stb format) and handling them via
$stringtabledata and $stringtabledesignform still works with Omnis Studio 6.0 for
compatibility. This technique is described in the Omnis Programming manual.
255
Chapter 6—Localization
256
Localization for the JavaScript Client
Standalone Client
If you run your application in the Standalone client you have to set the library preference
$serverlessclientstringtable to specify which string table to use for the remote form
instances in the SCAF for the library. This takes the name of a string table (tab-separated
value .tsv file in library folder).
String table functions
The client accesses the current string table for the stgettext() function, and properties
assigned with the $st prefix. In addition, server methods can also use stgettext() to look up
strings for the client locale (either the locale received from the client, or the locale set using
$stringtablelocale). If the locale is not present in the string table, stgettext() will return
values from column 2 of the string table.
257
Chapter 6—Localization
The following strings are present in the JavaScript Client, where \x01 is a place-holder
which is replaced by parameters added to the string when it is called by the client; you
should retain \x01 in your translated text.
258
Localization for the JavaScript Client
259
Chapter 7—Deploying your Web & Mobile Apps
Chapter 7—Deploying
your Web & Mobile Apps
To deploy your Omnis web or mobile application you need to host it on the Omnis App
Server which is the main engine at the heart of your Omnis app deployment. You will also
need a Web Server to host the HTML page containing your remote form(s) and any other
web pages or content. When the end user runs your application, the app connects to the
Omnis App Server, via the web server, and the JavaScript remote forms you have designed
are loaded in the end user’s desktop browser or the browser on their mobile device. You can
deploy your JavaScript Client based application to the web or mobile devices in two ways:
Web and mobile app deployment
you can deploy your application to the web and provide your end users with a URL to
the location of the app, which they can navigate to on their desktop, tablet or mobile
device; the initial remote form is embedded into an HTML file which is created for you
during development which you will need to edit for deployment
Standalone mobile app deployment
alternatively you can compile your app into one of the Application Wrappers to provide
a single standalone app for deployment to mobile devices; in effect the wrapper points
to the HTML page containing the initial remote form for your app. A standalone app
can operate “online” with a permanent connection to the internet and the Omnis App
Server; it can also work “offline” and then reconnect to the Omnis App Server to
synchronize data and content; or a standalone app can operate entirely in “serverless”
mode without any connection to the Omnis App Server
In addition to hosting your HTML page, you need to install the Omnis Web Server plug-in
into your web server which handles all communication between the Omnis App Server and
any connected web and mobile clients.
260
Omnis Web Architecture
261
Chapter 7—Deploying your Web & Mobile Apps
262
Editing Your HTML Pages
Server. If the Omnis App Server is on the same machine as the web server, then data-
omnisserverandport can be the port number of the Omnis App Server, e.g. it could be
"5000" if the Omnis App Server is at port 5000 on the same machine as the web server. If
the Omnis App Server is on a different server from the web server, then the data-
omnisserverandport parameter must be “IP-Address:Port-number” of the Omnis App
Server, e.g. it could be "111.222.000.111:5000" if the Omnis App Server is at port 5000 on
a machine with IP address 111.222.000.111.
data-omnislibrary and data-omnisclass
The data-omnislibrary parameter identifies the library containing your remote form, and
data-omnisclass is the remote form class displayed by the omnisform object.
data-commstimeout
The data-commstimeout parameter allows you to give the end user the option to timeout a
request or carry on waiting. The default value of zero means that no timeout is applied, and
the client will continue to wait for a response. To apply a timeout, you need to enter an
integer representing the timeout in seconds. When the client sends a message to the server it
must respond within this timeout period, otherwise the user will be prompted to either
continue waiting for a response, or abort the request.
263
Chapter 7—Deploying your Web & Mobile Apps
Fav icon
The icon used for the test HTML page (displayed in the top-left of the browser tab) is the
image file called 'favicon.ico' located in the html/images folder. The image file in the
development version of Omnis is the Omnis logo, but for deployment you can replace this
image with your own icon file.
264
Setting up the Omnis App Server
GIF which is in a DIV laid over the main JavaScript Client area. You can restyle the
working message overlay DIV by adding your own class in the ‘user.css’. The default style
for the working message is in the omnis.css style sheet:
#omnis_overlay {
background:url('images/xajax-loader.gif') 20px 20px no-repeat;
}
But you can override this in user.css, for example:
#omnis_overlay {
background-position:center;
}
Which will center the working image, and/or you could also add your own animated GIF.
Server Licensing
You can download the Omnis App Server installer from the Omnis website at:
www.tigerlogic.com/omnis. Having installed the Omnis App Server you will need to
serialize it according to the number and type of clients you expect to serve. There are a
number of different server deployment licenses for running web and mobile apps in the
JavaScript Client. Please refer to www.tigerlogic.com/omnis, or contact your local sales
265
Chapter 7—Deploying your Web & Mobile Apps
office for details about these Omnis App Server deployment licenses. In addition, you will
need to purchase a different development license and deployment server license to create
and deploy standalone mobile apps running in serverless client mode.
Server Activation
When you serialize the Omnis App Server, it will attempt to automatically activate, which
requires the server to be connected to the Internet for activation to occur. If activation is
successful following this process your server will be licensed and ready for use. Without
activation, the Omnis App Server will not run.
To allow you to switch your Omnis App Server activated license to another system, you can
deactivate your server using the Deactivate option in the Tools menu. Having deactivated
your server, you can install and serialize the server on a new system. Contact your local
sales office for further information about activation, or see the Activation FAQ on the
Omnis website.
266
Setting up the Omnis App Server
The Omnis App Server port number is stored in the Omnis.cfg file in the ‘Studio’ folder
under the main Omnis folder.
Server Multi-threading
The Omnis App Server allows multiple requests to be processed concurrently, allowing
smoother allocation of available processor time and avoiding any lengthy delays on the
client. To handle these multiple requests, the Omnis App Server is multi-threaded. By
default, the Omnis App Server is a standard single-threaded server handling client requests
in a strictly first-come, first-serve basis; client requests are queued, with each request being
handled only when the previous request has completed. You can however handle multiple
client requests concurrently using the Omnis Multi-threaded Server, which you can enable
by executing the Start server command on the Omnis App Server: see below.
The Multi-threaded Server maintains a pool of method stacks that can process web and
mobile client requests simultaneously. The pooling mechanism allows a balance to be struck
between performance and server resources - the number of method stacks in the pool is
configurable with the $root.$prefs.$serverstacks property, and also available in the Omnis
App Server Configuration dialog.
Multiple Method Stacks
The standard single-threaded Omnis App Server has only a single method stack to process
methods. Broadly speaking, once a method call has been pushed onto the method stack no
other method call can begin to execute until the first call has completed. For the majority of
web and mobile client applications this is fine for processing events, particularly if some
processing is performed on the client and your web server receives relatively few hits or
requests for data. By contrast, the Omnis Multi-threaded Server contains a pool of method
stacks which are available to process multiple client requests, and this is appropriate for
more data intensive web applications where lengthy calls to a server database are required,
or for web sites that receive higher volumes of traffic. When a request to execute a method
is received from a web or mobile client, that method call is pushed onto any unused stack
or, if there are no unused stacks, the message is queued until one becomes available. Each
method stack runs in its own thread, which means that if a method stack is stalled (for
example, it is waiting for the database server) the other stacks will continue to execute.
Potentially, the Multi-threaded Server may have to cope with a very large number of
simultaneous clients, each with their own remote form and remote task instances. Typically
though, a small proportion of clients will require the use of the server at any one time. In
fact, multi-threading does not increase the server processor time available, it just allows the
available processor time to be allocated in a smoother way. The method stack pool
mechanism allows a balance to be struck between performance and server resources - the
number of method stacks in the pool is configurable with the $root.$prefs.$serverstacks
property, which is set to 5 by default.
As method stacks are allocated dynamically, it is very likely that a remote client will not get
the same method stack every time it executes a method on the server. Each method stack
267
Chapter 7—Deploying your Web & Mobile Apps
contains its own state which, apart from during an individual method call, does not belong
to any particular client. This state includes the Current Record Buffers (CRBs) for all files
and variables (apart from class variables) and such modes as the current list. A client cannot
rely on any properties or values of this state being preserved across different method calls.
The only things belonging to the client are its instance and task variables. So a client must
do such things as setting the main file and current list each time one of its methods is
executed, and should not rely on such things as the values of memory-only fields being
maintained across method calls. As a special case, the class variables for the remote task
and remote form classes are shared amongst all clients so can be used to hold shared data
(see below for the warnings about the care needed when using shared variables).
Database Access
If you are accessing a server database in your web application, and using the Multi-threaded
Server, you must use the Object DAMs (introduced in Omnis Studio 3.0) which are capable
of multi-threading. Using the Object DAMs, you can connect directly to Oracle, MySQL,
PostgreSQL, DB2, and Sybase, as well as most ODBC- and JDBC-compliant databases
such as MS SQL Server.
268
Setting up the Omnis App Server
The Object DAMs are implemented as external components and use object variables based
on the Object DAMs, and interact with a DAM using the methods of the object. Using this
approach, you create object variables of a particular DAM class. There is a group of
common methods that apply to all DAM objects and a set of DAM specific methods based
on the type of object. Various chapters in the Omnis Programming manual provide more
information about accessing your data using the DAMs.
Start server
The Start server command is used to create the client method stacks and associated threads.
It takes an optional stack initialization method as a parameter. The command clears the flag
if it is used in a copy of Omnis which is not capable of supporting multi-threading or your
serial number does not allow clients to connect. A fatal error is generated if for some other
reason it is not possible to create the stacks and threads.
Stop server
The Stop server command stops the server from responding to client requests. Once the
server has been started you should stop it before quitting Omnis, before using Omnis for
anything apart from serving client requests (e.g. running a standard LAN-based Omnis
application), or before opening or closing any Omnis data files or libraries.
The Stop server command disposes of all remote task and form instances. The resources
used by the client stacks and threads are not released, but they will be reused by the next
Start server command.
Begin and End critical block
These commands are used to denote a section of code which needs to execute in single
threaded mode without allowing other client methods to execute. For example:
Set current list cList
Begin critical block
Build list from file
End critical block
Here cList is a class variable which is shared amongst the clients and the critical block is
used to prevent other clients from accessing the list whilst it is being built. Generally class
variables should only be used when the shared functionality is essential and only with care:
Calculate cString as 'abc' ;; OK
Calculate cString as $cinst.$xyz()
; only OK inside a critical block
269
Chapter 7—Deploying your Web & Mobile Apps
Simple atomic operations such as the first line of the above example are safe, but when a
method call is involved it may be interrupted by other threads and cause problems. Class
variables should not be used as bind variables or as the return list for SQL operations.
Yield to other threads
The Yield to other threads command is a hint that the executing thread is waiting for other
threads and is prepared to yield its processor time. It can be used when waiting for
semaphores (since with the Multi-threaded Server another client stack could be holding the
semaphore), as follows:
Do not wait for semaphores
Repeat
Prepare for edit
If flag true
Break to end of loop
End If
Yield to other threads
Until break
270
Setting up the Omnis App Server
N current users. If you are using SQL, you need a potentially large number of sessions to
the database server. There is nothing wrong with this in itself, and there are occasions when
you might want to use database access permissions, to control the tables and columns
accessible to different users. If this is the case, you require a separate session for each user.
However, if all users have the same access permissions, you really only need N SQL
sessions. This can significantly reduce the resource usage of the server. SQL Session Pools
provide a way to do this.
A SQL Session Pool is a set of multi-threaded DAM sessions, which can be shared by
clients. Typically, you would create a session pool with one session for each method stack.
Details of how to use SQL Session Pools can be found in the Methods chapter of the
manual Omnis Studio Reference.
271
Chapter 7—Deploying your Web & Mobile Apps
mobile client connections currently in use (using the serial number as the maximum), and
information about how much time the server has spent processing requests. The load sharing
process combines this information to determine which process is the least busy.
You can configure the time interval between polls of each Omnis App Server process via
the .ini file. Once every 10 or 20 seconds is usually frequent enough.
Enabling Load Sharing
To enable the load sharing process you need place the LSP program on your web server, or
a machine connected to your web server. It is a single executable called Omnislsp.exe
(Windows) or omnislsp (Linux and Mac OS X). A configuration file (omnislsp.ini) must be
made to accompany the Omnislsp program, and this takes the following format:
[Setup]
Port=6001
QuietMode=0
BucketSize=100
LogLineThreshold=16
Pool1=Omnis
[Omnis]
PollTimer=10
Server1=123.145.71.123:7001
Server2=123.145.71.124:7002
The commands for the lsp are: omnislsp -start
omnislsp -stop
(with the omnislsp.ini in the same directory as the program)
The Port entry in the .ini file identifies the TCP/IP port number on which the LSP listens for
requests from the Omnis web server plug-in.
The QuietMode entry in the .ini file indicates if the LSP generates OK messages, or
messages to the console, to report its status. When set to zero, it will generate messages.
When set to one, it will not.
The LogLineThreshold entry in the .ini file indicates when the text log generated by the LSP
will be reduced in size. If the LSP writes a line to the log, and the file contains
LogLineThreshold lines, it will reduce the file size to LogLineThreshold/2 lines,
maintaining the most recently written lines, before writing the line to the log. The log is in
the same directory as the omnislsp program.
The BucketSize entry specifies how the LSP breaks up the server processes into groups,
based on how busy they are. It is a value in milliseconds. The LSP divides the processes
into 10 buckets, based on the average time to process a request obtained from the
information it gathers by polling the server processes periodically. The buckets are
numbered 1-10, where 1 contains the least busy servers, and 10 the most busy servers. A
272
Setting up the Omnis App Server
server is in the smallest numbered bucket, for which its average time to process a request is
less than or equal to (bucket number)*BucketSize. If a server is so busy that this calculation
does not allocate it to a bucket, it belongs to bucket 10. You may need to experiment with
possible settings for BucketSize, in order to determine the optimum setting for your
application.
Each pool has its own section in the .ini file. The PollTimer entry indicates the frequency in
seconds at which the LSP polls the server processes in the pool for information. The
ServerN entries identify the TCP/IP address and port of each server process in the pool.
You also need to edit the 'data-omnisserverandport' parameter in your HTML file
containing the JavaScript Client plug-in, for example:
data-omnisserverandport="Omnis,6001" or
data-omnisserverandport="Omnis,123.456.789.010:6001"
where Omnis is the name of a pool of Omnis App Server processes and 6001 is the port
number of the LSP.
On the LSP servers
The Omnis App Servers may be stopped and restarted without the need to stop the LSP.
Load Sharing Mechanism
The load sharing process periodically polls the processes in a pool of Omnis App Server
processes. Each server returns the current number of connections to the server, the
maximum number of concurrent connections allowed to the server (specified by the serial
number), the number of requests since the last poll, and the total elapsed time in
milliseconds taken to process the requests. The load sharing process organizes the servers
into buckets, based on the results of the information returned from polling the servers.
When a connection request arrives at the load sharing process, it allocates a server to the
request as follows. It traverses the buckets, starting with that for the least busy servers,
looking for a server that has some free connections. Within a bucket, it looks for the server
with the smallest percentage of connections in use, using the results of the last poll. If there
is more than one server with the same smallest percentage of connections in use, the process
allocates the connection to the server to which it least recently allocated a connection. At
this point, the load sharing process also updates the connection statistics from the last poll,
to reflect the new connection. The traversal stops when a free process has been found. If all
servers are fully utilized, the LSP allocates the connection to a server at random; in this
case, it is likely that the server will reject the request, and return a suitable error to the
client.
273
Chapter 7—Deploying your Web & Mobile Apps
The startup-type for the new service is set to “Automatic” and the service uses the omnislsp
executable and .ini file at their current locations. When omnislsp runs as a service, dialog
boxes are disabled and messages are written to the application event log instead.
Socket Binding
For the development version, Omnis will retry the bind 5 times, once a second, and then
report an error via the trace log; this behavior is the same as previous versions. The Omnis
App Server will retry indefinitely once a second.
When running as a Service, after a few bind attempts, Omnis outputs a message to the
system event log (if the event log is being used for Studio), “Failed to bind web client
socket - will retry indefinitely”. If the bind is eventually successful, Omnis outputs a second
message, “Successful bind of web client socket”.
Note that you can stop the service while the indefinite retries are occurring, but you cannot
use the tray to bring Omnis to the front (or do anything else with the Studio service) as the
web client bind occurs quite early in the initialization of Studio.
The Omnis App Server displays a working message while the retries are occurring; this
allows the end-user to cancel the retry loop.
274
Setting Up Your Web Server
Two versions of the Apache web server plug-in are provided in the clientserver\server
folder, under the main Omnis folder, to support Version 2 and Version 2.2 Apache web
servers.
To install the Apache module
Copy mod_omnis.so to the Apache modules directory, e.g. on RedHat 9.x this is
/etc/httpd/modules
Add the following lines to httpd.conf, at the end of each block of similar directives:
LoadModule omnis_module modules/mod_omnis.so
AddModule mod_omnis.cpp
You need to restart httpd (restarting the system is the simplest way to do this). After
installing the Apache module, you can address it using /omnis_apache in the data-
webserverurl parameter in the JavaScript Client object.
Installing the Java Servlet
Omnis Studio includes a Java Servlet web server plug-in that allows you to run your Omnis
web applications with any web server that supports version 2.3 of the Servlet API. Web
servers that comply with Java Servlet API 2.3 include the Apache TomCat and Jetty web
servers, but there are several others. For more information about Java Servlets, see:
http://www.oracle.com/technetwork/java
The Java Servlet allows Omnis remote forms to connect to an Omnis App Server via a Java
web server. In this respect, the Servlet is the Java equivalent of the ISAPI, CGI or the
regular Apache plug-in available in Omnis Studio.
The Java Servlet is called RdtaServlet and can be found in the Omnis Studio installed tree
in the clientserver\server\omnisservlet folder. Inside the Servlet folder, the servlet files are
in the following folder structure:
275
Chapter 7—Deploying your Web & Mobile Apps
servlet
|
- WEB-INF
|
- rdtaserv.dll (Platform dependant)
|
- web.xml
|
- classes
|
- com
|
- rdta
|
- RdtaServ.class
To install the servlet on your web server, such as the Apache Tomcat server, you should
place the whole servlet folder in the Webapps folder within the Tomcat installation. If you
wish, you can rename the servlet folder.
You will need to restart the webserver in order for the servlet to be loaded.
Web server parameters for the Java Servlet
The data-webserverurl parameter in your HTML containing your remote form must have the
correct format to access a web server with the Java Servlet.
data-webserverurl
this must be the URL to the tomcat webserver appended with the name and path of the
servlet, such as "http://www.mydomain.com/servlet/%servletname%"
Note if you have renamed the servlet folder you should use the new name in the data-
webserverurl parameter instead of ‘servlet’;
The default value for %servletname% is 'rdtaservlet'. You can modify this or add others by
modifying the web.xml file. The following xml can be added to the <web-app> element in
the document to add a new servlet alias name. For example
<servlet-mapping>
<servlet-name>RdtaServ</servlet-name>
<url-pattern>/%servletname%</url-pattern>
</servlet-mapping>
276
Setting Up Your Web Server
direct connection to the Internet. Your ISP may want to test the web server plug-in, usually
the case for any files you place in their cgi-bin folder.
If your Omnis web application uses a web site hosted by an ISP you will need to adjust your
port settings in the Omnis App Server and HTML files. In this case you can use
DomainName:Port or IPAddress:Port in your port setting.
Secure Sockets
You can use secure sockets (HTTPS) if you have installed an SSL certificate on your web
server. The JavaScript Client will use a secure connection to connect the client to the web
server if you prefix the URL or IP_address in the data-webserverurl parameter with
“https://”, for example:
https://remainderOfFullURL
In addition, remote tasks have the $issecure property that lets you turn secure mode on and
off dynamically, by assigning to the property at runtime in your application.
Secure socket connections do not support the "address:port" format for the data-
webserverurl parameter of a JavaScript Client object.
277
Chapter 7—Deploying your Web & Mobile Apps
mod_omnis.so
If you are using mod_omnis.so under Linux or Windows, you need to change the value of
the location in your http.conf or equivalent apache configuration script to /omnis_apacheini,
for example:
<location /omnis_apacheini>
SetHandler omnis-apache
</location>
nph-omniscgi
Rename the nph-omniscgi.exe to nph-omniscgiini.exe for Windows, or rename nph-
omniscgi to nph-omniscgiini for Linux.
omnisapi.dll
For Windows IIS based servers, rename omnisapi.dll to omnisapiini.dll.
rdtaserv.dll
If you are using the Web Services enabled Web Server plug-in, rename rdtaserver.dll to
rdtaserverini.dll.
Creating a Configuration file
The configuration file should be named omnissrv.ini and be placed in the same directory as
your Web Server plug-in, for both Windows and Linux.
The format of the configuration file mirrors that of a Windows .ini file and is defined as
follows:
Section names are contained in square brackets e.g. [SectionName].
A section ends when another section begins or at End Of File (EOF).
Comments are lines beginning with a semicolon (‘;’).
All text following a comment is ignored until the line is terminated.
Keys are of the form keyname=value where keyname is a unique identifier within the
section and value is the value of the specified key.
Section names, key names and key values must not contain white space.
Section names and key names are case sensitive.
The new functionality in the Web Server plug-in is controlled using specific named sections
in the configuration file. The omnissrv.ini file can contain the AllowConnectionsTo section
which controls access to the Omnis App Server. The .ini file can also include either a
DefaultConnection or OverrideConnection section (but not both), which either provide
default parameters for the Omnis App Server or override parameters posted to the Omnis
App Server from the http web server.
278
Setting Up Your Web Server
279
Chapter 7—Deploying your Web & Mobile Apps
thing to note, if the parameter is present in the original request and the configuration file
also contains a definition for the parameter, the value is always taken from the request even
if the parameter has no associated value. For example:
[DefaultConnection]
OmnisServer=192.168.0.1:5920
OmnisClass=remoteTask
OmnisLibrary=TEST
param1=value1
param2=value2
PostDataParamName=PostData
In the context of the above DefaultConnection section, consider the following URL which
attempts to connect to Omnis:
/omnis_apacheini?OmnisClass=remoteTask¶m1=1234
The OmnisClass and param1 values are taken from the URL while the other values are
taken from the DefaultConnection section. In this case, no OmnisServer and OmnisLibrary
parameters are provided in the query string, so those values are taken from the configuration
file. Therefore the plug-in will amend the query string to:
/omnis_apacheini?OmnisClass=remoteTask&OmnisServer=192.168.0.1:5920&
OmnisLibrary=TEST¶m1=1234¶m2=value2&PostData=
Note PostData is empty as the content-type is application/x-www-form-urlencoded, so in
this case the data is not passed to Omnis.
Overriding Connections
You can override the server parameters passed to the Omnis App Server by an HTTP post
by including a [OverrideConnection] section in your configuration file. In this case, all the
values in the request are ignored, and the Omnis App Server uses values from the
configuration file. The OverrideConnection section may contain the following keys with
associated values:
OmnisServer
OmnisClass
OmnisLibrary
PostDataParamName
Any number of additional Parameter Name=value
These keys function exactly as described in the DefaultConnection section. An example
OverrideConnection section is as follows:
280
Setting Up Your Web Server
[OverrideConnection]
OmnisServer=192.168.0.1:5920
OmnisClass=rtTest
OmnisLibrary=TEST
param1=value1
param2=value2
PostDataParamName=PostData
In the context of the above OverrideConnection section, consider the following URL which
attempts to connect to Omnis:
/omnis_apacheini?OmnisClass=remoteTask¶m1=1234
In this case, the values in OmnisClass and param1 submitted in the post are ignored, and all
the values for the post are taken from the DefaultConnection section in the configuration
file. Therefore the query string is amended to:
/omnis_apacheini?OmnisClass=rtTest&OmnisServer=192.168.0.1:5920&
OmnisLibrary=TEST¶m1=value1¶m2=value2&PostData=
Note PostData is empty as the content-type is application/x-www-form-urlencoded, so in
this case the data is not passed to Omnis.
281
Chapter 7—Deploying your Web & Mobile Apps
282
Creating Standalone Mobile Apps
content via the Omnis App Server; this mode would suit end users who have an
intermittent connection, but often need to synchronize their data with a central location
<MenuIncludeSettings>1</MenuIncludeSettings>
<MenuIncludeOffline>1</MenuIncludeOffline>
<MenuIncludeAbout>1</MenuIncludeAbout>
<SettingsFloatControls>0</SettingsFloatControls
<SettingsScaleForm>1</SettingsScaleForm
<SettingsAllowHScroll>0</SettingsAllowHScroll>
283
Chapter 7—Deploying your Web & Mobile Apps
<SettingsAllowVScroll>0</SettingsAllowVScroll>
<SettingsMaintainAspectRatio>0</SettingsMaintainAspectRatio>
<SettingsOnlineMode>1</SettingsOnlineMode>
<ServerOmnisWebUrl>http://172.19.250.25:5911</ServerOmnisWebUrl>
<ServerOnlineFormName>/jschtml/rfOnline</ServerOnlineFormName>
<ServerOmnisServer></ServerOmnisServer>
<ServerOmnisPlugin></ServerOmnisPlugin>
<ServerOfflineFormName>rfOffline</ServerOfflineFormName>
<ServerAppScafName>mylib</ServerAppScafName>
<TestModeEnabled>0</TestModeEnabled>
<TestModeServerAndPort>172.19.250.25:5911</TestModeServerAndPort>
</settings>
The config.xml contains the following properties (note that some may not be included on a
particular platform):
AppTitle
whether or not the app displays a title bar at the top. Note that hiding the title on
Android 3 will hide the ActionBar which will remove access the testing menu
AppStandardMenu
whether or not the standard menu is displayed at the top.
AppTimeout
the time in milliseconds after which the app will close after being sent to the
background.
For all platforms:
MenuIncludeSettings
whether the “Settings” menu option is available in the app.
MenuIncludeOffline
whether the runtime menu option is available to switch to offline mode.
MenuIncludeAbout
whether the “About” menu option is available in the app.
The following settings control the scaling of the app (remote form) on the device:
SettingsFloatControls
This property is only significant when SettingsScaleForm is "0" (false). In this case, the
client uses the new $screensizefloat property of each JavaScript Client control on the
form. When applying the screen size, the client uses $screensizefloat to float the edges
of controls using the same rules as $edgefloat (note that the component values are not
supported, just the edge-related values). If the form is wider or taller than the screen,
floating only occurs if the relevant SettingsAllowHScroll or SettingsAllowVScroll
284
Creating Standalone Mobile Apps
parameter is false. The amount by which the controls float is the difference between the
actual screen width or height and the designed width or height of the form for the
closest matching $screensize. The value of $screensizefloat is stored for each setting of
$screensize in the remote form
SettingsScaleForm
If you set this to "1" (true), the client scales the form to fit the available screen space.
The scaling factor is the screen width or height divided by the width or height of the
closest matching $screensize. For these purposes, the actual screen size excludes the
operating system areas such as the status bar
SettingsAllowHScroll and SettingsAllowVScroll
set these to "1" if you want to allow horizontal or vertical scrolling of the form
respectively, or "0" if not
SettingsMaintainAspectRatio
If you set this to "1", scaling maintains the aspect ratio of the form. When turned on,
and depending on SettingsAllowHScroll and SettingsAllowVScroll, it may reduce the
scaling factor in one direction, to make the form fit, and center the form vertically or
horizontally as required
SettingsOnlineMode
whether the app starts in Online mode.
The following settings relate to the Omnis App Server:
ServerOmnisWebUrl
URL to the Omnis or Web Server. If using the Omnis Server it should be
http://<ipaddress>:<omnis port>. If using a web server it should be a URL to the root
of your Web server. http://myserver.com
ServerOnlineFormName
route to the form’s .htm file from ServerOmnisWebUrl. So if you’re using the built in
Omnis server, it will be of the form /jschtml/myform.htm. If you are using a web server,
it will be the remainder of the URL to get to the form, e.g. /omnisapps/myform. (Do not
add the .htm extension!)
Only ServerOmnisWebUrl & ServerOnlineFormName are needed for Online forms. The
other Server… properties are for Offline mode.
ServerOmnisServer
The Omnis Server <IP Address>:<Port>.
ServerOmnisPlugin
If you are using a web server plugin to talk to Omnis, the route to this from
ServerOmnisWebUrl. E.g. /cgi-bin/omnisapi.dll
ServerOfflineFormName
Name of the offline form. (Do not add .htm extension!)
285
Chapter 7—Deploying your Web & Mobile Apps
ServerAppScafName
Name of the App Scaf. This will be the same as your library name.
The remaining parameters refer to test mode.
TestModeEnabled
whether the app will start in test mode (Ctrl-M on form from Studio to test on device)
TestModeServerAndPort
the <ipaddress>:<port> of the Omnis Studio Dev version you wish to use test mode
with.
You can also change these parameters by pressing the menu button on the mobile device,
and using the menu options to change them. The app remembers the last setting made via
the menu, so the config.xml lets you set the initial values in the wrapper application.
286
The JavaScript Serverless Client
The client-side database can be SQLite and the synchronization of the local database with a
“consolidated database” administered by the SQLite Synchronization Server provided by
TigerLogic. Alternatively, you can use an UltraLite database from Sybase on the client and
a MobiLink server to synchronize the data on the backend.
287
Chapter 7—Deploying your Web & Mobile Apps
You can download the ‘SQLite Synchronization Server’ manual from the Omnis website:
www.tigerlogic.com/omnis/download
288
The JavaScript Serverless Client
device and used in the wrapper. Note that bundling SCAF files with the application will
increase the size of the application bundle.
If SCAF files are not distributed with the application the application will attempt to connect
to the Omnis App Server on startup and download the latest versions of the SCAF files.
For the application to know which application SCAF to use the option:
<APPSCAF>name</APPSCAF> (where name is the name of the Omnis library)
is used in the config.xml file within the wrapper application.
The wrapper configuration sub menu “Update Omnis Software Package” contains options
for updating the SCAF files. The available options are:
Never
the SCAF will never be updated
Always On Startup
will attempt to connect to the Omnis App Server and update the SCAF files every time
the application is run
Next Startup Only
will attempt this update only on the next execution of the wrapper application
It is also possible for the end-user to update the SCAF from inside the app by swiping down
the screen to open the runtime menu and selecting the appropriate menu item.
289
Chapter 7—Deploying your Web & Mobile Apps
Database Support
The JavaScript wrapper application contains embedded support for SQLite (or UltraLite
from Sybase) and provides client-executed methods with access to a local private SQL
database. The database can currently only be used by Serverless Client applications in
offline mode, inside the wrapper application on Android, iOS, and BlackBerry.
All interactions between the JavaScript Client and the wrapper will be asynchronous, so the
database API also takes this into account.
Data Types
When creating rows to be used for bind variables, it is important that the data types of the
columns in the row match those in the database.
Client methods only provide a ‘var’ data type when creating variables, which will generally
be interpreted as Character type. As such, it is safest to manually add columns to your row,
using the function:
Do lRow.$cols.$add(<name>,<data type>,<data subtype>,[<length>])
e.g.:
Do lRow.$cols.$add(‘Age’,kInteger,kShortint)
For example:
Calculate oVar as $cinst.$sqlobject
All requests to the SQL object are asynchronous (except $getlasterrortext and
$getlasterrorcode), and call a client-executed completion method ($sqldone) in the current
remote form instance upon completion. Each request returns an identifier when called and
the same identifier is passed as a parameter to the completion method, allowing the request
290
The JavaScript Serverless Client
291
Chapter 7—Deploying your Web & Mobile Apps
Example1:
Do iList.$definefromsqlclass(‘myQuery’)
Do oSQL.$selectfetch($clib.$queries.myQuery.$select, iList, 100)
Returns id
Example2:
Do oSQL.$selectfetch(‘select * from Table1 where age=@[age]’,
lBindVars,100) Returns id
$fetch()
Do oSQL.$fetch(selectfetchid, iFetchCap) Returns id
Fetches more rows from the result set generated by a $selectfetch()
selectfetchid is id returned by $selectfetch().
iFetchCap is the number of rows to fetch.
In this case, the returned id will be the same. On completion, $sqldone() is called with the
following parameters:
The request id (as returned by $selectfetch)
A list containing zero or more further rows from the result set.
$insert()
Do oSQL.$insert(cSQL, listorrow) Returns id
Inserts one or more rows into a database table.
cSQL is the insert statement. This may be hand-coded, or the result of $insert for a
schema class. cSQL can contain bind variable place-holders in the form
@[$column_name], where column_name is the name of a column in listorrow.
listorrow is the list or row containing the data to insert.
On completion, $sqldone() is called with the following parameters:
The request id (as returned from $insert()).
Example:
Do oSql.$insert("INSERT INTO Product (name, quantity) VALUES
(@[colName],@[colQuant])",lBindVars) Returns IDinsert
$delete()
Do oSQL.$delete(cSQL, row) Returns id
Deletes zero or more rows from a database table.
cSQL is the delete statement. This may be hand-coded, or the result of $delete() for a
schema class. cSQL can contain bind variable place-holders in the form
@[column_name], where column_name is the name of a column in row.
292
The JavaScript Serverless Client
293
Chapter 7—Deploying your Web & Mobile Apps
$selectcolumns()
Do oSQL.$selectcolumns(tableName) Returns id
Retrieves column names and type information for the specified table.
On completion, $sqldone() is called with the following parameters:
The request id (as returned from $selectcolumns ()).
A list describing the table column definitions, defined with the following columns:
ColumnName - name of the table column.
SqlType - name corresponding to the column’s SQL data type.
ColumnSize - the size of a variable-length data type, e.g. for CHAR and BINARY.
Precision - the numeric precision for a NUMERIC column. Zero for others.
Scale - the numeric scale for a NUMERIC column. Zero for others.
Default - the default value that was assigned to the column when the table was created.
$selectindexes()
Do oSQL.$selectindexes(tableName) Returns id
Retrieves column index information for the specified table.
On completion, $sqldone() is called with the following parameters:
The request id (as returned from $selectindexes ()).
A list describing the table column definitions, defined with the following columns:
IndexName - name of the index.
ColumnNames - comma-separated list of column names used by the index.
PrimaryKey - kTrue if the index was created with the PRIMARY KEY clause.
Unique - kTrue if the index was created with the UNIQUE clause.
Database Synchronization
The SQL object provides two further methods that facilitate dynamic synchronization with a
third-party synchronization server. The embedded UltraLite database requires connection to
a Sybase Mobilink server. This is installed as part of SQLAnywhere 12.01
Please refer to the Mobilink User Guide
(http://download.sybase.com/pdfdocs/awg0901e/dbmlen9.pdf) for guidance on:
Setting-up the MobiLink Synchronization server.
Configuring MobiLink users, tables and scripts.
Creating a Consolidated Database and Installing Mobilink system tables.
The user guide also provides a useful first-steps tutorial that should prove useful. As a
quick-start guide, following lessons 1-5 in the following tutorial should get you to a point at
which you can test synchronization with the wrapper:
http://dcx.sybase.com/1201/en/mlstart/ml-sc-tutorial.html
294
The JavaScript Serverless Client
$syncinit()
Do oSQL.$syncinit(syncParams) Returns id
Initializes synchronization with the (MobiLink) synchronization server. Synchronization
parameters are implementation-specific and supplied via a row variable. If synchronization
initialization is successful, an initial ‘sync’ is also performed. See $sync() for details.
The UltraLite module currently recognizes the following parameters:
Username – MobiLink synchronization user name.
Password – MobiLink synchronization user password, if required.
NewPassword – Allows the MobiLink user to change password to NewPassword, if
supplied.
Version – Determines which script version to use for various synchronization actions.
Stream – Determines the network protocol to be used, e.g. tcpip
StreamParams – Allows protocol-specific connection parameters to be supplied, e.g. host
Publications – Lists the MobiLink publications to which the user is subscribed.
AdditionalParams – A string of name=value; pairs specifying any additional parameters.
Ping – If present, confirms communication with the Mobilink Server only. No
synchronization occurs.
UploadOnly – If present, no changes are downloaded from the CDB, only uploads are
processed.
DownloadOnly – If present, no changes are uploaded to the CDB, only downloads are
received.
ResumePartialDownload – If present, UltraLite resumes a failed download only. No
upload occurs.
On completion, $sqldone() is called with the following parameters:
The request id (as returned from $syncinit ()).
Example:
Calculate config as row(Username,Version,Stream,StreamParams)
//define using local variables
Do
config.$assigncols(‘ml_sales2’,’default’,’tcpip’,’host=192.168.0.
10’)
Do oSQL.$syncinit(config) Returns id
$sync()
Do oSQL.$sync() Returns id
Once synchronization has been initialized using $syncinit(), $sync() performs ad-hoc
synchronization between the (UltraLite) database and the (MobiLink) synchronization
server. If it is required to modify the synchronization parameters, $syncinit() may be called
instead since this also performs synchronization on successful initialization.
On completion, $sqldone() is called with the following parameters:
295
Chapter 7—Deploying your Web & Mobile Apps
$syncinit()
Do oSQL.$syncinit(syncParams) Returns id
The SQLite module currently recognizes the following parameters:
Username – The synchronization user name (defined at the synchronization server).
Password – The synchronization user password (defined at the synchronization server).
HostString – Omnis Web-thin Client URL to the SQLite Synchronization Server.
Timeout – The timeout in seconds for synchronization operations.
On completion, $sqldone() is called with the following parameters:
The request id (as returned from $syncinit ()).
Example:
Do config.$define(Username, Password, HostString, Timeout)
;;define using local variables
Do config.$assigncols(
‘user1’,’xxxxxx’,’http://192.168.0.10:7001/ultra?
OmnisClass=rtSync&OmnisLibrary=SyncServer’, 5)
Do oSQL.$syncinit(config) Returns id
Please refer to the ‘SQLite Synchronization Server’ manual for information on the design,
implementation and usage of the synchronization server. You can download this manual
from the Omnis website (www.tigerlogic.com/omnis).
296
The JavaScript Serverless Client
No Database Support
If the remote client application does not require database support, the application can
instead be linked with the dbNoSQL library. This library provides stub definitions for the
database API calls required by the wrapper application. Note that in this mode however, any
calls to the SQL object will fail.
297
Chapter 7—Deploying your Web & Mobile Apps
UltraLite
Please note that, due to licensing restrictions, we are unable to ship the libulrt.a file, on
which the UltraLite target depends. As such, if you wish to build the UltraLite version of the
wrapper, you will first have to compile this file yourself.
In order to do this, you should install SQLAnywhere12. In the SQLAnywhere12
installation’s ultralite/iphone directory you will find the source code etc, and a readme file
which should guide you through the build process (Please note that we offer no support for
the compilation of this file).
Once you have built the libulrt.a (for device or simulator), you should drop it into the
appropriate folder (-iphoneos or –iphonesimulator) in the wrapper project’s dbInterface
directory. The project should now build successfully.
298
Index
Index
#ERRCODE, 83 $commandid, 86
#ERRTEXT, 83 $commitanimations, 67, 98
#F, 77 $communicationaddress, 138
#ICONS, 164 $communicationdata, 138
$action, 138 $connectbytessent, 60
File control, 148 $connectionid, 61, 251
$activitystyle, 120 $connectiontime, 61
$add $construct, 99, 154
Remote forms, 69 For complex grids, 128
$addcolorcss, 131 iOS forms, 190
$addcols(), 155 Parameters, 263
$alpha, 66 Row variable, 57
$alwaysenabledobject, 166 Subforms, 172
$animation, 121 Tasks, 57
$apikey, 158 Ultra-thin Omnis, 244
$attr, 121 $construct()
$autoscroll, 114 Remote tasks, 247
$backalpha, 66 $contact... properties, 143
$backcolor, 66 $container, 173
$backpattern, 66 $contenttip, 126, 147
$barcodeimage, 138 $contextmenu, 86
$barends, 122 $cssclassname, 115
$baseedgewidth, 175 $ctask
$beginanimations, 67, 98 Remote forms, 70
$borderradius, 114, 146 $ctrlname, 150
$buttonbackiconid, 124 $currentcolumn, 130
$cancelkeyobject, 66 $currentnodeident, 181
$canclose, 251 $currentpage, 163, 164
$changeform, 59 $currenttab, 174, 175
$chartdirection, 122 $customlink, 120
$classname, 171 $datamode, 177, 178
$client, 184 $dataname
$clientaddress, 61 Components, 110
$clientcommand, 67, 70, 104 Droplists, 145
Subform sets, 87 Edit control, 146
$colenabled, 165 File control, 148
$coltext, 165 For charts, 123
$columncount, 167 For check boxes, 125
$columndatacol, 130 For combo boxes, 126
$columnmode, 131, 132 For complex grids, 128
$columnnames, 130 For data grids, 130
$columnnumberformat, 132 Hyperlinks control, 153
$columnpicklist, 131 Lists, 154
$columnwidths, 130 Page pane, 164
299
Index
300
Index
301
Index
302
Index
303
Index
304
Index
305
Index
306
Index
307
Index
308