Openedge Development Mobile Applications Product - 59edeacf1723ddc769c559a4

Download as pdf or txt
Download as pdf or txt
You are on page 1of 262

® ®

PROGRESS
®

OPENEDGE
®

OpenEdge Development:
®

Mobile Applications
© 2013 Progress Software Corporation and/or its subsidiaries or affiliates. All rights reserved.

These materials and all Progress® software products are copyrighted and all rights are reserved by Progress Software Corporation. The
information in these materials is subject to change without notice, and Progress Software Corporation assumes no responsibility for any errors
that may appear therein. The references in these materials to specific platforms supported are subject to change.

Actional, Apama, Artix, Business Empowerment, Business Making Progress, Corticon, Corticon (and design), DataDirect (and design),
DataDirect Connect, DataDirect Connect64, DataDirect Technologies, DataDirect XML Converters, DataDirect XQuery, DataXtend, Dynamic
Routing Architecture, Empowerment Center, Fathom, IONA, Making Software Work Together, Mindreef, ObjectStore, OpenEdge, Orbix,
PeerDirect, Powered by Progress, PowerTier, Progress, Progress DataXtend, Progress Dynamics, Progress Business Empowerment,
Progress Empowerment Center, Progress Empowerment Program, Progress OpenEdge, Progress Profiles, Progress Results, Progress
Software Business Making Progress, Progress Software Developers Network, Progress Sonic, ProVision, PS Select, RulesCloud,
RulesWorld, Savvion, SequeLink, Shadow, SOAPscope, SOAPStation, Sonic, Sonic ESB, SonicMQ, Sonic Orchestration Server,
SpeedScript, Stylus Studio, Technical Empowerment, WebSpeed, Xcalia (and design), and Your Software, Our Technology–Experience the
Connection are registered trademarks of Progress Software Corporation or one of its affiliates or subsidiaries in the U.S. and/or other
countries. AccelEvent, Apama Dashboard Studio, Apama Event Manager, Apama Event Modeler, Apama Event Store, Apama Risk Firewall,
AppsAlive, AppServer, ASPen, ASP-in-a-Box, BusinessEdge, Cache-Forward, CloudEdge, DataDirect Spy, DataDirect SupportLink, Future
Proof, GVAC, High Performance Integration, ObjectStore Inspector, ObjectStore Performance Expert, OpenAccess, Orbacus, Pantero,
POSSE, ProDataSet, Progress Arcade, Progress CloudEdge, Progress Cloudware, Progress Control Tower, Progress ESP Event Manager,
Progress ESP Event Modeler, Progress Event Engine, Progress RFID, Progress RPM, Progress Responsive Cloud, Progress Responsive
Process Management, Progress Software, PSE Pro, SectorAlliance, SeeThinkAct, Shadow z/Services, Shadow z/Direct, Shadow z/Events,
Shadow z/Presentation, Shadow Studio, SmartBrowser, SmartComponent, SmartDataBrowser, SmartDataObjects, SmartDataView,
SmartDialog, SmartFolder, SmartFrame, SmartObjects, SmartPanel, SmartQuery, SmartViewer, SmartWindow, Sonic Business Integration
Suite, Sonic Process Manager, Sonic Collaboration Server, Sonic Continuous Availability Architecture, Sonic Database Service, Sonic
Workbench, Sonic XML Server, The Brains Behind BAM, WebClient, and Who Makes Progress are trademarks or service marks of Progress
Software Corporation and/or its subsidiaries or affiliates in the U.S. and other countries. Java is a registered trademark of Oracle and/or its
affiliates. Any other marks contained herein may be trademarks of their respective owners.

Third party acknowledgements — See the “Third party acknowledgements” section on page 17.

February 2013

Last updated with new content: Release 11.2.0 Product Code: 4496; R11.2.0

For the latest documentation updates see OpenEdge Product Documentation on PSDN (http://communities.progress.com/pcom/
docs/DOC-16074).
Contents

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

1. OpenEdge Mobile Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33


Run-time architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Supported Mobile App types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Client access to the AppServer using Mobile services. . . . . . . . . . . . . . . . 36
Access to AppServer classes and procedures using JavaScript objects . . 37
Access to Mobile services with user login sessions . . . . . . . . . . . . . . . . . . 40
Development architecture and tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Creating Mobile projects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Building Mobile services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Publishing Mobile services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Building Mobile Apps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Building Mobile Apps without the Mobile App Builder . . . . . . . . . . . . . . . . 45
Deployment options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

2. Example: A Simple Mobile App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47


Setting preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Creating a new Mobile OpenEdge project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Connecting to the OpenEdge Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Creating an include file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Creating a new Business Entity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Creating the Mobile App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Adding the JSDO service to the client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Building and testing the Mobile App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Developer Studio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Mobile App Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Web Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
General. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

OpenEdge® Development: Mobile Applications 3


Contents

3. Creating Mobile Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63


Getting started with OpenEdge Mobile development . . . . . . . . . . . . . . . . . . . . . . . . 64
Starting up Developer Studio for Mobile development . . . . . . . . . . . . . . . . 64
Configuring and managing OpenEdge servers from Developer Studio . . . 65
Creating an OpenEdge Mobile project . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Creating and testing a Mobile service. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Coding AppServer services for OpenEdge Mobile . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Singleton classes and procedures as Mobile resources. . . . . . . . . . . . . . . 69
Coding ABL routines to implement a Mobile resource . . . . . . . . . . . . . . . . 70
Creating Mobile resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Using the New Business Entity wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Using the Define Service Interface wizard . . . . . . . . . . . . . . . . . . . . . . . . . 78
Creating Mobile services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Using the New Mobile Service wizard. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Modifying and deleting Mobile services . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Publishing Mobile services for testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
URIs for accessing Mobile Web applications, services, and resources . . . . . . . . . . 81
Mobile URIs for Mobile App access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Mobile URIs for testing access from REST clients . . . . . . . . . . . . . . . . . . . 84
Using a REST client to invoke a Mobile operation . . . . . . . . . . . . . . . . . . . 86

4. Creating Mobile Apps using JSDOs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87


Creating a Mobile App from Developer Studio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Getting started with the Mobile App Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
JSDO overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Supporting OpenEdge classes and objects . . . . . . . . . . . . . . . . . . . . . . . . 91
How a JSDO maps to a Mobile resource . . . . . . . . . . . . . . . . . . . . . . . . . . 92
How JSDO local storage works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Methods of a JSDO and the JSRecord object . . . . . . . . . . . . . . . . . . . . . . 96
Asynchronous and synchronous execution . . . . . . . . . . . . . . . . . . . . . . . . 98
Properties of a JSDO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Requirements for using a JSDO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Creating a JSDO for a Mobile resource . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Accessing built-in CRUD operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Read operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Create operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Update operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Delete operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Batch saving of changes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Accessing non-built-in invoke operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Asynchronous vs. synchronous method execution. . . . . . . . . . . . . . . . . . . 115
Invocation method example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Managing user login sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Requirements for creating a user login session . . . . . . . . . . . . . . . . . . . . . 117
Default Web pages to support Mobile App login. . . . . . . . . . . . . . . . . . . . . 119
Getting started with other HTML coding tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Using the UIHelper class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Using a custom template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Publishing Mobile Apps for testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

5. Deploying Mobile Applications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129


Deployment overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
Packaging and deploying Mobile services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Packaging and Deploying iOS Apps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Packaging iOS Apps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Deploying iOS Apps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

4 OpenEdge® Development: Mobile Applications


Contents

Packaging and Deploying Android Apps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136


Packaging Android Apps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Deploying Android Apps. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Packaging and Deploying Mobile Web Apps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Packaging Mobile Web Apps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Deploying Mobile Web Apps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Security considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
Web server authentication models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
SSL connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Mobile device security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

A. ABL to JavaScript Data Type Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147


JavaScript data type overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Data type mapping between JavaScript and ABL . . . . . . . . . . . . . . . . . . . . . . . . . . 150

B. OpenEdge JavaScript Class and Object Reference. . . . . . . . . . . . . . . . . . . . . . . 153


JSRecord object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
progress.data.JSDO class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
progress.data.Session class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
progress.ui.UIHelper class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
request object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

C. OpenEdge JavaScript Class Properties, Methods, and Events Reference . . . . 173


add( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
addCatalog( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
addItem( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
addRecords( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
afterCreate event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
afterDelete event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
afterFill event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
afterInvoke event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
afterSaveChanges event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
afterUpdate event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
assign( ) method (JSDO class) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
assign( ) method (UIHelper class) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
async property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
authenticationModel property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
batch property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
beforeCreate event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
beforeDelete event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
beforeFill event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
beforeInvoke event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
beforeSaveChanges event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
beforeUpdate event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
catalogURIs property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
clearItems( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
data property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
display( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
fill( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
find( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
findById( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
fnName property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
foreach( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
getData( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
getFormFields( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
getFormRecord( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219

OpenEdge® Development: Mobile Applications 5


Contents

getId( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220


getListViewRecord( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
getSchema( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
invocation method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
jsdo property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
jsrecord property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
login( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
loginHttpStatus property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
loginResult property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
loginTarget property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
logout( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
name property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
onOpenRequest property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
paramObj property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
record property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
remove( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
response property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
saveChanges( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
services property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
serviceURI property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
setDetailPage( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
setFieldTemplate( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
setItemTemplate( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
setListView( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
showListView( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
subscribe( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
success property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
table reference property (JSDO) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
table reference property (UIHelper) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
unsubscribe( ) method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
useRelationships property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
userName property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
xhr property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261

6 OpenEdge® Development: Mobile Applications


Contents

Figures
Figure 1: OpenEdge Mobile run-time architecture for native and Web apps . . . . . . . . 34
Figure 2: Accessing OpenEdge Mobile services and resources . . . . . . . . . . . . . . . . . 36
Figure 3: Accessing AppServer data and business logic from Mobile Apps . . . . . . . . 37
Figure 4: OpenEdge Mobile development architecture and tools . . . . . . . . . . . . . . . . 42
Figure 5: Sample display using the UIHelper class . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

OpenEdge® Development: Mobile Applications 7


Contents

Tables
Table 1: Required ABL parameters for built-in Mobile operations . . . . . . . . . . . . . . . . 38
Table 2: Prescribed ABL parameters for built-in Mobile operations . . . . . . . . . . . . . . . 72
Table 3: Mobile Application Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
Table 4: JavaScript primitive data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Table 5: Supported non-standard data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Table 6: JavaScript complex data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
Table 7: ABL to JavaScript data type mappings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Table 8: JSRecord object properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Table 9: JSRecord object methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Table 10: progress.data.JSDO properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Table 11: progress.data.JSDO class-instance methods . . . . . . . . . . . . . . . . . . . . . . . . 158
Table 12: progress.data.JSDO table-reference methods . . . . . . . . . . . . . . . . . . . . . . . . 159
Table 13: progress.data.JSDO events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Table 14: Example — Using an OpenEdge JSDO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
Table 15: progress.data.Session properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Table 16: progress.data.Session class-instance methods . . . . . . . . . . . . . . . . . . . . . . . 166
Table 17: Example — Using the OpenEdge Session class . . . . . . . . . . . . . . . . . . . . . . 166
Table 18: progress.ui.UIHelper class-level methods . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Table 19: progress.ui.UIHelper table-reference methods . . . . . . . . . . . . . . . . . . . . . . . 167
Table 20: Example — index.html . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Table 21: Example — customers.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
Table 22: Request object properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

8 OpenEdge® Development: Mobile Applications


Preface

This Preface contains the following sections:

• Purpose

• Audience

• Organization

• Using this manual

• Typographical conventions

• Examples of syntax descriptions

• OpenEdge messages

• Third party acknowledgements

OpenEdge® Development: Mobile Applications 9


Preface

Purpose
Describes how to build and deploy mobile apps using OpenEdge Mobile, an OpenEdge
product that exposes application services running on the AppServer as JavaScript
objects running in either a Web or mobile client, and uses OpenEdge REST as the
transport between them.

This includes a description of the tools and technologies provided with OpenEdge to:

• Build a complete OpenEdge Mobile application, including both server and client
code, from a selected data model on an AppServer using Progress Developer
Studio for OpenEdge

• Code ABL classes and procedures on an AppServer to be exposed as customized


Mobile resources

• Expose specified AppServer procedures or classes as Mobile resources and


deploy them in Mobile services that are provided by and managed in an
OpenEdge Mobile Web application

• Code instances of OpenEdge JavaScript classes that allow you to access Mobile
resources as JavaScript objects similar to how ABL allows you to access data
sources through ProDataSet and temp-table objects; thus hiding the details of the
REST transport

• Create Web and mobile client UIs (Mobile Apps) using a visual design tool
(Progress OpenEdge Mobile App Builder) that is customized to access OpenEdge
Mobile services and bind OpenEdge Mobile data to the UI.

Audience
OpenEdge application partners and end users who want to access their OpenEdge
data and business logic from either mobile devices or the Web.

Organization
Chapter 1, “OpenEdge Mobile Overview”

Describes the OpenEdge Mobile run-time and development architectures and an


overview of how to use them to build Mobile Apps.

Chapter 2, “Example: A Simple Mobile App”

Walks through the process of creating a simple Mobile App directly from an
OpenEdge data model.

Chapter 3, “Creating Mobile Services”

Describes the requirements and tools for building Mobile services, including the
AppServer coding and Mobile interface annotations required to define Mobile
resources.

10 OpenEdge® Development: Mobile Applications


Preface

Chapter 4, “Creating Mobile Apps using JSDOs”

Describes how to access Mobile services from JavaScript, including how to build
Mobile Apps that access these services.

Chapter 5, “Deploying Mobile Applications”

Describes options for deploying Mobile services and the Mobile Apps that access
them.

Appendix A, “ABL to JavaScript Data Type Mapping”

Describes how OpenEdge Mobile maps ABL to JavaScript data types.

Appendix B, “OpenEdge JavaScript Class and Object Reference”

Provides a reference to the OpenEdge JavaScript classes that enable JavaScript


access to Mobile services and resources.

Appendix C, “OpenEdge JavaScript Class Properties, Methods, and Events


Reference”

Provides a reference to the properties and methods of the OpenEdge JavaScript


classes.

Using this manual


OpenEdge provides a special purpose programming language for building business
applications. In the documentation, the formal name for this language is ABL
(Advanced Business Language). With few exceptions, all keywords of the language
appear in all UPPERCASE, using a font that is appropriate to the context. All other
alphabetic language content appears in mixed case.

For the latest documentation updates see the OpenEdge Product Documentation
Overview page on PSDN:
http://communities.progress.com/pcom/docs/DOC-16074.

References to ABL compiler and run-time features


ABL is both a compiled and an interpreted language that executes in a run-time engine.
The documentation refers to this run-time engine as the ABL Virtual Machine (AVM).
When the documentation refers to ABL source code compilation, it specifies ABL or the
compiler as the actor that manages compile-time features of the language. When the
documentation refers to run-time behavior in an executing ABL program, it specifies the
AVM as the actor that manages the specified run-time behavior in the program.

OpenEdge® Development: Mobile Applications 11


Preface

For example, these sentences refer to the ABL compiler’s allowance for parameter
passing and the AVM’s possible response to that parameter passing at run time: “ABL
allows you to pass a dynamic temp-table handle as a static temp-table parameter of a
method. However, if at run time the passed dynamic temp-table schema does not
match the schema of the static temp-table parameter, the AVM raises an error.” The
following sentence refers to run-time actions that the AVM can perform using a
particular ABL feature: “The ABL socket object handle allows the AVM to connect with
other ABL and non-ABL sessions using TCP/IP sockets.”

References to ABL data types


ABL provides built-in data types, built-in class data types, and user-defined class data
types. References to built-in data types follow these rules:

• Like most other keywords, references to specific built-in data types appear in all
UPPERCASE, using a font that is appropriate to the context. No uppercase reference
ever includes or implies any data type other than itself.

• Wherever integer appears, this is a reference to the INTEGER or INT64 data type.

• Wherever character appears, this is a reference to the CHARACTER, LONGCHAR, or


CLOB data type.

• Wherever decimal appears, this is a reference to the DECIMAL data type.

• Wherever numeric appears, this is a reference to the INTEGER, INT64, or DECIMAL


data type.

References to built-in class data types appear in mixed case with initial caps, for
example, Progress.Lang.Object. References to user-defined class data types
appear in mixed case, as specified for a given application example.

References to JavaScript classes and data types


References to JavaScript classes and data types follow common conventions, with
JavaScript code in the same fixed-width font used for ABL code.

Typographical conventions
This manual uses the following typographical conventions:

Convention Description

Bold Bold typeface indicates commands or characters the user


types, provides emphasis, or the names of user interface
elements.

Italic Italic typeface indicates the title of a document, or signifies


new terms.

12 OpenEdge® Development: Mobile Applications


Preface

Convention Description

SMALL, BOLD Small, bold capital letters indicate OpenEdge key functions
CAPITAL LETTERS and generic keyboard keys; for example, GET and CTRL.

KEY1+KEY2 A plus sign between key names indicates a simultaneous


key sequence: you press and hold down the first key while
pressing the second key. For example, CTRL+X.

KEY1 KEY2 A space between key names indicates a sequential key


sequence: you press and release the first key, then press
another key. For example, ESCAPE H.

Syntax:

Fixed width A fixed-width font is used in syntax, code examples, system


output, and filenames.

Fixed-width Fixed-width italics indicate variables in syntax.


italics

Fixed-width bold Fixed-width bold italic indicates variables in syntax with


special emphasis.

UPPERCASE ABL keywords in syntax and code examples are almost


fixed width always shown in upper case. Although shown in uppercase,
you can type ABL keywords in either uppercase or
lowercase in a procedure or class.

This icon (three arrows) introduces a multi-step procedure.

This icon (one arrow) introduces a single-step procedure.

Period (.) All statements except DO, FOR, FUNCTION, PROCEDURE, and
or REPEAT end with a period. DO, FOR, FUNCTION, PROCEDURE,
colon (:) and REPEAT statements can end with either a period or a
colon.

[] Large brackets indicate the items within them are optional.

[] Small brackets are part of ABL.

{} Large braces indicate the items within them are required.


They are used to simplify complex syntax diagrams.

{} Small braces are part of ABL. For example, a called external


procedure must use braces when referencing arguments
passed by a calling procedure.

| A vertical bar indicates a choice.

... Ellipses indicate repetition: you can choose one or more of


the preceding items.

OpenEdge® Development: Mobile Applications 13


Preface

Examples of syntax descriptions


In this example, ACCUM is a keyword, and aggregate and expression are variables:

Syntax

ACCUM aggregate expression

FOR is one of the statements that can end with either a period or a colon, as in this
example:

FOR EACH Customer NO-LOCK:


DISPLAY Customer.Name.
END.

In this example, STREAM stream, UNLESS-HIDDEN, and NO-ERROR are optional:

Syntax

DISPLAY [ STREAM stream ][ UNLESS-HIDDEN ] [ NO-ERROR ]

In this example, the outer (small) brackets are part of the language, and the inner
(large) brackets denote an optional item:

Syntax

INITIAL [ constant [ , constant ] ]

A called external procedure must use braces when referencing compile-time


arguments passed by a calling procedure, as shown in this example:

Syntax

{ &argument-name }

In this example, EACH, FIRST, and LAST are optional, but you can choose only one of
them:

Syntax

PRESELECT [ EACH | FIRST | LAST ] record-phrase

In this example, you must include two expressions, and optionally you can include
more. Multiple expressions are separated by commas:

Syntax

MAXIMUM ( expression , expression [ , expression ] ... )

14 OpenEdge® Development: Mobile Applications


Preface

In this example, you must specify MESSAGE and at least one expression or SKIP [ (n)
], and any number of additional expression or SKIP [ ( n ) ] is allowed:

Syntax

MESSAGE { expression | SKIP [ ( n ) ] } ...

In this example, you must specify {include-file, then optionally any number of
argument or &argument-name = "argument-value", and then terminate with }:

Syntax

{ include-file
[ argument | &argument-name = "argument-value" ] ... }

Long syntax descriptions split across lines


Some syntax descriptions are too long to fit on one line. When syntax descriptions are
split across multiple lines, groups of optional and groups of required items are kept
together in the required order.

In this example, WITH is followed by six optional items:

Syntax

WITH [ ACCUM max-length ][ expression DOWN ]


[ CENTERED ] [ n COLUMNS ][ SIDE-LABELS ]
[ STREAM-IO ]

Complex syntax descriptions with both required and


optional elements
Some syntax descriptions are too complex to distinguish required and optional
elements by bracketing only the optional elements. For such syntax, the descriptions
include both braces (for required elements) and brackets (for optional elements).

In this example, ASSIGN requires either one or more field entries or one record.
Options available with field or record are grouped with braces and brackets:

Syntax

ASSIGN {[ FRAME frame ] {[ = expression ] }


field
[ WHEN expression ] } ...
| { record [ EXCEPT field ... ] }

OpenEdge® Development: Mobile Applications 15


Preface

OpenEdge messages
OpenEdge displays several types of messages to inform you of routine and unusual
occurrences:

• Execution messages inform you of errors encountered while OpenEdge is


running a procedure; for example, if OpenEdge cannot find a record with a
specified index field value.

• Compile messages inform you of errors found while OpenEdge is reading and
analyzing a procedure before running it; for example, if a procedure references a
table name that is not defined in the database.

• Startup messages inform you of unusual conditions detected while OpenEdge is


getting ready to execute; for example, if you entered an invalid startup parameter.

After displaying a message, OpenEdge proceeds in one of several ways:

• Continues execution, subject to the error-processing actions that you specify or


that are assumed as part of the procedure. This is the most common action taken
after execution messages.

• Returns to the Procedure Editor, so you can correct an error in a procedure. This
is the usual action taken after compiler messages.

• Halts processing of a procedure and returns immediately to the Procedure Editor.


This does not happen often.

• Terminates the current session.

OpenEdge messages end with a message number in parentheses. In this example, the
message number is 200:

** Unknown table name table. (200)

If you encounter an error that terminates OpenEdge, note the message number before
restarting.

Obtaining more information about OpenEdge messages


In Windows platforms, use OpenEdge online help to obtain more information about
OpenEdge messages. Many OpenEdge tools include the following Help menu options
to provide information about messages:

• Choose Help→ Recent Messages to display detailed descriptions of the most


recent OpenEdge message and all other messages returned in the current
session.

• Choose Help→ Messages and then type the message number to display a
description of a specific OpenEdge message.

• In the Procedure Editor, press the HELP key or F1.

16 OpenEdge® Development: Mobile Applications


Preface

On UNIX platforms, use the OpenEdge pro command to start a single-user mode
character OpenEdge client session and view a brief description of a message by
providing its number.

To use the pro command to obtain a message description by message number:

1. Start the Procedure Editor:

OpenEdge-install-dir/bin/pro

2. Press F3 to access the menu bar, then choose Help→ Messages.

3. Type the message number and press ENTER. Details about that message number
appear.

4. Press F4 to close the message, press F3 to access the Procedure Editor menu,
and choose File→ Exit.

Third party acknowledgements


One or more products in the Progress OpenEdge v11.2 release includes third party
components covered by licenses that require that the following documentation notices
be provided:

Progress OpenEdge v11.2 may incorporate ANT v1.5.4. Such technology is subject to
the following terms and conditions: The Apache Software License, Version 1.1, applies
to all versions of up to ant 1.6.0 included. The Apache Software License, Version 1.1 -
Copyright (C) 2000-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met: 1. Redistributions of source
code must retain the above copyright notice, this list of conditions and the following
disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution. 3. The end-user documentation included with
the redistribution, if any, must include the following acknowledgment: "This product
includes software developed by the Apache Software Foundation
(http://www.apache.org/)." Alternately, this acknowledgment may appear in the
software itself, if and wherever such third-party acknowledgments normally appear. 4.
The names "Ant" and "Apache Software Foundation" must not be used to endorse or
promote products derived from this software without prior written permission. For
written permission, please contact [email protected]. 5. Products derived from this
software may not be called "Apache", nor may "Apache" appear in their name, without
prior written permission of the Apache Software Foundation. THIS SOFTWARE IS
PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF

OpenEdge® Development: Mobile Applications 17


Preface

USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED


AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions
made by many individuals on behalf of the Apache Software Foundation. For more
information on the Apache Software Foundation, please see
<http://www.apache.org/>.

Progress OpenEdge v11.2 may incorporate Xalan XSLT Processor v2.5.1 and Xerces
for Java XML Parser v2.6.2. Such technology is subject to the following terms and
conditions: The Apache Software License, Version 1.1 Copyright (c) 1999 The Apache
Software Foundation. All rights reserved. Redistribution and use in source and binary
forms, with or without modification, are permitted provided that the following conditions
are met: 1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer. 2. Redistributions in binary form must
reproduce the above copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the distribution. 3. The
end-user documentation included with the redistribution, if any, must include the
following acknowledgment: "This product includes software developed by the Apache
Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment
may appear in the software itself, if and wherever such third-party acknowledgments
normally appear. 4. The names "Xerces" and "Apache Software Foundation" must not
be used to endorse or promote products derived from this software without prior written
permission. For written permission, please contact [email protected]. 5. Products
derived from this software may not be called "Apache", nor may "Apache" appear in
their name, without prior written permission of the Apache Software Foundation. THIS
SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions
made by many individuals on behalf of the Apache Software Foundation and was
originally based on software copyright (c) 1999, International Business Machines, Inc.,
http://www.ibm.com. For more information on the Apache Software Foundation,
please see <http://www.apache.org/>.

Progress OpenEdge v11.2 may incorporate Crimson v1.1.3 from Progress Extensions
for Eclipse v2.2.1. Such technology is subject to the following terms and conditions:
The Apache Software License, Version 1.1 Copyright (c) 1999-2003 The Apache
Software Foundation. All rights reserved. Redistribution and use in source and binary
forms, with or without modification, are permitted provided that the following conditions
are met: 1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer. 2. Redistributions in binary form must
reproduce the above copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the distribution. 3. The

18 OpenEdge® Development: Mobile Applications


Preface

end-user documentation included with the redistribution, if any, must include the
following acknowledgment: "This product includes software developed by the Apache
Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment
may appear in the software itself, if and wherever such third-party acknowledgments
normally appear. 4. The names "Xerces" and "Apache Software Foundation" must not
be used to endorse or promote products derived from this software without prior written
permission. For written permission, please contact [email protected]. 5. Products
derived from this software may not be called "Apache", nor may "Apache" appear in
their name, without prior written permission of the Apache Software Foundation. THIS
SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions
made by many individuals on behalf of the Apache Software Foundation and was
originally based on software copyright (c) 1999, International Business Machines, Inc.,
http://www.ibm.com. For more information on the Apache Software Foundation,
please see <http://www.apache.org/>.

Progress OpenEdge v11.2 may incorporate SOAP v2.3.1 from Apache Foundation.
Such technology is subject to the following terms and conditions: The Apache Software
License, Version 1.1

Copyright (c) 1999 The Apache Software Foundation. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.

3. The end-user documentation included with the redistribution, if any, must include the
following acknowledgment: "This product includes software developed by the Apache
Software Foundation (http://www.apache.org/)."

Alternately, this acknowledgment may appear in the software itself, if and wherever
such third-party acknowledgments normally appear.

4. The names "SOAP" and "Apache Software Foundation" must not be used to endorse
or promote products derived from this software without prior written permission. For
written permission, please contact [email protected].

OpenEdge® Development: Mobile Applications 19


Preface

5. Products derived from this software may not be called "Apache", nor may "Apache"
appear in their name, without prior written permission of the Apache Software
Foundation.

THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED


WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

This software consists of voluntary contributions made by many individuals on behalf


of the Apache Software Foundation. For more information on the Apache Software
Foundation, please see <http://www.apache.org/>.

Progress OpenEdge v11.2 may incorporate ANTLR (Another Tool for Language
Recognition) v2.7.6. Such technology is subject to the following terms and conditions:
ANTLR 3 License [The BSD License] Copyright (c) 2003-2006, Terence Parr All rights
reserved. Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer. Redistributions in binary form must reproduce
the above copyright notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. Neither the name
of the author nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written permission. THIS
SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Progress OpenEdge v11.2 may incorporate Decimal Conversion Code (dtoa.c;


g_fmt.c; rnd_prod.s; decstrod.c; decstrtof.c; dmisc.c; gdtoa.c; gdtoa.h; gdtoaimp.h;
gethex.c; gmisc.c; hd_init.c; misc.c; smisc.c; strtodg.c; strtord.c; sum.c; ulp.c). Such
technologies are subject to the following terms and conditions: dtoa.c License: The
author of this software is David M. Gay. Copyright (c) 1991, 2000, 2001 by Lucent
Technologies. Permission to use, copy, modify, and distribute this software for any
purpose without fee is hereby granted, provided that this entire notice is included in all
copies of any software which is or includes a copy or modification of this software and

20 OpenEdge® Development: Mobile Applications


Preface

in all copies of the supporting documentation for such software. THIS SOFTWARE IS
BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTY.
IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY
PARTICULAR PURPOSE. g_fmt.c License: The author of this software is David M.
Gay. Copyright (c) 1991, 1996 by Lucent Technologies. Permission to use, copy,
modify, and distribute this software for any purpose without fee is hereby granted,
provided that this entire notice is included in all copies of any software which is or
includes a copy or modification of this software and in all copies of the supporting
documentation for such software. THIS SOFTWARE IS BEING PROVIDED "AS IS",
WITHOUT ANY EXPRESS OR IMPLIED WARRANTY. IN PARTICULAR, NEITHER
THE AUTHOR NOR LUCENT MAKES ANY REPRESENTATION OR WARRANTY OF
ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS
FITNESS FOR ANY PARTICULAR PURPOSE.

rnd_prod.s License: The author of this software is David M. Gay. Copyright (c) 1991 by
Lucent Technologies. Permission to use, copy, modify, and distribute this software for
any purpose without fee is hereby granted, provided that this entire notice is included
in all copies of any software which is or includes a copy or modification of this software
and in all copies of the supporting documentation for such software. THIS SOFTWARE
IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTY.
IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY
PARTICULAR PURPOSE. decstrtod.c License: The author of this software is David M.
Gay. Copyright (C) 1998-2001 by Lucent Technologies All Rights Reserved Permission
to use, copy, modify, and distribute this software and its documentation for any purpose
and without fee is hereby granted, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this permission notice and
warranty disclaimer appear in supporting documentation, and that the name of Lucent
or any of its entities not be used in advertising or publicity pertaining to distribution of
the software without specific, written prior permission. LUCENT DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
decstrtof.c License: The author of this software is David M. Gay. Copyright (C) 1998,
2000 by Lucent Technologies All Rights Reserved Permission to use, copy, modify,
and distribute this software and its documentation for any purpose and without fee is
hereby granted, provided that the above copyright notice appear in all copies and that
both that the copyright notice and this permission notice and warranty disclaimer
appear in supporting documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to distribution of the software without
specific, written prior permission. LUCENT DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL LUCENT OR ANY OF ITS
ENTITIES BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR

OpenEdge® Development: Mobile Applications 21


Preface

OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE


USE OR PERFORMANCE OF THIS SOFTWARE. dmisc.c License: The author of this
software is David M. Gay. Copyright (C) 1998 by Lucent Technologies All Rights
Reserved Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided that the
above copyright notice appear in all copies and that both that the copyright notice and
this permission notice and warranty disclaimer appear in supporting documentation,
and that the name of Lucent or any of its entities not be used in advertising or publicity
pertaining to distribution of the software without specific, written prior permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. gdtoa.c License: The author of this software
is David M. Gay. Copyright (C) 1998, 1999 by Lucent Technologies All Rights
Reserved Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided that the
above copyright notice appear in all copies and that both that the copyright notice and
this permission notice and warranty disclaimer appear in supporting documentation,
and that the name of Lucent or any of its entities not be used in advertising or publicity
pertaining to distribution of the software without specific, written prior permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. gdtoa.h License: The author of this software
is David M. Gay. Copyright (C) 1998 by Lucent Technologies All Rights Reserved
Permission to use, copy, modify, and distribute this software and its documentation for
any purpose and without fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that the copyright notice and this permission
notice and warranty disclaimer appear in supporting documentation, and that the name
of Lucent or any of its entities not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission. LUCENT
DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT
SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY SPECIAL,
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
gdtoaimp.h License: The author of this software is David M. Gay. Copyright (C)
1998-2000 by Lucent Technologies All Rights Reserved Permission to use, copy,
modify, and distribute this software and its documentation for any purpose and without
fee is hereby granted, provided that the above copyright notice appear in all copies and
that both that the copyright notice and this permission notice and warranty disclaimer
appear in supporting documentation, and that the name of Lucent or any of its entities

22 OpenEdge® Development: Mobile Applications


Preface

not be used in advertising or publicity pertaining to distribution of the software without


specific, written prior permission. LUCENT DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL LUCENT OR ANY OF ITS
ENTITIES BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
USE OR PERFORMANCE OF THIS SOFTWARE. gethex.c License: The author of this
software is David M. Gay. Copyright (C) 1998 by Lucent Technologies All Rights
Reserved Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided that the
above copyright notice appear in all copies and that both that the copyright notice and
this permission notice and warranty disclaimer appear in supporting documentation,
and that the name of Lucent or any of its entities not be used in advertising or publicity
pertaining to distribution of the software without specific, written prior permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. gmisc.c License: The author of this software
is David M. Gay. Copyright (C) 1998 by Lucent Technologies All Rights Reserved
Permission to use, copy, modify, and distribute this software and its documentation for
any purpose and without fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that the copyright notice and this permission
notice and warranty disclaimer appear in supporting documentation, and that the name
of Lucent or any of its entities not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission. LUCENT
DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT
SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY SPECIAL,
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
hd_init.c License: The author of this software is David M. Gay. Copyright (C) 2000 by
Lucent Technologies All Rights Reserved Permission to use, copy, modify, and
distribute this software and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all copies and that both that
the copyright notice and this permission notice and warranty disclaimer appear in
supporting documentation, and that the name of Lucent or any of its entities not be
used in advertising or publicity pertaining to distribution of the software without specific,
written prior permission. LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL LUCENT OR ANY OF ITS
ENTITIES BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE

OpenEdge® Development: Mobile Applications 23


Preface

USE OR PERFORMANCE OF THIS SOFTWARE. misc.c License: The author of this


software is David M. Gay. Copyright (C) 1998, 1999 by Lucent Technologies All Rights
Reserved Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided that the
above copyright notice appear in all copies and that both that the copyright notice and
this permission notice and warranty disclaimer appear in supporting documentation,
and that the name of Lucent or any of its entities not be used in advertising or publicity
pertaining to distribution of the software without specific, written prior permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. smisc.c License: The author of this software
is David M. Gay. Copyright (C) 1998, 1999 by Lucent Technologies All Rights
Reserved Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided that the
above copyright notice appear in all copies and that both that the copyright notice and
this permission notice and warranty disclaimer appear in supporting documentation,
and that the name of Lucent or any of its entities not be used in advertising or publicity
pertaining to distribution of the software without specific, written prior permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. strtodg.c License: The author of this software
is David M. Gay. Copyright (C) 1998-2001 by Lucent Technologies All Rights Reserved
Permission to use, copy, modify, and distribute this software and its documentation for
any purpose and without fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that the copyright notice and this permission
notice and warranty disclaimer appear in supporting documentation, and that the name
of Lucent or any of its entities not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.

LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,


INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. strtord.c License: The author of this software
is David M. Gay. Copyright (C) 1998, 2000 by Lucent Technologies All Rights
Reserved Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided that the
above copyright notice appear in all copies and that both that the copyright notice and
this permission notice and warranty disclaimer appear in supporting documentation,
and that the name of Lucent or any of its entities not be used in advertising or publicity

24 OpenEdge® Development: Mobile Applications


Preface

pertaining to distribution of the software without specific, written prior permission.


LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. sum.c License: The author of this software is
David M. Gay. Copyright (C) 1998 by Lucent Technologies All Rights Reserved
Permission to use, copy, modify, and distribute this software and its documentation for
any purpose and without fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that the copyright notice and this permission
notice and warranty disclaimer appear in supporting documentation, and that the name
of Lucent or any of its entities not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission. LUCENT
DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT
SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY SPECIAL,
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ulp.c License: The author of this software is David M. Gay. Copyright (C) 1998, 1999
by Lucent Technologies All Rights Reserved Permission to use, copy, modify, and
distribute this software and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all copies and that both that
the copyright notice and this permission notice and warranty disclaimer appear in
supporting documentation, and that the name of Lucent or any of its entities not be
used in advertising or publicity pertaining to distribution of the software without specific,
written prior permission. LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL LUCENT OR ANY OF ITS
ENTITIES BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
USE OR PERFORMANCE OF THIS SOFTWARE.

Progress OpenEdge v11.2 may incorporate JSTL v1.0 from Sun Microsystems, Inc.
Such technologies are subject to the following terms and conditions: Code sample
License Copyright 1994-2006 Sun Microsystems, Inc. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met: Redistribution of source code
must retain the above copyright notice, this list of conditions and the following
disclaimer. Redistribution in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution. Neither the name of Sun Microsystems, Inc. or
the names of contributors may be used to endorse or promote products derived from
this software without specific prior written permission. This software is provided "AS
IS," without a warranty of any kind. ALL EXPRESS OR IMPLIED CONDITIONS,
REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR

OpenEdge® Development: Mobile Applications 25


Preface

NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC.


("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS
SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES. You acknowledge that this software is not designed, licensed or intended
for use in the design, construction, operation or maintenance of any nuclear facility.

Progress OpenEdge v11.2 may incorporate Quartz Enterprise Job Scheduler v1.3.2
from James House. Such technologies are subject to the following terms and
conditions: Copyright James House (c) 2001-2003 All rights reserved. Redistribution
and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met: 1. Redistributions of source code must
retain the above copyright notice, this list of conditions and the following disclaimer. 2.
Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR
AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION). HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. This product uses and includes within its distribution, software
developed by the Apache Software Foundation (http://www.apache.org/).

Progress OpenEdge v11.2 may incorporate YAJL v0.4.0 from Lloyd Hilaiel. Such
technology is subject to the following terms and conditions: Copyright 2007, Lloyd
Hilaiel. Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: 1. Redistributions of
source code must retain the above copyright notice, this list of conditions and the
following disclaimer. 2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. 3. Neither the name of Lloyd
Hilaiel nor the names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission. THIS SOFTWARE
IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF

26 OpenEdge® Development: Mobile Applications


Preface

LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING


NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Progress OpenEdge v11.2 may incorporate zlib v1.1.4 from Jean-loup Gailiy & Mark
Alder. Such technology is subject to the following terms and conditions: Copyright
notice: (C) 1995-2002 Jean-loup Gailly and Mark Adler This software is provided 'as-is',
without any express or implied warranty. In no event will the authors be held liable for
any damages arising from the use of this software. Permission is granted to anyone to
use this software for any purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions: 1. The origin of this software
must not be misrepresented; you must not claim that you wrote the original software. If
you use this software in a product, an acknowledgment in the product documentation
would be appreciated but is not required. 2. Altered source versions must be plainly
marked as such, and must not be misrepresented as being the original software. 3.
This notice may not be removed or altered from any source distribution.

Jean-loup Gailly Mark Adler

[email protected] [email protected]

Progress OpenEdge v11.2 may incorporate zlib ZLIB.NET Free v1.0.4 from
ComponentAce. Such technology is subject to the following terms and conditions:
Copyright (c) 2006-2007, ComponentAce http://www.componentace.com All rights
reserved. Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer. Redistributions in binary form must reproduce
the above copyright notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. Neither the name
of ComponentAce nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written permission. THIS
SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Progress OpenEdge v11.2 may incorporate Jing 20030619 from Progress Extensions
for Eclipse v2.2.1. Such technology is subject to the following terms and conditions:
Jing Copying Conditions. Copyright (c) 2001-2003 Thai Open Source Software Center
Ltd. All rights reserved. Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer. Redistributions in binary form must reproduce
the above copyright notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. Neither the name

OpenEdge® Development: Mobile Applications 27


Preface

of the Thai Open Source Software Center Ltd nor the names of its contributors may be
used to endorse or promote products derived from this software without specific prior
written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE. Third-party JARs - This distribution includes some additional JAR files,
which have their own copying conditions: saxon.jar Comes from the Saxon 6.5.2
distribution and is covered by these conditions xercesImpl.jar xml-apis.jar Come from
the Xerces-J 2.4.0 distribution and are covered by the Apache Software License
isorelax.jar Comes from ISO RELAX 2003/01/08 distribution and is covered by the
following license: Copyright (c) 2001-2002, SourceForge ISO-RELAX Project (ASAMI
Tomoharu, Daisuke Okajima, Kohsuke Kawaguchi, and MURATA Makoto) Permission
is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit persons to
whom the Software is furnished to do so, subject to the following conditions: The above
copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT
WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Progress OpenEdge v11.2 may incorporate Trang 20030619 from Progress


Extensions for Eclipse v2.2.1. Such technology is subject to the following terms and
conditions: Copyright (c) 2002, 2003 Thai Open Source Software Center Ltd. All rights
reserved. Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer. Redistributions in binary form must reproduce
the above copyright notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. Neither the name
of the Thai Open Source Software Center Ltd nor the names of its contributors may be
used to endorse or promote products derived from this software without specific prior
written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS “AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

28 OpenEdge® Development: Mobile Applications


Preface

CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,


PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

Progress OpenEdge v11.2 may incorporate xpp3-1.1.3.4.O from Progress Extensions


for Eclipse v2.2.1. Such technology is subject to the following terms and conditions:
Indiana University Extreme! Lab Software License Version 1.1.1 Copyright (c) 2002
Extreme! Lab, Indiana University. All rights reserved. Redistribution and use in source
and binary forms, with or without modification, are permitted provided that the following
conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.

3. The end-user documentation included with the redistribution, if any, must include the
following acknowledgment:

"This product includes software developed by the Indiana University Extreme! Lab
(http://www.extreme.indiana.edu/)."

Alternately, this acknowledgment may appear in the software itself, if and wherever
such third-party acknowledgments normally appear.

4. The names "Indiana Univeristy" and "Indiana Univeristy Extreme! Lab" must not be
used to endorse or promote products derived from this software without prior written
permission. For written permission, please contact
http://www.extreme.indiana.edu/.

5. Products derived from this software may not use "Indiana Univeristy" name nor may
"Indiana Univeristy" appear in their name, without prior written permission of the
Indiana University.

THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED


WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHORS, COPYRIGHT HOLDERS OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

Progress OpenEdge v11.2 may incorporate International Classes for Unicode


(International Components for Unicode) v2.4 from IBM. Such technology is subject to

OpenEdge® Development: Mobile Applications 29


Preface

the following terms and conditions: ICU License - The ICU project is licensed under
the X License (see also the x.org original), which is compatible with GPL but
non-copyleft. The license allows ICU to be incorporated into a wide variety of software
projects using the GPL license. The X license is compatible with the GPL, while also
allowing ICU to be incorporated into non-open source products. License ICU License
- ICU 1.8.1 and later COPYRIGHT AND PERMISSION NOTICE Copyright (c)
1995-2003 International Business Machines Corporation and others All rights
reserved. Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, and/or sell copies of the Software, and to permit persons to
whom the Software is furnished to do so, provided that the above copyright notice(s)
and this permission notice appear in all copies of the Software and that both the above
copyright notice(s) and this permission notice appear in supporting documentation.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR
ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. Except as contained in this notice, the name
of a copyright holder shall not be used in advertising or otherwise to promote the sale,
use or other dealings in this Software without prior written authorization of the copyright
holder. ------------------------------------------------------------------------- All trademarks and
registered trademarks mentioned herein are the property of their respective owners.

Progress OpenEdge v11.2 may incorporate International Components for Unicode


v4.8.0. Such technology is subject to the following terms and conditions: ICU License
- ICU 1.8.1 and later COPYRIGHT AND PERMISSION NOTICE Copyright (c)
1995-2011 International Business Machines Corporation and others All rights
reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify, merge,
publish, distribute, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, provided that the above copyright notice(s) and this
permission notice appear in all copies of the Software and that both the above
copyright notice(s) and this permission notice appear in supporting documentation.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR
ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

30 OpenEdge® Development: Mobile Applications


Preface

Except as contained in this notice, the name of a copyright holder shall not be used in
advertising or otherwise to promote the sale, use or other dealings in this Software
without prior written authorization of the copyright holder.

All trademarks and registered trademarks mentioned herein are the property of their
respective owners.

Progress OpenEdge v11.2 may incorporate Progress Extensions for Eclipse v2.2.1
which incorporates Saxon-B v8.9.0.4 (saxon8.jar, saxon8-xpath.jar, saxon8-xom.jar,
saxon8-sql.jar, saxon8-jdom.jar, saxon8-dom.jar). The contents of these files are
subject to the Mozilla Public License Version 1.0 (the "License") provided below; you
may not use this file except in compliance with the License. You may also obtain a copy
of the License at http://www.mozilla.org/MPL/. Software distributed under the
License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
either express or implied. See the License for the specific language governing rights
and limitations under the License. PSC will, at Licensee's request, provide copies of the
source code for this third party technology, including modifications, if any, made by
PSC. PSC may charge reasonable shipping and handling charges for such distribution.
Licensee may also obtain the source code through
http://communities.progress.com/pcom/docs/DOC-16051 by following the
instructions set forth therein. The Original Code of Saxon comprises all those
components which are not explicitly attributed to other parties. The Initial Developer of
the Original Code is Michael Kay. Until February 2001 Michael Kay was an employee
of International Computers Limited (now part of Fujitsu Limited), and original code
developed during that time was released under this license by permission from
International Computers Limited. From February 2001 until February 2004 Michael Kay
was an employee of Software AG, and code developed during that time was released
under this license by permission from Software AG, acting as a "Contributor".
Subsequent code has been developed by Saxonica Limited, of which Michael Kay is a
Director, again acting as a "Contributor". A small number of modules, or enhancements
to modules, have been developed by other individuals (either written specially for
Saxon, or incorporated into Saxon having initially been released as part of another
open source product). Such contributions are acknowledged individually in comments
attached to the relevant code modules. All Rights Reserved.

Progress OpenEdge v11.2 may incorporate Rhino v1.6R1 from Progress Extensions
for Eclipse v2.2.1. The contents of this file are subject to the Netscape Public License
Version 1.1 (the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at http://www.mozilla.org/NPL/.
Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
WARRANTY OF ANY KIND, either express or implied. See the License for the specific
language governing rights and limitations under the License.

The Original Code is Rhino code, released May 6, 1999. The Initial Developer of the
Original Code is Netscape Communications Corporation. Portions created by
Netscape are Copyright (C) 1997-1999 Netscape Communications Corporation. All
Rights Reserved. Contributor(s): Igor Bukanov. PSC will, at Licensee's request,
provide copies of the source code for this third party technology, including
modifications, if any, made by PSC. PSC may charge reasonable shipping and
handling charges for such distribution. Licensee may also obtain the source code
through http://communities.progress.com/pcom/docs/DOC-16051 by following
the instructions set forth therein.

OpenEdge® Development: Mobile Applications 31


Preface

Progress OpenEdge v11.2 includes the RSA Data Security, Inc. MD5 Message-Digest
Algorithm. Copyright ©1991-2, RSA Data Security, Inc. Created 1991. All rights
reserved. (MD5 Encryption Library v3.0 and MD5 Encryption vMD5C.C) These
technologies are subject to the following terms and conditions: RSA Data Security
MD5 message-digest algorithm RSA Data Security, Inc. MD5C.C - RSA Data Security,
Inc., MD5 message-digest algorithm Copyright (C) 1991-2, RSA Data Security, Inc.
Created 1991. All rights reserved. License to copy and use this software is granted
provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software or this function.
License is also granted to make and use derivative works provided that such works are
identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing the derived work. RSA Data
Security, Inc. makes no representations concerning either the merchantability of this
software or the suitability of this software for any particular purpose. It is provided "as
is" without express or implied warranty of any kind. These notices must be retained in
any copies of any part of this documentation and/or software.

32 OpenEdge® Development: Mobile Applications


1
OpenEdge Mobile Overview

OpenEdge Mobile allows you to build a complete mobile application, including the
mobile client UI, with access to AppServer business logic and data that you can deploy
on a variety of popular mobile and Web devices and platforms, including:

• Apple iOS devices, such as the iPhone and iPad

• Android devices, including numerous smart phones and tablets made by a variety
of manufacturers

• Web browsers running on a wide variety of computers and mobile devices

• Apache Tomcat Web server for REST access to the AppServer

OpenEdge Mobile supports development for two basic types of client UI (Mobile App):

• Mobile Web Apps that run in a Web browser on multiple platforms and devices

• Mobile Native Apps that are built the same as Web apps, but that are deployed to
run in native device containers using hybrid technology

You can build and test all application components end-to-end, including the AppServer
and corresponding Mobile services, the Mobile App, and the Web transport between
them, using OpenEdge Mobile tools available through Progress Developer Studio for
OpenEdge (Developer Studio). When your application development is complete, you
can then deploy the application components as required to supported mobile devices
and Web platforms.

The following sections describe OpenEdge Mobile in greater detail:

• Run-time architecture

• Development architecture and tools

• Deployment options

OpenEdge® Development: Mobile Applications 33


Chapter 1: OpenEdge Mobile Overview

Run-time architecture
The figures in this section provide an increasingly detailed overview of the OpenEdge
Mobile run-time architecture, with shaded and colored elements showing the
OpenEdge components. Note that these figures describe Mobile applications built with
largely OpenEdge Mobile components from end to end, including an OpenEdge REST
transport. However, from any Mobile App, you can also access non-OpenEdge REST
Web services using appropriate calls directly to available REST resources.

Supported Mobile App types


Figure 1 shows the basic end-to-end run-time architecture for the two Mobile App types
supported by OpenEdge Mobile—Mobile Native Apps running directly in the mobile
device OS and Mobile Web Apps running in the Web browser of any hardware
platform. The difference is in how the HTML and JavaScript are deployed and run on
the client. For a Mobile Native App, HTML and JavaScript files are deployed to an
Apple iOS or Android App store to be downloaded and installed on the mobile device
and run in the native device container. For a Mobile Web App, the HTML and
JavaScript files are deployed on a Web server (A) to load and run in a Web browser
(B), as with any HTML Web application. However, the UI might be designed to display
in the smaller real estate of a Web browser running in a mobile device.

Figure 1: OpenEdge Mobile run-time architecture for native and Web apps

34 OpenEdge® Development: Mobile Applications


Run-time architecture

As shown in Figure 1, both Mobile App types can use exactly the same Mobile services
to access the AppServer. A Mobile service supports a set of Mobile resources, which
provide Web access to an ABL application service on the AppServer.

A Mobile interface defines the ABL API for a single Mobile resource, which can be
implemented by either a singleton procedure or a singleton class. (For more
information on singleton procedures and classes, see the sections on AppServer
coding requirements, in Chapter 3, “Creating Mobile Services.”) A Mobile resource
provides access to either a single temp-table or a single ProDataSet with one or more
temp-tables, using a standard set of built-in operations that you implement on the
AppServer to read and modify the data. A Mobile resource can also provide access to
additional AppServer routines to operate on other AppServer data, or even to operate
on the same temp-table or ProDataSet data as the built-in operations, but in different
ways.

An OpenEdge JavaScript data object (JSDO) is an instance of the OpenEdge


JavaScript class, progress.data.JSDO, that provides client access to the data and
operations of a single Mobile resource. The Mobile App calls JavaScript methods on a
JSDO to execute the Mobile operations on the AppServer. The data for these
operations is serialized between the Mobile App and the Web server as JSON
(JavaScript Object Notation) media.

An OpenEdge Mobile Web application provides the transport (REST over HTTP) for
communications between any JSDO running in a Mobile App and a Mobile resource
that the application supports. A Mobile Web application can be deployed and the REST
transport, including application security, can be managed using the same OpenEdge
tools for managing any OpenEdge REST Web application. Note that a single Mobile
Web application supports access to Mobile resources implemented by a single
OpenEdge AppServer (or a single application service with load balancing).

OpenEdge® Development: Mobile Applications 35


Chapter 1: OpenEdge Mobile Overview

Client access to the AppServer using Mobile services


Figure 2 provides an overview of how an OpenEdge JSDO accesses a Mobile
resource, which works the same for a given JSDO regardless of the type of Mobile App.

Figure 2: Accessing OpenEdge Mobile services and resources

Each JSDO created by a Mobile App can access a single Mobile resource, which can
be any of the Mobile resources provided by a particular Mobile service of the Mobile
Web application. A single Mobile Web application can support one or more Mobile
services, and an Apache Tomcat Web server can host multiple Mobile Web
applications.

In Figure 2, the Mobile Web application contains two Mobile services, Inventory and
OrderEntry. The OrderEntry service contains two Mobile resources, Orders and
Customers, which are implemented by the ABL class files Orders.cls and
Customer.cls, respectively, and are accessed, respectively, by the Orders and
Customers JSDOs on the client.

Note: The breakdown of resources in the OrderEntry service is for illustration only.
It implies that the two resources provide a single temp-table each, one with
Order records and one with Customer records. In practice, these temp-tables
might be related using a ProDataSet that is provided by a single Mobile
resource accessed by a single JSDO.

Note that an OpenEdge Mobile Web application installs and runs in an Apache Tomcat
Java container similar to an OpenEdge REST Web application, and can be managed
using the same OpenEdge-supported tools. Likewise, an OpenEdge Mobile service is
very similar to an OpenEdge REST Web service. The difference between them is in
how a Mobile service makes resources available to a Mobile App.

36 OpenEdge® Development: Mobile Applications


Run-time architecture

An OpenEdge REST Web service identifies each resource as a unique URI to which a
REST client sends an explicit HTTP request that ultimately invokes an AppServer
routine. The REST Web service then returns the results of the AppServer routine to the
REST client as an HTTP response, which the client must interpret according to the
requirements of the particular REST Web service.

An OpenEdge Mobile service, instead, presents specified data and routines of an


AppServer singleton class or procedure object as data and operations of a single
Mobile resource and maps the operations for that resource directly to corresponding
JavaScript methods of a single JSDO. The Mobile service does this mapping with the
help of a JSDO catalog file that is generated for the service when it is created. This
JSDO catalog is a JSON file that contains information about the schema of the data
and the operations that each Mobile resource in the service supports. Therefore, a
Mobile App must load this JSDO catalog for a Mobile service before creating a JSDO
to access any Mobile resource that the service provides.

So, instead of a Mobile App having to identify the URI, send an HTTP request, and
interpret the HTTP response for a given REST resource (AppServer routine call), it only
has to call the appropriate method or methods on the JSDO to execute the
corresponding ABL routine in the class or procedure object on the AppServer. All input
parameters, output parameters, and other results of ABL routines are exchanged with
the JSDO and its JavaScript methods as corresponding properties of JavaScript
objects that the Mobile App passes and returns from the JSDO and its methods.

Access to AppServer classes and procedures using


JavaScript objects
Figure 3 shows, in greater detail, how a Mobile service maps the operations of a single
Mobile resource both to the methods of a JSDO in the Mobile App on the client side
and to the ABL routines of a singleton object on the AppServer side.

Figure 3: Accessing AppServer data and business logic from Mobile Apps

OpenEdge® Development: Mobile Applications 37


Chapter 1: OpenEdge Mobile Overview

In Figure 3, a singleton Customers class object provides ABL methods to implement


the operations of the Customers Mobile resource. The figure shows all the operations
that are available for a Mobile resource. The standard, built-in Mobile operations are
create, read, update, and delete (the familiar CRUD operations) and you can use
Developer Studio to annotate ABL routines of the corresponding Mobile interface that
implement them. For each built-in Mobile CRUD operation, you annotate only one ABL
routine as the implementation, in this case an ABL method. All the ABL routines that
implement the built-in Mobile operations must support exactly the same schema in the
form of a single temp-table or ProDataSet parameter. In addition, the read operation
implementation must provide an initial CHARACTER input parameter named filter (see
Table 1). For non-built-in invoke operations, you can annotate any number of ABL
routines using any supported ABL signature. (For more information on the supported
ABL data types, see Appendix A, “ABL to JavaScript Data Type Mapping.”) However,
the ABL routines you annotate as invoke operations cannot already be annotated to
implement built-in CRUD operations.

Table 1 shows the required parameter lists for ABL routines (class methods, internal
procedures, or user-defined functions) that implement the built-in Mobile CRUD
operations.

Table 1: Required ABL parameters for built-in Mobile operations

Built-in
operation Required parameter list for the implementing ABL routine1

create INPUT-OUTPUT { TABLE table-name | DATASET dataset-name


| TABLE-HANDLE table-hdl | DATASET-HANDLE dataset-hdl }2
read INPUT filter3 AS CHARACTER ,
OUTPUT { TABLE table-name | DATASET dataset-name
| TABLE-HANDLE table-hdl | DATASET-HANDLE dataset-hdl }2
update INPUT-OUTPUT { TABLE table-name | DATASET dataset-name
| TABLE-HANDLE table-hdl | DATASET-HANDLE dataset-hdl }2
delete INPUT-OUTPUT { TABLE table-name | DATASET dataset-name
| TABLE-HANDLE table-hdl | DATASET-HANDLE dataset-hdl }2
1. If the implementing ABL routine is a class method, its return type must be VOID. The return value of any
ABL routine is ignored.
2. Because all the built-in operations of a Mobile resource must support the same schema, their
implementations all must share either a TABLE, TABLE-HANDLE, DATASET, or DATASET-HANDLE
parameter with exactly the same temp-table or ProDataSet schema. NOTE: The schema for any
ProDataSet (DATASET or DATASET-HANDLE) parameter can have no data-relations defined with the
NESTED option.
3. The filter parameter is passed as a query string that is intended to filter the records returned for the
temp-table or ProDataSet parameter of a read operation. Your ABL routine can use this value for any
purpose, or ignore the parameter entirely. Note that to allow the prescribed mapping to work between the
ABL routine for the built-in read operation and the JavaScript method that calls it, you must name this
parameter filter in the signature of the ABL routine.

For information on coding and annotating these ABL routines, see Chapter 3, “Creating
Mobile Services.”

38 OpenEdge® Development: Mobile Applications


Run-time architecture

As shown in Figure 3 for the Customers resource, when you create a JSDO for a given
resource, the JSDO provides JavaScript methods that map to each Mobile operation
defined for the resource. Every JSDO supports the same set of built-in methods to call
the built-in Mobile operations. For example, calling the fill( ) method always
executes the Mobile read operation, which in this case is implemented by an ABL
ReadCustomers( ) method. This operation returns all the temp-table records provided
by the implementing ABL routine and stores them in a JSDO internal data store
referred to as JSDO local storage.

JSDO local storage always matches the schema supported by the JSDO resource as
defined by the JSDO catalog for the Mobile service. So, if the JSDO resource supports
a single temp-table schema, the JSDO local storage stores the records returned from
a single temp-table. If the schema is for a single ProDataSet, it stores the records
returned for all temp-tables of the ProDataSet, and maintains them, by default,
according to any defined data-relations.

The JSDO supports additional built-in methods to update the contents of its local
storage. For example, the add( ) method on the JSDO creates a new record in JSDO
local storage. Similarly, the assign( ) method updates, and the remove( ) method
deletes an existing record in JSDO local storage. When the Mobile App calls the JSDO
built-in saveChanges( ) method, it executes the appropriate built-in Mobile create,
update, or delete operation, one at a time, for each record that has changed in its local
storage. What happens on the AppServer to the record handled by each operation
depends entirely on the implementing ABL routine. In Figure 3, the routines that
implement these built-in operations on the AppServer are the DeleteCustomer( ),
CreateCustomer( ), and UpdateCustomer( ) methods, respectively.

A JSDO always executes the methods called for built-in CRUD operations
asynchronously and supports events to which the Mobile App can subscribe functions
to handle the results, whether successful or unsuccessful. These results are returned
in an OpenEdge-defined object (request object), with properties that depend on the
event and operation outcome. So, each ABL routine that implements a built-in
operation can return errors and the same (or a modified version of the) record it
received depending on how the operation succeeds or fails. The request object
returning these results supports a wide variety of success and failure responses that
can be defined for a given mobile application. Note that when a built-in operation fails,
any changes associated with that operation are reverted in JSDO local storage.

For non-built-in invoke operations, each ABL routine accepts its defined input
parameters and returns its defined output parameters and any return value without any
effect on JSDO local storage. Each invoke operation allows the parameters and any
return value to be passed as required for the implementing ABL routine. Input
parameters are passed as properties of an input JavaScript object, and all results,
including any output parameters, return value, and errors, are returned in an output
request object similar to the object returned for built-in operations.

To execute an invoke operation, the Mobile App calls the appropriate JSDO invocation
method, which executes the corresponding ABL routine. By default, an invocation
method executes asynchronously, but can execute synchronously by calling it using
the same signature with an added Boolean parameter set to false. For example, in
Figure 3, a call to the getCreditHistory( ) invocation method on the JSDO executes
the GetCreditHistory( ) method on the AppServer. If getCreditHistory( ) is
called asynchronously, the resulting JavaScript request object is returned to the Mobile
App as a parameter of any function subscribed as a handler for the appropriate JSDO
event. If called synchronously, getCreditHistory( ) returns the same JavaScript
request object as the method return value.

OpenEdge® Development: Mobile Applications 39


Chapter 1: OpenEdge Mobile Overview

Access to Mobile services with user login sessions


In Figure 3, it is the JSDO catalog for the OrderEntry service that ultimately enables
JavaScript methods of the Customers JSDO to execute ABL methods of the
Customers class to implement operations of the Customers resource. Before it can
create and use a JSDO to access a Mobile resource, an OpenEdge Mobile App must
log into the appropriate Mobile Web application and load the catalog file for the Mobile
service that provides the resource.

Depending on the Web server and Mobile Web application security configuration, the
Mobile App can log into the Web application as directed by the Web server, native
device container, or browser, or by using the login( ) method of the OpenEdge
JavaScript class, progress.data.Session. If the Mobile App login successfully
occurs before calling this login( ) method, the Mobile App must still call the method
in order to establish the login session with the Mobile Web application and load its
JSDO catalog files.

To use a Session object to establish the login session, the Mobile App creates an
instance of the class and invokes the login( ) method on that instance, passing the
Mobile Web application URI and optional user credentials as parameters. The exact
user login sequence can be affected by the Web server security configuration, the
Mobile App type, design, and platform, and how Mobile Web application resources are
protected on the Web server. For example, if the required user credentials have
already been authenticated prior to calling this method, any user credentials you pass
to the method are ignored. For more information on establishing a login session for a
Mobile App, see Chapter 4, “Creating Mobile Apps using JSDOs.”

Loading the JSDO catalog

Once the login( ) method on a Session object has been successfully called for a
given OpenEdge Mobile Web application, the Mobile App can then call the
addCatalog( ) method on the Session object to load the JSDO catalog for each
Mobile service in the Mobile Web application it needs to access. Each JSDO catalog
has a URI that you pass to this method, along with optional user credentials if the
catalog requires separate user authentication. Note that by default the filename for a
JSDO catalog has the name of the Mobile service for which the catalog is created.
Therefore, its filename and extension have the form, service-name.json. Once a login
session is successfully established, and all required JSDO catalogs are loaded, the
Mobile App can invoke operations for all authorized Mobile services and resources.

Note that Mobile services and resources in a Mobile Web application are protected
using the Spring Security framework, which is installed with OpenEdge to secure
Mobile and REST Web applications. For more information on using Spring Security to
secure Mobile or REST Web applications, see the sections on managing REST
application security in OpenEdge Application Server: Administration.

Single sign-on to the AppServer

OpenEdge also supports single sign-on (SSO) to the AppServer for a user login
session, depending on the OpenEdge Mobile Web application security configuration.
When appropriately configured, and after a Mobile Web application authenticates a
login session, the application creates an SSO client-principal that it sends to the
AppServer with each AppServer request generated by a JSDO. This client-principal
contains the user ID used to login a Mobile App and a unique session ID. The
AppServer can then access this client-principal using the CURRENT-REQUEST-INFO
attribute on the SESSION system handle and use it to establish an SSO login session
for the current request.

40 OpenEdge® Development: Mobile Applications


Run-time architecture

For information on configuring a Mobile Web application to provide an SSO


client-principal to the AppServer with each AppServer request, see the sections on
SSO support for REST applications in OpenEdge Application Server: Administration.
For more information on accessing this SSO client-principal on the AppServer, see the
reference entry for the CURRENT-REQUEST-INFO attribute in OpenEdge Development:
ABL Reference and the sections on establishing login sessions and client login context
in OpenEdge Application Server: Developing AppServer Applications.

OpenEdge® Development: Mobile Applications 41


Chapter 1: OpenEdge Mobile Overview

Development architecture and tools


Figure 4 shows an overview of the development architecture and tools for OpenEdge
Mobile.

Figure 4: OpenEdge Mobile development architecture and tools

The development tool set consists of two main components:

• Progress Developer Studio for OpenEdge (Developer Studio) — The main


OpenEdge on-premise tool where you initiate all OpenEdge Mobile development
work

• Progress OpenEdge Mobile App Builder — Available in the cloud, you can use
the Mobile App Builder to visually design and code a complete Mobile App for all
supported Web and Native App platforms. This tool provides built-in JSDO
services to help map JSDO local storage to the UI elements in a Mobile App.
When you are ready to test, you can run the Mobile App in an emulator for the
selected platform. If you choose not to use the Mobile App Builder, you can also
use other JavaScript and HTML coding tools in Developer Studio to build your
Mobile App.

Creating Mobile projects


To build Mobile services and Apps, you must work in a Mobile project, which is an
OpenEdge project type that you create in Developer Studio. You can create a Mobile
project either as a new project or by adding the required facets to or performing a
Mobile function in an existing OpenEdge project. When you first create a Mobile project
in Developer Studio, you must also enter Progress user credentials in Developer Studio
that you share with the Mobile App Builder. This allows the on-premise Mobile project
in Developer Studio and the corresponding Mobile App Builder project in the cloud to
exchange files and data.

42 OpenEdge® Development: Mobile Applications


Development architecture and tools

Building Mobile services


Once you have a Mobile project in Developer Studio, you can build Mobile services.
Depending on what you are trying to accomplish, might begin by defining a database
connection for the project and also defining a database connection for an OpenEdge
AppServer (outside of Developer Studio) that is associated with an AppServer facet of
the project. Also, when you develop the ABL source code for the Mobile resources you
include in Mobile services, it is created in a project folder associated with this
AppServer.

As noted in the “Run-time architecture” section on page 34, each Mobile resource is
created from a Mobile interface that defines the ABL API for that resource in a single
class or procedure file. This class or procedure must be coded as a singleton object
that a Mobile application creates on the AppServer to run the corresponding resource
of a given Mobile service.

You can use Developer Studio wizards to define a Mobile interface in one of the
following ways:

• Use the New Business Entity wizard to create a new Business entity class from a
data model based on a single temp-table or a ProDataSet with one or more
temp-tables. Creating a Business entity class defines a default set of ABL class
methods, each of which implements a create, read, update, or delete (CRUD)
operation on the specified data model. In addition, you can have a new Business
entity class and its methods automatically annotated to define the interface for the
built-in operations of a Mobile resource. You then manually code the body of each
ABL method to implement the functionality for each operation. You can then
directly use this new, annotated Business entity class file to define a single
resource in a Mobile service.

• Use the Define Service Interface wizard to annotate the ABL routines of existing
class or procedure files based on the corresponding temp-table or ProDataSet
data model. This can be a class or procedure file that is already coded as a
singleton, including an existing Business entity class that is not already annotated
as a Mobile interface. This allows you to define the Mobile interface from existing
AppServer code, or to define non-built-in invoke operations, for example, in an
existing Business entity class that currently has only built-in CRUD operations
defined. In any case, once an existing class or procedure file is appropriately
annotated, you can use this file to define a single Mobile resource in a Mobile
service.

Caution: Developer Studio relies on wizards to annotate all class and procedure files
as Mobile interface files in order to correctly define resources for Mobile
services. Do not manually enter or modify these annotations in source code,
or the Mobile service created with these resources might fail to function.

Once you have coded and annotated all the class and procedure files needed to define
the resources of a Mobile service, you can build the service in Developer Studio using
the New Mobile Service wizard to select the Mobile resource files to include in the
service. Once you complete this wizard, Developer Studio defines the Mobile service
along with its JSDO catalog file. (For an overview of JSDO catalog files, see the “Client
access to the AppServer using Mobile services” section on page 36.)

For more information on building Mobile services, see Chapter 3, “Creating Mobile
Services.”

OpenEdge® Development: Mobile Applications 43


Chapter 1: OpenEdge Mobile Overview

Publishing Mobile services


In order to create Mobile Apps to access the Mobile services you have built, you can
publish the services to a built-in Web server (OE Web Server) that is installed with
OpenEdge. The OE Web Server is an Apache Tomcat Web server configured to run
both OpenEdge Mobile Web applications and OpenEdge REST Web applications.
When you publish Mobile services, you package them in a WAR file that contains a
Mobile Web application with one or more Mobile services, including their JSDO
catalogs and related artifacts, and any Mobile App to be deployed to the Web server.
Developer Studio provides features to package your Mobile services (along with any
associated Mobile App) into the WAR file and deploy it to the OE Web Server. For the
default Tomcat configuration, this automatically installs the Mobile Web application and
its Mobile services, and enables them for access by any authorized Mobile App.

Building Mobile Apps


As previously described for Figure 4, the Progress OpenEdge Mobile App Builder is the
main OpenEdge Mobile tool for building Mobile Apps. It is hosted in the cloud and can
launch within any external Web browser that supports HTML5 and that you also
configure to run the Mobile App Builder from Developer Studio. When you build a
Mobile App with this tool, you design and build the UI for the App and code the
JavaScript to access the Mobile services and associated JSDO catalog files that you
have published to the OE Web Server. All the UI design and coding in the Mobile App
Builder creates the HTML and JavaScript files for the Mobile App in a project that is
also hosted in the cloud, but shared with your on-site Mobile project in Developer
Studio.

The Mobile App Builder allows you to visually design the UI for a Mobile App using
drag-and-drop, similar to the Visual Designer in Developer Studio for buildinOct 8, 2011
(OE 11.0)NET UIs. It also provides templates for designing HTML pages for a given
device type, such as a phone or tablet. You can then add JavaScript when coding
events on the HTML elements in a page. It also provides built-in code services (JSDO
services) for mapping JSDO data to HTML elements based on the Mobile resources
you intend to use in selected JSDO catalog files.

When you are ready to test, you can have the Mobile App Builder publish the HTML
and JavaScript files for the Mobile App to your on-site Mobile project in Developer
Studio, from where it can be published to the OE Web Server. A test function in the
Mobile App Builder then launches an emulator based on the type of Mobile App you
are building (Mobile Web App, or Mobile Native App for an iPhone or Android device),
so you can see the App run as it might appear in the target platform, but displayed in
your HTML5 Web browser. For a Mobile Native App, you can also have Mobile App
Builder package it into a mobile device deployment file (IPA for Apple iOS or APK for
Android), which you can install for testing on the appropriate mobile device.

44 OpenEdge® Development: Mobile Applications


Development architecture and tools

Building Mobile Apps without the Mobile App Builder


If you prefer, you can build your own Mobile Apps without using the Mobile App Builder.
You can use the built-in Developer Studio tools for coding HTML and JavaScript,
instead. OpenEdge Mobile provides a progress.ui.UIHelper JavaScript class to
help map JSDO data to HTML pages that you build yourself. For a Mobile Web App,
you can publish the files for testing and deployment using the OpenEdge Mobile
wizards in Developer Studio. For a Mobile Native App, you need, in addition, to have
external access to a hybrid packaging tool, such as Adobe PhoneGap, in order to test
your Mobile App in the native container of a mobile device.

For more information on building Mobile Apps, see Chapter 4, “Creating Mobile Apps
using JSDOs.”

OpenEdge® Development: Mobile Applications 45


Chapter 1: OpenEdge Mobile Overview

Deployment options
For production deployment, the options basically consist of what you can deploy to an
Apache Tomcat Web server (preferably an installed OE Web Server) and what you
need to deploy to mobile app stores for download and installation on mobile devices,
and the security considerations for all of it.

At a minimum, you deploy your Mobile services for a single Mobile application to the
Web server, typically all in one Mobile Web application WAR file. If you are deploying
a Mobile Web App for access by Web browsers on mobile devices, you can deploy it
either in the same WAR file with your Mobile services, if you can use the same Web
server, or in a separate Web application WAR file, if you need the Mobile App to load
from a different Web server.

For a Mobile Native App, which installs and runs in the native container of a mobile
device, you need to package an Apple iOS App in an IPK file and package an Android
App in an APK file for deployment to the appropriate app stores. Each type of Mobile
Native App has additional deployment requirements that you need to complete in order
to make the App available from an app store.

One consideration that affects all Mobile Native Apps and any Mobile Web App that you
deploy to a Web server that is different from the Web server where you deploy your
Mobile services is the need to use absolute URIs to login and access the JSDO
catalogs for your Mobile services. This means that you need to maintain separate
JavaScript sources for the different environments where you deploy these Mobile
Apps, for example, one source for development testing and another for production
deployment.

Security considerations really begin with Mobile App development, since Mobile App
design can affect your security options. You can make some of the important security
decisions during Mobile App development, which can then be duplicated during
deployment the deployment of Mobile Services. Other security options, especially
involving user controls, can only be configured during production deployment.

For more information on these deployment options and how to approach them, see
Chapter 5, “Deploying Mobile Applications.”

46 OpenEdge® Development: Mobile Applications


2
Example: A Simple Mobile App

This chapter steps you through the creation of a simple Mobile application. It describes
the creation of a simple Mobile service with access to an OpenEdge database using
Progress Developer Studio for OpenEdge. It also describes how to use the Progress
OpenEdge Mobile App Builder to create a simple Mobile App (UI) that accesses this
service and displays information from the database.

• Setting preferences

• Creating a new Mobile OpenEdge project

• Connecting to the OpenEdge Database

• Creating an include file

• Creating a new Business Entity

• Creating the Mobile App

• Adding the JSDO service to the client

• Building and testing the Mobile App

• Troubleshooting

OpenEdge® Development: Mobile Applications 47


Chapter 2: Example: A Simple Mobile App

Setting preferences
When you first start Progress Developer Studio for OpenEdge (Developer Studio) to
create a Mobile App, you need to set some preferences. The Mobile App Builder runs
in a Web browser, so you must specify one. The browser must be HMTL5 compliant.

Note: The names for the project, Mobile App, Business Entity, and other items given
in this example must be used exactly as is for the Mobile App to work. These
names are used in the code provided in this chapter. See the
“Troubleshooting” section on page 60 for more information.

To select a web browser:

1. Select Window→ Preferences→ General→ Web Browser.

2. Select Use external web browser.

3. Choose a supported browser. If no supported browser is listed but you have one
installed, click New, type in the browser’s name, and then browse to the installed
location.

4. Click Apply.

You must also enter login credentials to use the Mobile App Builder.

To enter your credentials:

1. Select Window→ Preferences. Expand Progress OpenEdge and select Mobile


App Builder. Click Next.

2. Enter the user name and password associated with your Progress account.
Click OK.

48 OpenEdge® Development: Mobile Applications


Creating a new Mobile OpenEdge project

Creating a new Mobile OpenEdge project


Now that you have selected a browser and entered your credentials, you can start
creating the app.

To create a new Mobile project:

1. Select File→ New→ Progress→ OpenEdge Project. Name the project


MyMobile and select Mobile from the drop-down menu. Click Next.

2. Click Next again to accept the defaults on the AVM and layout options page.

3. On the Define AppServer content module page, select restbroker1 as your server.
Click Next.

4. A Mobile service is created automatically. On the Create a Mobile Service page,


select restmgr1 as your server. Click Next.

5. On the Create a Mobile App page, select restmgr1 as your server. Note that
Developer Studio automatically appends “App” to your project name to create the
name of your Mobile App. Click Next.

6. Click Next to accept the PROPATH defaults.

7. Click Configure database. For this sample app, add a new connection to the
Sports2000 database provided with OpenEdge. Use localhost as the Host name
at port 5555.

8. Click Finish.

9. Click Yes when prompted if you want to open the server perspective.

By default, the Mobile App Builder will now be launched in a browser window. Minimize
the browser window for now and return to Developer Studio.

OpenEdge® Development: Mobile Applications 49


Chapter 2: Example: A Simple Mobile App

Connecting to the OpenEdge Database


To enable your app to display OpenEdge data, the App Server must be connected to
an OpenEdge database.

To connect the AppServer to the database:

1. Double-click on restbroker1 in the Server view.

2. Click Open launch configuration.

3. Go to the Database tab, and select the Show all radio button.

4. Select the Sports2000 database connection.

5. Close the restbroker editor.

6. Right-click on restbroker1 and choose Start.

50 OpenEdge® Development: Mobile Applications


Creating an include file

Creating an include file


Before creating a new Business Entity for the Mobile service, you must create an
include file that contains a temp table that describes the schema of the Sports2000
database.

To create an Include file:

1. Select File→ New→ ABL Include.

2. Select a container and name the file dsCustomer.i. Click Finish.

3. In the body of the include file, copy and paste the following code:

DEFINE TEMP-TABLE eCustomer NO-UNDO BEFORE-TABLE beCustomer


FIELD CustNum AS INTEGER
FIELD Name AS CHARACTER FORMAT "X(20)"
FIELD Address AS CHARACTER
FIELD Phone AS CHARACTER
FIELD SalesRep AS CHARACTER
FIELD Balance AS DECIMAL
FIELD State AS CHAR
FIELD numOrders AS INT
INDEX CustNum IS UNIQUE PRIMARY CustNum
INDEX Name NAME.

DEFINE DATASET dsCustomer


FOR eCustomer.

4. Save the file in your working directory and close the file.

OpenEdge® Development: Mobile Applications 51


Chapter 2: Example: A Simple Mobile App

Creating a new Business Entity


A Business Entity is an ABL class (CLS) file that includes pre-defined Mobile service
annotations. For more information, see “Coding ABL routines to implement a Mobile
resource” section on page 70.

To create a new Business Entity:

1. Select File→ New→ Business Entity.

2. Browse to \MyMobile\AppServer for the Package root, and enter dsCustomer as


the Business Entity name. Click Next.

3. In the Schema file field, browse to the location of the dsCustomer.i file you
created previously. From the schema displayed, choose dsCustomer.

4. Click Finish.

52 OpenEdge® Development: Mobile Applications


Creating a new Business Entity

5. In the Business Entity source code, copy and paste the following code to the
ReaddsCustomer method. This reads records from the Sports 2000 database.

DEFINE DATA-SOURCE srcCustomer FOR Customer.


EMPTY TEMP-TABLE eCustomer.

BUFFER eCustomer:ATTACH-DATA-SOURCE(DATA-SOURCE srcCustomer:HANDLE).

filter = "where custnum < 100".


IF filter NE "" AND filter NE ? THEN
DATA-SOURCE srcCustomer:FILL-WHERE-STRING = filter.

DATASET dsCustomer:FILL().

BUFFER eCustomer:DETACH-DATA-SOURCE().

RETURN.

6. Save and close the class file.

To add the Business Entity to the Mobile Service:

1. In the Project Explorer pane, expand Defined Services and right-click


MyMobileService. Click Edit.

2. Click Next on the Edit a Mobile Service page.

3. On the Modify a Mobile Service page, select the check box next to the
dsCustomer.cls file. Click Finish.

OpenEdge® Development: Mobile Applications 53


Chapter 2: Example: A Simple Mobile App

Creating the Mobile App


You are now ready to use the Mobile App Builder to create the Mobile App. By default,
the Mobile App Builder creates a home page that you can customize. You can open the
Mobile App Builder at any time by double-clicking your application name in the Project
Explorer pane. For more information, see “Getting started with the Mobile App Builder”
section on page 90.

To customize the client UI:

1. In the Project pane, expand the Pages folder and click the home page.

2. Click on the Caption and change the text to My Mobile App.

3. Add a list to the page by dragging and dropping from the Components pane. In
the Properties pane, change the Name field to CustList and change the Items
field to 1.

4. Click on the list item itself and change the Name field to CustItem.

5. Drag and drop a label on top of the list item. Change the name of the label to
CustName.

To add an event to the page:

1. Expand the events panel at the bottom of the designer.

2. In the Component menu, select home.

54 OpenEdge® Development: Mobile Applications


Creating the Mobile App

3. In the Event menu, select Load.

4. In the Action menu, select Run JavaScript.

5. In the JavaScript editor that appears, copy and paste the following code:

var settings;
try {
/* CHANGE THIS TO POINT TO YOUR SETTINGS SERVICE */
settings = MyMobileService_dsCustomer_Settings;

pdsession = new progress.data.Session();

var loginResult =
pdsession.login(settings.serviceURI,"","");

if (loginResult != progress.data.Session.LOGIN_SUCCESS) {
console.log('ERROR: Login failed with code: ' + loginResult);
switch (loginResult) {
case progress.data.Session.LOGIN_AUTHENTICATION_FAILURE:
cMsg = 'Invalid user-id or password';
break;
case progress.data.Session.LOGIN_GENERAL_FAILURE:
default:
cMsg = 'Service is unavailable';
break;
}
}
} catch (e) {
cMsg = "Failed to log in";
console.log(e.stack);
}

if (cMsg != "ok") {
alert(cMsg);
return;
}
pdsession.addCatalog(settings.catalogURI);

6. Click Add event.

OpenEdge® Development: Mobile Applications 55


Chapter 2: Example: A Simple Mobile App

Adding the JSDO service to the client


An OpenEdge JavaScript data object (JSDO) provides client access to ABL data. A
JSDO service is a coding service in the Mobile App Builder that simplifies the mapping
between JSDO data and the HTML elements of a Mobile App. For more information on
the JSDO class, see Chapter 4, “Creating Mobile Apps using JSDOs”.

To add the JSDO service to the client:

1. In the Project pane, select Create New→ Service.

2. Select the JSDO Service radio button.

3. Click Upload a file and browse to the MyMobileService.json file. The file is
located in your workspace folder in \MyMobile\WebContent.

4. Click Select resources.

5. Select MyMobileService.ds.Customer and click Create services.

6. Click Close.

7. In the Project pane, expand MyMobileService.ds.Customer and click on


MyMobileService_ds_Customer_Settings.

8. Change the default value of catalogURI to http://<your IP address>:8980/


MyMobileService/static/mobile/MyMobileService.json

9. Change the default value of serviceURI to


http://<your IP address>:8980/MyMobileService

10. Click Save.

11. In the Project pane, click on home to get back to the UI. Click on the Data tab that
appears to the left of the components.

56 OpenEdge® Development: Mobile Applications


Adding the JSDO service to the client

12. In the drop-down menu labeled Add data source, choose Service, and then
choose MyMobileService_dsCustomer_JSDO. Click Add and name the service
Customer.

13. Add another data source by choosing Service again. Choose


MyMobileService_dsCustomer_Read. Click Add and name the service Read.

14. Click Edit mapping next to the Read service.

15. Select the Response tab.

16. Expand dsCustomer and all of its components on the left, and do the same for
home and all of its components on the right.

17. Find Name under eCustomer and drag and drop it onto Text under CustName.

18. Drag and drop eCustomer onto CustItem.

19. Click Back to datasources.

20. Click on the Design tab and expand the Events tab at the bottom of the page.

21. Create a new event:

a. In the Component menu, select home.

b. In the Event menu, select Load.

c. In the Action menu, select Invoke Service.

d. Choose Customer for Service.

e. Click Add event.

OpenEdge® Development: Mobile Applications 57


Chapter 2: Example: A Simple Mobile App

22. Click on the Data tab and expand the Events tab at the bottom of the page.

23. Create a new event:

a. In the Component menu, select Customer.

b. In the Event menu, select Success.

c. In the Action menu, select Invoke Service.

d. Choose Read for Service.

e. Click Add event.

24. Click Save.

58 OpenEdge® Development: Mobile Applications


Building and testing the Mobile App

Building and testing the Mobile App


The Mobile App is now ready to be tested in the built-in emulator.

To test the app:

1. In the Server view in Developer Studio, right click restmgr1 and choose Start.

2. Choose Run→ Run Configurations.

3. Double-click Progress OpenEdge Mobile in the pane on the left.

4. Enter a name for the configuration. Select MyMobile from the Project menu, and
MyMobileApp from the Mobile App menu.

5. Select the radio button for Run on server. Developer Studio will automatically
generate the necessary link.

6. Click Run. After launching is complete, the mobile preview browser will open, and
the Mobile App will run in the emulator.

To view the app on a mobile device, open a browser on your device and enter the
following URL: http://<ip address>:8980/MyMobileApp

For information on deploying the Mobile App for Web, Android, or Apple iOS, see
Chapter 5, “Deploying Mobile Applications.”

OpenEdge® Development: Mobile Applications 59


Chapter 2: Example: A Simple Mobile App

Troubleshooting
If MyMobileApp does not display data, check the following possible sources of error.

Developer Studio
Choose the Servers tab.

1. Make sure restbroker1 is running and synchronized. If not, make sure your
database server is running and that restbroker1 is connected to it.

2. Make sure restmgr1 has an entry for the mobile service and is synchronized. If not,
you may need to stop the tomcat server, delete some artifacts, and then restart
the tomcat server.

a. In a proenv shell, type protc stop and press Enter.

b. Navigate to Progress/OpenEdge/servers/tomcat/webapps in your installation


directory. There should be two WAR files named MyMobileApp.war and
MyMobileService.war and two folders named MyMobileApp and
MyMobileService. Delete the WAR files and the folders. If all four artifacts are
not there, delete what is there.

c. In a proenv shell, type protc start and press Enter.

d. In the Servers tab, right-click on restmgr1 and choose Publish.

Note: After republishing several times, there are sometimes leftover files that can
be deleted. To delete these files, use the protc clean command after protc
stop and before protc start.

Mobile App Builder


Check the following in the Mobile App Builder in your web browser.

1. Open MyMobileService_dsCustomer_Settings in the Services folder. (If the name


of your _Settings document has a different name, open this file.)

a. The catalogURI should be:

http://<your-ip-address>:8980/MyMobileService/static/mobile/My
MobileService.json

If you did not use MyMobileService for the service name, replace
MyMobileService with your service name.

b. The serviceURI should be:

http://<your-ip-address>:8980/MyMobileService

c. The resourceName should be dsCustomer. If you did not use dsCustomer for
your business entity, replace dsCustomer with the correct name.

60 OpenEdge® Development: Mobile Applications


Troubleshooting

2. Check the JavaScript associated with the Load event of the home page.

a. The first parameter in the pdsession.login call should be


MyMobileService_dsCustomer_Settings.serviceURI. If your service name is
not MyMobileService and/or your business entity is not named dsCustomer,
modify this parameter.

b. The first parameter in the pdsession.addCatalog call should be


MyMobileService_dsCustomer_Settings.catalogURI. If your service name is
not MyMobileService and/or your business entity is not named dsCustomer,
modify this parameter.

c. Check that the Run JavaScript event is the first Load event and the Invoke
Service is the second Load event.

Web Browser
Open a new browser window and try the following.

1. The URL http://<your-ip-address>:8980 should display the tomcat home


page. If not, open a proenv shell, type protc start, and press Enter.

2. The URL http://ip-address:8980/MyMobileService/rest will display


available services. If you do not have any available RESTful services, you need
to republish MyMobileService. See the “Developer Studio” section on page 60.

General
Open the Windows Firewall and make sure port 8980 is open.

OpenEdge® Development: Mobile Applications 61


Chapter 2: Example: A Simple Mobile App

62 OpenEdge® Development: Mobile Applications


3
Creating Mobile Services

As you may recall from Chapter 1, “OpenEdge Mobile Overview,” an OpenEdge


JavaScript data object (JSDO) in a Mobile App allows you to access the data and
operations of a Mobile resource provided by a Mobile service. When you develop an
OpenEdge Mobile application, you typically first develop the interface to each Mobile
resource that you intend to access using JSDOs, then create the Mobile services to
provide these Mobile resources to a Mobile App. If this is your first Mobile application,
you need to create a new Mobile project in Progress Developer Studio for OpenEdge
(Developer Studio) in order to start OpenEdge Mobile development.

This chapter describes options and procedures for starting Mobile development and
creating and testing Mobile services, as follows:

• Getting started with OpenEdge Mobile development

• Coding AppServer services for OpenEdge Mobile

• Creating Mobile resources

• Creating Mobile services

• Publishing Mobile services for testing

• URIs for accessing Mobile Web applications, services, and resources

OpenEdge® Development: Mobile Applications 63


Chapter 3: Creating Mobile Services

Getting started with OpenEdge Mobile development


The following sections describe how to get started with Mobile development:

• Starting up Developer Studio for Mobile development

• Configuring and managing OpenEdge servers from Developer Studio

• Creating an OpenEdge Mobile project

• Creating and testing a Mobile service

Starting up Developer Studio for Mobile development


When starting up Mobile development, you might want to begin with a review of the
features you need and set some basic options.

To start up Developer Studio for MObile development:

1. Choose one of the items under Start→ Progress→ Developer Studio 3.7,
preferably using a separate Mobile workspace if you already have other
workspaces defined in Developer Studio.

2. If this is your first time using Developer Studio:

a. From the main menu, select Help→ Help Contents. The Help - Progress
Developer Studio window appears.

b. Open the Progress Developer Studio for OpenEdge Guide and begin with the
“Getting Started” and “OpenEdge Projects” topics for basic information about
using Developer Studio.

c. Continue with the “OpenEdge Mobile” topic for information on developing


OpenEdge Mobile applications.

The present manual also refers to the online help for more detailed instructions on
performing various tasks.

3. If you plan to use the Progress OpenEdge Mobile App Builder to build Mobile
Apps, follow the tasks in the online help for configuring the workspace for Mobile.
These include (but might not be limited to):

• Setting user credentials — You need to enter your Progress ID user


credentials in Developer Studio the first time you use the Mobile App Builder,
and again in the Progress ID login page each time Mobile App Builder starts
up without a Progress ID login active in the Web browser.

• Configuring an external Web browser — This browser runs the Mobile App
Builder (after you log in using your Progress ID account) and must support
HTML5.

Note: Developer Studio does not support running the Mobile App Builder in
an internal browser.

64 OpenEdge® Development: Mobile Applications


Getting started with OpenEdge Mobile development

For more information on getting started with the Mobile App Builder, see
Chapter 4, “Creating Mobile Apps using JSDOs.”

Configuring and managing OpenEdge servers from


Developer Studio
OpenEdge Mobile relies on OpenEdge servers to create and work with Mobile
services. Before you first start Developer Studio, you might start by configuring these
servers, including any database servers that you need for development. This
description assumes that you use OpenEdge Management or OpenEdge Explorer to
maintain your OpenEdge servers. For more information on these OpenEdge tools, see
OpenEdge Management and OpenEdge Explorer: Getting Started. When properly
configured, Developer Studio allows you to access these from various views and
menus.

Before configuring and managing OpenEdge servers from Developer Studio, you need
to configure a connection to OpenEdge Explorer or OpenEdge Management.

To configure an OpenEdge Explorer or OpenEdge Management connection:

1. From the main menu, select Window→ Preferences. The Preferences window
appears.

2. Select the Progress Explorer→ Server→ OpenEdge Explorer Connections


node. The OpenEdge Explorer Connections page appears.

3. Select the default connection and choose Edit. The Edit Connection Profile
window appears.

4. Modify the configuration settings that you require to access your installation of
OpenEdge Explorer or OpenEdge Management. Verify, especially, the user name
and password.

5. Choose Test Connection to verify that the connection works, and if necessary,
re-configure the connection (or your OpenEdge Explorer) settings until it does so.

6. Once your connection works, choose Create Servers and Finish. This ensures
that Developer Studio is connected to OpenEdge Explorer or OpenEdge
Management and all the default OpenEdge servers, and any others that you have
created. This closes the Edit Connection Profile window.

7. In the OpenEdge Explorer Connections page, choose OK to close the


Preferences window.

Once you have a working connection established, you can quickly open OpenEdge
Explorer or OpenEdge Management from either the Servers or the Progress
OpenEdge Server Monitor view, or from the OpenEdge→ Admin menu. Using
OpenEdge Explorer or OpenEdge Management, you might want to create and
configure any OpenEdge servers that you need for OpenEdge Mobile.

OpenEdge® Development: Mobile Applications 65


Chapter 3: Creating Mobile Services

OpenEdge installs with default instances for some servers that are appropriate for
Mobile development:

• OE Web Server — An Apache Tomcat Web server configured with a REST


Management Agent to deploy and monitor Mobile Web applications. The default
instance is restmgr1.

• AppServer — An AppServer configured with the state-free operating mode, the


only operating mode supported for OpenEdge Mobile. The default instance is
restbroker1.

• Database — You can create and startup any server or servers for
OpenEdge-supported databases you need to access from the AppServer and
your Mobile projects. Although you can configure OpenEdge RDBMS connections
for access from Developer Studio, creating a server for the database allows you
to connect and manage the database in multi-user mode from multiple clients,
including OpenEdge tools and utilities. There is no default installed database
server.

Note: You can define database connections for an AppServer either 1) in


Developer Studio by choosing from the list of available database
connections when you configure AppServer launch configuration settings
(typical for Mobile services development), or 2) in OpenEdge Explorer by
setting the server startup parameters in the Agent tab during AppServer
configuration (typical for Mobile services deployment).

Once you have defined the servers you want to use, you can start and manage the
AppServer and OE Web Server instances listed in the Servers view of Developer
Studio by opening the context menu on each instance.

Creating an OpenEdge Mobile project


You can create a new Mobile project or you can convert an existing OpenEdge project
into a Mobile project by performing a Mobile function in the project.

To create a new OpenEdge Mobile project:

1. From the main menu, select File→ New→ OpenEdge Project. The New
OpenEdge Project wizard appears. This wizard begins by asking you to enter a
name for the project (for example, SportsMobile) and to select its type from a list,
which is Mobile. It assigns a default folder for the project based on the location of
the workspace.

Note: Note that whatever name you select for the project becomes the basis for
the default names of some project components that you create. For
example, if you choose to create a Mobile App for the SportsMobile project,
the initial default name for the App is SportsMobileApp. Default names for
Mobile services are created in a similar way.

2. You then click Next and proceed similarly through several pages of the wizard,
which are described in the “Creating an OpenEdge Mobile project” topic of the
online help.

66 OpenEdge® Development: Mobile Applications


Getting started with OpenEdge Mobile development

3. When the Define AppServer content module page appears, the available
AppServers are displayed in a Supported servers list. Select a state-free
AppServer in the list. The installed default state-free AppServer is restbroker1.
If you want Mobile services to be updated on the Web server immediately after
changes are saved, select Publish changes immediately.

4. When the Create a Mobile service page appears, select Create a Mobile
service only if you want a default Mobile service created for the project. You still
must go back and add Mobile resources to it after you build them. Otherwise, you
can use the New Mobile Service wizard to both create the service and add Mobile
resources to it after you have built the resources. For information on building
Mobile resources, see the “Creating Mobile resources” section on page 77. For
information on using the New Mobile Service wizard, see the “Creating Mobile
services” section on page 79. If you choose to create the default service, note that
the service relative URI is the immediate parent URI for the URIs of all Mobile
resources that you add to the service. In the OE Web Servers list, select all
instances of OE Web Servers where you want the service to be published for
testing. The installed default is restmgr1.

5. When the Create a Mobile App page appears, select Create a Mobile App only
if you want a default Mobile App created with the new Mobile project. The process
for doing this is similar to creating a Mobile App using the New Mobile App dialog
after the Mobile project has been created. For more information, see the sections
on creating a Mobile App in Developer Studio in Chapter 4, “Creating Mobile Apps
using JSDOs.”

6. When the Define PROPATH page appears, you can configure the PROPATH
similar to setting the PROPATH as part of the project properties.

7. When the Select database connections page appears, you can configure and
select existing database connections or add and select new database connections
against which the Mobile project allows you to compile ABL source code and from
which the project allows you to choose to define given AppServer run
configurations.

8. When the Static Web Project page appears, the Context root allows you to
specify the default name of the Mobile Web application root, which is also the
name for the relative URI of the Web application and the parent URI of all Mobile
services that you create in the Web application; and it is also the name of the
top-level folder where the Mobile Web application is deployed on the Web server.
The Web content folder name allows you to specify the folder for OpenEdge
JavaScript files that are deployed with the Web application for a Mobile Web App.

9. At this point, choosing Finish creates the folders and all supporting files for the
specified Mobile project. If you chose to create a Mobile App and are using the
Mobile App Builder (see Step 5), the Mobile App is also created as a project in
Mobile App Builder, which automatically displays the project page in the external
browser.

OpenEdge® Development: Mobile Applications 67


Chapter 3: Creating Mobile Services

Creating and testing a Mobile service


You create a Mobile service by specifying one or more existing Mobile resources for it
to contain. Therefore, you need to create Mobile resources before you can create a
Mobile service to contain them. The following general procedure describes how to
create and deploy a Mobile service for testing in a development environment.

To create and test a Mobile service:

1. Create one or more Mobile resources from Mobile interfaces that you define from
new Business entity classes or existing classes and external procedures that can
be instantiated as singleton objects. Classes are inherently designed to be
instantiated as singletons. However, procedures need to be coded properly for
use as singleton objects. In addition, the ABL routines must meet the
requirements of any Mobile operations that they implement.

For more information, see the “Coding AppServer services for OpenEdge Mobile”
section on page 69 and the “Creating Mobile resources” section on page 77.

2. Define the Mobile service with one or more existing Mobile resources. For more
information, see the “Creating Mobile services” section on page 79.

3. Publish one or more of the Mobile services to an OE Web Server for testing. For
more information, see “Publishing Mobile services for testing” section on page 80.

4. Either write a Mobile App to access the published Mobile services and resources
using JSDOs or use a REST client, such as Postman, to access the individual
operations of a Mobile resource as REST resources. For more information, see
the “URIs for accessing Mobile Web applications, services, and resources”
section on page 81.

68 OpenEdge® Development: Mobile Applications


Coding AppServer services for OpenEdge Mobile

Coding AppServer services for OpenEdge Mobile


Several options and requirements apply especially to ABL written for an AppServer that
implements the services and resources of a Mobile Web application:

• Only a singleton class or procedure object can implement the interface to a Mobile
resource.

• The ABL routines that implement Mobile operations have specific coding
requirements.

Singleton classes and procedures as Mobile resources


The ABL to implement the interface to a single Mobile resource must be coded in a
single class or external procedure that can be executed as a singleton object. A
singleton object is a class or external procedure that once initially instantiated, the
same instance is shared by all consumers of the class or procedure no matter how
many times it is instantiated in a given AppServer session.

When on behalf of a Mobile App, a Mobile Web application executes any Mobile
operation of a Mobile resource on an AppServer agent, if the ABL class or external
procedure has not yet been instantiated as a singleton object, the agent instantiates it
and executes ABL routine that implements the operation. When the operation
completes, the object remains instantiated for access by other client requests. So,
when the Mobile Web application executes another operation of the same Mobile
resource, on the same AppServer agent, the same singleton object is then used to
execute the ABL routine for that operation, and so on. If another AppServer agent
executes the operation for the same Mobile resource, the same process repeats itself,
instantiating the singleton if it does not exist and remaining instantiated for all additional
calls to the same resource on that or another AppServer agent where the same object
is instantiated. Once all running AppServer agents have executed an operation for that
same Mobile resource, they all maintain their singleton objects as long as they continue
to run. Again, the process repeats for any additional agent that runs on the AppServer
and responds to a Mobile operation request.

ABL classes are inherently coded to be instantiated as singletons. However, external


procedures must meet a basic requirement to be instantiated as singletons, and that is
they cannot contain any DEFINE PARAMETER statements in the main block. They can
contain internal procedures and user-defined functions with their own parameters,
each of which can implement a Mobile operation exactly like a method of a class.

Note that the singleton coding requirement for external procedures applies only to an
external procedure that implements the interface for a Mobile resource and its
operations. Any additional procedures or classes that a singleton class or procedure
accesses can be implemented as any type of class or procedure that runs on the
AppServer.

For more information on singleton procedures instantiated in the context of an ABL


client, see the RUN statement in OpenEdge Development: ABL Reference. Although
from the ABL client viewpoint, the description of singleton procedure behavior and
coding requirements apply to OpenEdge Mobile as well.

OpenEdge® Development: Mobile Applications 69


Chapter 3: Creating Mobile Services

Coding ABL routines to implement a Mobile resource


When you create a Mobile resource in Developer Studio (see the “Creating Mobile
resources” section on page 77), you can either create a new class to implement the
resource using the New Business Entity wizard or you can use the Define Service
Interface wizard to create the resource from an existing ABL class or external
procedure coded to run as a singleton. Using these wizards, you can define ABL
routines that provide the interface to one or more Mobile resources, each of which
supports one or more Mobile operations.

The two basic options that you must define for any class or procedure that implements
a Mobile resource include the data model and the Mobile operations that the class or
procedure supports. As described previously (see Chapter 1, “OpenEdge Mobile
Overview”), a Mobile resource can support a single data model that is managed by its
built-in Mobile operations, create, read, update, and delete (CRUD). This data model
can be the ABL definition for a single temp-table or a single ProDataSet that contains
one or more temp-tables, including any data-relations defined for them. In the
Developer Studio wizards, you select the data model from any temp-tables and
ProDataSets that are defined in the class or procedure file, or in an external file that
you specify. Once completed, the wizard, if directed, inserts the selected data definition
in the main block of the class or procedure.

Creating an ABL class with the New Business Entity wizard

When you create a Business entity class to define the Mobile resource (using the New
Business Entity wizard), it defines either a single Mobile read operation or a full set of
Mobile CRUD operations for the selected data model. If the selected data model is a
ProDataSet with multiple temp-tables, it also defines a separate invoke operation for
each temp-table that is intended to read the table and return its data to a Mobile App
as a JavaScript object.

Each Mobile CRUD operation is defined by a single VOID ABL method whose name
consists of a concatenation of the operation name with the name of the resource data
model instance, has an empty code block, and has a parameter list that is tailored to
reference the selected data model. The exact parameter list for each method is
prescribed by the Mobile operation that it implements. For example, if the data for the
resource is a ProDataSet named dsCustomer and the read operation is being defined,
the method name is created as ReaddsCustomer. You must then add the code for each
Mobile CRUD operation to implement each operation according to OpenEdge Mobile
functional requirements. For more information, see the “Coding the ABL for Mobile
operations” section on page 71.

In addition, when the wizard is directed to generate a Mobile interface, both the first
ABL statement in the file and each METHOD statement in the class are preceded by a
set of annotations that start with the '@' character and specify how the class and each
method is to be accessed and executed as a Mobile resource and operation.

Caution: Do not modify the annotations in the ABL source file for a Mobile resource.
Doing so can make the resource inaccessible from a Mobile App or otherwise
fail to function.

70 OpenEdge® Development: Mobile Applications


Coding AppServer services for OpenEdge Mobile

Using existing ABL code with the Define Service Interface wizard

When you define a Mobile resource from an existing ABL class or procedure (using the
Define Service Interface wizard), you select the existing class or procedure file, the
data model for the new Mobile resource to support, and the existing ABL routines you
want to implement Mobile operations for the resource. In this case, you select an
operation, and choose the ABL routine you want to implement it. Each ABL routine you
have selected for the resource can implement only one operation, whether it is a
built-in Mobile CRUD operation or a non-built-in invoke operation. Once you have
chosen a routine for every CRUD operation, any remaining routines in the list can each
implement an invoke operation. (If you choose all the ABL routines to implement an
invoke operation, the Mobile resource then supports no CRUD operations.)

When the wizard completes, it annotates the file and the ABL routines chosen to
implement Mobile operations similar to the annotations in the class file and methods
annotated for a new Business entity class.

Note that the Define Service Interface wizard does not verify that the existing ABL
routines you choose are coded properly to implement a given operation. For a Mobile
CRUD operation, the wizard does not even verify that the prescribed parameter list for
the operation is correct. If a Mobile CRUD operation has an incorrect parameter list, the
operation will not work. So, you might have to revise any existing ABL routines that you
chose to implement Mobile CRUD operations to perform the work of that operation, at
least according to OpenEdge Mobile functional requirements (described in the
following section).

Coding the ABL for Mobile operations

No matter how you obtain the ABL class or procedure to implement a Mobile resource,
any ABL routines defined in the source file that you intend to implement Mobile
operations must conform to specific coding requirements. Otherwise, a Mobile App
cannot access the data using JSDOs. These requirements depend on the operation
and the data that you want the resource to provide:

• The ABL routines that implement Mobile CRUD operations must all operate on the
same data model.

• Each ABL routine that implements a built-in Mobile create, read, update, or delete
operation must have a prescribed parameter list, based on the data model that the
Mobile resource supports. When you create a new Business entity for a data
model, the wizard generates correct parameter lists for interacting with that data
model.

• For the fields of temp-tables in the data model, and for the parameter lists and
return types of ABL routines that implement Mobile invoke operations, you can
include all supported ABL data types except RAW and RECID. The ABL RAW and
RECID data types are not supported by OpenEdge Mobile.

• For all built-in Mobile CRUD operations, the return type for class methods must be
VOID and any return values from internal procedures and user-defined functions
are ignored.

OpenEdge® Development: Mobile Applications 71


Chapter 3: Creating Mobile Services

Table 2 shows a complete description of the prescribed parameter list for each built-in
Mobile CRUD operation. The notes in the table describe important additional
requirements and limitations that you need to consider.

Table 2: Prescribed ABL parameters for built-in Mobile operations

Built-in
operation Prescribed ABL parameter list1

create INPUT-OUTPUT { TABLE table-name | DATASET dataset-name


| TABLE-HANDLE table-hdl | DATASET-HANDLE dataset-hdl }2
read INPUT filter3 AS CHARACTER ,
OUTPUT { TABLE table-name | DATASET dataset-name
| TABLE-HANDLE table-hdl | DATASET-HANDLE dataset-hdl }2
update INPUT-OUTPUT { TABLE table-name | DATASET dataset-name
| TABLE-HANDLE table-hdl | DATASET-HANDLE dataset-hdl }2
delete INPUT-OUTPUT { TABLE table-name | DATASET dataset-name
| TABLE-HANDLE table-hdl | DATASET-HANDLE dataset-hdl }2
1. If the implementing ABL routine is a class method, its return type must be VOID. The return value of any
ABL routine is ignored.
2. Because all the built-in operations of a Mobile resource must support the same schema, their
implementations all must share either a TABLE, TABLE-HANDLE, DATASET, or DATASET-HANDLE
parameter with exactly the same temp-table or ProDataSet schema. NOTE: The schema for any
ProDataSet (DATASET or DATASET-HANDLE) parameter can have no data-relations defined with the
NESTED option.
3. The filter parameter is passed as a query string that is intended to filter the records returned for the
temp-table or ProDataSet parameter of a read operation. Your ABL routine can use this value for any
purpose, or ignore the parameter entirely. Note that to allow the prescribed mapping to work between the
ABL routine for the built-in read operation and the JavaScript method that calls it, you must name this
parameter filter in the signature of the ABL routine.

72 OpenEdge® Development: Mobile Applications


Coding AppServer services for OpenEdge Mobile

As noted previously, when you define a Mobile resource by creating a new Business
entity class, it creates the class methods to implement the Mobile CRUD operations
using the correct parameter list, but leaves the code block for each method empty for
you to complete. For this purpose, and for any revisions you might need to make to an
existing class or procedure you are using to define a Mobile resource, you need to
account for certain features of the OpenEdge JSDO:

• A JSDO has an internal data store (JSDO local storage) that is structured to match
the data model selected for the Mobile resource that it accesses. So, if the data
model is a ProDataSet containing ten temp-tables with data-relations, JSDO local
storage is structured to map the data for these ten temp-tables and their
data-relations.

• The built-in Mobile CRUD operations interact directly with the JSDO local storage.
The read operation reads some set of records from its temp-table or its the
temp-tables of its ProDataSet on the AppServer and loads them into JSDO local
storage. The create, update, and delete operations each send a single record
from JSDO internal storage to the AppServer, where they, respectively, add the
new record, update an existing record, or delete the record from the data source.
These operations execute multiple times in order to send multiple records to the
AppServer. So, if the data model is a ProDataSet with multiple tables, the ABL
routine that implements the operation must query each table for which the
operation applies in order to find that one record to create, update, or delete in the
data source.

• When a Mobile create, update, or delete operation completes, it can only return a
single record to JSDO local storage. For example, if an update operation fails, it
might return the record with the field values that currently exist in the data source,
along with raising an ABL error explaining how the update failed.

OpenEdge® Development: Mobile Applications 73


Chapter 3: Creating Mobile Services

Following is a simple ABL class defined for a Mobile resource (with all annotations
removed). It implements the built-in Mobile CRUD operations for a Mobile resource
defined for a ProDataSet named dsCustomer with the following methods:

• Create — CreatedsCustomer( )

• Read — ReaddsCustomer( )

• Update — UpdatedsCustomer( )

• Delete — DeletedsCustomer( )

In the case, the ProDataSet contains a single temp-table, eCustomer, with a


before-table, beCustomer, that is defined for the Customer table in the sports2000
database. The data model follows the class. All the operation methods dispatch their
function to private methods that manage the business logic, such as for the filter string
passed to the ReaddsCustomer( ) method. The create, update, and delete operations
rely on a commitCustomers( ) method to apply the row state from the operation
method to the changed record and execute the SAVE-ROW-CHANGES( ) on the buffer
accordingly.

Simple Business entity class for a Mobile resource (1 of 2)

USING Progress.Lang.*.

ROUTINE-LEVEL ON ERROR UNDO, THROW.

CLASS dsCustomer:

{"dsCustomer.i"}

DEFINE DATA-SOURCE srcCustomer FOR Customer.

METHOD PUBLIC VOID ReaddsCustomer(


INPUT filter AS CHARACTER,
OUTPUT DATASET dsCustomer):

THIS-OBJECT:applyFillMethod (INPUT filter).

END METHOD.

METHOD PUBLIC VOID CreatedsCustomer(INPUT-OUTPUT DATASET dsCustomer):

THIS-OBJECT:commitCustomers(INPUT "", ROW-CREATED).

END METHOD.

METHOD PUBLIC VOID UpdatedsCustomer(INPUT-OUTPUT DATASET dsCustomer):

THIS-OBJECT:commitCustomers(INPUT "", ROW-MODIFIED).

END METHOD.

METHOD PUBLIC VOID DeletedsCustomer(INPUT-OUTPUT DATASET dsCustomer):

THIS-OBJECT:commitCustomers(INPUT "", ROW-DELETED).


END METHOD.

74 OpenEdge® Development: Mobile Applications


Coding AppServer services for OpenEdge Mobile

Simple Business entity class for a Mobile resource (2 of 2)

METHOD PRIVATE VOID commitCustomers(INPUT pcFieldMapping AS CHARACTER,


INPUT piRowState AS INTEGER ):

BUFFER eCustomer:ATTACH-DATA-SOURCE (DATA-SOURCE srcCustomer:HANDLE,


pcFieldMapping).

FOR EACH eCustomer.


BUFFER eCustomer:MARK-ROW-STATE (piRowState).
IF piRowState = ROW-DELETED THEN
DELETE eCustomer.
END.

/* NOTE:
** For the ROW-CREATE case, the code needs to know that there
** is a create trigger in the database for Customer, and
** SAVE-ROW-CHANGES needs to make sure it doesn't clobber the
** CustNum value that was generated from the NextCustNum sequence
** Possible solution: From Developer Studio, when data source is
** specified, you can specify the fields that are auto-generated
** during create.
*/

FOR EACH beCustomer:


BUFFER beCustomer:SAVE-ROW-CHANGES(1, "CustNum").
END.

FINALLY:
BUFFER eCustomer:DETACH-DATA-SOURCE().
RETURN.
END FINALLY.

END METHOD.

METHOD PRIVATE VOID applyFillMethod(INPUT pcWhere AS CHARACTER):

/* get rid of any existing data */


EMPTY TEMP-TABLE eCustomer.

BUFFER eCustomer:ATTACH-DATA-SOURCE(DATA-SOURCE srcCustomer:HANDLE).

IF pcWhere NE "" AND pcWhere NE ? THEN


DATA-SOURCE srcCustomer:FILL-WHERE-STRING = pcWhere.

DATASET dsCustomer:FILL().

FINALLY:
BUFFER eCustomer:DETACH-DATA-SOURCE().
DATA-SOURCE srcCustomer:FILL-WHERE-STRING = ?.
RETURN.
END FINALLY.

END METHOD.

END CLASS.

Note that for the Mobile create, update, and delete operations, the input side of the
INPUT-OUTPUT DATASET parameter replaces the data left over from a prior operation
with the data input for the currently executing operation.

OpenEdge® Development: Mobile Applications 75


Chapter 3: Creating Mobile Services

Following is the dsCustomer.i include file for the simple Business entity class.

dsCustomer.i for the simple Business entity class

DEFINE TEMP-TABLE eCustomer NO-UNDO BEFORE-TABLE beCustomer


FIELD CustNum AS INTEGER
FIELD Name AS CHARACTER FORMAT "X(20)"
FIELD Address AS CHARACTER
FIELD Phone AS CHARACTER
FIELD SalesRep AS CHARACTER
FIELD CreditLimit AS DECIMAL
FIELD Balance AS DECIMAL
FIELD State AS CHAR
FIELD numOrders AS INT
INDEX CustNum IS UNIQUE PRIMARY CustNum
INDEX Name NAME.

DEFINE DATASET dsCustomer


FOR eCustomer.

76 OpenEdge® Development: Mobile Applications


Creating Mobile resources

Creating Mobile resources


As noted in the “Coding AppServer services for OpenEdge Mobile” section on page 69,
you can create a Mobile resource from Developer Studio in the following ways:

• Create a new Business entity class for the resource using the New Business
Entity wizard.

• Define a mobile interface for the resource in an existing ABL class or procedure
using the Define Service Interface wizard.

The following sections describe how to do this, with some additional notes on the
available options. Also, see the tasks for defining Mobile resources in the Developer
Studio online help.

Using the New Business Entity wizard


The New Business Entity wizard creates a Mobile resource from a new Business
entity class that implements specified Mobile operations with empty methods defined
with the signatures required for the corresponding operations.

To create a Mobile resource using the New Business Entity wizard:

1. From the Progress Explorer view, right-click an OpenEdge Mobile project and
select New→ Business Entity on the context menu. The Create a Business
entity class page of the New Business Entity wizard appears.

2. Enter the Business entity name, select your choice of class options and click Next
through the wizard to define the Business entity.

3. On the Select a schema file page enter the resource name (or accept the default),
select the access methods (Mobile operations to define) and the schema (data
model), whether to expose the Business entity as a Mobile resource, and a
resource URI (or accept the default). If you select Read-only operations for the
access methods, only the built-in Mobile read operation is defined for the selected
data model. However, selecting CRUD operations defines all of the Mobile
create, read, update, and delete operations for the selected data model. Note that
for a ProDataSet with multiple tables, the wizard always defines a separate Mobile
invoke operation to read data from each temp-table in the ProDataSet. If you
select Expose as mobile service (the default) the Business entity is created with
the annotations to define it as a Mobile resource. Otherwise, it is created without
these annotations and is not a Mobile resource; to make it a Mobile resource, you
then need to use the Define Service Interface wizard to make the existing
Business entity class a Mobile resource (see the following section), where you can
also define additional Mobile invoke operations.

4. Clicking Finish generates the Business entity class with empty methods for the
specified operations.

You need to add the necessary code to the class to implement the Mobile operations.
For more information, see the “Coding AppServer services for OpenEdge Mobile”
section on page 69.

OpenEdge® Development: Mobile Applications 77


Chapter 3: Creating Mobile Services

Using the Define Service Interface wizard


The Define Service Interface wizard creates a Mobile resource from an existing class
or procedure by selecting existing ABL routines (class methods, internal procedures,
or user-defined functions) to implement selected Mobile operations.

To create a Mobile resource using the Define Service Interface wizard:

1. From the Progress Explorer view, right-click an OpenEdge Mobile project and
select Progress OpenEdge→ Define Service Interface on the context menu.
The Define Service Interface wizard appears.

2. From the Definition Mode drop-down, select Mobile.

3. From the Workspace resources list, select the class or procedure files you would
like to define as Mobile resources. For each file, select the ABL routines that you
want to use to implement Mobile operations. Click Next.

4. From the Edit Annotation page, you can select a file, then specify the
annotations to define both the file as a Mobile resource and selected methods to
implement its Mobile operations. In the Main Annotation tab, you can enter a
resource name and URI (or accept the defaults), select a schema (data model) for
the resource. In the CRUD annotations and Invoke annotations tabs, you can
choose which among the selected ABL routines in the file implements a given
Mobile operation. A given routine can implement only one operation. Once chosen
for a CRUD or invoke operation, it can not be chosen again for another CRUD or
invoke operation.

5. Once you have completed Step 4 for all the class and procedure files you have
selected to define as Mobile resources, clicking Finish annotates all the files as
Mobile resources.

However, note that this wizard does not check that the ABL routines you have
annotated have the correct parameter lists defined and otherwise implement the
functionality of any of the built-in Mobile CRUD operations according to OpenEdge
Mobile functional requirements. So, you might have to revise the implementing ABL
routines accordingly. For more information, see the “Coding AppServer services for
OpenEdge Mobile” section on page 69.

78 OpenEdge® Development: Mobile Applications


Creating Mobile services

Creating Mobile services


Once you have created Mobile resources, you can create Mobile services that provide
these resources and which you can publish for testing or deploy to an external Apache
Tomcat Web server.

Using the New Mobile Service wizard


The New Mobile Service wizard allows you to define a new Mobile service with
selected Mobile resources.

Note: If you created a default Mobile service when you created a Mobile project, you
can also modify that service to add its Mobile resources. For more information,
see the “Modifying and deleting Mobile services” section on page 79.

To define a new Mobile service:

1. From the Progress Explorer view, right-click an OpenEdge Mobile project and
select New→ Mobile Service on the context menu. The New Mobile Service
wizard appears. Click Next from page to page.

2. On the first page, you must specify a name for the service and a relative URI,
which defaults tot he service name with a preceding slash (/). You can also
change the project into which to generate the service artifacts. Select at least one
OE Web Server instance where you want to publish the service for testing.

3. On the next page, you can select any of the available Mobile resources to include
in the service.

4. Clicking finish generates all the artifacts for the service, including its JSDO catalog
file, which a Mobile App needs to load to access the service.

Once you create a Mobile service, you can modify, delete, or publish the service for
testing or deployment. For more information publishing the service, see the “Publishing
Mobile services for testing” section on page 80.

Modifying and deleting Mobile services


You can edit or delete a Mobile service by right-clicking on the service and choosing
Delete or Edit from the context menu. If you choose Edit, the Edit Mobile Service
wizard appears, which works much like the New Mobile Service wizard to modify
some of the options to create the service.

OpenEdge® Development: Mobile Applications 79


Chapter 3: Creating Mobile Services

Publishing Mobile services for testing


When you create a Mobile project in Developer Studio, if you choose the option to
publish changes immediately, as long as the OE Web Server that you have selected
for a Mobile service is running, when you create or in any way update the Mobile
service and its resources, the Web server publishes the service.

If the OE Web Server is not running when you create the Mobile service, or you did not
select the project option to publish changes immediately, you can use the Servers view
to publish the service by first starting the AppServer for the project (right-click on the
AppServer and select Start). Once the AppServer is started and synchronized, you can
start the OE Web Server instance for the Mobile service (right-click on the OE Web
Server and select Start). Once the OE Web Server is started and synchronized,
right-click on it and select Publish, and any Mobile services not yet published should
publish. Developer Studio publishes each Mobile service in the project as a separate
WAR file, with the name of the Mobile service as its filename, to the selected OE Web
Server for testing.

To test a published Mobile service, you either need to write a Mobile App or use a
REST client, such as the Postman REST Client, and use the absolute URIs of Mobile
operations to send HTTP requests to execute those operations. For more information,
see the “URIs for accessing Mobile Web applications, services, and resources” section
on page 81.

For information on deploying Mobile services for production, see Chapter 5, “Deploying
Mobile Applications.”

80 OpenEdge® Development: Mobile Applications


URIs for accessing Mobile Web applications, services, and resources

URIs for accessing Mobile Web applications, services, and


resources
The URIs required to access Mobile Web applications, services, and resources depend
on what type of client you use to access them, a Mobile App using JSDOs or another
REST client, such as you might use for testing and debugging Mobile resources. The
following sections describe the requirements for forming these URIs:

• Mobile URIs for Mobile App access

• Mobile URIs for testing access from REST clients

• Using a REST client to invoke a Mobile operation

Mobile URIs for Mobile App access


For a Mobile App to access the Mobile services and resources of a Mobile Web
application, it needs only the relative or absolute URI of both the Mobile Web
application and the JSDO catalogs for any Mobile services that the Mobile App
accesses. After logging into the Web application and loading the required JSDO
catalogs, the Mobile App has only to call methods on JSDOs created for each Mobile
resource to access operations of the resource. No other URIs are required.

OpenEdge® Development: Mobile Applications 81


Chapter 3: Creating Mobile Services

The following syntax describes the URIs that you need to log into a Mobile Web
application and access its services using a JSDO:

Syntax

scheme://host[:port]/web-app[/static-resource]

scheme//host[:port]

The beginning of every absolute URI:

• scheme — A URI scheme supported for OpenEdge Mobile, which can be


either HTTP or HTTPS.

• host — The host name or IP address, which is typically localhost for testing
Mobile services on the same machine as both the Web browser and the OE
Web Server that hosts the Mobile services.

• port — Optional port where the Web server is listening for HTTP requests.
The default value, if you do not specify this option, is 80. The default value
configured for the OE Web Server is 8980.

The host:port can also be replaced by a Web domain (such as,


www.progress.com) that accesses the required host and port.

/web-app

The relative URI for the Mobile Web application, where web-app is the name of
the Mobile Web application that contains your Mobile service or services, and
serves as the root URI for all Mobile resources provided by the Mobile Web
application. By default, this is the filename of the WAR file that you use to publish
or deploy the Mobile services to your OE Web Server, and it is also the name of
the Web server folder in which all of the Web application’s Mobile services and
Web resources are deployed. As noted during development (see the “Publishing
Mobile services for testing” section on page 80), Developer Studio publishes each
Mobile service defined for a project in its own WAR file with the filename set to
name of the Mobile service. For production deployment, you can export multiple
Mobile and REST services in a single WAR file, which by default has the name of
the Mobile project. Note that during production deployment, a Web administrator
can change the filename of the WAR file and the name of the Web application to
a different value.

Note: During development, you cannot change the name of the WAR file that
Developer Studio publishes for each Mobile service in a project.

If you run the Mobile App in a Web browser and deploy it as a Mobile Web App to
the same OE Web Server as the Mobile services, the Mobile App only needs to
access this relative URI to log into the Mobile Web application and access Mobile
services.

82 OpenEdge® Development: Mobile Applications


URIs for accessing Mobile Web applications, services, and resources

If you install and run the Mobile App as a Mobile Native App in a native device
container, or deploy and run it as a Mobile Web App from a different Apache Tomcat
Web server from where the Web services are deployed, the Mobile App must access
the absolute URI to log into the Mobile Web Application.

/static-resource

The relative URI for a static file or Web page that the Mobile App accesses from
the Mobile Web application. For example:

• /static/mobile/service-name.json — The default relative URI of the


JSDO catalog for a Mobile service, where service-name is the name of the
service. The Mobile App can load this catalog to access Mobile resources
provided by the service after logging into the Mobile Web application. To load
the catalog, it can use the relative URI (starting with the Mobile Web
application, /web-app) or the absolute URI, depending on the same
conditions for using a relative or absolute URI for logging into the Mobile Web
application.

• /static/home.html — The default relative URI of a non-UI login target


available to support login to a Mobile Web application using HTTP Basic
Authentication.

• /static/auth/login.html — The default relative URI of a login form page


available to support login to a Mobile Web application using HTTP Forms
Authentication.

For more information on logging into a Mobile Web Application from a Mobile App, see
Chapter 4, “Creating Mobile Apps using JSDOs.”

OpenEdge® Development: Mobile Applications 83


Chapter 3: Creating Mobile Services

Mobile URIs for testing access from REST clients


After first developing and publishing Mobile services, you might want to test the Mobile
resources they provide before you create a Mobile App to access them using JSDOs.
You can do this using various REST clients, such as the Postman REST Client, that
allow you to access Mobile operations directly as REST resources. (Remember that a
single Mobile resource encapsulates several REST resources as Mobile operations.)
In this case, you need to know the exact absolute REST URI for the Mobile resource
that represents each Mobile operation.

As described in previous sections of this chapter, when you create Mobile resources
and the Mobile services to contain them, you assign a relative URI (or use the default)
for each Mobile service and resource that you define. In addition, each operation that
you define for a Mobile resource is assigned a prescribed relative URI as part of the
resource annotations added to the ABL.

The absolute URI to access a given operation is a concatenation of all these relative
URIs with the absolute root URI of the deployed Mobile Web application, as specified
using the following syntax:

Syntax

scheme://host[:port]/web-app/rest/service-name/resource-name[op-element]

scheme//host[:port]

The beginning of every absolute URI, as described previously (see the “Mobile
URIs for Mobile App access” section on page 81).

/web-app

The relative URI for the Mobile Web application, where web-app is the name of
the Mobile Web application that contains your Mobile service or services, and
serves as the root URI for all Mobile resources provided by the Mobile Web
application. By default, this is the filename of the WAR file that you use to publish
or deploy the Mobile services to your OE Web Server, and it is also the name of
the Web server folder in which all of the Web application’s Mobile services and
Web resources are deployed. As noted during development (see the “Publishing
Mobile services for testing” section on page 80), Developer Studio publishes each
Mobile service defined for a project in its own WAR file with the filename set to
name of the Mobile service. For production deployment, you can export multiple
Mobile and REST services in a single WAR file, which by default has the name of
the Mobile project. Note that during production deployment, a Web administrator
can change the filename of the WAR file and the name of the Web application to
a different value.

Note: During development, you cannot change the name of the WAR file that
Developer Studio publishes for each Mobile service in a project.

84 OpenEdge® Development: Mobile Applications


URIs for accessing Mobile Web applications, services, and resources

/rest

This is a literal relative URI that identifies the root for all OpenEdge REST
resources provided by a Mobile Web application.

Note: Unlike the /static relative URI that identifies the physical location of most
static Web resources, such as Web pages, this URI does not represent a
physical folder on the Web server, but simply identifies a dynamic point in
a URI where the relative URI to a given REST resource begins.

/service-name

The relative URI for the Mobile service, where service-name defaults to the name
you assign the service when you define it in Developer Studio. You can also
assign a different name for the URI at the time the Mobile service is defined. For
more information, see the “Creating Mobile services” section on page 79.

/resource-name

The relative URI for the Mobile resource, where resource-name defaults to the
name you assign the resource when you define it in Developer Studio. You can
also assign a different name for the URI at the time the Mobile resource is defined.
For more information, see the “Creating Mobile resources” section on page 77.

op-element

A relative URI or a URI query parameter that is specified to identify only certain
Mobile operations, as follows:

• ?filter=filter-string — For the read operation, identifies the INPUT


filter parameter value passed to the implementing ABL routine, where
filter-string is the string value you type, quoted if necessary.

• /routine-name — For an invoke operation, where routine-name is the


case-sensitive name of the ABL routine that implements the specified invoke
operation

Note that all other INPUT (and the input side of INPUT-OUTPUT) parameters passed
to the implementing ABL routines for Mobile operations are passed in the body of
the HTTP request. For more information, see the following section on using Mobile
URIs in a REST client.

OpenEdge® Development: Mobile Applications 85


Chapter 3: Creating Mobile Services

Using a REST client to invoke a Mobile operation


Once you have constructed the correct URI for the REST resource that represents a
given Mobile operation, you can specify it as part of the HTTP request to invoke the
operation from a REST client, such as Postman. However, a REST client requires four
basic pieces of information to send an HTTP request:

• URI — As described in the previous section

• Media type — Always application/json for Mobile operations

• HTTP method — As specified for each Mobile operation:

– Create — POST

– Read — GET

– Update — PUT (with no op-element in the URI—see previous section)

– Delete — DELETE

– Invoke — PUT (for all invoke operations, each of which is identified and
distinguished from the others by the name of the implementing ABL routine
specified as the op-element in the URI—see previous section)

• Other HTTP request components — Especially other INPUT parameters to


include in the body of the HTTP request

Note that, other than the filter parameter that is passed as the op-element in the
URI of a Mobile read operation request (see previous section), all other INPUT (and the
input side of INPUT-OUTPUT) parameters passed to the implementing ABL routines for
Mobile operations are passed in the body of the HTTP request. This includes the JSON
object for an INPUT-OUTPUT temp-table or ProDataSet parameter that is passed for the
Mobile create, update, and delete operations, and a JSON object with properties for
passing the values of any INPUT and INPUT-OUTPUT parameters for Mobile invoke
operations.

For the REST client, the input JSON objects specified for relational data must conform
to the structure defined by OpenEdge for passing the JSON representations of
temp-tables and ProDataSets, as appropriate. For more information, see OpenEdge
Development: Working with JSON. Note that this structure is similar to the structure
used to return the data for a Mobile read operation (GET). For an invoke operation, the
property names in the simple JSON object must have the same case-sensitive names
as the corresponding parameters defined in the implementing ABL routines.

Note also that for the Mobile create, update, and delete operations, all of which have
the same type of input JSON object for relational data, only the HTTP method specified
for the HTTP request distinguishes one Mobile operation from the other.

86 OpenEdge® Development: Mobile Applications


4
Creating Mobile Apps using JSDOs

As described in Chapter 1, “OpenEdge Mobile Overview,” OpenEdge Mobile supports


the development of Mobile Apps with access to OpenEdge data resources on an
AppServer using OpenEdge JavaScript data objects (JSDOs), which are instances of
the OpenEdge JavaScript class, progress.data.JSDO. With the help of additional
OpenEdge JavaScript classes and objects, JSDOs access these data resources
through Mobile services running on a Web server and make that data available through
the Mobile App. For a reference to the basic OpenEdge JavaScript classes and objects
available for access in Mobile Apps, see Appendix B, “OpenEdge JavaScript Class and
Object Reference” and Appendix C, “OpenEdge JavaScript Class Properties,
Methods, and Events Reference.” The Progress OpenEdge Mobile App Builder, which
provides advanced support for building OpenEdge Mobile Apps, supports additional
built-in client services for managing JSDOs.

Using OpenEdge Mobile, you can build two basic types of Mobile Apps that access the
same Mobile resources, but which run on different types of client platforms: Mobile
Web Apps that run in a Web browser on any client platform or device, and Mobile
Native Apps, packaged using hybrid technology, that run in a native device container
deployed to either an Apple iOS or Google Android device. You can build these Mobile
Apps using the Mobile App Builder, which provides visual services for building Web
pages and mapping JSDO data to Web page elements, or you can use basic HTML
and JavaScript coding tools, such as those available in Progress Developer Studio for
OpenEdge (Developer Studio).

OpenEdge® Development: Mobile Applications 87


Chapter 4: Creating Mobile Apps using JSDOs

This chapter describes how to use the features of a JSDO and associated OpenEdge
Mobile JavaScript objects to access Mobile services, regardless of the type of Mobile
App or coding platform. It then describes how to get started with building Mobile Apps
using either the Mobile App Builder and its data mapping services or more basic HTML
coding tools in the following sections:

• Creating a Mobile App from Developer Studio

• Getting started with the Mobile App Builder

• JSDO overview

• Creating a JSDO for a Mobile resource

• Accessing built-in CRUD operations

• Accessing non-built-in invoke operations

• Managing user login sessions

• Getting started with other HTML coding tools

• Publishing Mobile Apps for testing

88 OpenEdge® Development: Mobile Applications


Creating a Mobile App from Developer Studio

Creating a Mobile App from Developer Studio


You can begin to create a Mobile App in Developer Studio when you first create an
OpenEdge Mobile project using the New OpenEdge Project wizard, or after the
project is created using the New Mobile App dialog. The basic procedure for these
tasks is similar either way. This procedure basically creates the folder for the Mobile
App HTML and JavaScript files in the Mobile project from which to publish them as a
Mobile Web App on an OE Web Server or to export them in a WAR file for deployment
to an external Web server. This location is shared with the Progress OpenEdge Mobile
App Builder, where it saves the files that you create in the Mobile App Builder project.
For information on how to create a Mobile App as part of creating a new OpenEdge
Mobile project, see Chapter 3, “Creating Mobile Services.”

To create a new Mobile App for an existing Mobile project:

1. From the Project Explorer view, right-click on an OpenEdge project for which you
want to define the Mobile App, then select New→ Mobile App on the context
menu. The New Mobile App dialog appears.

2. Here, you can:

• Enter the Mobile App name. Note that any name you choose for a Mobile App
must be unique across all projects and workspaces of Developer Studio.

• Change the Mobile App project in which it is created.

• Specify a template with which to build the Mobile App. The Mobile App type
label only identifies the template used in Mobile App Builder to design the
pages of the App for a given general device category (such as a phone or
tablet) or for an application example (for example, a Twitter or weather app).
It has nothing to do with the type of deployment for the Mobile App (such as
a Mobile Web App a Mobile Native App).

• Select a backup from which to create the Mobile App.

• Select an OE Web Server instance (or instances) on which to publish the


Mobile App. The installed default is restmgr1.

3. If you have not yet entered Progress ID user credentials in Developer Studio, this
page displays an error message reminding you to do so, and also provides a link
to the Mobile App Builder preferences page to do so. You only need to provide
these user credentials if you intend to use the Mobile App Builder to create your
Mobile Apps. If you use other HTML and JavaScript coding tools, such as the
JSDT in Developer Studio, you do not need to enter any user credentials. For
more information on the JSDT, see the JavaScript Development Guide in the
Developer Studio online help. If you have not yet configured an external HTML5
Web browser to run the Mobile App Builder or to test Mobile Apps, you can also
click a link to the Web Browser preferences page to do that.

4. When you click Finish, Developer Studio creates an entry for the new Mobile App
in the Mobile Apps folder of the project. If you are set up to build the App in Mobile
App Builder, the configured external browser opens to the Progress ID login page,
where you can login to open the Mobile App Builder, where you will find a new
project for the Mobile App.

OpenEdge® Development: Mobile Applications 89


Chapter 4: Creating Mobile Apps using JSDOs

Getting started with the Mobile App Builder


Using the Progress OpenEdge Mobile App Builder you can visually build a single client
that can be deployed as a Mobile Web App, an iOS App or an Android App.

The Mobile App Builder is a cloud-based development tool integrated with Progress
Developer Studio for OpenEdge. A Developer Studio project can contain one or more
Mobile Apps, each of which is associated with a unique Mobile App Builder project. The
Mobile App Builder is secure and requires a Progress ID along with an active
subscription.

The Mobile App Builder simplifies the development of a Mobile App by handling much
of the complexity of jQuery Mobile, HTML5, CSS, JavaScript, and Native App
deployment (managed with Apache Cordova). The Mobile App Builder provides page
templates, along with jQuery Mobile components, to make it fast and easy to prototype
and build the UI of the Mobile App. Simply select any component and drag and drop it
into the phone or tablet image. Once a component is added, you can set various
properties available on the right-hand side. The Mobile App Builder generates
standards-based code for maximum compatibility.

The Mobile App Builder hides the complexity of building the UI as well as adding
behavior to the pages such, as event handlers, page and link navigation, and REST
service invocation. These can all be done without the need for you to write any
JavaScript. In the event that you need to write custom logic, you can always provide
your own JavaScript for the page.

One of the most powerful features of the Mobile App Builder is the tight data-binding
with OpenEdge ProDataSets and temp-tables. As described in Chapter 3, “Creating
Mobile Services,” the data and ABL business logic are accessible by creating an
OpenEdge Mobile service. Within the Mobile App Builder, you simply upload the JSDO
catalog associated with the OpenEdge Mobile service, select the resources and data
model (schema) that you want to use in the Mobile App, and Mobile CRUD operations
and custom business logic for the selected resources are automatically imported as
JSDO Services. These services can be used to pass data back and forth from the
Mobile App to the OpenEdge AppServer as well as invoke custom business logic. All
communication and data transformation is automatically handled by these services. In
addition, data returned from a JSDO Service can be visually mapped to UI
components.

Once the Mobile App is built, it can be previewed for immediate feedback and
collaboration. The preview is a Mobile Web App that runs in an emulator. This can be
automatically deployed on the Mobile App Builder server in the cloud or it can be
downloaded locally and deployed to a local Web server of your choice. Other available
deployment choices include building an iOS App deployed through the Apple AppStore
or building an Android App deployed through Google Play. For more information on
these Mobile App deployment options, see Chapter 5, “Deploying Mobile Applications.”

90 OpenEdge® Development: Mobile Applications


JSDO overview

JSDO overview
A JSDO is an object designed to simplify access to OpenEdge relational data in a
Mobile App. It does this by providing JavaScript methods to execute the Mobile
operations supported by a single Mobile resource, and supports an internal data store
(JSDO local storage) to cache the OpenEdge data defined, and initially returned to the
Mobile App, by the Mobile resource.

The JSDO relies on a JSON catalog file (JSDO catalog) that defines the Mobile
resource it is accessing. This resource definition includes the schema (data model) for
the OpenEdge data supported by the resource as well as the definitions for JSDO
methods to call the Mobile operations of the resource. The schema of the Mobile
resource, therefore, determines both the structure of the data in JSDO local storage
and how Mobile operations can interact with it. Other JSDO methods allow the Mobile
App to read and manipulate the data in JSDO local storage for ultimate update on the
AppServer by calling the supported Mobile operations. In addition, the JSDO’s local
storage provides features that facilitate mapping its data to HTML elements of a Mobile
App.

The following sections briefly describe:

• Supporting OpenEdge classes and objects

• How a JSDO maps to a Mobile resource

• How JSDO local storage works

• Methods of a JSDO and the JSRecord object

• Asynchronous and synchronous execution

• Properties of a JSDO

• Requirements for using a JSDO

Supporting OpenEdge classes and objects


OpenEdge Mobile provides the following classes and objects to support JSDO creation
and access:

• progress.data.JSDO class — Allows you to create JSDOs for Mobile resources


that can execute the resource-supported Mobile operations that exchange the
data defined by these resources between a Mobile App and an AppServer where
the data is stored, as described in this “JSDO overview” section and the current
chapter.

• progress.data.Session class — Allows you to create a Session object that


manages a user login session between the Mobile App and a Mobile Web
application. This enables a JSDO to access the resources that a Mobile service
supported by the Mobile Web application provides, as described in this “JSDO
overview” section. For more information, see the “Managing user login sessions”
section on page 117.

• JSRecord object — References a JavaScript record object from JSDO local


storage, as described in this “JSDO overview” section.

OpenEdge® Development: Mobile Applications 91


Chapter 4: Creating Mobile Apps using JSDOs

• Request object — Contains data both sent in HTTP requests for Mobile
operations when they are executed and returned in HTTP responses when the
Mobile operation execution completes, as described in this “JSDO overview”
section. For more information, see the “Accessing built-in CRUD operations”
section on page 106 and the “Accessing non-built-in invoke operations” section on
page 115.

• A set of JSDO services built into the Mobile App Builder — For mapping
JSDO data to any HTML page elements you can create, and supporting the
marshalling of that data between the Web page and Mobile operations. For more
information, see the “Getting started with the Mobile App Builder” section on
page 90.

• progress.ui.UIHelper class — Provides basic features for mapping JSDO data


to Web page elements in Mobile Apps built with HTML tools other than the Mobile
App Builder. For more information, see the “Getting started with other HTML
coding tools” section on page 122.

How a JSDO maps to a Mobile resource


A JSDO is an instance of the progress.data.JSDO JavaScript class that you create to
access exactly one Mobile resource provided by a Mobile service. As described in
Chapter 3, “Creating Mobile Services,” a Mobile resource provides access to either a
single temp-table or a single ProDataSet with one or more temp-tables on an
OpenEdge AppServer. The exact type of data that a Mobile resource provides depends
on the data model selected to create the resource. A Mobile resource is also created
with a set of built-in operations to access its data model. These can include a complete
set of create, read, update, and delete operations (CRUD), or only a single read
operation, depending on the options chosen to create the Mobile resource. In any case,
the same basic set of Mobile operations access the data for every Mobile resource
regardless of the data model it supports. The ABL routines that implement these
operations have prescribed signatures that depend on the type of data model selected
for the Mobile resource.

The prescribed relationship between the built-in operations and the data model of a
Mobile resource allows the JSDO class to provide a corresponding set of built-in
JavaScript methods that implicitly map to the built-in operations of a Mobile resource,
no matter what data model it supports. In addition, for every JSDO, the internal
structure of the JSDO local storage reflects the schema of the particular data model
supported by the Mobile resource. Therefore, the built-in methods of a JSDO work on
the data in its local storage according to the schema defined for the supported data
model.

The basic unit of data for a Mobile resource is the temp-table record, which is
represented in JSDO local storage as a JavaScript record object. The built-in create,
update, and delete operations of a Mobile resource operate on one AppServer
temp-table record at a time, according to the implementation of the corresponding ABL
routines. The read operation returns a set of records from the AppServer for one or
more temp-tables, depending on the data model. The set of records that the Mobile
read operation returns depends on the implementing ABL routine and an optional filter
parameter that you pass to it from the Mobile App. The corresponding built-in JSDO
methods call these operations accordingly, loading temp-table records into JSDO local
storage from the AppServer, or creating, updating, and deleting records on the
AppServer from posted changes to the record objects in JSDO local storage.

92 OpenEdge® Development: Mobile Applications


JSDO overview

A Mobile resource can also support non-built-in invoke operations which can be
implemented by any ABL routines defined for the resource on the AppServer except
routines that already implement built-in Mobile operations. Routines that implement
invoke operations can have any signature defined with supported ABL data types. A
JSDO created for a Mobile resource with invoke operations has corresponding
non-built-in invocation methods that map to these invoke operations. Calling an
invocation method on the JSDO calls the implementing ABL routine, passing the
required input parameters and returning its output parameters and any return value to
the Mobile App with no direct effect on JSDO local storage. The Mobile App can do
whatever it needs to do with the results of an invocation method, including merging
them with JSDO local storage, if appropriate.

For more information on coding the implementing ABL routines of Mobile operations on
the AppServer, see Chapter 3, “Creating Mobile Services.”)

How JSDO local storage works


JSDO local storage stores temp-table records as JavaScript record objects according
to the schema of the data model supported by the Mobile resource of the JSDO. If the
data model is for a single temp-table, local storage can contain only record objects for
the specified temp-table.

If the data model is for a ProDataSet, local storage can contain record objects for the
temp-tables defined for the ProDataSet. By default, record objects for a ProDataSet are
maintained in local storage according to any data-relations defined for the ProDataSet.
This means, for example, that when a JSDO method finds a record object of a parent
temp-table, if a method is then called to search through the record objects of a
temp-table that is a child of that parent, the search will find only record objects that are
related to the record object found in the parent; if new record objects are added to the
same child temp-table, they are added with key fields set implicitly in relation to the
parent record object. The JSDO also supports the run-time option (by setting the
useRelationships property) of toggling between honoring these data-relations and
ignoring them when accessing temp-table data in local storage

Table and field references

You can access the data in local storage using table references. A table reference is a
property on the JSDO that references a given JavaScript temp-table object as defined
by the schema of the data model. So, local storage contains one table reference
property for each temp-table referenced in local storage. The name of each property is
the same as the name of a corresponding temp-table defined in the schema selected
to define the Mobile resource in Developer Studio (see Chapter 3, “Creating Mobile
Services”), and it is specified with the same letter case as the temp-table name in the
selected schema.

JSDO methods that operate on local storage operate either on the entire data store, in
which case they are called on the JSDO itself, or on one table reference at a time, in
which case they are called directly on the corresponding table reference property. For
example, given a JSDO referenced by dsOrderEntry whose local storage references
several temp-tables of a ProDataSet, including ttCustomer, two JSDO methods might
be called as follows:

dsOrderEntry.fill( );
dsOrderEntry.ttCustomer.foreach( function ( record-object ) { ... } );

OpenEdge® Development: Mobile Applications 93


Chapter 4: Creating Mobile Apps using JSDOs

In this example, the fill( ) method is called on the dsOrderEntry JSDO to load the
available data for the Mobile resource into local storage by calling the built-in Mobile
read operation. Then, the foreach( ) method is called on the ttCustomer property of
the JSDO to loop through all the record objects loaded for the ttCustomer temp-table,
allowing each one to be accessed from within the function that is passed as a
parameter.

Working records

When a JSDO method is called, depending on the method and the situation, it might
result in setting a working record for one or more of the table references. A working
record is a record object for a given temp-table in local storage that is available to
reference implicitly using the table reference. If a table reference has a working record
set for it, you can then reference any field value in the corresponding record object
using a corresponding field reference property on the table reference. The name of the
field reference property is the same as the temp-table field name in the schema defined
for the Mobile resource. You can also use the working record on a table reference to
return the record object for the working record and store it for future reference.

For example, when the foreach( ) method in the previous example returns from
execution (based on the return value of its function parameter), it leaves a working
record set for the ttCustomer table reference. You can assign a value to the Name field
of this working record using the Name field reference property on the table reference:

dsOrderEntry.ttCustomer.Name = "Evellyn Doe";

This is one of the supported mechanisms to update a field value in local storage. The
other is to call the assign( ) method directly on a table reference or on a record object,
itself.

Also, if local storage has a ProDataSet data model with active data-relations and a
working record is set in a parent table reference, a search through the records of a child
table reference reflects the data-relation. For example, with a working record set for a
ttCustomer that is a parent of ttOrder, calling the foreach( ) method on ttOrder
loops only through records related to the working record in ttCustomer.

Note: Table references for temp-tables referenced in local storage use a flat
reference model. In other words, regardless of data-relations, you reference
the property for each table reference directly on the JSDO
(dsOrderEntry.ttOrder.Ordernum).

Depending on the results of JSDO methods that you call, local storage either maintains
a working record for each table reference or leaves the working record for one or more
table references undefined. Essential programming for a JSDO involves calling
appropriate methods to locate working records in local storage in order to read and
modify their contents. The documentation for each JSDO method (see Appendix C,
“OpenEdge JavaScript Class Properties, Methods, and Events Reference”) indicates
whether and how it leaves a working record when it completes execution.

94 OpenEdge® Development: Mobile Applications


JSDO overview

If a method leaves a working record, you can reference the field values of the record
object using field reference properties on the table reference, as described in the
previous section. You can also use the record property on the table reference to return
a reference to a JSRecord object for the working record that you can reference directly
or store separately to access the record object later. A JSRecord object provides a
data property that references a separate JavaScript object with the actual field
reference properties for the record. Also as a convenience, if the JSDO supports only
a single temp-table, you can access the record property for the working record directly
on the JSDO reference itself.

So, using the previous example with ttCustomer, where it is the only temp-table in
local storage, you can access the Name field using a JSRecord object reference in the
following ways:

var custName = dsOrderEntry.record.data.Name; // Single temp-table only


var custName = dsOrderEntry.ttCustomer.record.data.Name;

var custRecord = dsOrderEntry.ttCustomer.record; // Stored for later reference


var custName = custRecord.data.Name;

Once stored, an existing record object remains available using the stored JSRecord
reference even when it is no longer the working record for the temp-table. Note that
using the data property to write a value to a field is not recommended, because the
record object is not marked as changed in local storage and won’t be updated on the
AppServer. To update a field value on a JSRecord object reference so the change is
made on the AppServer, call the assign( ) method directly on the JSRecord
reference.

Note: One reason to use the record.data property on a table reference to read a
field value is when the field has the same name as a JSDO method that you
can call on a table reference.

Caution: Because the record object is not marked as changed in local storage, never
use the data property on a JSRecord reference to update the value of a field.
The change will never be posted to AppServer. Use the data property to read
the field value only.

Record IDs

One difference between the JavaScript record objects in JSDO local storage and the
temp-table records that they represent is that each record object contains a record ID.
This is an internal field that uniquely identifies the record in JSDO local storage. This
record ID has no relationship to the internal RECID and ROWID values maintained for the
records of an OpenEdge database. Instead, this record ID is used by the client JSDO
services built into the Mobile App Builder, and also by the progress.ui.UIHelper
class, to map the record objects in JSDO local storage to the HTML elements of Mobile
Apps. Also, you can retrieve this record ID from any record object in local storage and
store it for future reference in order to efficiently retrieve the record object, again, from
local storage.

OpenEdge® Development: Mobile Applications 95


Chapter 4: Creating Mobile Apps using JSDOs

Methods of a JSDO and the JSRecord object


Every JSDO has a number of methods, many of which interact with JSDO local
storage. Some are called on the JSDO itself, while most are called on a JSDO table
reference. Most execute synchronously, but some execute asynchronously as noted.
For more information, see the “Asynchronous and synchronous execution” section on
page 98. A few JSDO methods are also available on a JSRecord object.

A JSDO includes methods for:

• Executing built-in Mobile operations and calling their implementing AppServer


routines:

– fill( ) — Executes the read operation of a Mobile resource, loading the


temp-table records sent from the AppServer into JSDO local storage
according to the resource data model; the first record of every loaded
temp-table reference is set as its working record.

– saveChanges( ) — Executes the create, update, or delete operation of a


Mobile resource for each record that has changed in JSDO local storage
since the last execution of the fill( ) or saveChanges( ) method; no
working records for any table references in local storage are set.

These methods are always called on the JSDO and execute asynchronously.

• Executing non-built-in Mobile invoke operations and calling their implementing


AppServer routines. There is a uniquely named JSDO method defined for each
invoke operation in the Mobile resource; these methods have no effect on JSDO
local storage.

These methods are always called on the JSDO and, by default, execute
asynchronously, but can optionally execute synchronously. To pass input
parameters to the implementing ABL routine, you pass an input object to the
invocation method that contains properties with the values for any ABL input
parameters. A property for an ABL input parameter has the same name (and letter
case) as the corresponding input parameter, and has a JavaScript data type that
maps to the ABL data type of the input parameter (see Appendix A, “ABL to
JavaScript Data Type Mapping”)

• Updating JSDO local storage:

– add( ) — Called on a JSDO table reference, this method creates a new


record object for the temp-table in JSDO local storage; the new record is set
as the working record for the table reference.

– addRecords( ) — Called either on a JSDO or on a JSDO table reference,


this method updates JSDO local storage with record objects obtained from
an object passed as a parameter to the method that follows the same
schema as JSDO local storage; has no effect on existing working record
settings.

96 OpenEdge® Development: Mobile Applications


JSDO overview

– assign( ) — Called on a JSDO table reference or a JSRecord reference,


this method updates field values for an existing record in JSDO local storage
from property values of an object passed as a parameter to the method; has
no effect on existing working record settings.

Note: An assign( ) method is also available on a table reference of a


progress.ui.UIHelper object. However, it updates the field values
of an existing record from values in an HTML page. For more
information, see the “Getting started with other HTML coding tools”
section on page 122.

– remove( ) — Called on a JSDO table reference or a JSRecord reference,


this method deletes an existing record in JSDO local storage; no working
record is set for the table reference or any of its child table references.

These methods always execute synchronously. You save the changes that these
methods make in JSDO local storage to the AppServer by calling the
saveChanges( ) method on the JSDO, which executes asynchronously.

• Searching for record objects in JSDO local storage:

– find( ) — Searches for a record in a referenced temp-table according to the


criteria defined by a function that you pass, and returns the record object if
the function indicates it has been found; sets any record found as the working
record for the table reference, and sets the working record for any child table
references to the first record that is related to the parent working record.

– findById( ) — Searches for a record in a referenced temp-table with the


specified record ID, and returns the record object if found; sets any record
found as the working record for the table reference, and sets the working
record for any child table references to the first record that is related to the
parent working record.

– foreach( ) — Loops through the records of a referenced temp-table, and


allows a function that you pass to access each record object and perform
whatever actions you define until the function tells the method to stop looping
or the method has reached the end of the record set; the record for each
iteration is set as the working record for the table reference, and sets the
working record for any child table references to the first record that is related
to the parent working record. If the loop terminates, the last working record
remains the working record for the table reference.

These methods are called on a JSDO table reference and always execute
synchronously.

OpenEdge® Development: Mobile Applications 97


Chapter 4: Creating Mobile Apps using JSDOs

• Returning data and information from JSDO local storage:

– getData( ) — Called on a JSDO table reference, this method returns an


array of record objects for a referenced temp-table; has no effect on existing
working record settings.

– getId( ) — Called on a JSDO table reference or a JSRecord reference, this


method returns the unique internal record ID for the specified record object;
has no effect on existing working record settings.

– getSchema( ) — Called on a JSDO table reference, this method returns an


array of objects, one for each field, that defines the schema of the referenced
temp-table; has no effect on existing working record settings.

These methods always execute synchronously.

• Managing JSDO event subscriptions:

– subscribe( ) — Subscribes a given event handler function to a named


event on a JSDO or on a JSDO table reference; has no effect on existing
working record settings.

– unsubscribe( ) — Unsubscribes a given event handler function from a


named event on a JSDO or on a JSDO table reference; has no effect on
existing working record settings.

These methods are called on the JSDO or on a JSDO table reference, and
execute synchronously. For more information on JSDO events and managing
JSDO event subscriptions, see the “Asynchronous and synchronous execution”
section on page 98.

Asynchronous and synchronous execution


As described in the previous section, most JSDO methods execute synchronously,
which means that the Mobile App waits for the method to complete execution before
executing the next JavaScript statement or evaluating the next term of an expression.
When method execution completes and returns its results, the Mobile App continues
with the next JavaScript operation.

However, the JSDO fill( ) and saveChanges( ) methods, which execute built-in
Mobile operations, always execute asynchronously, and any non-built-in invocation
methods, which execute non-built-in Mobile invoke operations, execute
asynchronously by default, but can optionally execute synchronously. Asynchronous
execution means that immediately after the Mobile App calls the method, it continues
to execute the next JavaScript statement or to evaluate the next term of an expression.
Results of an asynchronous method execution only become available to the Mobile
App when an event associated with the method fires and an event handler function that
is subscribed to the event executes and receives the results.

98 OpenEdge® Development: Mobile Applications


JSDO overview

Comparing asynchronous and synchronous execution

Asynchronous execution is mandatory for the methods that execute the built-in Mobile
CRUD operations. These operations usually involve AppServer access to its data
sources, which are typically OpenEdge databases. The Mobile read operation
executed by the fill( ) method can involve reading and returning hundreds to
thousands (or more) records in multiple temp-tables of a ProDataSet across the
network. The Mobile create, update, and delete operations, which require writes to and
lock management of databases, are executed across the network by the
saveChanges( ) method one record at a time, and for as many records as are marked
as changed in JSDO local storage. This means that completion of these methods can
require detectable wait times. If they were executed synchronously, the Mobile App
user would be prevented from doing any work within the app while these methods were
executing. With asynchronous execution, they can perform other tasks, such as setting
application options, while waiting for a list of customers and orders, for example, to be
displayed in a list view, or while waiting for notification that changes they have posted
have been saved in the database.

Asynchronous execution is the default for non-built-in invocation methods, again,


because these operations execute across the network and can involve complex
database interactions on the AppServer. However, it is also possible that an invocation
method might perform a simple function and return a primitive value used in an
expression—for example, an age or credit limit. In this case, you might prefer to
execute the method synchronously in the expression to complete the calculation with
its return value. This you can do by passing false as an additional Boolean parameter
that indicates that the invocation method is to be executed synchronously. For more
information on the execution options for invocation methods, see the “Accessing
non-built-in invoke operations” section on page 115.

Named events for asynchronous execution

For all methods that execute asynchronously, the JSDO supports a set of named
events to which you can subscribe event handler functions, functions that execute with
a signature defined to receive the results of a particular event. The JSDO defines a set
of unique before and after events for each Mobile operation and also for the
saveChanges( ) method, itself, because in one call, this method can execute all three
of the create, update, and delete operations for any number of records in JSDO local
storage.

In other words, there is a unique event that fires before a given Mobile operation
executes across the network and one that fires after a given Mobile operation
executes. In addition, there is one event that fires before the saveChanges( ) method
executes any Mobile operations and another that fires after all Mobile operations
executed by the saveChanges( ) method have completed. Note that the after events
all fire (including for saveChanges( )) whether Mobile operations complete
successfully or with an error.

OpenEdge® Development: Mobile Applications 99


Chapter 4: Creating Mobile Apps using JSDOs

So, each asynchronous method has a set of unique 'before*' and 'after*' events
defined to fire for it as follows:

• fill( ):

– 'beforeFill' — Fires before the Mobile read operation executes

– 'afterFill' — Fires after the Mobile read operation completes execution

• saveChanges( ):

– 'beforeSaveChanges' — Fires before the method executes any Mobile


operations

– 'beforeDelete' — Fires before any Mobile delete operation executes

– 'afterDelete' — Fires after each Mobile delete operation completes


execution

– 'beforeCreate' — Fires before any Mobile create operation executes

– 'afterCreate' — Fires after each Mobile create operation completes


execution

– 'beforeUpdate' — Fires before any Mobile update operation executes

– 'afterUpdate' — Fires after each Mobile update operation completes


execution

– 'afterSaveChanges' — Fires after all the Mobile operations executed by


the method have completed

Note: These events are listed in general firing order for a single call to the
saveChanges( ) method. When there are multiple changes to the same
record, the order and number of changes is optimized to send the fewest
number of operations to the AppServer.

• Non-built-in invocation methods:

– 'beforeInvoke' — Fires before the specified Mobile invoke operation


executes

– 'afterInvoke' — Fires after the specified Mobile invoke operation


completes execution

Note: When you subscribe an event handler to an invoke event, you also specify
the name of the JSDO invocation method so the event handler can identify
which invoke operation is about to be, or has been, executed. Note also that
these invoke events never fire when you execute an invocation method
synchronously because all invoke operation results are returned by the
method itself.

Note: The JSDO event names are quoted because they are always referenced as
strings in JavaScript.

100 OpenEdge® Development: Mobile Applications


JSDO overview

Managing JSDO event subscriptions

You can subscribe event handlers to JSDO events using either the subscribe( )
method on the JSDO or by setting appropriate properties in an initialization object that
you can pass to the constructor to instantiate the JSDO. If you use the subscribe( )
method after the JSDO is instantiated and its local storage has been loaded with
records, you can also subscribe to events for the Mobile create, update, and delete
operations that execute only for a specific table reference.

When you subscribe an event handler function to a JSDO event, the parameter list for
the function must match the parameter list defined for the event. However, every event
handler receives a reference to the JSDO as its first parameter and a reference to a
request object as its last parameter that contains event results (see the following
section). All handlers for 'after*' events receive a Boolean parameter that indicates
the success of the Mobile operation (or operations for 'afterSaveChanges'). All
handlers for events fired by Mobile create, update, and delete operations receive a
JSRecord object parameter that represents the record object in local storage that is
created, updated, or deleted. For more information on the required parameter list for
each event, see the reference entry for the event in Appendix C, “OpenEdge
JavaScript Class Properties, Methods, and Events Reference.”

Regardless of how you subscribe event handlers to an event, you can remove an event
subscription for an event handler using the unsubscribe( ) method. If an event has
no event handler subscribed and the event fires, it returns no results to the Mobile App.

Handling asynchronous and synchronous execution results

For the synchronous JSDO methods (such as add( ) or find( )) that do not execute
Mobile operations, the results for both successful and unsuccessful execution are as
defined for each method. For more information, see the reference entry for the method
in Appendix C, “OpenEdge JavaScript Class Properties, Methods, and Events
Reference.”

For methods that execute Mobile operations asynchronously (fill( ),


saveChanges( ), and invocation methods), the results for each event are returned in
a general request object that is passed as the last parameter to the event handler. For
invocation methods that you execute synchronously, a reference to this same request
object is available as the return value of the method. This request object has a number
of properties whose values depend on the event. Some properties (including the jsdo,
jsrecord, and success properties) duplicate the settings of the other parameters
passed to the event handler. The settings of other properties provide additional
information appropriate for the event.

One of the most important is the response property of the request object. This property
is set only for the 'after*' events of all Mobile operations (that is, all except the
'afterSaveChanges' event). It references a JavaScript object that a Mobile operation
returns for a successful completion or with ABL errors.

For a built-in Mobile operation that completes successfully, this property references a
JavaScript object that contains the data of the returned temp-table or ProDataSet
converted from any valid JSON returned for the operation over the network, and is
otherwise null.

OpenEdge® Development: Mobile Applications 101


Chapter 4: Creating Mobile Apps using JSDOs

For a non-built-in invoke operation that completes successfully, the response property
references an object that contains properties with the values of any output parameters
and return value returned by the ABL routine. A property for an ABL output parameter
has the same name (and letter case) as the corresponding output parameter, and has
a JavaScript data type that maps to the ABL data type of the output parameter (see
Appendix A, “ABL to JavaScript Data Type Mapping”). Any return value from the
routine is returned as the OpenEdge-defined property, _retVal, also with a
ABL-mapped JavaScript data type.

For a Mobile operation that completes with one or more ABL errors, the response
property references an object that contains two OpenEdge-defined properties:

• _retVal — A String with the value of any ABL RETURN ERROR string or
ReturnValue property for a thrown AppError object

• _errors — An array of JavaScript objects, each of which contains properties with


the ABL error message string and error number for one of possibly many
ABL-returned errors.

Note: In the current OpenEdge release, this array always returns one object only
for the first ABL error (the equivalent of ERROR-STATUS:GET-MESSAGE(1) in
ABL).

For more information on the request object and its available properties, see its
reference entry in Appendix B, “OpenEdge JavaScript Class and Object Reference”.

General error handling for Mobile operations

For any Mobile operation that completes with an error of any kind (ABL, Mobile Web
application, or network), the success property of the returned request object (and the
success parameter of the event handler) is set to false. As noted in the previous
section, any ABL errors can be found in the object returned by the response property.
All other Web application and network errors can be inspected using the xhr property
of the request object. For more information on the XMLHttpRequest object that this
property references, see the software development documentation for your Web
browser or mobile device.

Note that for a Mobile create, update, or delete operation, if any error, at any point
causes the operation to complete unsuccessfully, the record in JSDO local storage is
reverted prior to any change that caused the operation to be executed. So, for example,
a failed create operation causes the added record to be removed from local storage.
The record object that was originally added for the operation is then available for your
re-use as the jsrecord property of the request object (or the record parameter if the
event handler). A similar reversion occurs for the update and delete operations, with
the field values of any updated record reverted to their original values, and any deleted
record added back to local storage.

Properties of a JSDO
Every JSDO has several properties to manage its state. We have already introduced
the table reference properties that provide access to temp-table data loaded into JSDO
local storage, and the record property, which provides access to individual record
objects on a given table reference (see the “How JSDO local storage works” section on
page 93).

102 OpenEdge® Development: Mobile Applications


JSDO overview

Two additional properties are available for access on a JSDO:

• name — A String property that returns the name of the Mobile resource for which
the JSDO is created. You must set this value either directly or indirectly using the
progress.data.JSDO class constructor when you instantiate a JSDO. You can
read the property on the JSDO after it is created.

• useRelationships — A Boolean property that when set to true makes all


data-relations active in JSDO local storage so that searches on a child temp-table
reference involve only records related to a its parent. In addition, record objects
created for a child temp-table have their key fields automatically set in relation to
their parent. When set to false, searches on a child temp-table reference involve
all record objects stored for the temp-table, regardless of data-relations, and any
record objects created for a child temp-table have no automatic settings for their
key fields. This property can be set and reset at any time during the life of the
JSDO to change the effect of data-relations on local storage.

In addition to these JSDO properties, you can set additional initialization properties in
the class constructor, along with the name property itself. These initialization properties,
which you cannot access after the JSDO is created, allow you to specify that certain
JSDO methods are called during instantiation, including:

• Automatically calling the fill( ) method to initialize JSDO local storage as the
object is created

• Subscribing event handlers for JSDO events, especially the 'beforeFill' and
'afterFill' events to handle the automatic execution of the fill( ) method

For more information on setting the name and initialization properties in the JSDO class
constructor, see the “Creating a JSDO for a Mobile resource” section on page 105.

Requirements for using a JSDO


The basic requirements for using a JSDO include having access to the Mobile resource
it needs to access and set up a user login session to access that Mobile resource.

To use a JSDO in a Mobile App, you need to ensure that the following actions
have been completed:

1. Deploy a Mobile Web application that contains a Mobile service with the Mobile
resource, or resources, you need to an Apache Tomcat Web server (such as the
OpenEdge-installed OE Web Server), whether for testing or production. For more
information on deployment for testing, see the sections on publishing Mobile
services for testing in Chapter 3, “Creating Mobile Services.” For more information
on deployment for production, see the sections on deploying Mobile Web
applications in Chapter 5, “Deploying Mobile Applications.”

2. Instantiate the progress.data.Session class to create a user login session


between the Mobile App and the Mobile Web application and ensure that you
initialize it to use the same Web server authentication model as the Mobile Web
application. For more information on coding for security considerations like the
Web server authentication model, see the “Managing user login sessions” section
on page 117.

OpenEdge® Development: Mobile Applications 103


Chapter 4: Creating Mobile Apps using JSDOs

3. Call the login( ) method on the Session object to establish an authenticated


login session with the Mobile Web application. Depending on the Web server
authentication model, you should do this in a way that ensures your Mobile App
authenticates the user against a separate Web application resource, such as an
HTML page, before you attempt to access Mobile services and resources in the
Web application. You can do this using features of the login( ) method itself that
allow you to access a default Web resource or one of your own that you build into
the Web application. For more information, see “Managing user login sessions”
section on page 117.

4. Once you have successfully called the login( ) method on the Session object,
call the addCatalog( ) method on the Session object to load the JSDO catalog
file for a Mobile service you need. For more information, see “Managing user login
sessions” section on page 117.

5. Once you have the JSDO catalog file loaded in your Mobile App, you can
instantiate the progress.data.JSDO class to create the JSDO for the Mobile
resource you need. For more information, see “Creating a JSDO for a Mobile
resource” section on page 105.

104 OpenEdge® Development: Mobile Applications


Creating a JSDO for a Mobile resource

Creating a JSDO for a Mobile resource


The following code fragment shows a simple JavaScript coding sequence for creating
a JSDO, starting the attempted login of the user:

// create Session and set it for HTTP Basic Authentication


var pdsession = new progress.data.Session();
pdsession:authenticationModel = progress.data.Session.AUTH_TYPE_BASIC;

// log in, i.e., authenticate to the Mobile Web application


pdsession.login('/SportsMobile', username, password);

if pdsession.loginResult == progress.data.Session.LOGIN_SUCCESS {

// load catalog for a service that's part of the Mobile Web application
pdsession.addCatalog('/SportsMobile/static/mobile/SportsMobileSvc.json');

// create JSDO
var dsCustomer = new progress.data.JSDO({
name : 'dsCustomer',
autoFill : true,
events : {
'afterFill' :
[ {
scope : this,
fn : function (jsdo, success, request) {
// afterFill event handler statements ...
}
} ]
}

});

// JSDO access continues ...


}

// Login error begins ...

The fragment shows the setting of the authenticationModel property on the Session
object, pdsession, to code for the Web server HTTP Basic Authentication model for
which the Mobile Web application is configured. After logging into the Mobile Web
application with its relative URI, /SportsMobile, the code tests for the success of the
login, and for a positive test, immediately loads the JSDO catalog for the
SportsMobileSvc service.

It then instantiates a JSDO using an initialization object passed to the constructor,


which specifies the:

• Mobile resource, dsCustomer

• Setting of the initialization property, autoFill, to invoke the fill( ) method


upon instantiation

• Subscription of an in-line function to the afterFill event to check the results of


the fill( ) method

OpenEdge® Development: Mobile Applications 105


Chapter 4: Creating Mobile Apps using JSDOs

Accessing built-in CRUD operations


After creating a JSDO as explained in the preceding section, you can use the built-in
JSDO methods to read, create, update, and delete records. The sections that follow
provide guidance and examples for each of these operations. In all cases, examples
are based on a JSDO having been created and associated with a Mobile resource
named dsOrderEntry.

In the case of all four CRUD operations, the ABL routine that is associated with the
JSDO method must have a parameter whose type is either DATASET or TABLE. For
operations to work properly, this parameter must refer to the same ProDataSet or
temp-table in all ABL routines associated with CRUD operations for a given JSDO. No
validation of this requirement occurs on the client.

Note: Built-in JSDO methods execute asynchronously.

Read operation
To load data into local storage on the client, you call the fill( ) method on the JSDO.
Each time fill( ) is called, all records currently in local storage are cleared and
replaced by the records returned by the method.

When the operation is complete, the working record for each referenced temp-table is
set to its first record, depending on any active parent-child relationships. So, for each
child temp-table, the first record is determined by its relationship to the related working
record in its parent temp-table.

This method executes the ABL method or user-defined function that is associated in
the JSDO catalog with the read operation.

Associated ABL routine: Read

The ABL routine associated with a read operation must have the following signature:

• An input parameter of type CHARACTER, named filter. This parameter is optional


for the fill( ) call that initiates the read operation; if specified, it defines the
criteria for a filtered subset of records to be returned. The format and content of
the filter string depend on the application.

• A DATASET or TABLE output parameter.

106 OpenEdge® Development: Mobile Applications


Accessing built-in CRUD operations

The following example shows a ReadOrderEntry( ) method that might be associated


with Mobile read operations:

METHOD PUBLIC VOID ReadOrderEntry(


INPUT filter AS CHARACTER,
OUTPUT DATASET dsOrderEntry):

DEFINE DATA-SOURCE srcCustomer FOR Customer.

EMPTY TEMP-TABLE ttCustomer.

BUFFER ttCustomer:ATTACH-DATA-SOURCE(DATA-SOURCE srcCustomer:HANDLE).


IF filter NE "" AND filter NE ? THEN
DATA-SOURCE srcCustomer:FILL-WHERE-STRING = filter.

DATASET dsOrderEntry:FILL( ).
BUFFER ttCustomer:DETACH-DATA-SOURCE( ).
RETURN.

END METHOD.

Client JavaScript code: Read

The following example illustrates calling fill( ) on the JSDO to load records from the
database into local storage:

var strFilter = 'where CustNum < 100';


/* subscribe to event */
dsOrderEntry.subscribe('afterFill', onAfterFill);
dsOrderEntry.fill(strFilter);

function onAfterFill(jsdo , success , request ) {


if (success) {
/* for example, add code to display all records on a list */
jsdo.foreach(function (jsrecord) {
/* the code here is executed for each record on the table.
You can reference the fields as jsrecord.data.field */
});
}
else {
if (request.response && request.response._errors &&
request.response._errors.length > 0){
var lenErrors = request.response._errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) {
var errorEntry = request.response._errors[idxError];
var errorMsg = errorEntry._errorMsg;
var errorNum = errorEntry._errorNum;
/* handle error */
}
}
}
};

Notice that the sample code:

• Passes a filter parameter, strFilter, to the fill( ) method. This filter causes
the method to load only those records with a CustNum value lower than 100.

• Subscribes an event-handler function, onAfterFill, to the afterFill event to


enable processing and error-checking of the returned records.

OpenEdge® Development: Mobile Applications 107


Chapter 4: Creating Mobile Apps using JSDOs

Create operation
To create a new record in local storage on the client, you call the add( ) method on a
table reference on the JSDO. The fields of the new record are initialized with the values
specified in an object passed to the method. For any fields whose values are not
provided in this object, default values are taken from schema in the JSDO catalog.

When the operation is complete, the new record becomes the working record for the
associated temp-table. If the temp-table has child temp-tables, the working record for
these child tables is not set.

When you call saveChanges( ) to synchronize changes made by this method with the
database, the AppServer executes the ABL routine that is associated in the JSDO
catalog with the create operation.

Note: If execution on the AppServer results in changes to the record as compared


with the record sent from the client (for example, the addition of a sequence
value), the JSDO's local storage is automatically synchronized with the
changes when the request object is returned.

If an error occurs on the server, the record is automatically deleted from the
JSDO’s local storage.

Associated ABL routine: Create

The signature of the ABL routine associated with a create operation must have a
DATASET or TABLE input-output parameter.

The following example shows a CreateOrderEntry( ) method that might be


associated with Mobile create operations:

METHOD PUBLIC VOID CreateOrderEntry(INPUT-OUTPUT DATASET dsOrderEntry):


END METHOD.

108 OpenEdge® Development: Mobile Applications


Accessing built-in CRUD operations

Client JavaScript code: Create

The following example illustrates calling add( ) on a table reference in the JSDO to
create a record:

/* subscribe to event */
dsOrderEntry.ttCustomer.subscribe('afterCreate', onAfterCreate);

/* some code that would add a record and save it */


var jsrecord = dsOrderEntry.ttCustomer.add( {State : 'MA'} );

<...>

dsOrderEntry.saveChanges();

function onAfterCreate (jsdo , record , success , request ) {


if (success) {
/* for example, get the values from the record for redisplaying */
var myField = record.data.myField;
<...>
}
else {
if (request.response && request.response._errors &&
request.response._errors.length > 0){
var lenErrors = request.response._errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) {
var errorEntry = request.response._errors[idxError];
var errorMsg = errorEntry._errorMsg;
var errorNum = errorEntry._errorNum;
/* handle error */
}
}
}
};

Notice that the sample code:

• Subscribes an event-handler function, onAfterCreate, to the afterCreate event


to enable error-checking and manipulation of the new record.

• Adds the record to the ttCustomer table, with an initial value of MA for the State
field. (The table reference could be omitted if ttCustomer were the only
temp-table in the dsOrderEntry ProDataSet.)

• Calls saveChanges( ) to execute CreateOrderEntry( ) on the AppServer and


thereby synchronize the content of local storage with the database.

Update operation
To modify an existing record in local storage on the client, you call the assign( )
method. The values of fields to be updated are specified in an object passed to the
method.

The assign( ) method can be called on either of the following:

• A table reference on the JSDO. When called on a table reference, as in the


example below, assign( ) operates on the working record for that table.

• A specific JSRecord object.

OpenEdge® Development: Mobile Applications 109


Chapter 4: Creating Mobile Apps using JSDOs

When the operation is complete, any working records previously set before the method
executed remain as the working records.

When you call saveChanges( ) to synchronize changes made by this method with the
database, the AppServer executes the ABL routine that is associated in the JSDO
catalog with the update operation.

Note: If execution on the AppServer results in changes to the record as compared


with the record sent from the client (for example, an update caused by a
database trigger), the JSDO's local storage is automatically synchronized with
the changes when the request object is returned.

If an error occurs on the server, the record automatically reverts to its original
state in the JSDO’s local storage.

Associated ABL routine: Update

The signature of the ABL routine associated with an update operation must have a
DATASET or TABLE input-output parameter.

The following example shows an UpdateOrderEntry( ) method that might be


associated with Mobile update operations:

METHOD PUBLIC VOID UpdateOrderEntry(INPUT-OUTPUT DATASET dsOrderEntry):


END METHOD.

110 OpenEdge® Development: Mobile Applications


Accessing built-in CRUD operations

Client JavaScript code: Update

The following example illustrates calling assign( ) on a table reference in the JSDO
to update a record:

/* subscribe to event */
dsOrderEntry.subscribe('afterUpdate', onAfterUpdate);

var updatedDataObject = {City: 'Nashua'};


/* some code that would update a record and send it to the server */
var jsrecord = dsOrderEntry.ttCustomer.findById(myid);
dsOrderEntry.ttCustomer.assign( updatedDataObject );
dsOrderEntry.saveChanges();

function onAfterUpdate (jsdo , record , success , request ) {


if (success) {
/* for example, get the values updated by the server from the record
to redisplay */
var newValue = record.data.myField;
<...>
}
else {
if (request.response && request.response._errors &&
request.response._errors.length > 0){
var lenErrors = request.response._errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) {
var errorEntry = request.response._errors[idxError];
var errorMsg = errorEntry._errorMsg;
var errorNum = errorEntry._errorNum;
/* handle error */
}
}
}
}

Notice that the sample code:

• Subscribes an event-handler function, onAfterUpdate, to the afterUpdate event


to enable error-checking and manipulation of the revised record.

• Calls findById( ) to retrieve the record to be updated, which becomes the


working record for the ttCustomer table, and changes the value of the City field
to Nashua. (The table reference could be omitted if ttCustomer were the only
temp-table in the dsOrderEntry ProDataSet.)

• Calls saveChanges( ) to execute UpdateOrderEntry( ) on the AppServer and


thereby synchronize the content of local storage with the database.

Delete operation
To delete an existing record from local storage on the client, you call the remove( )
method.

The remove( ) method can be called on either of the following:

• A table reference on the JSDO. When called on a table reference, assign( )


operates on the working record for that table.

• A specific JSRecord object. The example below uses this technique.

OpenEdge® Development: Mobile Applications 111


Chapter 4: Creating Mobile Apps using JSDOs

When the operation is complete, any working record for an associated temp-table and
for any child temp-tables is not set.

When you call saveChanges( ) to synchronize changes made by this method with the
database, the AppServer executes the ABL routine that is associated in the JSDO
catalog with the delete operation.

Note: If an error occurs on the server, the record is automatically restored in the
JSDO’s local storage.

Associated ABL routine: Delete

The signature of the ABL routine associated with a delete operation must have a
DATASET or TEMP-TABLE INPUT-OUTPUT parameter.

The following example shows a DeleteOrderEntry( ) method that might be


associated with Mobile delete operations:

METHOD PUBLIC VOID DeleteOrderEntry(INPUT-OUTPUT DATASET dsOrderEntry):


END METHOD.

Client JavaScript code: Delete

The following example illustrates calling remove( ) on a JSRecord object:

/* subscribe to event */
dsOrderEntry.subscribe('afterDelete', onAfterDelete);

var jsrecord = dsOrderEntry.ttCustomer.findById(myid);


jsrecord.remove();
dsOrderEntry.saveChanges();

function onAfterDelete (jsdo , record , success , request ) {


if (success) {
/* for example, get the values from the record that was
deleted to display a confirmation message */
var myKeyField = record.data.myKeyField;
<...>
}
else {
if (request.response && request.response._errors &&
request.response._errors.length > 0){
var lenErrors = request.response._errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) {
var errorEntry = request.response._errors[idxError];
var errorMsg = errorEntry._errorMsg;
var errorNum = errorEntry._errorNum;
/* handle error */
}
}
}
};

112 OpenEdge® Development: Mobile Applications


Accessing built-in CRUD operations

Notice that the sample code:

• Subscribes an event-handler function, onAfterDelete, to the afterDelete event


to enable error-checking and manipulation of the revised record.

• Calls findById( ) to retrieve the record to be deleted, and then calls remove( )
on this JSRecord object.

• Calls saveChanges( ) to execute DeleteOrderEntry( ) on the AppServer and


thereby synchronize the content of local storage with the database.

OpenEdge® Development: Mobile Applications 113


Chapter 4: Creating Mobile Apps using JSDOs

Batch saving of changes


As an alternative to calling saveChanges( ) to update the database after each discrete
CRUD operation, you can have OpenEdge Mobile apply all pending changes with a
single call. The following example illustrates this approach:

/* subscribe to event */
dsOrderEntry.subscribe('afterSaveChanges', onAfterSaveChanges);
dsOrderEntry.saveChanges();

function onAfterSaveChanges(jsdo , success , request ) {

/* number of operations on batch */


var len = request.batch.operations.length;

if (success) {
/* all operations in batch succeeded */
/* for example, redisplay records in list */
jsdo.foreach( function(jsrecord) {
/* reference the record/field as jsrecord.data.fieldName */
});
}
else {
/* one or more operations in batch failed */
for(var idx = 0; idx < len; idx++) {
var operationEntry = request.batch.operations[idx];

console.log("Operation: " + operationEntry.fnName);


var opName;
switch (operationEntry.operation) {
case progress.data.JSDO._OP_CREATE:
opName = 'create';
break;
case progress.data.JSDO._OP_UPDATE:
opName = 'update';
break;
case progress.data.JSDO._OP_DELETE:
opName = 'delete';
break;
}

if (!operationEntry.success) {
/* handle error condition */
if (operationEntry.response &&
operationEntry.response._errors &&
operationEntry.results._errors.length > 0){
var lenErrors = operationEntry.response._errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) {
var errors = operation.results._errors[idxError];
var errorMsg = errors._errorMsg;
var errorNum = errors._errorNum;
/* handle error */
}
}
}
else {
/* operation succeed */
}
}
}
};

114 OpenEdge® Development: Mobile Applications


Accessing non-built-in invoke operations

Accessing non-built-in invoke operations


In addition to the built-in CRUD methods, a JSDO can call invocation methods that
correspond to ABL routines defined in the Mobile resource and annotated with an
"invoke" operation type. The JSDO catalog identifies the available invoke operations.
Calling an invoke operation on the JSDO causes the corresponding routine to execute
on the AppServer.

The signature of an ABL routine designated as an invoke operation is unrestricted.


Parameters of ABL data types supported by OpenEdge Mobile can be used.

The invocation method name can be the same as that of the ABL routine, or it can be
an alias, as defined by the resource. The method passes any ABL input parameters as
properties of an object parameter. The method returns results from the ABL routine,
including any return value and output parameters, in the response property of a
request object.

The response property is an object in which parameter names match the names
defined in the ABL routine. Since JavaScript is case-sensitive, code that accesses the
value of an output parameter must exactly match the name defined in the ABL routine.

For user-defined functions and non-void ABL methods, the return value is available in
the _retVal property of the response object. The _retVal property also contains any
error information returned by the server If the request fails.

Note: The JSDO local storage is not automatically updated with the results of an
invoke operation. To add records returned by the invoke operation to local
storage, call addRecords( ) on the appropriate table.

Asynchronous vs. synchronous method execution


Invocation methods can execute either asynchronously (the default behavior) or
synchronously. An optional Boolean “async flag,” provided as a second parameter to
the method (in addition to the Object parameter, if any, containing ABL input
parameters), specifies the execution mode. The value of this second parameter
defaults to true if omitted. For synchronous execution, set the flag to false.

To process the results of an asynchronous method call, you subscribe an


event-handler function to the afterInvoke event. For a synchronous call, you do not
subscribe to the event, but access the data through the response property of the
request object returned by the method.

Invocation method example


To illustrate working with different data types, the following example involves an invoke
operation that both returns a DECIMAL value and has an output parameter of type
TABLE.

OpenEdge® Development: Mobile Applications 115


Chapter 4: Creating Mobile Apps using JSDOs

ABL invoke routine: GetCreditLimit( )

The following example shows a method that might be designated as an invoke method,
which can be called on the JSDO:

METHOD PUBLIC DECIMAL GetCreditInfo ( INPUT piCustNum AS INT, OUTPUT TABLE


eTable):

END METHOD.

Client JavaScript code: Invoking GetCreditLimit( )

The following example illustrates an asynchronous call to the preceding method:

dsOrderEntry.subscribe('afterInvoke', 'GetCreditInfo',
onAfterInvokeGetCreditInfo);
dsOrderEntry.GetCreditInfo ( { piCustNum : 10 } );

function onAfterInvokeGetCreditInfo (jsdo , success , request ) {

var res = request.response;

if (success) {
var creditLimit = res._retVal;
var eTableObj = res.eTable.eTable;
}
else {
if (res && res._errors &&
res._errors.length > 0){
var lenErrors = res._errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) {
var errorEntry = res._errors[idxError];
var errorMsg = errorEntry._errorMsg;
var errorNum = errorEntry._errorNum;
/* handle error */
}
}
}
};

Notice that the sample code:

• Subscribes an event-handler function, onAfterInvokeGetCreditInfo, to the


afterInvoke event to enable error-checking and processing of the results.

• Declares the eTableObj variable with a value of request.eTable.eTable. The


parameter name (eTable) must be specified twice. The first instance refers to the
parameter name as defined in the ABL routine; the second instance is for the
temp-table serialized as a JSON object.

116 OpenEdge® Development: Mobile Applications


Managing user login sessions

Managing user login sessions


The first task in accessing a Mobile resource with a JSDO is to create a user login
session for the Mobile Web application that provides the Mobile service and resource
you need. This might require user authentication prior to calling the login( ) method
on an instance of the OpenEdge JavaScript class, progress.data.Session. Once
user authorization is obtained, you must then call the addCatalog( ) method on this
Session object to load the JSDO catalog for the service into your Mobile App. You can
then create a JSDO for a Mobile resource defined in the catalog.

However, you need to gather some information to determine how best to configure and
code the user login sequence.

Requirements for creating a user login session


You need to identify the following information to configure and code a user login
session:

• The Web server authentication model that the Mobile Web application will
use:

Web servers support a number of authentication models to manage client access


to Web resources. OpenEdge Mobile supports the following authentication
models:

– Anonymous — No authentication is required. This is the default value.

– HTTP Basic Authentication — The Mobile Web application requires a valid


user ID and password, but does not provide a page containing a login form
(credentials are typically entered in a generic login dialog provided by either
the Mobile App, the Web browser, or the native device container in which the
App is running).

– HTTP Forms Authentication — The Mobile Web application requires a valid


user ID and password and provides a page containing a login form.

The exact user login sequence depends on the Web server authentication model,
the Mobile App type and platform, and how Mobile Web application resources are
protected on the Web server. Because of this, differences in platform behavior can
cause problems with reliable access to Mobile resources. To minimize the
chances of such access problems, you must know the Web server authentication
model to be configured for the Mobile Web application and set the
authenticationModel property on the Session object accordingly. For more
information on Web server authentication models and OpenEdge Mobile, see the
sections on security considerations in Chapter 5, “Deploying Mobile Applications.”

OpenEdge® Development: Mobile Applications 117


Chapter 4: Creating Mobile Apps using JSDOs

• Whether the Web browser(s) or mobile device(s) where the Mobile App runs
will have cookies enabled:

If the Mobile Web application you access will use HTTP Form Authentication, the
mobile devices and Web browsers that access the Mobile Web application must
have cookies enabled. Otherwise, the Mobile App cannot login and access Mobile
services. If there is any question about the availability of cookies on client
platforms, you might consider using HTTP Basic Authentication for the Mobile
Web application, instead, and set the authenticationModel property on the
Session object accordingly.

If the Mobile Web application will use HTTP Basic Authentication and the mobile
devices and Web browsers will not have cookies enabled, you must set a property
in the single sign-on (SSO) configuration of the Mobile Web application to allow
session logins to work from the Mobile App. For more information, see the
sections on enabling SSO for a Web application in Chapter 5, “Deploying Mobile
Applications.”

• A protected Web resource, such as a Web page, provided by the Mobile Web
application against which your Mobile App can authenticate before it tries
to access its first protected Mobile resource:

In general, you need to be sure that security is configured to complete


authentication before a Mobile App requests resources in the JSDO catalog.
Although it is possible to configure Web application security so that the Mobile
resources in the catalog are the only resources that require authentication,
Progress Software does not recommend this approach. In certain situations where
a Mobile resource is the first Web application resource to require user
authentication, a Mobile App can be prevented from accessing the resource even
when user authentication succeeds. Instead, Progress Software recommends
that you require user authentication to access at least one Web application
resource in addition to those defined in the catalog, and require that this user
access and authentication occur prior to accessing any Mobile resources in the
catalog. Once the user is authenticated in this way, the Web server provides
access to all other resources of the Mobile Web application, including catalog
resources, according to the user's authorization settings.

Note: An OpenEdge Mobile Web application includes default features to support


this approach to authenticating users before any catalog resources are
accessed. For more information, see the “Default Web pages to support
Mobile App login” section on page 119.

118 OpenEdge® Development: Mobile Applications


Managing user login sessions

• The type of Mobile App you are writing and where it will be deployed: a
Mobile Web App deployed to a Web server or a Mobile Native App deployed
to an app store:

In order to log into a Mobile Web application and load any of its JSDO catalogs,
you need to provide appropriate URIs for both. If you are writing a Mobile Web
App, and it will be deployed to the same Apache Tomcat Web server as the Mobile
Web application it is accessing, all of these URIs can be relative to the Web server
root (domain or host and port). The Web browser automatically prepends these
relative URIs to the Web server root from which the Mobile Web App is loaded.
However, if a Mobile Web App is deployed to a different Web server from the one
where the Mobile Web application is deployed, all of these URIs must be absolute
and include the Web server root for the Mobile Web application.

If you are writing a Mobile Native App, all of the URIs for the Mobile Web
application and its JSDO catalogs must also be provided as absolute URIs,
because a Mobile Native App is loaded and executed from the local storage of the
mobile device, which knows nothing of the Mobile Web application its Mobile Web
App is going to access.

Note: In general, if a Mobile App requires absolute URIs, you need to maintain
separate JavaScript sources for versions of the Mobile App that you deploy
for different Mobile Web application environments, such as one for testing
and another for production.

Depending on the Web server authentication model, you might need to set up Web
resources differently to help with the Mobile App login sequence. OpenEdge provides
some default Web resources with every deployed Mobile Web application that you can
use for this purpose, or you define similar Web resources of your own.

Default Web pages to support Mobile App login


When you deploy Mobile services to a Tomcat Web server as a Mobile Web
application, OpenEdge provides default Web pages that you can use to configure
Mobile Web application authentication. The URIs for the following Web pages
(provided relative to the Mobile Web application root) support the startup and user login
of a Mobile App in a way that authenticates the user prior to requesting access to
Mobile resources, depending on the Web server authentication model:

• /index.html — Default public welcome page for Mobile App startup. This page
can be protected or unprotected depending on how you design authentication for
your Mobile App.

• /static/auth/login.html — Default Mobile Web application login page to


support HTTP Forms Authentication. With a login page configured (such as this
default), the Mobile Web application can then provide a protected Web resource
for access by the user. This might be a link on the public welcome page to a
protected Web page that the user must access to use Mobile resources, or it
might be the welcome page, itself, that is protected and requires authentication for
access by the user.

OpenEdge® Development: Mobile Applications 119


Chapter 4: Creating Mobile Apps using JSDOs

In any case, when the user goes to the first Web application-protected Web page,
the Web server returns the configured login page to the browser or mobile device,
which displays the login form for the user to enter their credentials. When the user
submits their credentials, the browser or device sends them to the Mobile Web
application for authentication. If successful, the Web application then returns the
protected Web page to the browser or device for display to the user. At this point,
the user is authenticated and all further access to Mobile Web application
resources is provided according to the user’s authorization settings.

The Mobile App must then call the login( ) method on a newly instantiated
Session object, passing it the URI of the Mobile Web application to establish the
login session to access its Mobile services. Since user authentication has already
occurred, there is no need to pass user credentials, and any that you do pass to
the login( ) method are ignored. The Mobile App is now ready to load a JSDO
catalog.

An alternative approach is supported by OpenEdge Mobile for HTTP Forms


Authentication, where no protected Web page or other Web resource is provided
before calling the login( ) method. When this happens, after obtaining user
credentials, perhaps using a Mobile App-provided login page, the method both
authenticates the user directly with the HTTP Forms Authentication system and
sends a request to start a login session to access JSDO catalogs.

• /static/home.html — Default Mobile Web application login target page to


support HTTP Basic Authentication. Generally, this page is not designed to be
displayed as part of Mobile App UI, but to be used only as a protected Web
resource against which to authenticate the user prior to accessing Mobile
resources. In this case, the Mobile App obtains the user credentials either by using
a prompt directly from the browser or mobile device when the user first tries to
access a protected Web page of the Mobile Web application or by using a
separate login page that the Mobile App provides for the user to access and enter
their credentials for authentication during session login.

If the credentials are prompted by user access to a protected Web page, the
browser or device sends them to the Mobile Web application for authentication. If
successful, the Web application then returns the protected Web page to the
browser or device for display to the user. At this point, the user is authenticated
and all further access to Mobile Web application resources is provided according
to the user’s authorization settings.

The Mobile App must then call the login( ) method on a newly instantiated
Session object, passing it the URI of the Mobile Web application to establish the
login session to access its Mobile services. If the user credentials have already
been prompted by the browser or device, and successfully authenticated by the
Web application, there is no need to pass them, and any that you do pass to the
login( ) method are ignored. The Mobile App is now ready to load a JSDO
catalog.

120 OpenEdge® Development: Mobile Applications


Managing user login sessions

If the credentials have been entered using a separate login page that the Mobile
App provides for the user to access, you must pass them explicitly as parameters
to the login( ) method in order to have them sent to the Mobile Web application
for authentication together with the session login request. In this case, the Mobile
Web application authenticates the user against the protected login target page,
which can be the /static/home.html default or another protected page whose
URI you pass explicitly to the login( ) method. If authentication against this login
target page is successful, the user is authenticated and the login session to
access Mobile services is established. All further access to Mobile Web
application resources is provided according to the user’s authorization settings,
and the Mobile App is now ready to load a JSDO catalog.

Again, using these suggested options for designing a login sequence, at each point
where the Mobile App is ready to load a JSDO catalog, user authentication has already
occurred against a protected Mobile Web application resource prior to requesting a
Mobile resource.

OpenEdge® Development: Mobile Applications 121


Chapter 4: Creating Mobile Apps using JSDOs

Getting started with other HTML coding tools


If you do not need the support for the Mobile App Builder, or have other client
requirements, you can also build the Mobile App using the basic HTML and JavaScript
coding tools of Progress Developer Studio for OpenEdge. For this purpose, OpenEdge
Mobile provides a JSDO helper class, progress.ui.UIHelper, to map JSDO data to
HTML elements using supported UI frameworks, such as JQuery Mobile.

The UIHelper class assists in building Mobile applications with a list view and a detail
page. It can be used in the following scenarios and JavaScript frameworks:

• JQuery Mobile

• JQuery Mobile using the Mobile App Builder

• iUI

• User interface based on HTML and JavaScript where list views are built directly
using the <li> element

Figure 5 shows a sample screen generated using the UIHelper class

Figure 5: Sample display using the UIHelper class

Using the UIHelper class


The UIHelper is instantiated to work with a JSDO instance. The setListView( )
method is used to specify the HTML element for the list (<ul> element). The
clearItems( ) and addItem( ) methods are used to build the list view. The
showListView( ) method is used to show the list view on the screen.

Note: For complete information on the methods of the UIHelper class, see
Appendix C, “OpenEdge JavaScript Class Properties, Methods, and Events
Reference.”

122 OpenEdge® Development: Mobile Applications


Getting started with other HTML coding tools

The following is a sample HTML file using JQuery Mobile (index.html):

Sample HTML file using JQuery Mobile (index.html)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1"
/>
<title>Customers</title>
<link rel="stylesheet"
href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
<style>
/* App custom styles */
</style>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
</script>
<script
src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js">
</script>
<script src="progress.session.js"></script>
<script src="progress.js"></script>
<script src="customers.js"></script>
</head>
<body>
<div data-role="page" id="custlist">
<div data-theme="b" data-role="header">
<h3>Customers</h3>
</div>
<div data-role="content">
<ul id="listview" data-role="listview" data-divider-theme="b"
data-inset="true" data-filter="true">
</ul>
</div>
</div>

<div data-role="page" id="custdetail" data-add-back-btn="true"


data-theme="b">
<div data-theme="b" data-role="header"><h1>Customer</h1></div>
<div data-role="content">
<form action="" id="customerform">
</form>
</div>
</div>
</body>
</html>

OpenEdge® Development: Mobile Applications 123


Chapter 4: Creating Mobile Apps using JSDOs

The following is the customers.js script used in the sample HTML.

Sample JavaScript file using JQuery Mobile (customers.js)

var customers;
var uihelper;
var forminitialized = false;

$(document).ready(function() {
var session = new progress.data.Session();

session.login("http://localhost:8980/SportsApp", "", "");


session.addCatalog(
'http://localhost:8980/SportsApp/static/mobile/CustomerOrderSvc.json');

customers = new progress.data.JSDO({ name: 'CustomerOrder' });


customers.subscribe('AfterFill', onAfterFillCustomers, this);

uihelper = new progress.ui.UIHelper({ jsdo: customers });

uihelper.eCustomer.setDetailPage({ name: 'custdetail' });

uihelper.eCustomer.setListView({
name:'listview',
format: '{CustNum}<br>{Name}<br>{State}',
autoLink: true
});

$('#customerform').html(
uihelper.eCustomer.getFormFields()
+ '<input type="button" value="Add" id="btnAdd" />'
+ '<input type="button" value="Save" id="btnSave" />'
+ '<input type="button" value="Delete" id="btnDelete" />'
);

customers.fill();
});

function onAfterFillCustomers() {
uihelper.eCustomer.clearItems();
customers.eCustomer.foreach(function(customer) {
uihelper.eCustomer.addItem();
});
uihelper.eCustomer.showListView();
}

The setDetailPage( ) method is used to specify the name of the HTML element,
generally a <div>, that represents the detail page.

The getFormFields( ) method can be used to obtain the HTML text for the fields of
the specified table reference. This HTML text is generally added to the HTML element
representing the form in the detail page. This element does not need to be a <form>
element; it can be a <div> element.

The format property of the initialization object for setListView( ) contains


substitution parameters that are replaced when addItem( ) is called: {CustNum},
{Name}, and {State}. The working record of the specified table reference is used to
determine the values of the fields. In the sample customer.js script, the call to
addItem( ) queries the working record to obtain the values of the fields CustNum, Name
and State. The addItem( ) method then builds a list item using a default template for
list items.

124 OpenEdge® Development: Mobile Applications


Getting started with other HTML coding tools

Using a custom template


You can specify a different template for the list items using one of the following
methods:

• Using the itemTemplate property in the initialization object for setListView( ).

• Calling progress.ui.UIHelper.setItemTemplate( ).

• By not specifying the format property. In this case, the UIHelper uses the first
item element in the list view as the template for the items.

You can also specify a different template for the fields returned when calling
getFormFields( ):

• Specify the fieldTemplate property in the initialization object for


setDetailPage( ).

• Call progress.ui.UIHelper.setFieldTemplate( ).

Alternatively, you can define the layout for the detail page using HTML instead of
calling getFormFields( ).

The default item template looks like this:

<li data-theme="c" data-id="{__id__}">


<a href="#{__page__}" class="ui-link"
data-transition="slide">{__format__}</a>
</li>

The default field template looks like this:

<div data-role="fieldcontain">
<label for="{__name__}">{__label__}</label>
<input id="{__name__}" name="{__name__}" placeholder="" value=""
type="text" />
</div>

The templates use the following substitution parameters:

• Used when building the list items by calling addItem( ):

– {__id__} — The internal ID of the record

– {__page__} — The name attribute of the object passed as a parameter to


setDetailPage( ), which defines the detail page

– {__format__} — The format attribute of the object passed as a parameter


to setListView( ) or (optionally) to addItem( ), which identifies the fields
to be included for each item in the list view

OpenEdge® Development: Mobile Applications 125


Chapter 4: Creating Mobile Apps using JSDOs

• Used for the HTML text returned when calling getFormFields( ):

– {__name__} — The field name in a temp-table as defined by the name


property in the catalog

– {__label__} — The label of the field in a temp-table as defined by the title


property in the catalog

The properties itemTemplate and the fieldTemplate can be used to change the
template for a specific UIHelper instance.

For example:

uiHelper.eCustomer.setListView({
name: 'cust-listview',
format: '{CustNum} {Name}<br>{Address}',
autoLink: true,
itemTemplate: '<li data-id="{__id__}"><a href="#{__page__}"
>{__format__}</a></li>'
});

uiHelper.eCustomer.setDetailPage({
name: 'cust-detail-page',
fieldTemplate: '<input id="{__name__}"></input>'
});

The methods progress.ui.UIHelper.setItemTemplate( ) and


progress.ui.UIHelper.setFieldTemplate( ) can be used to change the template
to be used by the UIHelper for a JavaScript session.

For example:

progress.ui.UIHelper.setItemTemplate('<li data-id="{__id__}"><a
href="#{__page__}" >{__format__}</a></li>');

progress.ui.UIHelper.setFieldTemplate('<input id="{__name__}"></input>');

126 OpenEdge® Development: Mobile Applications


Publishing Mobile Apps for testing

Publishing Mobile Apps for testing


When you create a Mobile project in Developer Studio, if you choose the option to
publish changes immediately, as long as the OE Web Server that you have selected
for a Mobile App is running, when you create or in any way update the Mobile App and
its resources in Developer Studio, the Web server publishes it as a Mobile Web App.
This also occurs after you save a Mobile App project in Mobile App Builder. The saved
Mobile App is automatically downloaded to the Mobile Apps folder in the shared
Developer Studio project. Developer Studio publishes the Mobile App from this folder
as a WAR file, with the name of the Mobile App as its filename, to the selected OE Web
Server for testing.

If the OE Web Server is not running when you initially create the Mobile App, or you did
not select the project option to publish changes immediately, you can use the Servers
view to publish the Mobile App by first starting the AppServer for the project (right-click
on the AppServer and select Start). Once the AppServer is started and synchronized,
you can start the OE Web Server instance for the Mobile App (right-click on the OE
Web Server instance and select Start). Once the OE Web Server is started and
synchronized, right-click on it and select Publish, and any Mobile App not yet
published should publish.

To test a published Mobile App, you should already have coded the appropriate URIs
to login to the Mobile Web application that provides the JSDO catalog for the published
Mobile services you need. For more information, see the section on identifying URIs for
Mobile Web applications in Chapter 3, “Creating Mobile Services.”

For information on deploying Mobile Apps for production, see Chapter 5, “Deploying
Mobile Applications.”

OpenEdge® Development: Mobile Applications 127


Chapter 4: Creating Mobile Apps using JSDOs

128 OpenEdge® Development: Mobile Applications


5
Deploying Mobile Applications

This chapter provides information on production deployment for both Mobile Web
applications and the Mobile Apps that access them. Production deployment
considerations can also be helpful for Mobile application developers who need to test
their Mobile Apps and services prior to deployment. Also, the Mobile App developer
needs to know some production security considerations in order to properly design and
code their Mobile App.

The following sections describe these deployment considerations in detail:

• Deployment overview

• Packaging and deploying Mobile services

• Packaging and Deploying iOS Apps

• Packaging and Deploying Android Apps

• Packaging and Deploying Mobile Web Apps

• Security considerations

OpenEdge® Development: Mobile Applications 129


Chapter 5: Deploying Mobile Applications

Deployment overview
There are three options for packaging and deployment of a Mobile App:

• iOS App

• Android App

• Mobile Web App

Table 3 lists the terminology used in this chapter to describe the considerations for
deployment of different types of mobile applications.

Table 3: Mobile Application Terminology

Term Description

Mobile Web The Mobile App and/or Mobile services deployed to a web server
application

Mobile The services deployed to a web server and accessed by a Mobile


services Native App or Mobile Web App

Mobile App Any Mobile client UI that runs natively on a mobile device (Mobile
Native App) or in a web browser on a mobile device (Mobile Web
App)

Mobile Native An application that runs natively on a mobile device


App

Mobile Web An application that runs in a web browser on a mobile device


App

Mobile A Mobile App and all of its associated backend services


application

130 OpenEdge® Development: Mobile Applications


Packaging and deploying Mobile services

Packaging and deploying Mobile services


To package Mobile services for deployment (with or without a Mobile Web App
included), you can use the Export as Mobile Web Application wizard in Progress
Developer Studio for OpenEdge (Developer Studio).

To package Mobile services:

1. In Developer Studio, right-click on the name of your project in the Project Explorer
view and choose Export→ Mobile Web Application.

2. Choose the Mobile Project name, Destination, and Mobile/REST services.


Optionally, choose a Mobile Web App to package with the services.

3. Checking the Include default runtime library files box includes the files
necessary to create a standalone Mobile Web application that can be deployed on
any server.

4. Click Finish. The WAR file is created and placed in the destination you selected.

Deployment can be done by using OpenEdge Explorer or OpenEdge Management to


deploy the WAR file to an OE Web Server. This applies the default settings necessary
to enable and make the Mobile Web application available for access by Mobile Apps.
Alternatively, you can manually copy the WAR file to the webapps folder of an Apache
Tomcat server, which requires manual configuration of the settings necessary to make
the Mobile Web application available for access by Mobile Apps.

The tools and options for deploying the WAR file for a Mobile Web application are
similar to those for deploying the WAR file for a REST Web application. For more
information, see the sections on REST administration in OpenEdge Application Server:
Administration.

OpenEdge® Development: Mobile Applications 131


Chapter 5: Deploying Mobile Applications

Packaging and Deploying iOS Apps


Packaging a Mobile App for iOS (IPA file) requires a certificate and a provisioning
profile. These credentials are required during development as well as deployment. For
more information on creating the certificate and provisioning profile, see the “Deploying
iOS Apps” section on page 134.

Note: When deploying iOS Apps to different environments (development and testing
vs. production deployment), different source code must be deployed. The URIs
for logging into Mobile Web applications and accessing their services in each
environment must be different absolute URIs. The JavaScript source for
production deployment should have the required absolute URIs hard coded to
log into all Mobile Web applications whose Mobile services are accessed by
the iOS App.

Packaging iOS Apps


To build and package a Mobile App for iOS:

1. In Progress Developer Studio for OpenEdge (Developer Studio), right-click on the


project and choose Properties→ Progress OpenEdge→ Mobile App Builder.

2. On the Build options page, select iOS. Click OK.

3. Expand the Mobile Apps folder in the Project pane and double-click on the name
of the Mobile App. The Mobile App Builder will open in a browser.

4. In the Mobile App Builder, expand Project and click App settings. Click the iOS
binary IPA properties tab.

5. Enter the Mobile App name in the Label field.

6. Enter the Bundle ID in the Bundle ID field.

7. The icon is the graphic that will launch the Mobile App on an iOS device. Upload
an icon file using the Browse button in the Icons area.

8. Upload a launch image file for the application using the Browse button in the
Launch Images area.

132 OpenEdge® Development: Mobile Applications


Packaging and Deploying iOS Apps

9. To upload the certificate:

a. Click Change next to Certificate file.

b. Click Upload file.

c. Click Upload a file and locate the certificate. Once the upload is complete,
click Back to files list.

d. Click on the certificate file and click Select.

10. Enter the certificate password.

11. To upload the provisioning profile:

a. Click Change next to Provisioning profile file.

b. Click Upload file.

c. Click Upload a file and locate the provisioning profile. Once the upload is
complete, click Back to files list.

d. Click on the provisioning profile file and click Select.

12. Click Save.

13. In Developer Studio, right-click on the name of the Mobile App in the Mobile Apps
folder and choose Copy source local to get the updated Mobile App in the
Developer Studio project.

14. To package the IPA, right-click on the name of the Mobile App in the Mobile Apps
folder and choose Export local. The IPA file will in the bin directory.

You can test your app during development by copying the IPA directly to an Apple
device.

To copy the IPA to an iOS device:

1. Open iTunes on your computer.

2. Drag the IPA into the iTunes Library.

3. Plug the iOS device into the computer.

4. Drag the IPA from the iTunes Library onto the icon showing the device.

If you get an installation error, verify that the UUID of the device is registered correctly
and that the provisioning profile includes that device. For more information, see the
“Deploying iOS Apps” section on page 134.

OpenEdge® Development: Mobile Applications 133


Chapter 5: Deploying Mobile Applications

Deploying iOS Apps


Building a Mobile App for iOS (IPA file) requires registration as an Apple Developer, a
developer certificate, and a provisioning profile. The sections below point you to
information to help you create your own credentials. Note that a Mac is required for this.
For more detailed information visit:

https://developer.apple.com/devcenter/ios/index.action

Apple Developer

To register as an Apple Developer, visit this website:

https://developer.apple.com/programs/register/

iOS Provisioning Portal

To create the certificate and provisioning profile, use the iOS Provisioning Portal. This
portal is part of the iOS Dev Center. To access the portal, log in at the following link
with the Apple ID you used to register as a developer:

https://developer.apple.com/devcenter/ios/index.action

Click on the iOS Provisioning Portal link.

Certificates

The following video has more information on certificates:

https://developer.apple.com/ios/manage/overview/index.action

Note that a certificate must be in P12 format in order to be used in the Mobile
Application Builder.

App IDs

An App ID has three parts: Description, Bundle Seed ID (App ID Prefix), and Bundle
Identifier (App ID Suffix). The Description of the App ID can be anything, e.g.,
OEMobile. The Bundle Seed ID (App ID Prefix) is assigned for you and is assigned to
be your Team ID. The Bundle Identifier can be unique for each application or use a
wildcard for many applications. Although it is possible to use "*" by itself, the
recommended practice is to use the following notation: com.progresssoftware.* or
com.progresssoftware.applicationname.

It is important to remember what you entered for the Bundle Identifier. This will be used
when creating the IPA in the Mobile App Builder. The following link describes Bundle
Identifiers:

http://developer.apple.com/library/ios/#DOCUMENTATION/FileManagement/C
onceptual/understanding_utis/understand_utis_conc/understand_utis_conc
.html

The following video has information about app IDs:

https://developer.apple.com/ios/manage/overview/index.action

134 OpenEdge® Development: Mobile Applications


Packaging and Deploying iOS Apps

Devices

Each device must be registered. This is accomplished by using the device UUID. The
UUID can be found by running a free UUID app on the device.

The following video has more information on devices:

https://developer.apple.com/ios/manage/overview/index.action#

Provisioning Profiles

A Provisioning Profile has four parts: Profile Name, Certificate(s), App ID, and
Device(s). The Profile Name can be anything, e.g., OEMobile. The following video has
more information on provisioning:

https://developer.apple.com/ios/manage/overview/index.action#

The following link also has more information:

http://developer.apple.com/library/ios/#technotes/tn2250/_index.html

OpenEdge® Development: Mobile Applications 135


Chapter 5: Deploying Mobile Applications

Packaging and Deploying Android Apps


Packaging a Mobile App (APK file) for Android requires a signing key/certificate, but
during development and testing, the signing key/certificate inputs are not required. For
more information on creating the signing key/certificate, see the “Deploying Android
Apps” section on page 138.

Note: When deploying Android Apps to different environments (development and


testing vs. production deployment), different source code must be deployed.
The URIs for logging into Mobile Web applications and accessing their
services in each environment must be different absolute URIs. The JavaScript
source for production deployment should have the required absolute URIs
hard coded to log into all Mobile Web applications whose Mobile services are
accessed by the Android App.

Packaging Android Apps


To build and package a Mobile App for Android:

1. In Progress Developer Studio for OpenEdge (Developer Studio), right-click on the


project and choose Properties→ Progress OpenEdge→ Mobile App Builder.

2. On the Build options page, select Android. Click OK.

3. To open the Mobile App within the Mobile App Builder, double-click on the name
of the Mobile App. The Mobile App Builder will open in a browser.

4. From within the Mobile App Builder, choose Project→ App settings and click
Android binary APK properties.

5. Enter the Mobile App name in the Label field.

136 OpenEdge® Development: Mobile Applications


Packaging and Deploying Android Apps

6. The launcher icon is the visual representation of your app on the mobile device.
To upload an icon:

a. Click Change next to Icon.

b. Click Upload file.

c. Click Upload a file and locate the icon file. Once the upload is complete, click
Back to images list.

d. Click on the icon file and click Select.

e. Click Upload a file and locate the provisioning profile. Once the upload is
complete, click Back to files list.

f. Click on the provisioning profile file and click Select.

7. Enter the Version code.

8. Enter the Version name.

9. Enter the Package name.

10. Enter the Minimum SDK version.

11. Enter the Target SDK version.

12. Enter the Maximum SDK version.

13. To upload the Keystore file:

a. Click Change in the Keystore file field. Click Upload file.

b. Click Upload a file and locate the Keystore. Once the upload is complete,
click Back to files list.

c. Click on the Keystore file and click Select.

d. Enter the Key alias.

e. Enter the Key password.

f. Enter the Keystore password.

14. Click Save.

15. In Developer Studio, right-click on the Mobile App in the Mobile Apps folder and
choose Copy source local to get the updated Mobile App to the Developer Studio
project.

16. To package the APK, right-click on the Mobile App in the Mobile Apps folder and
choose Export local. The APK file will in the bin directory.

OpenEdge® Development: Mobile Applications 137


Chapter 5: Deploying Mobile Applications

During development, there are several ways to get the newly created APK on an
Android device for testing. One

1. Create an account on http://dropbox.com.

2. Click and drag the APK into dropbox.

3. Open http://dropbox.com from a browser on the mobile device and log in.

4. Click on the APK from within the dropbox application. This will begin downloading
the application onto the device.

5. When the download is complete, click on the downloaded file on the mobile
device. Follow the device directions for installing the app.

Deploying Android Apps


For detailed information on Android development and deployment, visit this website:

http://developer.android.com/index.html

Versioning your Mobile App

Versioning is important for application upgrades and maintenance. Users need to have
specific information about the application version that is installed on their devices and
the upgrade versions available for installation, and other applications and services may
need to check the version of your application for compatibility issues. For more
information go to:

http://developer.android.com/tools/publishing/versioning.html

Package Name

The Application package is an identifier of the application. This identifier is unique


among all the apps installed on device at a given moment; there cannot be two apps
with the same Application package installed at the same time. It is also unique on the
Android market; there cannot be two apps with the same Application package on the
Market. Conflict over the Application package with unforeseen third-party apps is
possible. Using the Java package name convention (“com.mydomain.myapp”) for the
Application package name is recommended to avoid such conflict.

Signing your application

The Android system requires all installed applications be digitally signed with a
certificate whose private key is held by the application’s developer. To test and debug
your application, the build tools sign your application with a special debug key. When
you are ready to release your application for end-users you must sign it with a suitable
private key. For more information go to:

http://developer.android.com/tools/publishing/app-signing.html

138 OpenEdge® Development: Mobile Applications


Packaging and Deploying Mobile Web Apps

Packaging and Deploying Mobile Web Apps


You can package a Mobile Web App with or without associated Mobile services using
Developer Studio.

Note: When you deploy a Mobile Web App to the same Web server as the Mobile
Web application that it accesses, its URIs for logging into the Mobile Web
application and accessing its services can be relative to the host location (or
domain) of the Web server where both the Mobile Web App and Mobile Web
application are deployed. However, when a Mobile Web App and its Mobile
Web application are deployed to different Web servers, the JavaScript for the
Mobile Web App must be hard coded with the absolute URIs to access the
Mobile Web application and its services. This also means that when deployed
to different environments (development and testing vs. production
deployment), you must deploy different source code to allow the Mobile Web
App to access the Mobile Web application and its services in each
environment.

Packaging Mobile Web Apps


To package a Mobile Web App with associated Mobile services, you can use the Export
as Mobile Web Application wizard in Developer Studio. A single Mobile Web App can
be packaged with the Mobile service.

To package a Mobile Web application with mobile services:

1. In Developer Studio, right-click on the name of your project in the Project Explorer
view and choose Export→ Mobile Web Application.

2. Choose the Mobile Project name, Destination, Mobile App, and Mobile/REST
services.

3. Checking the Include default runtime library files box includes the files
necessary to create a standalone Mobile Web application that can be deployed on
any server.

4. Click Finish. The WAR file is created and placed in the destination you selected

To package a Mobile Web application without mobile services:

Right-click on the application name in the Project Explorer view in Developer Studio
and choose Export Local. The packaged app will appear as a ZIP file in the bin
directory. (The default export format is WebApp, but you can change that by navigating
to Properties→ Progress OpenEdge→ Mobile App Builder and selecting a native
format.)

OpenEdge® Development: Mobile Applications 139


Chapter 5: Deploying Mobile Applications

Deploying Mobile Web Apps


Deployment can be done by using OpenEdge Explorer or OpenEdge Management to
deploy the WAR file to an OE Web Server. This applies the default settings necessary
to enable and make the Mobile Web application available for access by Mobile Apps.
Alternatively, you can manually copy the WAR file to the webapps folder of an Apache
Tomcat server, which requires manual configuration of the settings necessary to make
the Mobile Web application available for access by Mobile Apps.

The tools and options for deploying the WAR file for a Mobile Web application are
similar to those for deploying the WAR file for a REST Web application. For more
information, see the sections on REST administration in OpenEdge Application Server:
Administration.

For more information on packaging a Mobile App as part of a Mobile Web application,
see the new “Packaging and deploying Mobile services” section on page 131.

140 OpenEdge® Development: Mobile Applications


Security considerations

Security considerations
The security considerations for OpenEdge Mobile applications described in this section
apply variously to both development environments (which might be managed by a
developer or development administrator) and production environments (which are
often managed by an IT administrator). For specific considerations that apply to the
development and testing of Mobile services, you can also find more information in
Chapter 3, “Creating Mobile Services.” For specific considerations that apply to the
development and testing of Mobile Apps, you can also find more information in
Chapter 4, “Creating Mobile Apps using JSDOs.” Generally, this section addresses the
security requirements of production environments unless otherwise indicated.
Developers will also be interested in this information when they need to make
application design and coding decisions for a particular production environment.

In general, security considerations for OpenEdge Mobile applications using the


HTTP/HTTPS REST transport include the following:

• Web server authentication models — The Mobile Web application can be


configured to support one of several Web server authentication models in order to
authenticate user access to its Mobile App and Mobile services. OpenEdge Mobile
supports a subset of the available Web server authentication models, and many
of a Web application’s security options depend on the authentication model that
you select.

• SSL connections — OpenEdge allows you to configure SSL connections, which


enables your Mobile application to use URIs based on HTTPS between the Mobile
App and its Mobile Web application, and AppServer SSL between the Mobile Web
application and the AppServer. Each SSL connection enables secure data
exchange between a Mobile App and its Mobile resources running in an
AppServer.

• Mobile device security — You might need to consider options for securely
hosting a Mobile App on a particular mobile device, such as securing the Mobile
App on the device or registering a public certificate for the Web server where
Mobile services are deployed to allow SSL connections to these services.

The following sections describe how these security considerations affect Mobile
application deployment.

Web server authentication models


The Mobile Web application must be configured to use one of the authentication
models supported by OpenEdge Mobile.

OpenEdge® Development: Mobile Applications 141


Chapter 5: Deploying Mobile Applications

OpenEdge Mobile supports the following Web server authentication models:

• Anonymous — The Web server requires no user authentication or login session


management for access.

• HTTP Basic Authentication — The Mobile App must obtain and send the
required user name and password to the Mobile Web application in order to
access the requested resource. Note that the Mobile App (using a Session object)
sends the required user name and password automatically (assuming that
authentication has not already occurred) if you provide them at session login.

• HTTP Form Authentication — If the Mobile App requests a resource that


requires authentication it may take one of two actions: 1) respond to an HTML user
login page from the Mobile Web application after it references the resource, or 2)
send the Mobile Web application the required user ID and password before
requesting the resource. If the Mobile Web application can validate the user with
the credentials provided, it allows the client access to the resource.

Note: Progress supplies application security templates that are used to define the
protection on the Mobile services and/or the Mobile App (when the Mobile App
is a Mobile Web App deployed to the Web server). These templates are files
named appSecurity-authentication_type.xml, where
authentication_type indicates the Web server authentication model. These
files are located in the WEB-INF directory of an OpenEdge Mobile project in
Progress Developer Studio for OpenEdge. See the templates for information
on specific protection schemes, and see the sections on configuring security
for REST applications in OpenEdge Application Server: Administration for
additional information on Mobile Web application security.

Your Mobile App design can significantly affect how it responds to the selected Web
server authentication model. For more information, see the sections on creating a user
login session in Chapter 4, “Creating Mobile Apps using JSDOs.”

To operate effectively together, a Mobile Web application and any Mobile App that
accesses its Mobile services must be configured and coded (respectively) by the
developer for the same Web server authentication model.

To configure the Web server authentication model for a Mobile Web application, you
use the same options for choosing the security model for a REST Web application.
These options work together with the Spring Security framework installed with
OpenEdge to manage security for REST applications. For more information, see the
sections on choosing and applying a security configuration for REST applications in
OpenEdge Application Server: Administration.

Note: If you select HTTP Form Authentication, the mobile devices and Web browsers
that access the Mobile Web application must have cookies enabled.
Otherwise, the Mobile App cannot login and access Mobile services.

If you select HTTP Basic Authentication and the mobile devices and Web
browsers do not have cookies enabled, you must set a property in the SSO
configuration of the Mobile Web application to allow session logins from Mobile
Apps. For more information, see the “Enabling SSO for a Web application”
section on page 143.

142 OpenEdge® Development: Mobile Applications


Security considerations

In order to avoid certain problems that can result when authenticating from different
mobile devices and Web browsers, you must ensure that any Mobile App that accesses
the services of a Mobile Web application is built to use the same Web server
authentication model as the Web application it is accessing. The developer must code
the Mobile App to use the appropriate authentication model. For more information on
coding the authentication model for a Mobile App, see the sections on creating a user
login session in Chapter 4, “Creating Mobile Apps using JSDOs.”

The following is a series of general steps you can follow to configure the security
features associated with your selected authentication model:

To configure the Mobile Web application security features associated with its
selected Web server authentication model:

1. If you have coded the ABL application services on the AppServer to rely on a
single sign-on (SSO) client-principal passed with each request from the Mobile
Web application to establish an AppServer login session for each request, you
must enable the Web application for SSO.

2. For the selected authentication model, you can add application users and their
access roles for the Mobile Web application.

3. Once you have configured user access roles, you can define access control lists
for the resources requested by a Mobile App based on these access roles.

4. You can also configure the Mobile Web application to support cross-origin
resource sharing (CORS), which allows a Mobile App to make requests for Mobile
resources hosted in different Web domains.

As with configuring the Web server authentication model, you can configure associated
security features for a Web application using the options available to configure these
same features for a REST application. The following sections provide more information
on configuring each of these features.

Enabling SSO for a Web application

If enabled, your Web application will create an SSO client-principal for the user
credentials authenticated by the Mobile Web application. When the Mobile App
executes an operation for a supported Mobile resource, the Mobile Web application
passes its authenticated user ID and login session ID in the form of a client-principal to
the AppServer. The AppServer can use it to establish the login session to complete the
operation request. For more information on establishing an SSO login session on the
AppServer, see the sections on AppServer coding in Chapter 3, “Creating Mobile
Services.” For information on enabling SSO for an OpenEdge REST or Mobile Web
application, see the sections on SSO support for REST applications in OpenEdge
Application Server: Administration.

Note: If you have selected HTTP Basic Authentication for the Web application and
cookies will not be enabled for the mobile devices and Web browsers that
access its Mobile services, you must set the ccid property appropriately in
your SSO configuration in order to allow the session ID to be passed between
the Mobile App and its Web application.

OpenEdge® Development: Mobile Applications 143


Chapter 5: Deploying Mobile Applications

Defining user roles for a Web application

User roles allow you to define access controls for the Mobile services and resources of
a Mobile Web application so that only users that have a given assigned role can access
a given resource. OpenEdge provides a built-in set of predefined roles or you can
define your own user roles for a Web application. For more information, see the
sections on adding users, and user roles and privileges, for REST applications in
OpenEdge Application Server: Administration.

Setting access controls based on user roles

The tools for setting access controls on a Web application's resources are provided
entirely using the Spring Security framework installed with OpenEdge. For more
information on using the Spring Security framework to apply access controls, see the
Spring Security documentation at
http://static.springsource.org/spring-security/site/reference.html.

Cross-origin resource sharing (CORS)

Cross-origin resource sharing (CORS) is a W3C group standard that allows a Mobile
App's JavaScript to access Web application resources in a DNS domain different from
the one the current HTTP page and JavaScript were loaded from. Such “cross-domain”
requests are otherwise forbidden by Web browser’s JavaScript engine. The CORS
standard defines a way in which a Mobile App's JavaScript can ask the Web application
if it can make the cross-origin request, and the Web application's configuration can
determine if the cross-domain request will be granted. The W3C CORS standard works
by adding new HTTP headers that allow servers to control resource access to
permitted origin domains.

CORS support is enabled in Mobile Web applications and its defaults are configured to
grant access to all Mobile services from any generic HTTP requests (made by a non
JavaScript client) and any JavaScript engine from any DNS domain. This means that
a Mobile App can load a Web page from one DNS domain and perform Mobile
operations on any Mobile service's resources residing in another DNS domain. CORS
support is extended to all modern mobile devices and Web browsers. Before using
devices and browsers with a CORS-enabled Mobile application, ensure that they
support the CORS standard. For more information on the CORS standard, see the
documentation at http://www.w3.org/TR/cors/.

You might need to configure CORS support for a Mobile Web application specific to a
production site's requirements. You can do this in exactly the same way as for a REST
Web application. OpenEdge supports CORS configuration using the Spring Security
framework embedded in each Mobile and REST Web application. For more information
on configuring this CORS support, see the sections on managing security for REST
applications in OpenEdge Application Server: Administration.

144 OpenEdge® Development: Mobile Applications


Security considerations

SSL connections
Secure Sockets Layer (SSL) allows you to configure secure (encrypted) HTTPS
connections between your Mobile App and the Mobile services hosted in your Mobile
Web application. You typically configure a Mobile Web application to use HTTPS
connections when the data being sent between the Mobile App and the Web
application is restricted to only authenticated users or when logging into the Mobile
application (to protect the exchange of user credentials).

When a Mobile application is configured to use HTTPS, the Mobile App communicates
with its Mobile services using URIs based on HTTPS (HTTP over SSL). To enable SSL,
you configure appropriate digital certificate stores for the Web server and configure the
Mobile Web application's security policy to require HTTPS connections from its clients
(Mobile Apps). You might also require the use of SSL connections between the Mobile
Web application and its ABL application services on the AppServer when the
AppServer is located on the site's intranet. You also need to ensure that the mobile
devices or Web browsers that run the Mobile App are configured to validate the
Certificate Authority (CA) public certificates who issued the Web server's server
certificate.

You can configure HTTPS for a Mobile application in exactly the same way as for a
REST application. For more information on configuring a REST application and its
AppServer for SSL, see the sections on SSL support for REST applications in
OpenEdge Application Server: Administration. For more information on using SSL in
OpenEdge generally, see OpenEdge Getting Started: Core Business Services -
Security and Auditing.

OpenEdge® Development: Mobile Applications 145


Chapter 5: Deploying Mobile Applications

Mobile device security


The options for mobile device security, such as securing Mobile Apps on a mobile
device or support for public certificates to allow SSL access to Mobile services depend
on the particular device or Web browser. For more information, see the documentation
on hosting Apps for the particular device or browser.

146 OpenEdge® Development: Mobile Applications


A
ABL to JavaScript Data Type Mapping

An OpenEdge progress.data.JSDO (JSDO) is a JavaScript class instance that


provides the Mobile App behavior for a data resource that is implemented in ABL. A
JSDO communicates with the OpenEdge AppServer through a Mobile service to
marshal ABL data for parameters (and return values) of ABL routines that pass the
following ABL data types: ProDataSets, temp-tables, arrays, and primitive values. The
JSDO provides this ABL data to the Mobile App programmer as JavaScript data types.
For more information on ABL data types, see the reference entry on data types in
OpenEdge Development: ABL Reference. For more information on the format and use
of JavaScript data types, you can review sources on the Web, such as
http://www.w3schools.com/js/js_datatypes.asp.

The following sections present a brief description of JavaScript data types and how
they map to data types in ABL:

• JavaScript data type overview

• Data type mapping between JavaScript and ABL

For more information on JSDOs and how they communicate with an AppServer
through a Mobile service, see the “progress.data.JSDO class” section on page 155.

OpenEdge® Development: Mobile Applications 147


Appendix A: ABL to JavaScript Data Type Mapping

JavaScript data type overview


JavaScript supports four primitive data types, as shown in Table 4.

Table 4: JavaScript primitive data types

Data type Description Examples

String A string of characters enclosed in double or single "jump rope"


quotes.

Number An unquoted numeric value, which can include an 17


exponent using scientific notation.
54.35
0.9582e-42

Boolean The unquoted, lowercase, literal value true or false. true

null The unquoted, lowercase, literal value, null. null

The data type of a primitive value is determined by the format of the value:

• A string of characters surrounded by quotes indicates the value is a String.

• A string of numeric characters—without quotes—with an optional decimal point,


an optional negative sign, or an optional exponent indicates a Number.

• The string true or false—without quotes—indicates a Boolean.

• The unquoted string null indicates a null (or undefined) value, which maps to
the ABL Unknown value (?).

In addition to these standard primitive data types, there are some commonly-used
(though not officially supported) data types for certain values. For this purpose,
specially formatted strings represent values for which there is no standard primitive
JavaScript data type.

Table 5 shows the non-standard data types that ABL supports.

Table 5: Supported non-standard data types

Non-standard
data type Representation

Date A String in the ISO 8601 format,


"yyyy-mm-ddThh:mm:ss.sss+hh:mm". JavaScript does
support a Date object for working with dates and times.
However, all dates and times returned from the
AppServer to an OpenEdge JSDO are stored as a String
in the ISO 8601 format.

Binary data A String consisting of the Base64 encoded equivalent of


the binary data

148 OpenEdge® Development: Mobile Applications


JavaScript data type overview

JavaScript also supports two complex data types, used to aggregate values of all
JavaScript data types, including both primitive and complex data, as shown in Table 6:

Table 6: JavaScript complex data types

Data type Description Examples

Object A comma-delimited { myString : "jump rope",


list of named values 'myNum' : 17,
(properties), either 'myBool' : false }
primitive or complex,
enclosed in braces
({}). The property
names can either be
literal values or
quoted strings.

Array A comma-delimited [ "jump rope", 17, false ]


list of unnamed
values, either
primitive or complex,
enclosed in brackets
([])

Note: JavaScript also supports standard objects with the same type names as the
primitive data types, for example, a Number object. These objects serve as
wrappers for the corresponding primitive types and provide additional
operations on these primitive types.

OpenEdge® Development: Mobile Applications 149


Appendix A: ABL to JavaScript Data Type Mapping

Data type mapping between JavaScript and ABL


Table 7 shows how the AVM maps ABL data types to JavaScript data types. Note that
an ABL data element of any primitive type set to the Unknown value (?) maps to the
JavaScript null value. The ABL BLOB and CLOB are only allowed as fields of temp-table
parameters, and their respective equivalents, MEMPTR and LONGCHAR, are only allowed
as scalar parameters or as elements of Array parameters.

Table 7: ABL to JavaScript data type mappings (1 of 2)

ABL data type JavaScript data type

BLOB1 String (Base64 encoded)

CHARACTER String

CLOB1 String

COM-HANDLE Number

DATASET2 An Object that maps to a ProDataSet and contains


one or more Object instances, each of which maps to
an ABL temp-table in the ProDataSet (see
TEMP-TABLE)

DATE String (ISO 8601 formatted string of the form


"yyyy-mm-dd")

DATETIME String (ISO 8601 formatted string of the form


"yyyy-mm-ddThh:mm:ss.sss")

DATETIME-TZ String (ISO 8601 formatted string of the form


"yyyy-mm-ddThh:mm:ss.sss+hh:mm")

DECIMAL Number

primitive EXTENT2 Where primitive is an ABL primitive data type (not a


DATASET or TEMP-TABLE), maps to an Array of the
JavaScript primitive data type that maps to the
corresponding ABL primitive data type

HANDLE Number

INT64 Number

INTEGER Number

LOGICAL Boolean (true or false)

LONGCHAR3 String

MEMPTR3 String (Base64 encoded)

RAW Not supported

RECID Not supported

150 OpenEdge® Development: Mobile Applications


Data type mapping between JavaScript and ABL

Table 7: ABL to JavaScript data type mappings (2 of 2)

ABL data type JavaScript data type

ROWID String (Base64 encoded)

TEMP-TABLE2 An Object that contains a single Array of Object


instances, where each Object in the Array maps to a
record in the corresponding temp-table

1. In temp-tables only.
2. ABL ProDataSets, temp-tables, and arrays map to JavaScript objects and arrays using a structure that is
identical to the OpenEdge-supported mapping to JSON objects and arrays. JSON (JavaScript Object
Notation) is a character representation of JavaScript data types that is often used as a lightweight
alternative to XML. For more information on ABL support for JSON, including the JSON representation of
these ABL data types, see OpenEdge Development: Working with JSON.
3. As scalar parameters or elements of Array parameters only.

OpenEdge® Development: Mobile Applications 151


Appendix A: ABL to JavaScript Data Type Mapping

152 OpenEdge® Development: Mobile Applications


B
OpenEdge JavaScript Class and Object
Reference

This appendix describes the JavaScript classes and objects installed with OpenEdge
to support access to OpenEdge Mobile services from OpenEdge Mobile Apps. Each
class or object description lists the documented class or object members by category:
properties, methods, and events, with a short description of each member. For a
detailed description of each member, see Appendix C, “OpenEdge JavaScript Class
Properties, Methods, and Events Reference.”

Notes: JavaScript is a case-sensitive language. So, class type, property, method, and
event names, as well as other defined language elements (such as data types)
must have the specified letter case.

In addition to the documented members, these classes and objects might also
contain undocumented members that are reserved for internal use by
OpenEdge.

The OpenEdge JavaScript classes and objects for Mobile App development include
the:

• JSRecord object

• progress.data.JSDO class

• progress.data.Session class

• progress.ui.UIHelper class

• request object

OpenEdge® Development: Mobile Applications 153


JSRecord object

JSRecord object
JSRecord is a JavaScript object that returns a record instance for any temp-table stored
in the local storage of an associated progress.data.JSDO class instance (JSDO).

Properties
Table 8: JSRecord object properties

Brief description
Member (See also the reference entry)

data property An object containing the data for a temp-table


record specified by a JSRecord object

Methods
Table 9: JSRecord object methods

Brief description
Member (See also the reference entry)

assign( ) method (JSDO Updates field values for a temp-table record


class) specified by a JSRecord object

getId( ) method Returns the unique internal ID for the specified


temp-table record referenced in JSDO local
storage

remove( ) method Deletes the temp-table record specified by a


JSRecord object

Events This object has no events.

Example The following example assumes that a JSDO is referenced by the jsdo variable, and
that a UIHelper instance associated with that JSDO is referenced by the uihelper
variable. The example creates a new record object and displays it, along with a
message with credit information using properties of the record object:

function addRecord() {
var jsrecord = jsdo.add({Balance: 10000, State: 'MA'});
uihelper.display( );
alert('Record ID: ' + jsrecord.getId( ) + ' CreditLimit: ' +
jsrecord.data.CreditLimit);
}

Note Using the add( ), find( ), findById( ), or foreach( ) method, or the record
property, on a given JSDO and table reference, a JSRecord instance returns a working
record for the temp-table referenced in JSDO local storage. You can then use
properties and methods of the JSRecord to update, delete, or display the specified
record from the JSDO.

See also add( ) method, find( ) method, findById( ) method, foreach( ) method,
progress.data.JSDO class, record property, table reference property (JSDO)

154 OpenEdge® Development: Mobile Applications


progress.data.JSDO class

progress.data.JSDO class
The progress.data.JSDO is a JavaScript class that provides access to ABL
application services as OpenEdge Mobile resources. A single progress.data.JSDO
object (JSDO) provides access to one Mobile resource in an OpenEdge Mobile service.
A Mobile resource maps to an ABL singleton procedure or class running on an
OpenEdge AppServer. The JSDO provides application-oriented, JavaScript methods
to invoke the internal procedures, user-defined functions, or methods (ABL routines) of
the corresponding singleton procedure or class. A Mobile resource maps specified ABL
routines as one of several supported Mobile operation types, each of which
corresponds to a particular method of the JSDO.

You identify how a JSDO maps JavaScript methods to operations of a given Mobile
resource by adding annotations to the singleton procedure or class source code. These
annotations define a Mobile interface for accessing the procedure or class as a Mobile
resource. You can define a Mobile interface using features of Progress Developer
Studio for OpenEdge (Developer Studio) in two ways: 1) when creating an ABL
Business entity class, which supports common business operations on data models,
and 2) for any existing ABL singleton class or procedure, whether or not the singleton
accesses a separate Business entity object.

You can also use Developer Studio to define a Mobile resource as part of a Mobile
service, and to generate the Mobile service together with the client-side artifacts
required to create a corresponding JSDO for the resource. These client-side artifacts
include a JSDO catalog file that identifies how a JSDO that you create can access the
corresponding Mobile resource using methods of the JSDO.

At run time, the JSDO maintains local storage for managing temp-table data that is
exchanged between the AppServer and JavaScript client, and it provides methods to
read and write the data in JSDO local storage as individual JavaScript record objects.
To support this data exchange, a Mobile resource can be organized into basic
operation types that include built-in create, read, update, and delete (CRUD)
operations, and non-built-in invoke operations. The built-in Mobile operations can
operate on a single temp-table or on a single ProDataSet containing one or more
temp-tables. Each built-in operation type maps to a corresponding built-in method of
the JSDO. The records of each temp-table are presented as an array of record objects,
which the built-in methods use to exchange the data with the AppServer. The built-in
methods, through their corresponding operation types, support the common business
operations that can be generated directly from an ABL Business entity. Other methods
of the JSDO provide access to individual record objects of JSDO local storage. Based
on the results of its methods, the JSDO also maintains a working record for each
temp-table in its local storage that you can access directly using table and field
references (see the notes). Thus, using the methods of a JSDO and its table
references, you can interact with a corresponding Mobile resource in a consistent
manner from one resource (and its corresponding JSDO) to another.

A JSDO also supports non-built-in invoke operations that allow specific ABL routines
to be exposed in a Mobile resource and executed as corresponding JavaScript
methods. You can do this in Developer Studio by annotating ABL routines specifically
as invoke operations. You can then call each ABL routine annotated as an invoke
operation using a unique invocation method on the JSDO. Note that data exchanged
between the AppServer and client using invoke operations is not automatically stored
in JSDO local storage. It is initially accessible only through parameters and return
values of the invocation methods provided by the JSDO. You can subsequently use
JSDO methods for accessing JSDO local storage to exchange data between the
invocation methods and local storage, which is maintained and synchronized with the
AppServer using the JSDO built-in methods.

OpenEdge® Development: Mobile Applications 155


progress.data.JSDO class

When you instantiate a JSDO, it relies on a prior login session that you can establish
using an instance of the progress.data.Session class. This login session enables
optionally secure communications between the client JSDO and the Web server,
specified Mobile services, and ultimately the AppServer that implements the Mobile
resource accessed by the JSDO.

Constructors Two constructors are available for the JSDO. The first constructor takes the name of
the corresponding Mobile resource as a parameter; the second constructor takes an
initialization object as a parameter:

Syntax

progress.data.JSDO ( resource-name )
progress.data.JSDO ( init-object )

resource-name

A string expression set to the name of a resource provided by a Mobile service for
which a login session has been started.

init-object

An object that can contain any writable JSDO properties. It must contain the
required JSDO name property, which specifies the Mobile resource for the JSDO.
It can also contain either or both of the following initialization properties:

• autoFill — A Boolean that specifies whether the the JSDO invokes its
fill( ) method upon instantiation to initialize its local storage with data from
the Mobile resource. The default value is false.

• events — An object that specifies one or more JSDO event subscriptions,


each with its properties represented as an array, with the following syntax:

Syntax

events : {
'event' : [ {
[ scope : object-ref , ]
fn : function-ref
} ] [ ,
'event' : [ {
[ scope : object-ref , ]
fn : function-ref
} ] ] ...
}

event

The name of an event to which the JSDO instance subscribes. See


Table 13 for a list of available JSDO events.

156 OpenEdge® Development: Mobile Applications


progress.data.JSDO class

object-ref

An optional object reference that defines the execution scope of the


function called when the event fires. If the scope property is omitted, the
execution scope is the global object (usually the browser or device
window).

function-ref

A reference to an event handler function that is called when the event


fires.

Each event passes a fixed set of parameters to its event handler, as


described in the reference entry for the event in Appendix C,
“OpenEdge JavaScript Class Properties, Methods, and Events
Reference.”

The resource name specified for the constructor must match the name of a Mobile
resource provided by a Mobile service for which a login session has already been
started. After the JSDO is created, it uses the information stored in the JSDO catalog
that is loaded for the Mobile service to communicate with the specified resource.

Example The following example illustrates the use of an initialization object to instantiate a
JSDO:

dsItems = new progress.data.JSDO({


name : 'Item',
autoFill : false,
events : {
'afterFill' : [ {
scope : this,
fn : function (jsdo, success, request) {
// afterFill event handler statements ...
}
} ]
}

});

Properties
Table 10: progress.data.JSDO properties (1 of 2)

Brief description
Member (See also the reference entry)

name property The name of the Mobile resource for which the
current JSDO is created

record property A property on a JSDO table reference that


references a JSRecord object with the data for the
working record of a temp-table referenced in JSDO
local storage

OpenEdge® Development: Mobile Applications 157


progress.data.JSDO class

Table 10: progress.data.JSDO properties (2 of 2)

Brief description
Member (See also the reference entry)

table reference property A property on a JSDO that has the name of a


(JSDO) temp-table mapped by the Mobile resource for
which the current JSDO is created

useRelationships property A Boolean that specifies whether JSDO methods


that operate on table references in JSDO local
storage work with the table relationships defined in
the schema (that is, work only on the records of a
child table that are related to the parent)

Methods Certain methods of the progress.data.JSDO class are called on the JSDO object
itself, without regard to a table reference, whether that reference is explicit (specified
in the method signature) or implicit (in the case of a JSDO containing only one
temp-table that is not explicitly specified). Other methods can be called on a reference
to a temp-table mapped by the Mobile resource for which the current JSDO is created.

Table 11: progress.data.JSDO class-instance methods

Brief description
Member (See also the reference entry)

addRecords( ) method Reads a specified object and updates the local


storage of the JSDO

fill( ) method Initializes the JSDO local storage from the data
records in a single temp-table, or in one or more
temp-tables of a ProDataSet, as returned by the
built-in read operation of the Mobile resource for
which the JSDO is created

invocation method Any method on the JSDO that is defined by the


Mobile resource to execute a corresponding ABL
routine on the AppServer as an invoke operation

saveChanges( ) method Synchronizes to the AppServer all changes made


to JSDO local storage since the last call to the
fill( ) or saveChanges( ) method

subscribe( ) method Subscribes a given event handler function to a


named event for a JSDO or table reference

unsubscribe( ) method Unsubscribes a given event handler function from


a named event of a JSDO or table reference

158 OpenEdge® Development: Mobile Applications


progress.data.JSDO class

Table 12: progress.data.JSDO table-reference methods

Brief description
Member (See also the reference entry)

add( ) method Creates a new record object for a temp-table


referenced in JSDO local storage and returns a
reference to the new record

addRecords( ) method Reads a specified object and updates the local


storage of the JSDO

assign( ) method (JSDO Updates field values for the specified temp-table
class) record referenced in JSDO local storage

find( ) method Searches for a record in a temp-table referenced in


JSDO local storage and returns a reference to that
record if found

findById( ) method Locates and returns the record in JSDO local


storage with the internal ID you specify

foreach( ) method Loops through the records of a temp-table


referenced in JSDO local storage and invokes a
function as a parameter on each iteration

getData( ) method Returns an array of record objects for a temp-table


referenced in JSDO local storage

getId( ) method Returns the unique internal ID for the specified


temp-table record referenced in JSDO local
storage

getSchema( ) method Returns an array of objects, one for each field that
defines the schema of a temp-table referenced in
JSDO local storage

remove( ) method Deletes the specified temp-table record referenced


in JSDO local storage

subscribe( ) method Subscribes a given event handler function to a


named event for a JSDO or table reference

unsubscribe( ) method Unsubscribes a given event handler function from


a named event of a JSDO or table reference

OpenEdge® Development: Mobile Applications 159


progress.data.JSDO class

Events
Table 13: progress.data.JSDO events

Brief description
Member (See also the reference entry)

afterCreate event Fires after the JSDO, by means of a


saveChanges( ) call following an add( ) call,
sends a request to create a record and receives a
response to this request from the AppServer

afterDelete event Fires after the JSDO, by means of a


saveChanges( ) call following a remove( ) call,
sends a request to delete a record and receives a
response to this request from the AppServer

afterFill event Fires after the JSDO, by means of a fill( ) call,


sends a request to read a temp-table or
ProDataSet into JSDO local storage and receives
a response to this request from the AppServer

afterInvoke event Fires after a non–built-in method is called


asynchronously on a JSDO and a response to the
request is received from the AppServer

afterSaveChanges event Fires once for each call to the saveChanges( )


method on a JSDO, after responses to all create,
update, and delete requests have been received
from the AppServer

afterUpdate event Fires after the JSDO, by means of a


saveChanges( ) call following an assign( ) call,
sends a request to update a record and receives a
response to this request from the AppServer

beforeCreate event Fires before the JSDO, by means of a


saveChanges( ) call following an add( ) call,
sends a request the AppServer to create a record

beforeDelete event Fires before the JSDO, by means of a


saveChanges( ) call following a remove( ) call,
sends a request the AppServer to delete a record

beforeFill event Fires before the JSDO, by means of a fill( )


call, sends a request to the AppServer to read a
temp-table or ProDataSet into JSDO local storage

beforeInvoke event Fires when a non–built-in method is called


asynchronously on a JSDO, before the request for
the operation is sent to the AppServer

beforeSaveChanges event Fires once for each call to the saveChanges( )


method on a JSDO, before any create, update, or
delete requests are sent to the AppServer

beforeUpdate event Fires before the JSDO, by means of a


saveChanges( ) call following an assign( ) call,
sends a request the AppServer to update a record

160 OpenEdge® Development: Mobile Applications


progress.data.JSDO class

The JSDO can subscribe to the events listed in Table 13 in either of two ways:

• Subscription via JSDO constructor — In the init-object parameter of


the constructor, list each subscribed event with an optional scope object and
an event handler method to be executed when the event fires. See the
“Constructors” section on page 156.

• Subscription via subscribe( ) method — See the “subscribe( ) method”


section on page 251.

Note: JSDO events do not fire if the method call is synchronous.

Example The following example reads customer records from a server-side temp-table or
ProDataSet and displays fields from the records in a list on the current Web page:

Table 14: Example — Using an OpenEdge JSDO

var session = new progress.data.Session();


// assuming userName and password came from the UI
var loginResult = session.login('/MobileApp', userName, password );
if (loginResult != progress.data.Session.LOGIN_SUCCESS) {
//process login failure here and return/throw error, etc
throw new Error("Login failed");
}
session.addCatalog('/MobileApp/static/mobile/MobileSvc.json');

var jsdoOrderEntry = new progress.data.JSDO( 'OrderEntry' );


jsdoOrderEntry.subscribe('AfterFill', onAfterFill);
var uihelper = new progress.ui.UIHelper({ jsdo: dataSet });
// set list view and detail page for displaying data
uihelper.eCustomer.setDetailPage({ name: 'custdetail' });
uihelper.eCustomer.setListView({
name:'listview',
format: '{CustNum}<br>{Name}<br>{State}',
autoLink: true
});

function onAfterFill() {
uihelper.eCustomer.clearItems();
jsdoOrderEntry.eCustomer.foreach(function(jsrecord) {
uihelper.eCustomer.addItem();
});
uihelper.eCustomer.showListView();
}

OpenEdge® Development: Mobile Applications 161


progress.data.JSDO class

Notes • For more information on defining a Mobile interface, including the built-in CRUD
and non-built-in invoke operations of a Mobile resource, see Chapter 3, “Creating
Mobile Services.”

• The JSDO supports a working record for each temp-table referenced in its local
storage. Certain methods set a specific record as the working record. After other
methods execute, there is no working record or existing working records remain
unchanged. When there is a working record, you can access the fields of the
record using one of the following mechanisms:

Syntax

jsdo.table-ref.field-ref
jsdo.record.data.field-ref // Read only when a single table-ref is defined
jsdo.table-ref.record.data.field-ref // Read only
jsrecord-ref.data.field-ref // Read only

jsdo

The reference to a JSDO, and if the JSDO has only one temp-table, an
implied reference to the working record defined for that temp-table.

table-ref

A table reference with the name of a temp-table in jsdo local storage and a
reference to the temp-table working record. There is one table reference in a
JSDO for each temp-table referenced by the JSDO.

field-ref

A field reference on a table-ref, or a property on the data property object,


with the name and value of a field in the working record of the referenced
temp-table. There is one such field reference and data object property for
each field defined in the temp-table schema.

record

A property of type JSRecord on a table reference, which references the


working record of a temp-table specified by:

• jsdo.table-ref

• jsdo if the JSDO has only one temp-table

If the JSDO has more than one temp-table, the record property is null at
the JSDO level and is available only on a table-ref.

data

A property on a JSRecord object with the field values for the working record
specified by:

• jsdo.table-ref

• jsdo if the JSDO has only one temp-table

• js-record of an associated JSDO temp-table

162 OpenEdge® Development: Mobile Applications


progress.data.JSDO class

Note: If a field-ref has the same name as a built-in property or method of


the JSDO, you must use the data property to reference its value in the
working record.

Caution: Never write directly to a field-ref using this data property; in this
case, use field-ref only to read the data. Writing to data using
such a reference does not mark the record for update when calling
the saveChanges( ) method. To mark a record for update, you
must assign a field value either by setting a
jsdo.table-ref.field-ref for a working record or by calling the
assign( ) method on a valid table-ref or JSRecord object
reference.

jsrecord-ref

A reference to a JSRecord object of a temp-table in JSDO local storage. You


can return a jsrecord-ref for a working record as the value of the record
property or as a value returned by supported JSDO built-in methods that
return a working record, such as add( ) and find( ).

For more information on the properties available to reference working record fields
using this syntax, see Table 10 and Table 8. For more information on the methods
for setting the working record for referenced temp-tables, see Table 11 and
Table 9.

• Many JSDO built-in methods are actually invoked on a JSDO table reference, and
can only be invoked on the JSDO itself when its local storage is initialized with a
single temp-table.

• For a multi-table ProDataSet, the JSDO accesses the data for all unrelated
temp-tables in local storage as top-level tables of the JSDO. Access to data for all
related child temp-tables depends on the working record of the parent temp-table
in the JSDO and the setting of the useRelationships property.

See also JSRecord object, progress.data.Session class, record property, table reference
property (JSDO), table reference property (UIHelper)

OpenEdge® Development: Mobile Applications 163


progress.data.Session class

progress.data.Session class
The progress.data.Session is a JavaScript class that can manage user
authentication and session identification information in HTTP/S messages sent
between progress.data.JSDO objects (JSDOs) running in an OpenEdge Mobile App
and Mobile services running on a Web server. The authentication information includes
a user ID and password (user credentials). The session identification information
includes a URI, which identifies the Mobile Web application that provides the REST
transport between its defined set of Mobile services and the client that accesses them,
and a session ID, which identifies the user login session for the entire set of Mobile
services supported by the Mobile Web application.

To start a user login session, you can either allow the Web browser or hybrid
application wrapper to complete the user login process or invoke the login( ) method
on a Session object that you have instantiated, passing as parameters the Mobile Web
application URI, optional user credentials, and an optional specified Mobile Web
application resource (such as a static HTML page) to authenticate access. Once
started, a login session for a Mobile Web application supports all Mobile services that
the application provides, each of which can provide one or more Mobile resources.

Each Mobile service provided by a Mobile Web application relies on a separate JSDO
catalog file to define the communications between its Mobile resources and the JSDOs
that access them from the client. Once a user login session is established for a Mobile
Web application, you can use its Session object to load the catalog for each Mobile
service provided by the Web application. Once the JSDO catalog is loaded for the
Mobile service, you can instantiate a JSDO to access any Mobile resource provided by
the service in the catalog. If required, the authentication information for the session is
also used to authorize access to the Mobile resource by its JSDO.

All JSDOs can thus rely on a single Session object to manage the user login session
for all Mobile services and their resources provided by a single Mobile Web application.
This single Session object then manages the session life cycle from startup (login) to
shutdown (logout) for all JSDOs of a Mobile App and the Mobile services they access
from the same Mobile Web application.

Constructor
progress.data.Session ( )

Instantiates a Session object that you can use to start a user login session for a Mobile
Web application and load the JSDO catalog for each supported Mobile service whose
resources are accessed using JSDOs.

164 OpenEdge® Development: Mobile Applications


progress.data.Session class

Properties
Table 15: progress.data.Session properties

Brief description
Member (See also the reference entry)

authenticationModel property A string constant that specifies the type of


authentication that the server requires from the
client

catalogURIs property Returns the list of URIs used to load the JSDO
catalogs to access the Mobile services provided
by the Mobile Web application for which the
current Session object manages a user login
session

loginHttpStatus property Returns the specific HTTP status code returned


in the response from the most recent login
attempt on the current Session object

loginResult property Returns the return value of the login( )


method, which is the basic result code for the
most recent login attempt on the current Session
object

loginTarget property Returns the string appended to the Mobile Web


application URI passed to the login( ) method
to form the URI of an application resource against
which the user has been authenticated for the
current login session

onOpenRequest property Returns a developer-specified callback function


that the Session object executes to modify a
request object before sending the request object
to the server

services property Returns an array of objects that identifies the


Mobile services that have been loaded for the
current Session object and its Mobile Web
application

serviceURI property Returns the URI to the Mobile Web application


passed as a parameter to the most recent call to
the login( ) method on the current Session
object, whether or not the most recent call to
login( ) succeeded

userName property Returns the user ID passed as a parameter to the


most recent call to the login( ) method on the
current Session object

OpenEdge® Development: Mobile Applications 165


progress.data.Session class

Methods
Table 16: progress.data.Session class-instance methods

Brief description
Member (See also the reference entry)

addCatalog( ) method Loads the JSDO catalog for a login session


established using the login( ) method

login( ) method Starts a user login session on the current Session


object by sending an HTTP request with user
credentials to a URI for a specified Mobile Web
application

logout( ) method Terminates the login session on the Web server


associated with the Session object

Events This class has no events.

Example This is an example of how you might create a Session object and use the URI to a
Mobile Web application to log into the application, load the JSDO catalog for a Mobile
service provided by that application, and create a JSDO for a Customer Mobile
resource defined by that service in the catalog:

Table 17: Example — Using the OpenEdge Session class

// create Session
pdsession = new progress.data.Session();

// log in, i.e., authenticate to the Mobile Web application


pdsession.login('/SportsApp', username, password);

// load catalog for a service that's part of the Mobile Web application
pdsession.addCatalog('/SportsApp/static/mobile/OrderEntrySvc.json');

// create JSDO
customers = new progress.data.JSDO( { name: 'Customer' } );

/* etc. - additional code to fill and use the JSDO */

The JSDO automatically finds and uses the Session object on which a catalog that
defines the Customer resource is loaded.

Notes • Use an instance of this class to call the login( ) method to start a user login
session, call the addCatalog( ) method to load one or more JSDO catalogs for
the session, and possibly call the logout( ) method to terminate the session. To
use the same Session instance to start a new login session, you must call the
logout( ) method first.

• The behavior of a login session using this class depends on the authentication
model of the Web server and how its resources are protected and accessed. For
more information, see the description of the login( ) method.

• If you have special requirements for sending Mobile requests to the Web server,
you can modify the XMLHttpRequest object that is sent by the Session object. To
do so, assign a callback function as the value of Session.onOpenRequest.

See also addCatalog( ) method, login( ) method, logout( ) method, progress.data.JSDO class

166 OpenEdge® Development: Mobile Applications


progress.ui.UIHelper class

progress.ui.UIHelper class
The progress.ui.UIHelper class is an OpenEdge class that provides methods for
managing the user interface of a OpenEdge Mobile App. This class is intended for use
by:

• Developers using JavaScript libraries, such as jQuery Mobile, to build user


interfaces by creating HTML-based lists and fields.

• Developers using OpenEdge Mobile App Builder without JSDO Services. JSDO
Services eliminate the need for UIHelper functionality.

Each instance of UIHelper supports the display of data for a specific JSDO, and
typically controls the format and content of a list view (showing items representing table
records) and a detail page (showing a form with input fields for the list item clicked by
the user).

Constructor
Syntax

progress.ui.UIHelper( JSDO-object )

Instantiates a UIHelper object for use in managing the UI for a specified JSDO.

JSDO-object

An object reference to the JSDO associated with the UIHelper instance.

Properties This class has no properties.

Methods
Table 18: progress.ui.UIHelper class-level methods

Brief description
Member (See also the reference entry)

setFieldTemplate( ) method Specifies the format or all detail forms created


during the JavaScript session

setItemTemplate( ) method Specifies the format for items in all list views
created during the JavaScript session

Table 19: progress.ui.UIHelper table-reference methods (1 of 2)

Brief description
Member (See also the reference entry)

addItem( ) method Adds an item based on the working record to a list


view

assign( ) method (UIHelper Updates the working record in JSDO local storage
class) with the values currently displayed on the detail
page form

clearItems( ) method Clears the items from a list view

OpenEdge® Development: Mobile Applications 167


progress.ui.UIHelper class

Table 19: progress.ui.UIHelper table-reference methods (2 of 2)

Brief description
Member (See also the reference entry)

display( ) method Copies the field values of a given record to


corresponding fields in the current HTML
document for display in the form on the detail page

getFormFields( ) method Reads the schema of the specified table and


returns HTML text that defines corresponding input
fields to appear on the form on the detail page

getFormRecord( ) method Returns a JSRecord object for the record shown on


the form on the detail page

getListViewRecord( ) method Returns a JSRecord object for a specified item in a


list view

setDetailPage( ) method Specifies the HTML page that contains the form in
which item details are displayed

setListView( ) method Defines a list view for a given table

Events This class has no events.

Example The sample Mobile app shown below is followed by the code for its index page
(index.html) and client logic (customers.js):

168 OpenEdge® Development: Mobile Applications


progress.ui.UIHelper class

Table 20: Example — index.html


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1"
/>
<title>Customers</title>
<link rel="stylesheet"
href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
<style>
/* App custom styles */
</style>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></scri
pt>
<script
src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></scrip
t>
<script src="../progress.session.js"></script>
<script src="../progress.js"></script>
<script src="customers.js"></script>
</head>
<body>
<div data-role="page" id="custlist">
<div data-theme="b" data-role="header">
<h3>Customers</h3>
</div>
<div data-role="content">
<ul id="listview" data-role="listview" data-divider-theme="b"
data-inset="true" data-filter="true">
</ul>
</div>
</div>

<div data-role="page" id="custdetail" data-add-back-btn="true"


data-theme="b">
<div data-role="header"><h1>Customer</h1></div>
<div data-role="content">
<form action="" id="customerform">
</form>
</div>
</div>
</body>
</html>

OpenEdge® Development: Mobile Applications 169


progress.ui.UIHelper class

Table 21: Example — customers.js

var customers;
var uihelper;
var forminitialized = false;

$(document).ready(function() {
var session = new progress.data.Session();

session.login("http://localhost:8980/SportsApp", "", "");


session.addCatalog(
'http://localhost:8980/SportsApp/static/mobile/CustomerOrderSvc.json' );

customers = new progress.data.JSDO({ name: 'CustomerOrder' });


customers.subscribe('AfterFill', onAfterFillCustomers,
this);

uihelper = new progress.ui.UIHelper({ jsdo: customers });

uihelper.eCustomer.setDetailPage({
name: 'custdetail'
});

uihelper.eCustomer.setListView({
name:'listview',
format: '{CustNum}<br>{Name}<br>{State}',
autoLink: true
});

$('#customerform').html(
uihelper.eCustomer.getFormFields()
+ '<input type="button" value="Add" id="btnAdd" />'
+ '<input type="button" value="Save" id="btnSave" />'
+ '<input type="button" value="Delete" id="btnDelete"
/>'
);

customers.fill();
});

function onAfterFillCustomers() {
uihelper.eCustomer.clearItems();
customers.eCustomer.foreach(function(customer) {
uihelper.eCustomer.addItem();
});
uihelper.eCustomer.showListView();
}

Notes •

See also progress.data.JSDO class

170 OpenEdge® Development: Mobile Applications


request object

request object
An object containing data and status information pertaining to a call to one of the
methods of an associated progress.data.JSDO class instance (JSDO) that executes
a Mobile built-in or invoke operation on the AppServer. The request object is returned
by the method call. In the case of an asynchronous call, the request object is passed
as a parameter to the event handler function defined on the JSDO.

Properties
Table 22: Request object properties

Brief description
Member (See also the reference entry)

async property A Boolean that indicates, if set to true, that the


Mobile operation was executed asynchronously on
the client

batch property A reference to an object with a property named


operations, which is an array containing the
request objects for each of the several operations
performed in response to a call to the JSDO
saveChanges( ) method

fnName property For an invoke operation, the name of the JSDO


invocation method that called the operation.

jsdo property An object reference to the JSDO that performed


the operation returning the request object

jsrecord property An object reference to the record created, updated,


or deleted by the operation

paramObj property A reference to the object, if any, that was passed


as a parameter to the method that returned the
request object

response property Returns an object whose properties contain data


from a Mobile built-in or invoke operation executed
on the AppServer

success property A Boolean that indicates, if set to true, that the


Mobile operation was successfully executed

xhr property A reference to the XMLHttpRequest object used to


perform the request

Methods This object has no methods.

Events This object has no events.

See also fill( ) method, invocation method, progress.data.JSDO class, saveChanges( ) method

OpenEdge® Development: Mobile Applications 171


request object

172 OpenEdge® Development: Mobile Applications


C
OpenEdge JavaScript Class Properties,
Methods, and Events Reference

This appendix describes the following properties and methods of OpenEdge


JavaScript classes:

• add( ) method

• addCatalog( ) method

• addItem( ) method

• addRecords( ) method

• afterCreate event

• afterDelete event

• afterFill event

• afterInvoke event

• afterSaveChanges event

• afterUpdate event

• assign( ) method (JSDO class)

• assign( ) method (UIHelper class)

• async property

• authenticationModel property

• batch property

OpenEdge® Development: Mobile Applications 173


Appendix C: OpenEdge JavaScript Class Properties, Methods, and Events Reference

• beforeCreate event

• beforeDelete event

• beforeFill event

• beforeInvoke event

• beforeSaveChanges event

• beforeUpdate event

• catalogURIs property

• clearItems( ) method

• data property

• display( ) method

• fill( ) method

• find( ) method

• findById( ) method

• fnName property

• foreach( ) method

• getData( ) method

• getFormFields( ) method

• getFormRecord( ) method

• getId( ) method

• getSchema( ) method

• getListViewRecord( ) method

• invocation method

• jsdo property

• jsrecord property

• login( ) method

• loginHttpStatus property

• loginResult property

• loginTarget property

• logout( ) method

• name property

174 OpenEdge® Development: Mobile Applications


• onOpenRequest property

• paramObj property

• record property

• remove( ) method

• response property

• saveChanges( ) method

• services property

• serviceURI property

• setDetailPage( ) method

• setFieldTemplate( ) method

• setItemTemplate( ) method

• setListView( ) method

• showListView( ) method

• subscribe( ) method

• success property

• table reference property (JSDO)

• unsubscribe( ) method

• useRelationships property

• userName property

• xhr property

OpenEdge® Development: Mobile Applications 175


add( ) method

add( ) method
Creates a new record object for a temp-table referenced in JSDO local storage and
returns a reference to the new record.

After completing execution, the new record becomes the working record for the
associated temp-table. If the temp-table has child temp-tables, the working record for
these child tables is not set. To synchronize the change on the AppServer, call the
saveChanges( ) method.

Return type: JSRecord object


Applies to: progress.data.JSDO class, table reference property (JSDO)

Syntax

[table-ref.]add ( [ new-record-object ] )

table-ref

A table reference on the JSDO. If the JSDO references only a single temp-table,
the method can be called on the JSDO itself.

new-record-object

If specified as a non-null object, passes in the data to create the record for the
JSRecord instance. The data to create the record is identified by one or more
properties, each of which has the name of a corresponding field in the temp-table
schema and has the value to set that field in the new table record.

If you omit or set the parameter to null, or you do not include properties of
new-record-object for all fields in the new record, the method uses the default
values from the temp-table schema stored in the catalog to set the unspecified
record fields.

If table-ref references a child temp-table in a ProDataSet, when the


useRelationships property is true, add( ) uses the relationship to set related field
values of the new child record from the working record of the parent temp-table.
However, if the working record of the parent is not set, add( ) throws an error. If
useRelationships is false, the fields for the new record are set as specified by
new-record-object and no error is thrown.

For example, given a JSDO created for a ProDataSet resource with a customer and
related child order temp-table, the add( ) method in the following code fragment uses
this relationship to automatically set the CustNum field in a new record added to the
order table:

var dataSet = new Progress.data.JSDO( 'CustomerOrderDS' );


dataSet.customer.add( { CustNum: 1000, Balance: 10000, State: 'MA' } );

// CustNum is set automatically by using the relationship


dataSet.order.add( { OrderNum: 1000 } );

See also: getSchema( ) method, data property, saveChanges( ) method

176 OpenEdge® Development: Mobile Applications


addCatalog( ) method

addCatalog( ) method
Loads the JSDO catalog for a login session established using the login( ) method. If
the login( ) method has not been called on the current Session object, or has been
called but failed, the method throws an Error object.

Return type: Number

Applies to: progress.data.Session class

Syntax

addCatalog ( catalog-uri [ , cat-user-name [ , cat-password ]] )

catalog-uri

The URI of a JSDO catalog file. The file is typically in a location relative to the
Mobile Web application where the Session object has a login session.

If the Mobile App from which you are logging in is a Mobile Web App deployed to
the same Apache Tomcat server as the Mobile Web application, you can specify
catalog-uri as a relative URI, for example:
/SportsMobileApp/static/mobile/OrderEntrySvc.json, which is relative to
the deployment end point (Tomcat server domain or host and port).

If the Mobile App from which you are logging in is a Mobile Native App that will be
installed to run directly in a native device container, or if it is a Mobile Web App
deployed to a different Web server from the Mobile Web application, you must
specify catalog-uri as an absolute URI to the Tomcat server domain or host and
port, for example,
http://www.progress.com/SportsMobileApp/static/mobile/OrderEntrySv
c.json, or perhaps for testing,
http://testmach:8980/SportsMobileApp/static/mobile/OrderEntrySvc.j
son.

Note: For any Mobile App that must specify catalog-uri as an absolute URI,
you must maintain separate JavaScript sources to deploy the Mobile App
for different Mobile Web application environments, such as one for testing
and one for production.

Note: The default catalog URI for a catalog created for a Mobile service, relative
to the Apache Tomcat server domain or host and port where the session is
logged in, is the following:

/MobileWebApplicationName/static/mobile/ServiceName.json

Where MobileWebApplicationName is the name of the Mobile Web


application and ServiceName is the name of the Mobile service for which
the JSDO catalog is created.

cat-user-name

A string expression containing a user ID to authenticate access to a protected


catalog. If you do not specify cat-user-name, catalog access is authorized using
existing user credentials (if any).

OpenEdge® Development: Mobile Applications 177


addCatalog( ) method

cat-password

A string expression containing a password (if required) to authenticate the user


specified by cat-user-name.

Note: Typically, you do not need to specify, cat-user-name or cat-password.


These optional parameters are available primarily if you store the catalog
somewhere other than as part of the Mobile Web application where the user
session is logged in.

You can read the catalogURIs property to return the URIs for all catalogs previously
loaded for the login session.

When the method completes, it returns one of the following numeric constants to
indicate the result:

• progress.data.Session.SUCCESS — The specified JSDO catalog loaded


successfully.

• progress.data.Session.AUTHENTICATION_FAILURE — The catalog failed to


load because of a user authentication error.

• progress.data.Session.CATALOG_ALREADY_LOADED — The specified JSDO


catalog did not load because it is already loaded.

For all other errors, this method throws an Error object.

See also: catalogURIs property, login( ) method

178 OpenEdge® Development: Mobile Applications


addItem( ) method

addItem( ) method
Adds an item based on the working record to a list view. The appearance and content
of the list view item are controlled by a specified template and format, respectively:

• The template is defined by setItemTemplate( ), optionally overridden for this list


view by setListView( ). OpenEdge Mobile provides a default template suitable
for use in a jQuery Mobile environment.

• The format is defined by setListView( ), optionally overridden for this item by


the format parameter.

Return type: null

Applies to: progress.ui.UIHelper class, table reference property (UIHelper)

Syntax

[table-ref.]addItem ( [ ‘format’ ] )

table-ref

A table reference on the UIHelper instance. If the JSDO associated with the
UIHelper instance references only a single temp-table, the method can be called
on the UIHelper instance itself.

format

A string specifying the fields displayed for the list item, overriding the format
defined by setListView( ). For example:

addItem ( '{CustNum}<br>{Name}<br>{State}<br>{Country}' )

See also: setListView( ) method, setItemTemplate( ) method

OpenEdge® Development: Mobile Applications 179


addRecords( ) method

addRecords( ) method
Reads a specified object and updates the local storage of the JSDO. This updates all
temp-tables read in for a ProDataSet or a specified temp-table, depending on how the
method is called. The data is merged into JSDO local storage and affects existing data
according to a specified merge mode and optional key fields.

After execution, the working record for each temp-table referenced by the JSDO is not
set.

Return type: null

Applies to: progress.data.JSDO class, table reference property (JSDO)

Syntax

[table-ref.]addRecords ( merge-object , add-mode [ , key-fields ] )

table-ref

A table reference on the JSDO. If you call the method on table-ref, the method
merges data only for the referenced temp-table. If you call the method on the
JSDO itself, the method merges data for all temp-tables referenced for a
ProDataSet.

merge-object

An object with the data to merge. If you call the method on table-ref, the object
can either be an object that contains an array of record objects to merge with the
referenced temp-table or a ProDataSet-formatted object containing such an array.

Note: This object must have a supported JavaScript object format that matches
the data returned from the built-in read operation (JSDO fill( ) method).
For example, the object returned from an invocation method for an output
temp-table or ProDataSet that has the same schema as supported output
from the built-in read operation should work.

180 OpenEdge® Development: Mobile Applications


addRecords( ) method

In Release 11.2, the following formats are supported for merge-object:

• ProDataSet with a single temp-table or multiple temp-tables at the same level


only. For example:

{
dsCustomerOrder: {
eCustomer: [
// Record objects ...
],
eOrder: [
// Record objects
]
}
}

• Single temp-table. For example:

{
eCustomer: [
// Record objects ...
]
}

Note: If you pass a record object with an array or a ProDataSet with nested
temp-table records, the method throws an error object.

add-mode

An integer that represents a merge mode to use. For Release 11.2, you can
specify the following numeric constants, which affect how the temp-table record
objects in merge-object are added to JSDO local storage:

• progress.data.JSDO.MODE_APPEND — Adds the temp-table record objects


in merge-object to the existing record objects in JSDO local storage. An
error is thrown if a duplicate key is found.

• progress.data.JSDO.MODE_EMPTY — Empties all temp-table record objects


from JSDO local storage and replaces them with the contents of
merge-object.

Note: If merge-object is an empty object ({}), this effectively empties the


data from JSDO local storage.

OpenEdge® Development: Mobile Applications 181


addRecords( ) method

key-fields

An object with a list of key fields to use to check for duplicate records. For
example, when merging with a ProDataSet that has eCustomer and eOrder table
references, you might use the following object:

{
eCustomer: [ "CustNum" ],
eOrder: [ "CustNum", "Ordernum" ]
}

When merging with a single table reference, you might use the following array
object:

[ "CustNum", "Ordernum" ]

A typical use for addRecords( ) is to merge additional data returned by an invocation


method without having to re-load local storage with all the data from the fill( )
method.

For example, given a JSDO, dataset, that you fill with available records from the
eCustomer and eOrder temp-tables, you might retrieve a new eOrder record as the
result of a getNewOrder( ) invocation method on the JSDO and add the new record
to JSDO local storage as follows:

var dataset = progress.data.JSDO( "dsCustomerOrder" );


dataset.fill(); // Loads the ProDataSet with all available records

// Adds a new eOrder record restrieved from the service


var request = dataset.getNewOrder(null,false);
dataset.eOrder.addRecords( request.response, progress.data.JSDO.MODE_APPEND,
[ "CustNum", "Ordernum" ],
);

This code fragment adds the eOrder record for an existing eCustomer record specified
by the CustNum property and a new order number specified by the Ordernum property
of the single record object returned in result.dsCustomerOrder.eOrder[0].

See also: fill( ) method, invocation method

182 OpenEdge® Development: Mobile Applications


afterCreate event

afterCreate event
Fires after the JSDO, by means of a saveChanges( ) call following an add( ) call,
sends a request to create a record and receives a response to this request from the
AppServer.

Applies to: progress.data.JSDO class, saveChanges( ) method, table reference


property (JSDO)

The following parameters appear in the signature of the event handler function:

Syntax

function ( jsdo , record , success , request )

jsdo

A reference to the JSDO that invoked the create operation. For more information,
see the description of the jsdo property of the request object.

record

A reference to the temp-table record upon which the create operation acted. For
more information, see the description of the jsrecord property of the request
object.

success

A Boolean that is true if the create operation was successful. For more
information, see the description of the success property of the request object.

request

A reference to the request object returned after the create operation completes.
For more information, see the description of the request object.

OpenEdge® Development: Mobile Applications 183


afterCreate event

Example:

/* subscribe to event */
myjsdo.subscribe('afterCreate', onAfterCreate);

/* some code that would add a record and save it */


var jsrecord = myjsdo.add();

. . .

myjsdo.saveChanges();

function onAfterCreate (jsdo , record , success , request ) {


if (success) {
/* for example, get the values from the record for redisplay */
var myField = record.data.myField;
. . .
}
else {
if (request.response && request.response._errors &&
request.response._errors.length > 0){
var lenErrors = request.response._errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) {
var errorEntry = request.response._errors[idxError];
var errorMsg = errorEntry._errorMsg;
var errorNum = errorEntry._errorNum;
/* handle error */
}
}
}
};

See also: add( ) method, record property, subscribe( ) method, unsubscribe( )


method

184 OpenEdge® Development: Mobile Applications


afterDelete event

afterDelete event
Fires after the JSDO, by means of a saveChanges( ) call following a remove( ) call,
sends a request to delete a record and receives a response to this request from the
AppServer.

Applies to: progress.data.JSDO class, saveChanges( ) method, table reference


property (JSDO)

The following parameters appear in the signature of the event handler function:

Syntax

function ( jsdo , record , success , request )

jsdo

A reference to the JSDO that invoked the delete operation. For more information,
see the description of the jsdo property of the request object.

record

A reference to the temp-table record upon which the delete operation acted. For
more information, see the description of the jsrecord property of the request
object.

success

A Boolean that is true if the delete operation was successful. For more
information, see the description of the success property of the request object.

request

A reference to the request object returned after the delete operation completes.
For more information, see the description of the request object.

OpenEdge® Development: Mobile Applications 185


afterDelete event

Example:

/* subscribe to event */
myjsdo.subscribe('afterDelete', onAfterDelete);

/* some code that would delete a record and send to the server */
var jsrecord = myjsdo.findById(myid);
myjsdo.remove();
myjsdo.saveChanges();

function onAfterDelete (jsdo , record , success , request ) {


if (success) {
/* for example, get the values from the record that was
deleted to display a confirmation message */
var myKeyField = record.data.myKeyField;
. . .
}
else {
if (request.response && request.response._errors &&
request.response._errors.length > 0){
var lenErrors = request.response._errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) {
var errorEntry = request.response._errors[idxError];
var errorMsg = errorEntry._errorMsg;
var errorNum = errorEntry._errorNum;
/* handle error */
}
}
}
};

See also: remove( ) method, subscribe( ) method, unsubscribe( ) method

186 OpenEdge® Development: Mobile Applications


afterFill event

afterFill event
Fires after the JSDO, by means of a fill( ) call, sends a request to read a temp-table
or ProDataSet into JSDO local storage and receives a response to this request from
the AppServer.

Applies to: progress.data.JSDO class, fill( ) method

The following parameters appear in the signature of the event handler function:

Syntax

function ( jsdo , success , request )

jsdo

A reference to the JSDO that invoked the fill operation. For more information, see
the description of the jsdo property of the request object.

success

A Boolean that is true if the fill operation was successful. For more information,
see the description of the success property of the request object.

request

A reference to the request object returned after the fill operation completes. For
more information, see the description of the request object.

Example:

myjsdo.subscribe('afterFill', onAfterFill);
myjsdo.fill();

function onAfterFill(jsdo , success , request ) {


if (success) {
/* for example, add code to display all records on a list */
jsdo.foreach(function (jsrecord) {
/* you can reference the fields as jsrecord.data.field */
});
}
else {
if (request.response && request.response._errors &&
request.response._errors.length > 0){
var lenErrors = request.response._errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) {
var errorEntry = request.response._errors[idxError];
var errorMsg = errorEntry._errorMsg;
var errorNum = errorEntry._errorNum;
/* handle error */
}
}
}

};

See also: subscribe( ) method, unsubscribe( ) method

OpenEdge® Development: Mobile Applications 187


afterInvoke event

afterInvoke event
Fires after a non–built-in method is called asynchronously on a JSDO and a response
to the request is received from the AppServer. Synchronous method calls do not cause
this event to fire.

Applies to: progress.data.JSDO class, invocation method

The following parameters appear in the signature of the event handler function:

Syntax

function ( jsdo , success , request )

jsdo

A reference to the JSDO that invoked the method. For more information, see the
description of the jsdo property of the request object.

success

A Boolean that is true if the operation was successful. For more information, see
the description of the success property of the request object.

request

A reference to the request object returned after the operation completes. For more
information, see the description of the request object.

Example:

myjsdo.subscribe('afterInvoke', 'myMethodName',
onAfterInvokeMyMethodName);
myjsdo.myMethodName( paramObject);

function onAfterInvokeMyMethodName(jsdo , success , request )


if (success) {
var response = request.result.response;

var retval = response._retval;


var myOutputParm = response.myOutParam;

}
else {
if (request.response && request.response._errors &&
request.response._errors.length > 0){
var lenErrors = request.response._errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) {
var errorEntry = request.response._errors[idxError];
var errorMsg = errorEntry._errorMsg;
var errorNum = errorEntry._errorNum;
/* handle error */
}
}
}

};

See also: subscribe( ) method, unsubscribe( ) method

188 OpenEdge® Development: Mobile Applications


afterSaveChanges event

afterSaveChanges event
Fires once for each call to the saveChanges( ) method on a JSDO, after responses to
all create, update, and delete requests have been received from the AppServer.

Applies to: progress.data.JSDO class, saveChanges( ) method

The following parameters appear in the signature of the event handler function:

Syntax

function ( jsdo , success , request )

jsdo

A reference to the JSDO that invoked the saveChanges( ) method. For more
information, see the description of the jsdo property of the request object.

success

A Boolean that is true if all operations initiated by saveChanges( ) were


successful. For more information, see the description of the success property of
the request object.

request

A reference to the request object returned after all requested operations complete.
For more information, see the description of the request object.

OpenEdge® Development: Mobile Applications 189


afterSaveChanges event

Example:

/* subscribe to event */
myjsdo.subscribe('afterSaveChanges', onAfterSaveChanges);

/* some code that would do multiple CRUD operations and


send them to the server */
var newrec = myjsdo.add();
. . .
var jsrecord = myjsdo.findById(myid);
myjsdo.remove();
myjsdo.saveChanges();

function onAfterSaveChanges(jsdo , success , request ) {

/* number of operations on batch */


var len = request.batch.operations.length;

if (success) {
/* all operations in batch succeeded */
/* for example, redisplay records in list */
jsdo.foreach( function(jsrecord) {
/* reference the record/field as jsrecord.data.fieldName */
});
}
else {
/* one or more operations in batch failed */
for(var idx = 0; idx < len; idx++) {
var operationEntry = request.batch.operations[idx];

console.log("Operation: " + operationEntry.fnName);


console.log("Operation code: " + operationEntry.operation)

if (!operationEntry.success) {
/* handle error condition */
if (operationEntry.response && operationEntry.response._errors
&&
operationEntry.response._errors.length > 0){
var lenErrors = operationEntry.response._errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) {
var errors = operation.response._errors[idxError];
var errorMsg = errors._errorMsg;
var errorNum = errors._errorNum;
/* handle error */
}
}
}
else {
/* operation succedeed */
}
}
}
};

See also: subscribe( ) method, unsubscribe( ) method

190 OpenEdge® Development: Mobile Applications


afterUpdate event

afterUpdate event
Fires after the JSDO, by means of a saveChanges( ) call following an assign( ) call,
sends a request to update a record and receives a response to this request from the
AppServer.

Applies to: progress.data.JSDO class, saveChanges( ) method, table reference


property (JSDO)

The following parameters appear in the signature of the event handler function:

Syntax

function ( jsdo , record , success , request )

jsdo

A reference to the JSDO that invoked the update operation. For more information,
see the description of the jsdo property of the request object.

record

A reference to the temp-table record upon which the update operation acted. For
more information, see the description of the jsrecord property of the request
object.

success

A Boolean that is true if the update operation was successful. For more
information, see the description of the success property of the request object.

request

A reference to the request object returned after the update operation completes.
For more information, see the description of the request object.

OpenEdge® Development: Mobile Applications 191


afterUpdate event

Example:

/* subscribe to event */
myjsdo.subscribe('afterUpdate', onAfterUpdate);

/* some code that would update a record and send to the server */
var jsrecord = myjsdo.findById(myid);
myjsdo.assign( updatedDataObject );
myjsdo.saveChanges();

function onAfterUpdate (jsdo , record , success , request ) {


if (success) {
/* for example, get the values updated by the server from the record
to redisplay */
var newValue = record.data.myField;
. . .
}
else {
if (request.response && request.response._errors &&
request.response._errors.length > 0){
var lenErrors = request.response._errors.length;
for (var idxError=0; idxError < lenErrors; idxError++) {
var errorEntry = request.response._errors[idxError];
var errorMsg = errorEntry._errorMsg;
var errorNum = errorEntry._errorNum;
/* handle error */
}
}
}
};

See also: assign( ) method (JSDO class), subscribe( ) method, unsubscribe( )


method

192 OpenEdge® Development: Mobile Applications


assign( ) method (JSDO class)

assign( ) method (JSDO class)


Updates field values for the specified temp-table record referenced in JSDO local
storage. The specified record can be either the working record of a referenced
temp-table or any record provided by a JSRecord object.

After execution, any working records previously set before the method executed
remain as the working records. To synchronize the change on the AppServer, call the
saveChanges( ) method.

Return type: Boolean

Applies to: JSRecord object, progress.data.JSDO class, table reference property


(JSDO)

Syntax

[table-ref.]assign ( update-object )
jsrecord-ref.assign ( [ update-object ] )

table-ref

A table reference on the JSDO for a temp-table that has a working record. If the
JSDO references only a single temp-table, the method can be called on the JSDO
itself.

jsrecord-ref

A reference to a JSRecord object for a temp-table record in JSDO local storage.

update-object

Passes in the data to update the specified record object in JSDO local storage.
Each property of the object has the name of a temp-table field name and the value
to set for that field in the specified record. Any temp-table fields without
corresponding properties in update-object remain unchanged in the record.

The following code fragment shows a jQuery event defined on a save button to save
the current field values for a customer detail form to the corresponding eCustomer
record in JSDO local storage:

dataSet = new progress.data.JSDO( 'dsCustomerOrder' );

$('#btnSave').bind('click', function(event) {
var jsrecord = dataSet.eCustomer.findById($('#custdetail #id').val());
jsrecord.assign(update-object);
dataSet.saveChanges();
});

The form has been displayed with previous values of the same record. When the button
is clicked, the event handler uses the findById( ) method to find the original record
with the matching internal record ID (jsrecord) and invokes the assign( ) method on
jsrecord with an object parameter to update the fields in eCustomer with any new
values entered into the form.

See also: getSchema( ) method, saveChanges( ) method

OpenEdge® Development: Mobile Applications 193


assign( ) method (UIHelper class)

assign( ) method (UIHelper class)


Updates the working record in JSDO local storage with the values currently displayed
on the detail page form.

Return type: Boolean

Applies to: progress.ui.UIHelper class, table reference property (UIHelper)

Syntax

[table-ref.]assign ( )

table-ref

A table reference on the UIHelper instance. If the JSDO associated with the
UIHelper instance references only a single temp-table, the method can be called
on the UIHelper instance itself.

See also: getFormFields( ) method

194 OpenEdge® Development: Mobile Applications


async property

async property
A Boolean that indicates, if set to true, that the Mobile operation was executed
asynchronously on the Mobile App.

Data type: Boolean

Access: Read-only
Applies to: request object

This request object property is available only for the following events:

• afterCreate

• afterDelete

• afterFill

• afterInvoke

See also: add( ) method, remove( ) method, fill( ) method, invocation method

OpenEdge® Development: Mobile Applications 195


authenticationModel property

authenticationModel property
A string constant that specifies the type of authentication that the server requires from
the Mobile App. Valid values are:

• progress.data.Session.AUTH_TYPE_ANON — No authentication is required.


This is the default value.

• progress.data.Session.AUTH_TYPE_BASIC — The Mobile Web application


requires a valid user ID and password, but does not provide a page containing a
login form (credentials are typically entered in a generic login dialog provided by
either the Mobile App, the browser, or the native device container in which the App
is running).The Mobile Web application requires a valid user ID and password, but
does not provide a page containing a login form (credentials are typically entered
in a generic login dialog provided by either the Mobile App, the browser, or the
native device container in which the App is running).

• progress.data.Session.AUTH_TYPE_FORM — The Mobile Web application


requires a valid user ID and password and provides a page containing a login
form.

Data type: String

Access: Writable
Applies to: progress.data.Session class

If the Mobile Web application requires authentication, you must set this value correctly
to ensure that users can log in.

See also: login( ) method

196 OpenEdge® Development: Mobile Applications


batch property

batch property
A reference to an object with a property named operations, which is an array
containing the request objects for each of the several operations performed in
response to a call to the JSDO saveChanges( ) method.

Data type: Object

Access: Read-only
Applies to: request object

This request object property is available only for the following events:

• afterSaveChanges

• beforeSaveChanges

See also: saveChanges( ) method

OpenEdge® Development: Mobile Applications 197


beforeCreate event

beforeCreate event
Fires before the JSDO, by means of a saveChanges( ) call following an add( ) call,
sends a request the AppServer to create a record.

Applies to: progress.data.JSDO class, saveChanges( ) method, table reference


property (JSDO)

The following parameters appear in the signature of the event handler function:

Syntax

function ( jsdo , record , request )

jsdo

A reference to the JSDO that is invoking the create operation. For more
information, see the description of the jsdo property of the request object.

record

A reference to the temp-table record upon which the create operation is about to
act. For more information, see the description of the jsrecord property of the
request object.

request

A reference to the request object returned before the create operation begins. For
more information, see the description of the request object.

Example:

/* subscribe to event */
myjsdo.subscribe('beforeCreate', onBeforeCreate);

/* some code that would add a record and save it */


var jsrecord = myjsdo.add();

. . .

myjsdo.saveChanges();

function onBeforeCreate( jsdo , record , request ) {


/* for instance, here you can update data in the record
before it is sent to the server */
record.data.myField = myvalue;
};

See also: add( ) method, record property, subscribe( ) method, unsubscribe( )


method

198 OpenEdge® Development: Mobile Applications


beforeDelete event

beforeDelete event
Fires before the JSDO, by means of a saveChanges( ) call following a remove( ) call,
sends a request the AppServer to delete a record.

Applies to: progress.data.JSDO class, saveChanges( ) method, table reference


property (JSDO)

The following parameters appear in the signature of the event handler function:

Syntax

function ( jsdo , record , request )

jsdo

A reference to the JSDO that is invoking the delete operation. For more
information, see the description of the jsdo property of the request object.

record

A reference to the temp-table record upon which the delete operation is about to
act. For more information, see the description of the jsrecord property of the
request object.

request

A reference to the request object returned before the delete operation begins. For
more information, see the description of the request object.

Example:

/* subscribe to event */
myjsdo.subscribe('beforeDelete', onBeforeDelete);

/* some code that would delete a record and send to the server */
var jsrecord = myjsdo.findById(myid);
myjsdo.remove();
myjsdo.saveChanges();

function onBeforeDelete( jsdo , record , request ) {


/* code to execute before sending request to the server */

};

See also: remove( ) method, subscribe( ) method, unsubscribe( ) method

OpenEdge® Development: Mobile Applications 199


beforeFill event

beforeFill event
Fires before the JSDO, by means of a fill( ) call, sends a request to the AppServer
to read a temp-table or ProDataSet into JSDO local storage.

Applies to: progress.data.JSDO class, fill( ) method

The following parameters appear in the signature of the event handler function:

Syntax

function ( jsdo , request )

jsdo

A reference to the JSDO that is invoking the read operation. For more information,
see the description of the jsdo property of the request object.

request

A reference to the request object returned before the read operation begins. For
more information, see the description of the request object.

Example:

myjsdo.subscribe('beforeFill', onBeforeFill);
myjsdo.fill();

function osBeforeFill ( jsdo , request ) {


/* for instance, do any preparation for receiving data from the server */
};

See also: subscribe( ) method, unsubscribe( ) method

200 OpenEdge® Development: Mobile Applications


beforeInvoke event

beforeInvoke event
Fires when a non–built-in method is called asynchronously on a JSDO, before the
request for the operation is sent to the AppServer.

Applies to: progress.data.JSDO class, invocation method

The following parameters appear in the signature of the event handler function:

Syntax

function ( jsdo , request )

jsdo

A reference to the JSDO that is invoking the method. For more information, see
the description of the jsdo property of the request object.

request

A reference to the request object returned before the operation begins. For more
information, see the description of the request object.

Example:

myjsdo.subscribe('beforeInvoke', 'myMethodName',
onBeforeInvokeMyMethodName);
myjsdo.myMethodName( paramObject);

function onBeforeInvoke ( jsdo , request ) {


/* code to execute before sending request to the server */
};

See also: subscribe( ) method, unsubscribe( ) method

OpenEdge® Development: Mobile Applications 201


beforeSaveChanges event

beforeSaveChanges event
Fires once for each call to the saveChanges( ) method on a JSDO, before any create,
update, or delete requests are sent to the AppServer.

Applies to: progress.data.JSDO class, saveChanges( ) method

The following parameters appear in the signature of the event handler function:

Syntax

function ( jsdo , request )

jsdo

A reference to the JSDO that is invoking the saveChanges method. For more
information, see the description of the jsdo property of the request object.

request

A reference to the request object returned before the requested save operations
begin. For more information, see the description of the request object.

Example:

myjsdo.subscribe('beforeSaveChanges', onBeforeSaveChanges);

/* some code that would do multiple CRUD operations and


send them to the server */
var newrec = myjsdo.add();
. . .
var jsrecord = myjsdo.findById(myid);
myjsdo.remove();
myjsdo.saveChanges();

function onBeforeSaveChanges ( jsdo , request ) {


/* code to execute before sending request to the server */
};

See also: subscribe( ) method, unsubscribe( ) method

202 OpenEdge® Development: Mobile Applications


beforeUpdate event

beforeUpdate event
Fires before the JSDO, by means of a saveChanges( ) call following an assign( )
call, sends a request the AppServer to update a record.

Applies to: progress.data.JSDO class, saveChanges( ) method, table reference


property (JSDO)

The following parameters appear in the signature of the event handler function:

Syntax

function ( jsdo , record , request )

jsdo

A reference to the JSDO that is invoking the update operation. For more
information, see the description of the jsdo property of the request object.

record

A reference to the temp-table record upon which the update operation is about to
act. For more information, see the description of the jsrecord property of the
request object.

request

A reference to the request object returned before the update operation begins. For
more information, see the description of the request object.

Example:

myjsdo.subscribe('beforeInvoke', 'myMethodName',
onBeforeInvokeMyMethodName);
myjsdo.myMethodName( paramObject );

function onBeforeInvoke ( jsdo , request ) {


/* code to execute before sending request to the server */
};

See also: assign( ) method (JSDO class), subscribe( ) method, unsubscribe( )


method

OpenEdge® Development: Mobile Applications 203


catalogURIs property

catalogURIs property
Returns the list of URIs used to load the JSDO catalogs to access the Mobile services
provided by the Mobile Web application for which the current Session object manages
a user login session.

Data type: String array

Access: Read-only
Applies to: progress.data.Session class

This list includes the URI for each JSDO catalog loaded using the addCatalog( )
method. To return a corresponding list of Mobile service names for which the JSDO
catalogs are loaded, read the serviceNames property.

See also: addCatalog( ) method, services property

204 OpenEdge® Development: Mobile Applications


clearItems( ) method

clearItems( ) method
Clears the items from a list view.

Return type: null

Applies to: progress.ui.UIHelper class, table reference property (UIHelper)

Syntax

[table-ref.]clearItems ( )

table-ref

A table reference on the UIHelper instance. If the JSDO associated with the
UIHelper instance references only a single temp-table, the method can be called
on the UIHelper instance itself.

OpenEdge® Development: Mobile Applications 205


data property

data property
An object containing the data for a temp-table record associated with a JSRecord
object.

Data type: Object

Access: Read-only
Applies to: JSRecord object

Each property (field-ref) of the object corresponds to a field (column) in the


temp-table, where the property name is identical to a temp-table field name and the
property value is the value for that field in the specified record.

Caution: Never write directly to a to a field-ref using this data property; in this
case, use field-ref only to read the data. Writing to data using such a
reference does not mark the record for update when calling the
saveChanges( ) method. To mark a record for update, you must assign a
field value either by setting a jsdo.table-ref.field-ref for a working
record or by calling the assign( ) method on a valid table-ref or JSRecord
object reference. For information on a table-ref, see the reference entry on
the table reference property (JSDO).

See also: add( ) method, assign( ) method (JSDO class), assign( ) method
(UIHelper class), findById( ) method, foreach( ) method, table
reference property (JSDO)

206 OpenEdge® Development: Mobile Applications


display( ) method

display( ) method
Copies the field values of a given record to corresponding fields in the current HTML
document for display in the form on the detail page. The record is the working record
of a temp-table referenced in the local storage of a JSDO that is associated with a
UIHelper instance.

After execution, any working records previously set before the method executed
remain as the working records.

Return type: null

Applies to: progress.ui.UIHelper class, table reference property (UIHelper)

Syntax

[table-ref.]display ( )

table-ref

A table reference on a UIHelper instance. If the JSDO associated with the


UIHelper instance references only a single temp-table, the method can be called
on the UIHelper instance itself. The table must have a working record.

If a form field’s id attribute (or dsid attribute, if OpenEdge Mobile App Builder was
used to design the form), as specified by the HTML DOM, matches the name of a
record field, the form field displays the value of the record field. If no HTML field
corresponds to a given record field, the value of that field is not displayed.

The following code fragment shows the display( ) method displaying each record of
an eCustomer temp-table in JSDO local storage to its respective row of a previously
established jQuery listview:

dataSet = new progress.data.JSDO( 'dsCustomerOrder' );


uihelper = new progress.ui.UIHelper({ jsdo: dataSet });
uihelper.eCustomer.setListView({
name:'listview',
format: '{CustNum}<br>{Name}<br>{State}',
autoLink: true
});

See also: getFormFields( ) method

OpenEdge® Development: Mobile Applications 207


fill( ) method

fill( ) method
Initializes the JSDO local storage from the data records in a single temp-table, or in one
or more temp-tables of a ProDataSet, as returned by the built-in read operation of the
Mobile resource for which the JSDO is created. This built-in operation is the single
resource operation that is annotated in the Mobile interface with the "read" operation
type. The result of calling this method replaces any prior data in JSDO local storage
with the records returned by the built-in read operation.

After completing execution, the working record for each referenced temp-table is set to
its first record, depending on any active parent-child relationships. So, for each child
temp-table, the first record is determined by its relationship to the related working
record in its parent temp-table.

Return type: null

Applies to: progress.data.JSDO class

Syntax

fill ( [ filter-string ] )

filter-string

A string that can be used on the AppServer to select records to be returned, much
like the WHERE option of the ABL record phrase. The actual format of this string and
its affect on the records returned is determined by the ABL routine on the
AppServer that uses it. For example, you might pass:

• A single key value (e.g., "30")

• A relational expression (e.g., "CustNum > 10 AND CustNum < 30")

• An actual WHERE string (e.g., 'Item.CatDescription CONTAINS "ski &


(gog* ! pol*)"')

Note: The JSDO requires the URI for the "read" operation of the resource to
contain the following query string: "?filter=~{filter~}", where filter
is the name of a string input parameter defined for the ABL routine that
implements the operation (INPUT filter AS CHARACTER).

Caution: Using an actual WHERE string for a dynamic ABL query can create a
potential security issue.

If you do not specify filter-string, the records returned, again, depend on the
ABL routine.

This method always executes asynchronously, and fires the following JSDO named
events, shown in operational order:

1. beforeFill event

2. afterFill event

208 OpenEdge® Development: Mobile Applications


fill( ) method

After this method completes execution, you can read the record objects of JSDO local
storage by using the find( ), findById( ), foreach( ), and getData( ) methods
of the JSDO. You can return the schema for this data by using the getSchema( )
method. You can create a new record object in local storage using the JSDO add( )
method, and you can update or delete a single record object in local storage by using
the assign( ) or remove( ) method, respectively. You can display a record in a form
by calling the display( )method on a UIHelper instance. You can merge data
returned by an invocation method with the data in local storage using the
addRecords( ) method.

The following code fragment shows the fill( ) method invoked on a JSDO for a
ProDataSet resource (dsCustomerOrder):

dataSet = new progress.data.JSDO( 'dsCustomerOrder' );

dataSet.fill();

See also: invocation method, saveChanges( ) method, progress.ui.UIHelper


class

OpenEdge® Development: Mobile Applications 209


find( ) method

find( ) method
Searches for a record in a temp-table referenced in JSDO local storage and returns a
reference to that record if found. If no record is found, it returns null.

After completing execution, any record found becomes the working record for the
associated temp-table. If the searched temp-table has child temp-tables, and the
useRelationships property is true, the working record of the result set for each child
is set to the first record as determined by the relationship to its respective parent. If a
record is not found, the working record is not set, and the working records of any child
temp-tables are also not set.

Return type: JSRecord object


Applies to: progress.data.JSDO class, table reference property (JSDO)

Syntax

[table-ref.]find ( funcRef )

table-ref

A table reference on the JSDO. If the JSDO references only a single temp-table,
the method can be called on the JSDO itself.

funcRef

A reference to a JavaScript function that returns a Boolean value and has the
following signature:

Syntax

function [ func-name ] ( jsrecord-ref )

Where func-name is the name of a function that you define external to the
find( ) parameter list and jsrecord-ref is a JSRecord reference to the next
available record on table-ref. You can also define funcRef without func-name
directly as an in-line function definition.

The find( ) function executes your funcRef for each record of table-ref, until
it returns true, indicating that funcRef has found the record. You can test the field
values on the data property of jsrecord-ref to determine the result. Otherwise,
you return false, and the find( ) function executes funcRef for the next
available record.

If funcRef finds the record, find( ) completes execution with both its return value and
the record property of table-ref set to the JSRecord reference of the found working
record. If find( ) reaches the end of available records without funcRef returning
true, find( ) completes execution with both its return value and the record property
on table-ref set to null, indicating that the sought for record is not found.

If table-ref references a child temp-table in a ProDataSet, when the


useRelationships property is true, find( ) uses the relationship to filter out all but
the child records of the working record in the parent temp-table. However, if the working
record of the parent is not set, find( ) throws an error. If useRelationships is false,
the search includes all records of the child temp-table and no error is thrown.

210 OpenEdge® Development: Mobile Applications


find( ) method

In following code fragment, jsdo references a single customer temp-table:

var jsdo = new progress.data.JSDO( 'customer' );

jsdo.find(function(jsrecord) {
return (jsrecord.data.CustNum == 10);
});

The function passed to find( ) returns true or false based on the value of the
CustNum property of the object returned by the data property for the currently available
JSRecord reference.

See also: data property, record property

OpenEdge® Development: Mobile Applications 211


findById( ) method

findById( ) method
Locates and returns the record in JSDO local storage with the internal ID you specify.
If no record is found, it returns null. You can access the internal ID of a record by
calling the getId( ) method.

After completing execution, any record found becomes the working record for the
associated temp-table. If the searched temp-table has child temp-tables, and the
useRelationships property is true, the working record of the result set for each child
is set to the first record as determined by the relationship to its respective parent. If a
record is not found, the working record is not set, and the working records of any child
temp-tables are also not set.

Return type: JSRecord object


Applies to: progress.data.JSDO class, table reference property (JSDO)

Syntax

[table-ref.]findById ( id )

table-ref

A table reference on the JSDO for a temp-table that has a working record. If the
JSDO references only a single temp-table, the method can be called on the JSDO
itself.

id

The internal record ID used to match a record of table-ref. This is the same
value originally returned for the record using the getId( ) function. It is typically
used to create a jQuery listview row to display the record or a detail form used to
display the record in the current HTML document. Later, when a listview row or
detail form is selected, the corresponding id attribute with this value can be used
to return the record from the JSDO, possibly to update the record with new data
values input by the user.

If findById( ) locates a record with the matching record ID, it completes execution
with both its return value and the record property of table-ref set to the JSRecord
reference of the found working record. If the function does not locate the record, it
completes execution with both its return value and the record property on table-ref
set to null, indicating that no record of table-ref has a matching internal record ID.

If table-ref references a child temp-table in a ProDataSet, when the


useRelationships property is true, findById( ) uses the relationship to filter out all
but the child records of the working record in the parent temp-table; the remaining child
records are excluded from the search. If useRelationships is false or the working
record of the parent is not set, the search includes all records of the child temp-table
and no error is thrown.

212 OpenEdge® Development: Mobile Applications


findById( ) method

The following code fragment shows a jQuery event defined on a save button to save
the current field values for a customer detail form to the corresponding eCustomer
record in JSDO local storage:

dataSet = new progress.data.JSDO( 'dsCustomerOrder' );

$('#btnSave').bind('click', function(event) {
var jsrecord = dataSet.eCustomer.findById($('#custdetail #id').val());
jsrecord.assign();
dataSet.saveChanges();
});

The form has been displayed with previous values of the same record. When the button
is clicked, the event handler finds the original eCustomer record by calling
findById( ) with the id attribute of the form ($('#custdetail #id').val()), which
is set to the internal ID of the record. The jsrecord.assign( ) method then updates
the record from the values of the corresponding form fields and saveChanges( )
invokes the resource "update" operation on the AppServer to save the updated record
to its data source.

See also: data property, foreach( ) method, getId( ) method

OpenEdge® Development: Mobile Applications 213


fnName property

fnName property
For an invoke operation, the name of the JSDO invocation method that called the
operation. The fnName property is null in the case of a request object returned by a
built-in create, read, update, or delete method.

Data type: String

Access: Read-only
Applies to: request object

This request object property is available only for the following event:

• afterInvoke

Note: The value of the fnName property is the same as that of the op-name parameter
passed to the subscribe( ) method that subscribed to the current invoke
operation event.

See also: invocation method, subscribe( ) method

214 OpenEdge® Development: Mobile Applications


foreach( ) method

foreach( ) method
Loops through the records of a temp-table referenced in JSDO local storage and
invokes a function as a parameter on each iteration. With each iteration, it also sets the
current record as the working record and passes it as a parameter to the function. This
function can then operate on the working record and return a value indicating whether
the foreach( ) terminates the loop or invokes the function for the next working record
of the temp-table.

If the referenced temp-table has child temp-tables, and the useRelationships


property is true, with each iteration through the loop, the working record of the result
set for each child is set to the first record as determined by the relationship to its
respective parent.

After completing execution, the working records of the associated temp-table, and any
child temp-tables, are the most recent working records established when the function
terminates the loop.

Return type: null

Applies to: progress.data.JSDO class, table reference property (JSDO)

Syntax

[table-ref.]foreach ( funcRef )

table-ref

A table reference on the JSDO for a temp-table that has a working record. If the
JSDO references only a single temp-table, the method can be called on the JSDO
itself.

funcRef

A reference to a JavaScript function that returns a Boolean value and has the
following signature:

Syntax

function [ func-name ] ( jsrecord-ref )

Where func-name is the name of a function that you define external to the
foreach( ) parameter list and jsrecord-ref is a JSRecord object reference to
the next working record on table-ref. You can also define funcRef without
func-name directly as an in-line function definition.

The foreach( ) function executes your funcRef for each record of table-ref,
making this record the working record and passing it in as jsrecord-ref. You can
then access the field values of the working record using the data property on
jsrecord-ref or any field references available from table-ref. You can also
invoke other JSDO methods, for example, to operate on the working record,
including additional calls to foreach( ) to operate on working records of any child
temp-tables.

OpenEdge® Development: Mobile Applications 215


foreach( ) method

Your funcRef can terminate the foreach( ) loop be returning false. If the
function does not return false, the loop continues.

If table-ref references a child temp-table in a ProDataSet, when the


useRelationships property is true, foreach( ) uses the relationship to filter out all
but the child records of the working record in the parent temp-table. However, if the
working record of the parent is not set, foreach( ) throws an error. If
useRelationships is false, the loop includes all records of the child temp-table and
no error is thrown.

The following code fragment shows a foreach( ) looping through eCustomer records
in JSDO local storage and displaying each record to its respective row of a previously
established jQuery listview:

dataSet = new progress.data.JSDO( 'dsCustomerOrder' );


uihelper = new progress.ui.UIHelper({ jsdo: dataSet });
uihelper.eCustomer.setListView({
name:'listview',
format: '{CustNum}<br>{Name}<br>{State}',
autoLink: true
});

See also: data property, find( ) method, JSRecord object

216 OpenEdge® Development: Mobile Applications


getData( ) method

getData( ) method
Returns an array of record objects for a temp-table referenced in JSDO local storage.
If this is a child temp-table, and the useRelationships property is true, the specific
record objects in the result set depends on the relationship to its parent.

After completing execution, any working records previously set before the method
executed remain as the working records.

Return type: Object array

Applies to: progress.data.JSDO class, table reference property (JSDO)

Syntax

[table-ref.]getData ( )

table-ref

A table reference on the JSDO. If the JSDO references only a single temp-table,
the method can be called on the JSDO itself.

See also: getSchema( ) method

OpenEdge® Development: Mobile Applications 217


getFormFields( ) method

getFormFields( ) method
Reads the schema of the specified table and returns HTML text that defines
corresponding input fields to appear on the form on the detail page. The returned HTML
includes a hidden field for the internal record ID.

Return type: String


Applies to: progress.ui.UIHelper class, table reference property (UIHelper)

Syntax

[table-ref.]getFormFields ( [array] )

table-ref

A table reference on the UIHelper instance. If the JSDO associated with the
UIHelper instance references only a single temp-table, the method can be called
on the UIHelper instance itself.

array

An array of strings specifying a subset of fields to be returned from the table


schema. If this parameter is omitted, all fields are returned. For example:

uiHelper.eCustomer.getFormFields([ '_id', 'CustNum' , 'Name' ]);

OpenEdge Mobile provides a default form field template for a jQuery Mobile
environment. The following code fragment shows the default template values:

<div data-role="fieldcontain">
<label for="{__name__}">{__label__}</label>
<input id="{__name__}" name="{__name__}" placeholder="" value=""
type="text" />
</div>

As shown above, the default template uses the following substitution parameters:

• {__name__} — The field name as defined in the schema

• {__label__} — The field’s title property as defined in the schema

You can define a template to be used in place of the default by calling


setFieldTemplate( ).

See also: setFieldTemplate( ) method

218 OpenEdge® Development: Mobile Applications


getFormRecord( ) method

getFormRecord( ) method
Returns a JSRecord object for the record shown on the form on the detail page.

Return type: String


Applies to: progress.ui.UIHelper class, table reference property (UIHelper)

Syntax

[table-ref.]getFormRecord ( [array] )

table-ref

A table reference on the UIHelper instance. If the JSDO associated with the
UIHelper instance references only a single temp-table, the method can be called
on the UIHelper instance itself.

OpenEdge® Development: Mobile Applications 219


getId( ) method

getId( ) method
Returns the unique internal ID for the specified temp-table record referenced in JSDO
local storage. The specified record can be either the working record of a referenced
temp-table, or any record provided by a JSRecord object.

After execution, any working records previously set before the method executed
remain as the working records.

Return type: String

Applies to: JSRecord object, progress.data.JSDO class, table reference property


(JSDO)

Syntax

[table-ref.]getId ( )
jsrecord-ref.getId ( )

table-ref

A table reference on the JSDO for a temp-table that has a working record. If the
JSDO references only a single temp-table, the method can be called on the JSDO
itself.

jsrecord-ref

A reference to a JSRecord object for a temp-table record in JSDO local storage.

The internal ID returned by this function is a unique value generated by OpenEdge for
each temp-table record in JSDO local storage. You can pass a returned value to the
findById( ) method called on the associated temp-table to set the specified record
as the working record for the temp-table.

See also: findById( ) method, foreach( ) method

220 OpenEdge® Development: Mobile Applications


getListViewRecord( ) method

getListViewRecord( ) method
Returns a JSRecord object for a specified item in a list view.

Return type: JSRecord

Applies to: progress.ui.UIHelper class, table reference property (UIHelper)

Syntax

[table-ref.]getListViewRecord ( list_item )

table-ref

A table reference on the UIHelper instance. If the JSDO associated with the
UIHelper instance references only a single temp-table, the method can be called
on the UIHelper instance itself.

list_item

The HTML list item element corresponding to the desired record.

See also: setListView( ) method, addItem( ) method

OpenEdge® Development: Mobile Applications 221


getSchema( ) method

getSchema( ) method
Returns an array of objects, one for each field that defines the schema of a temp-table
referenced in JSDO local storage. The properties of each object define the schema
elements of the respective field.

After completing execution, any working records previously set before the method
executed remain as the working records.

Return type: Object array

Applies to: progress.data.JSDO class, table reference property (JSDO)

Syntax

[table-ref.]getSchema ( )

table-ref

A table reference on the JSDO. If the JSDO references only a single temp-table,
the method can be called on the JSDO itself.

See also: getData( ) method, fill( ) method

222 OpenEdge® Development: Mobile Applications


invocation method

invocation method
Any method on the JSDO that is defined by the Mobile resource to execute a
corresponding ABL routine on the AppServer as an invoke operation. This can be any
ABL routine in the Mobile interface that is annotated with an "invoke" operation type.
The invocation method name can be the same as the ABL routine or an alias, as
defined by the resource. The method passes any ABL input parameters as properties
of an object parameter. The method returns results from the ABL routine, including any
return value and output parameters, as properties of a request object that is returned
by the method.

Note: The results of an invoke operation have no effect on JSDO local storage.

After completing execution, any working records previously set before the method
executed remain as the working records.

Return type: request object


Applies to: progress.data.JSDO class

Syntax

op-name ( [ input-object [ , async-flag ] ] )

op-name

The name (specified as an identifier) of the invocation method as defined by the


Mobile resource.

input-object

An object whose properties and values match the case-sensitive names and data
types of the input parameters specified for the ABL routine. If the routine does not
take input parameters, specify null or leave out the argument entirely.

async-flag

A Boolean that when true causes the method to execute asynchronously and
when false causes the method to execute synchronously. The default value is
true.

For a synchronous invocation, the method returns a request object that contains
several properties depending on the status of the invoke operation. However, if there
are any ABL output parameters or return value, they are returned as properties of an
object referenced by the response property of the request object. The response object
properties for output parameters match the case-sensitive names and data types of the
output parameters specified for the ABL routine. Any return type is returned by an
OpenEdge-defined _retVal property with a matching data type.

For an asynchronous invocation, the method returns a similar request object as input
to any event handler function subscribed to the following named events that fire in the
following operational order:

1. beforeInvoke event

2. afterInvoke event

OpenEdge® Development: Mobile Applications 223


invocation method

Note: If you are calling an invocation method that either sends a temp-table or
ProDataSet object as a property of input-object or returns a temp-table or
ProDataSet object as a property of the response property object, you need to
apply a rule in order to access this temp-table or ProDataSet object. The rule
is that wherever you dereference or reference a temp-table or ProDataSet
object, you must reference that value twice, separated by a period or a colon,
depending on the context. For example, to access a temp-table object, ttCust
returned by the response property in a request object, you must code the
following dereference: request.response.ttCust.ttCust. Similarly, if you
pass ttCust to an invocation method, InputTT( ), you must code the
following reference: jsdo.InputTT( {ttCust: {ttCust:ttCust}});

See also: fill( ) method, record property, request object, saveChanges( ) method

224 OpenEdge® Development: Mobile Applications


jsdo property

jsdo property
An object reference to the JSDO that performed the operation returning the request
object.

Data type: progress.data.JSDO class


Access: Read-only
Applies to: request object

This request object property is available for all events.

See also: fill( ) method, invocation method, saveChanges( ) method

OpenEdge® Development: Mobile Applications 225


jsrecord property

jsrecord property
An object reference to the record created, updated, or deleted by the operation.

Data type: JSRecord object


Access: Read-only
Applies to: request object

This request object property is available only for the following events:

• afterCreate

• afterDelete

• afterUpdate

• beforeCreate

• beforeDelete

• beforeUpdate

See also: saveChanges( ) method

226 OpenEdge® Development: Mobile Applications


login( ) method

login( ) method
Starts a user login session on the current Session object by sending an HTTP request
with user credentials to a URI for a specified Mobile Web application. If the user
credentials are authenticated, the login session is started with a unique session ID for
that session that is also passed to the AppServer that implements the Mobile Web
application. If the Mobile Web application is so configured, along with the session ID, it
also sends a single sign-on (SSO) client-principal with the user credentials to the
AppServer. The method also returns a code indicating the success of the login request.

Notes: Before invoking this method, ensure that you set the authenticationModel
property on the Session object correctly (see the notes on authentication
models).

If the browser or mobile device has already authenticated a user login session,
this method completes successfully.

This method does not support proxy servers (servers that function as a security
service) in Release 11.2.

Return type: Number

Applies to: progress.data.Session class

Syntax

login ( service-uri [ , username , password [ , login-target ]] )

service-uri

A string expression containing the URI of the Mobile Web application for which to
start the user login session. This Mobile Web application must support one or
more OpenEdge Mobile services in order to create JSDOs for the service
resources provided by the application. If HTTP Basic Authentication is in effect for
the Mobile Web application (see the notes on authentication models), this URI is
appended with a string that identifies a protected resource against which to
authenticate the login session (see login-target).

If the Mobile App from which you are logging in is a Mobile Web App deployed to
the same Apache Tomcat server as the Mobile Web application, you can specify
service-uri as a relative URI, for example, /SportsMobileApp, which is relative
to the deployment end point (Tomcat server domain or host and port).

If the Mobile App from which you are logging in is a Mobile Native App that will be
installed to run directly in a native device container, or if it is a Mobile Web App
deployed to a different Web server from the Mobile Web application, you must
specify service-uri as an absolute URI to the Tomcat server domain or host and
port, for example, http://www.progress.com/SportsMobileApp, or perhaps for
testing, http://testmach:8980/SportsMobileApp.

Note: For any Mobile App that must specify service-uri as an absolute URI,
you must maintain separate JavaScript sources to deploy the Mobile App
for different Mobile Web application environments, such as one for testing
and one for production.

OpenEdge® Development: Mobile Applications 227


login( ) method

username

A string expression containing a user ID for the method to send to the Web server
for authentication.

Note: The userName property returns the most recent value passed to this
method for the current Session object.

password

A string expression containing a password for the method to send to the Web
server to authenticate the specified user.

login-target

A string expression that when appended to service-uri specifies a Mobile Web


application resource against which the specified user is authenticated. If you do
not specify a value for login-target, the value is set to "/static/home.html"
by default.

Note: The value returned by the loginTarget property of the Session object is
either the value of the login-target parameter or the default
("/static/home.html").

When the method completes, it returns one of the following numeric constants to
indicate the result:

• progress.data.Session.SUCCESS — User login session started successfully.


After you have downloaded JSDO catalogs using the addCatalog( ) method for
supported Mobile services, you can create JSDOs for each Mobile resource
provided by these services.

• progress.data.Session.AUTHENTICATION_FAILURE — User login failed


because of invalid user credentials (username or password).

• progress.data.Session.GENERAL_FAILURE — User login failed because of a


non-authentication failure.

You can also return the result for the most recent login attempt on the current Session
object by reading the loginResult property. For a more specific status code returned
in the HTTP response, you can check the value of the loginHttpStatus property.

The general Web server interaction with and response to this method depends on the
authentication model that the Web server uses and how resources are accessed and
protected. You configure the authentication model for each Mobile Web application
deployed to the Apache Tomcat.

228 OpenEdge® Development: Mobile Applications


login( ) method

OpenEdge Mobile supports the following authentication models:

• Anonymous — No authentication is required. This is the default value.

• HTTP Basic Authentication — The Mobile Web application requires a valid user
ID and password, but does not provide a page containing a login form (credentials
are typically entered in a generic login dialog provided by either the Mobile App,
the browser, or the native device container in which the App is running).

• HTTP Forms Authentication — The Mobile Web application requires a valid user
ID and password and provides a page containing a login form.

For more information on these authentication models and how to configure them for a
Mobile Web application, see the sections on Web server authentication models in
Chapter 5, “Deploying Mobile Applications.” For more information on the interaction
between this method and the Web server, see the sections on managing login session
in Chapter 4, “Creating Mobile Apps using JSDOs.”

Caution: You must be sure that security is configured to complete authentication


before the application requests resources in the JSDO catalog. Although it is
possible to configure application security so that the only the Mobile
resources in the catalog require authentication, Progress Software does not
recommend this approach. Instead, Progress Software recommends that
you require authentication for application resources in addition to those
defined in the catalog, and require that the authentication occur prior to
accessing any resources in the catalog. (Note: This is the purpose of the
login-target parameter, either one you pass to the login( ) method or its
default.) Once the user is authenticated, the Web server provides access to
all other resources, including catalog resources, according to the user's
authorization settings.

Note: Unless the application design guarantees that the user will be prompted by the
Web browser or native device container to provide credentials before a
login( ) call occurs, Progress Software recommends (in some cases
requires) that the Mobile App pass the credentials as parameters to the
login( ) method. In addition, you must correctly set the value of the Session
object’s authenticationModel property. Coding the Mobile App in this way
ensures that the proper credentials are submitted to the server and promotes
a favorable user experience.

See also: addCatalog( ) method, loginHttpStatus property, loginResult property,


loginTarget property, logout( ) method, serviceURI property,
userName property, authenticationModel property

OpenEdge® Development: Mobile Applications 229


loginHttpStatus property

loginHttpStatus property
Returns the specific HTTP status code returned in the response from the most recent
login attempt on the current Session object.

Data type: Number

Access: Read-only
Applies to: progress.data.Session class
See also: login( ) method

230 OpenEdge® Development: Mobile Applications


loginResult property

loginResult property
Returns the return value of the login( ) method, which is the basic result code for the
most recent login attempt on the current Session object.

Data type: Number

Access: Read-only
Applies to: progress.data.Session class

Possible login return values include the following numeric constant values:

• progress.data.Session.LOGIN_SUCCESS — User login session started


successfully.

• progress.data.Session.LOGIN_AUTHENTICATION_FAILURE — User login failed


because of invalid user credentials.

• progress.data.Session.LOGIN_GENERAL_FAILURE — User login failed because


of a non-authentication failure.

For a more specific status code returned in the HTTP response, you can check the
value of the loginHttpStatus property.

See also: login( ) method, loginHttpStatus property

OpenEdge® Development: Mobile Applications 231


loginTarget property

loginTarget property
Returns the string appended to the Mobile Web application URI passed to the
login( ) method to form the URI of an application resource against which the user
has been authenticated for the current login session. By default, this appended string
is "/static/home.html".

Data type: String

Access: Read-only
Applies to: progress.data.Session class

You initially provide the Mobile Web application URI as a parameter to the login( )
method. You can also pass a parameter to this method to specify a non-default value
for the string appended to this URI.

See also: login( ) method, serviceURI property

232 OpenEdge® Development: Mobile Applications


logout( ) method

logout( ) method
Terminates the login session on the Web server associated with the Session object,
and invalidates any session currently maintained by the server and the browser or
hybrid native wrapper. Once logout( ) is executed, no further communication (other
than a login( ) call) can occur between the Mobile App and the server until a new
login session is established.

Return type: null

Applies to: progress.data.Session class

Syntax

logout ( )

When this method terminates the associated login session, the Session object can be
re-used to start a new session. The Session object’s properties retain their values, with
the following exceptions:

• loginResult is reset to null.

• loginHttpStatus is reset to null.

• clientContextId is reset to null.

Existing JSDOs and catalog information are not affected by logout( ). However, any
attempt to call addCatalog( ) or a JSDO method that requires contacting the server
results in an error being thrown.

Note: You need not invoke this method if the Web server is using the HTTP Basic
Authentication model, unless you want to re-use the Session object.

See also: login( ) method

OpenEdge® Development: Mobile Applications 233


name property

name property
The name of the Mobile resource for which the current JSDO is created. This value
must match the name of a resource provided by the Mobile service for which a login
session has already been started.

Data type: String

Access: Writable
Applies to: progress.data.JSDO class

Note: To set this property, you must pass its value to the JSDO constructor.

See also: services property, progress.data.Session class

234 OpenEdge® Development: Mobile Applications


onOpenRequest property

onOpenRequest property
Returns a developer-specified callback function that the Session object executes to
modify a request object before sending the request object to the server. Such a function
might serve, for example, to add a header to the request.

It is not normally necessary to use this property, because OpenEdge Mobile properly
handles preparation of the request object for normal circumstances.

Data type: function

Access: Writable
Applies to: progress.data.Session class

By default, the value of the onOpenRequest property is null, meaning that the request
object is sent without modification. If the value is set to a function, the function takes a
single parameter.

Syntax

mysession.onOpenRequest = myFunction( params )

params

An object that has the following properties:

• xhr — An object reference to the XMLHttpRequest object (XHR) to be used to


send the request. The current request object can be modified by the function.
When the callback is called, XMLHttpRequest.open( ) will already have been
called on the XHR , but the callback can call open( ) again, overriding the effects
of the first open( ). When the callback function is used for a login( ),
addCatalog( ), or logout( ) call, although it should not be necessary and is not
recommended, it is possible to replace the XHR entirely by creating a new object
and assigning it as the value of the xhr property.

• verb — The HTTP operation (GET, PUT, etc.) to be performed by the request.

• uri — The URI to which the request is addressed.

• session — A reference to the Session object that invoked the callback.

• formPreTest — A Boolean specifying whether the current login( ) request is a


preliminary request, used in cases of Form authentication, to determine whether
the user is already logged in (true) or an actual login request (false).

• async — A Boolean specifying whether the request is asynchronous (true) or


synchronous (false).

Note: If the callback function is used for a login( ), addCatalog( ), or


logout( ) call, and if it calls XMLHttpRequest.open( ), the request must
be sent synchronously.

OpenEdge® Development: Mobile Applications 235


onOpenRequest property

If you assign a function as the value of onOpenRequest, it remains in effect for all
requests for the duration of the session unless it is replaced by another function or is
set to null. Therefore, be sure to reset the value of the property as necessary, as in
the following example:

mysession.onOpenRequest = function( params ) {


params.xhr.setRequestHeader('Authorization', auth);
};
mysession.login(serviceURI, username, password);
mysession.onOpenRequest = null;

See also: request object, xhr property

236 OpenEdge® Development: Mobile Applications


paramObj property

paramObj property
A reference to the object, if any, that was passed as a parameter to the method that
returned the request object. If no parameter was passed to the method, the paramObj
property is undefined.

Data type: Object

Access: Read-only
Applies to: request object

This request object property is available for all events where it is passed, but does not
apply to the following events:

• afterSaveChanges

• beforeSaveChanges

See also: fill( ) method, invocation method, saveChanges( ) method

OpenEdge® Development: Mobile Applications 237


record property

record property
A property on a JSDO table reference that references a JSRecord object with the data
for the working record of a temp-table referenced in JSDO local storage. If no working
record is set for the referenced temp-table, this property is null.
Data type: JSRecord object
Access: Read-only
Applies to: progress.data.JSDO class, table reference property (JSDO)

The table reference that provides this property can either be the value of a property on
the JSDO with the name of a referenced temp-table in JSDO local storage or a
reference to the JSDO itself if the JSDO references only a single temp-table.

The field values for the working record are provided by the data property of the
JSRecord object returned by the record property.

See also: data property

238 OpenEdge® Development: Mobile Applications


remove( ) method

remove( ) method
Deletes the specified temp-table record referenced in JSDO local storage. The
specified record can either be the working record of a referenced temp-table or any
record provided by a JSRecord object.

After execution, any working record for an associated temp-table, and for any child
temp-tables is not set. To synchronize the change on the AppServer, call the
saveChanges( ) method.

Return type: Boolean

Applies to: JSRecord object, progress.data.JSDO class, table reference property


(JSDO)

Syntax

[table-ref.]remove ( )
jsrecord-ref.remove ( )

table-ref

A table reference on the JSDO for a temp-table that has a working record. If the
JSDO references only a single temp-table, the method can be called on the JSDO
itself.

jsrecord-ref

A reference to a JSRecord object for a temp-table record in JSDO local storage.

The following code fragment shows a jQuery event defined on a delete button to delete
the record displayed in a customer detail form from the eCustomer temp-table
referenced in JSDO local storage:

dataSet = new progress.data.JSDO( 'dsCustomerOrder' );

$('#btnDelete').bind('click', function(event) {
var jsrecord = dataSet.eCustomer.findById($('#custdetail #id').val());
jsrecord.remove();
dataSet.saveChanges();
});

The form has been previously displayed with values from the same record. When the
button is clicked, the event handler uses the findById( ) method to find the original
record with the matching internal record ID (jsrecord) and invokes the remove( )
method on jsrecord to delete the record from eCustomer.

See also: data property, saveChanges( ) method

OpenEdge® Development: Mobile Applications 239


response property

response property
Returns an object whose properties contain data from a Mobile built-in or invoke
operation executed on the AppServer.

Data type: Object

Access: Read-only
Applies to: request object

If a built-in Mobile operation (create, read, update, or delete) returns successfully and
the response is valid JSON that can be converted to a JavaScript object, the response
property is a reference to the temp-table or ProDataSet object that is returned from the
AppServer. If the server response is not valid JSON, the response property is
undefined.

If an invoke operation returns successfully and has no return value or output


parameters, the property is null. If the invoke operation has a return value, you can
read it as the value of the object _retVal property. If the operation has output
parameters, you can read these parameters as the values of object properties whose
case-sensitive names and data types match the ABL names and data types of the
output parameters specified for the operation on the AppServer.

If the operation returns an ABL error, the object contains the following properties:

• _retVal — A String with the value of any ABL RETURN ERROR string or
ReturnValue property for a thrown AppError object

• _errors — An array of JavaScript objects, each of which contains two properties:


_errorMsg with the ABL error message string and _errorNum with the error
number, for one of possibly many ABL-returned errors

Note: In the current OpenEdge release, this array always returns one object only
for the first ABL error (the equivalent of ERROR-STATUS:GET-MESSAGE(1) in
ABL).

This request object property is available only for the following events:

• afterCreate

• afterDelete

• afterFill

• afterInvoke

• afterUpdate

See also: fill( ) method, invocation method, saveChanges( ) method

240 OpenEdge® Development: Mobile Applications


saveChanges( ) method

saveChanges( ) method
Synchronizes to the AppServer all changes made to JSDO local storage since the last
call to the fill( ) or saveChanges( ) method. The saveChanges( ) method
completes this data synchronization by invoking appropriate built-in resource
operations on each changed record, one at a time, and in the following general order
of operation type:

1. "delete" — All record deletions are applied, one at a time across the network.

2. "create" — The creation of all new records is applied, one at a time across the
network.

3. "update" — Updates are applied to all modified records, one at a time across the
network.

The sending of changes for multiple operations on the same record is optimized, so the
fewest possible changes are sent to the AppServer. For example, if a record is
updated, then deleted in local storage, only the deletion is sent to the AppServer.

Note: In the current release, there is no batching of built-in record-change


operations. That is, the built-in delete operation is invoked over the network for
each deleted record, followed by the built-in create operation for each created
record, and finally by the built-in update operation for each updated record. So,
even for a ProDataSet, a built-in record operation executes over the network
only one record at a time and cannot be part of a transaction.

After execution, the working record for each temp-table referenced by the JSDO is not
set.

Return type: null

Applies to: progress.data.JSDO class

Syntax

saveChanges ( )

This method always executes asynchronously, and fires the following JSDO named
events, as required by JSDO changes, and shown in operational order:

1. beforeSaveChanges event

2. beforeDelete event

3. afterDelete event

4. beforeCreate event

5. afterCreate event

6. beforeUpdate event

7. afterUpdate event

8. afterSaveChanges event

OpenEdge® Development: Mobile Applications 241


saveChanges( ) method

If any create, update, or delete operation fails, the operation is automatically undone
and the applicable record in the JSDO’s local storage reverts to its last-saved state in
the database. Specifically:

• If a create operation fails, the record is removed from JSDO memory.

• If an update operation fails, the record reverts to the state it was in immediately
preceding the assign( ) operation that led to the failure.

• If a delete operation fails, the record is restored to JSDO memory in its last-saved
state. This state does not reflect any unsaved assign( ) operations that may
have occurred before the remove( ) call.

You can use the request object returned by the method or event-handler function to
retrieve information about the failure and any changes that were discarded as a result:

• To determine where a failure occurred, inspect the success and batch properties
of the request object.

• To retrieve discarded changes, inspect the jsrecord property of the request


object.

The following code fragment shows a jQuery event defined on a save button to save
the current field values for a customer detail form to the corresponding eCustomer
record in JSDO local storage:

dataSet = new progress.data.JSDO( 'dsCustomerOrder' );

$('#btnSave').bind('click', function(event) {
var jsrecord = dataSet.eCustomer.findById($('#custdetail #id').val());
jsrecord.assign();
dataSet.saveChanges();
});

The form has been displayed with previous values of the same record. When the button
is clicked, the event handler uses the findById( ) method to find the original record
with the matching internal record ID (jsrecord) and invokes the assign( ) method on
jsrecord with an empty parameter list to update its fields in eCustomer with any new
values entered into the form. It then invokes the saveChanges( ) method to update the
corresponding record on the AppServer.

See also: fill( ) method, invocation method

242 OpenEdge® Development: Mobile Applications


services property

services property
Returns an array of objects that identifies the Mobile services that have been loaded
for the current Session object and its Mobile Web application.

Data type: Object array

Access: Read-only
Applies to: progress.data.Session class

You load Mobile services for a Session object by loading the corresponding JSDO
catalogs using the addCatalog( ) method after you login using the login( ) method.

Each object in the array contains two properties:

• name — The name of a Mobile service

• uri — The URI for the service. If the address of the service in the catalog is an
absolute URI, this value is that URI. If the service address is relative, this value is
the relative address concatenated to the value of the Session object's
serviceURI property, which contains the Mobile Web application URI passed to
the login( ) method.

Given the following service names and URIs loaded for a Session object:

• "CustomerSvc" service with this URI:


"/rest/CustomerSvc"

• "ItemSvc" service with this URI:


"http://itemhost:8080/SportsApp/rest/ItemSvc"

The following code fragment produces the output that follows:

// create Session
pdsession = new progress.data.Session();

// log in
pdsession.login('/SportsApp');

// load 2 catalogs
pdsession.addCatalog ("/SportsApp/static/mobile/CustomerSvc.json");
pdsession.addCatalog ("/SportsApp/static/mobile/ItemSvc.json");

// Use services property to print services loaded by this Session object


for (var i=0; i < pdsession.services.length; i++) {
console.log( pdsession.services[i].name + " " +
pdsession.services[i].uri);
}

Output from the preceding code fragment:

CustomerSvc /SportsApp/rest/CustomerSvc
ItemSvc http://itemhost:8080/SportsApp/rest/ItemSvc

OpenEdge® Development: Mobile Applications 243


services property

Note: To return a corresponding list of URIs for the loaded JSDO catalogs, read the
catalogURIs property.

See also: addCatalog( ) method, catalogURIs property, login( ) method,


serviceURI property

244 OpenEdge® Development: Mobile Applications


serviceURI property

serviceURI property
Returns the URI to the Mobile Web application passed as a parameter to the most
recent call to the login( ) method on the current Session object, whether or not the
most recent call to login( ) succeeded.

Data type: String

Access: Read-only
Applies to: progress.data.Session class
See also: loginTarget property, login( ) method

OpenEdge® Development: Mobile Applications 245


setDetailPage( ) method

setDetailPage( ) method
Specifies the HTML page that contains the form in which item details are displayed.

Return type: null


Applies to: progress.ui.UIHelper class

Syntax

[table-ref.]setDetailPage( object )

table-ref

A table reference on the UIHelper instance. If the JSDO associated with the
UIHelper instance references only a single temp-table, the method can be called
on the UIHelper instance itself.

object

A JavaScript object with the following properties:

• name — The id propety of the HTML div (or other) element that contains the
form page

• fieldTemplate — (Optional) An HTML string specifying the fields and labels


(and their format) included on the form, overriding the default settings or
those specified by setFieldTemplate( ).

For example:

uiHelper.eCustomer.setDetailPage({
name: 'cust-detail-page',
fieldTemplate: '<input id="{__name__}"></input>'
});

246 OpenEdge® Development: Mobile Applications


setFieldTemplate( ) method

setFieldTemplate( ) method
Specifies the format or all detail forms created during the JavaScript session. These
settings can be overridden for specific forms by the optional fieldTemplate property
of the JavaScript object passed to the setDetailPage( ) method.

Return type: null


Applies to: progress.ui.UIHelper class

Syntax

progress.ui.UIHelper.setFieldTemplate( ‘string’)

string

An HTML string.

It is not necessary to call setFieldTemplate( ) unless:

• You are not using a jQuery Mobile environment, or

• You are using a jQuery Mobile environment, but you want to change the default
settings (see below)

OpenEdge Mobile provides a default form template for a jQuery Mobile environment.
The following code fragment shows the default template values:

progress.ui.UIHelper.setItemTemplate = '<div data-role="fieldcontain">


<label for="{__name__}">{__label__}</label>
<input id="{__name__}" name="{__name__}" placeholder="" value=""
type="text" />
</div>';

As shown in the preceding example, the template uses the following substitution
parameters:

• {__name__} — The name of the field, as defined by the schema

• {__label__} — The title property of the field, as defined by the schema

See also: setDetailPage( ) method

OpenEdge® Development: Mobile Applications 247


setItemTemplate( ) method

setItemTemplate( ) method
Specifies the format for items in all list views created during the JavaScript session.
These settings can be overridden for specific list views by setListView( ). In
addition, the __format__ parameter can be overridden for specific items by
addItem( ).

Return type: null


Applies to: progress.ui.UIHelper class

Syntax

progress.ui.UIHelper.setItemTemplate( ‘string’)

string

An HTML string.

It is not necessary to call setItemTemplate( ) unless:

• You are not using a jQuery Mobile environment, or

• You are using a jQuery Mobile environment, but you want to change the default
settings (see below)

OpenEdge Mobile provides a default item template for a jQuery Mobile environment.
The following code fragment shows the default template values:

progress.ui.UIHelper.setItemTemplate = '<li data-theme="c"


data-id="{__id__}"><a href="#{__page__}"class="ui-link"
data-transition="slide">{__format__}</a></li>';

As shown in the preceding example, the template uses the following substitution
parameters:

• {__id__} — The internal ID of the record

• {__page__} — The name attribute of the object pased as a parameter to


setDetailPage( ), which defines the form for each individual list item

• {__format__} — The format property of the object pased as a parameter to


setListView( ) or (optionally) to addItem( ), which identifies the fields to be
included for each item in the list view

See also: setListView( ) method, addItem( ) method

248 OpenEdge® Development: Mobile Applications


setListView( ) method

setListView( ) method
Defines a list view for a given table.

Return type: null


Applies to: progress.ui.UIHelper class, table reference property (UIHelper)

Syntax

[table-ref.]setListView( object )

table-ref

A table reference on the UIHelper instance. If the JSDO associated with the
UIHelper instance references only a single temp-table, the method can be called
on the UIHelper instance itself.

object

A JavaScript object that contains one or more of the following properties:

• name — A string that identifies the list view.

• format — (Optional) A string that specifies the fields shown for each item
and the line breaks between them. If the format property is omitted, the
UIHelper instance uses the list item in the HTML ListView as a template.

• autoLink — A Boolean that specifies whether events are automatically


generated to display the corresponding form on the detail page when an item
is clicked.

• itemTemplate — An HTML string that overrides, for this list view, the settings
in the default item template or in the ‘string’ parameter passed to the
setItemTemplate( ) method.

For example:

uihelper.eCustomer.setListView({
name:'listview',
format: '{CustNum}<br>{Name}<br>{Phone}<br>{Address}<br>{State}',
autoLink: true
});

See also: setItemTemplate( ) method

OpenEdge® Development: Mobile Applications 249


showListView( ) method

showListView( ) method
Displays the specified table’s list view on the Mobile App device or browser.

Return type: null


Applies to: progress.ui.UIHelper class, table reference property (UIHelper)

Syntax

[table-ref.]showListView( )

table-ref

A table reference on the UIHelper instance. If the JSDO associated with the
UIHelper instance references only a single temp-table, the method can be called
on the UIHelper instance itself.

See also: setListView( ) method

250 OpenEdge® Development: Mobile Applications


subscribe( ) method

subscribe( ) method
Subscribes a given event handler function to a named event for a JSDO or table
reference. For more information on these events, see Table 13.

After execution, the working record for any associated table reference remains
unchanged.

Return type: null

Applies to: progress.data.JSDO class, table reference property (JSDO)

Syntax

[table-ref.]subscribe ( event-name [ , op-name ] , event-handler , scope )

table-ref

A table reference on the JSDO, which allows the method to subscribe an event
handler for events that fire only for a referenced temp-table. If invoked on the
JSDO directly, the method can subscribe an event handler for all JSDO events.

event-name

The name of an event to which the JSDO instance or table-ref subscribes. See
Table 13 for a list of available JSDO events.

If you call the subscribe( ) method on table-ref, the method can subscribe only to
the following events:

• afterCreate

• afterDelete

• afterUpdate

• beforeCreate

• beforeDelete

• beforeUpdate

op-name

The name of a JSDO invocation method, a call to which causes the event to fire.
This parameter is required in cases where event-name is beforeInvoke or
afterInvoke. It should be used only with those event names, and only when
subscribing the JSDO (that is, not a table-ref). The value of op-name is the
same as that of the fnName property of the request object.

event-handler

A reference to an event handler function that is called when the event fires.

OpenEdge® Development: Mobile Applications 251


subscribe( ) method

scope

An optional object reference that defines the execution scope of the function
called when the event fires. If the scope property is omitted, the execution scope
is the global object (usually the browser or device window).

See also: invocation method, unsubscribe( ) method, Table 13

252 OpenEdge® Development: Mobile Applications


success property

success property
A Boolean that indicates, if set to true, that the Mobile operation was successfully
executed. A successful Mobile operation returns an HTTP status in the range of 200 -
299.

Data type: Boolean

Access: Read-only
Applies to: request object

This request object property is available only for the following events:

• afterCreate

• afterDelete

• afterFill

• afterInvoke

• afterSaveChanges

• afterUpdate

In the case of an afterSaveChanges event, this property is true only if all requests that
are part of the batch of requests were successfully executed.

See also: fill( ) method, invocation method, saveChanges( ) method

OpenEdge® Development: Mobile Applications 253


table reference property (JSDO)

table reference property (JSDO)


A property on a JSDO that has the name of a temp-table mapped by the Mobile
resource for which the current JSDO is created. Its value is a reference (table
reference) to the temp-table object in JSDO local storage. This temp-table object
provides access to the working record, if defined, of the temp-table. If a Mobile
resource maps a ProDataSet, its JSDO provides one table reference for every
temp-table in the ProDataSet.

Data type: Temp-table object reference in JSDO local storage


Access: Read-only
Applies to: progress.data.JSDO class

In syntax wherever a table reference can be used, table-ref represents the name of
the property containing the table reference. A referenced temp-table object provides
the following properties:

• record property— A reference to a JSRecord object that has the data for the
working record of the temp-table through a data property. If no working record is
defined for the temp-table, the record property is null.

• field reference property — A property on the temp-table object that has the
name of a field (as defined in the temp-table schema) and the value for that field
in the working record, also referred to as a field reference. In syntax wherever a
field reference can be used, field-ref represents the name of the property
containing the field reference. A temp-table object provides one field reference for
each field defined in the original temp-table. If no working record is defined, all field
references are null, except when fields are referenced on the data property of a
JSRecord object reference.

Caution: Never write directly to a field-ref using this record property or any
JSRecord object reference; in this case, use field-ref only to read the
data. Writing to data using such a reference does not mark the record for
update when calling the saveChanges( ) method. To mark a record for
update, you must assign a field value either by setting a
jsdo.table-ref.field-ref for a working record or by calling the
assign( ) method on a valid table-ref or JSRecord object reference.

You can therefore reference the field values in the working record of a given table
reference using either the JSRecord object returned by its record property or its field
references. The field references provide a convenient way to access table fields that is
similar to how you reference table fields in ABL. The record property provides an
alternative way to access table fields, especially one that has the same name as a
property or method of a JSDO that you can invoke from a table reference.

For example, the following code fragment shows two different ways to access the
CustNum field of a record added to a customer temp-table provided by a resource
ProDataSet:

var dataSet = new Progress.data.JSDO( 'CustomerOrderDS' );


dataSet.customer.add();
alert(dataSet.customer.record.data.CustNum);
alert(dataSet.customer.CustNum);

254 OpenEdge® Development: Mobile Applications


table reference property (JSDO)

Both calls to the alert( ) function access the same CustNum field in the working
record of the customer table created by the add( ) method.

For more information on accessing the working record of a table reference, see the
notes for the section on the progress.data.JSDO class.

See also: JSRecord object, record property

OpenEdge® Development: Mobile Applications 255


table reference property (UIHelper)

table reference property (UIHelper)


A property on a UIHelper instance that corresponds to a temp-table of the JSDO with
which the instance is associated.

Data type: Temp-table object reference in JSDO local storage


Access: Read-only
Applies to: progress.ui.UIHelper class

Note: A table reference (table-ref in syntax) on a UIHelper object does not have
a record property. Therefore you cannot use this table reference to directly
access temp-table field values, but only to invoke methods on the UIHelper
object.

See also: table reference property (JSDO)

256 OpenEdge® Development: Mobile Applications


unsubscribe( ) method

unsubscribe( ) method
Unsubscribes a given event handler function from a named event of a JSDO or table
reference. For more information on these events, see Table 13

After execution, the working record for any associated table reference remains
unchanged.

Return type: null


Applies to: progress.data.JSDO class, table reference property (JSDO)

Syntax

[table-ref.]unsubscribe ( event-name [ , op-name ] , event-handler , scope )

table-ref

A table reference on the JSDO, which allows the method to unsubscribe an event
handler for events that fire only for a referenced temp-table. If invoked on the
JSDO, the method can unsubscribe an event handler for all JSDO events.

event-name

If you call the unsubscribe( ) method on table-ref, the method can


unsubscribe only from the following events:

• afterCreate

• afterDelete

• afterUpdate

• beforeCreate

• beforeDelete

• beforeUpdate

op-name

The name of a JSDO invocation method, a call to which causes the event to fire.
This parameter is required in cases where event-name is beforeInvoke or
afterInvoke, and op-name should be used only with those event names. To be
meaningful, the op-name value must match that of the corresponding parameter
in a preceding subscribe( )call.

event-handler

A reference to an event handler function that is called when the event fires.

scope

An object reference that defines the execution scope of the specified


event-handler. Specifying the scope is optional in the event subscription. If the
subscription does specify an execution scope, you must specify a matching scope
parameter to the unsubscribe( ) method.

OpenEdge® Development: Mobile Applications 257


unsubscribe( ) method

See also: invocation method, subscribe( ) method, Table 13

258 OpenEdge® Development: Mobile Applications


useRelationships property

useRelationships property
A Boolean that specifies whether JSDO methods that operate on table references in
JSDO local storage work with the table relationships defined in the schema (that is,
work only on the records of a child table that are related to the parent).

Data type: Boolean

Access: Writable
Applies to: progress.data.JSDO class

When set to true, methods, such as add( ), find( ), and foreach( ), that have
default behavior for related table references respect these relationships when
operating on related tables. When set to false, these methods operate on all table
references as if they have no relationships. The default value is true.

See also: add( ) method, find( ) method, foreach( ) method

OpenEdge® Development: Mobile Applications 259


userName property

userName property
Returns the user ID passed as a parameter to the most recent call to the login( )
method on the current Session object.

Data type: String

Access: Read-only
Applies to: progress.data.Session class

This value is returned, whether or not the most recent call to login( ) succeeded.

Note: This property does not always specify the name of the user logged in for the
current session. The logged-in user can be different from this property setting
if the authentication was done by the browser or hybrid native wrapper prior to
the login( ) method being called, or if the login( ) method was passed
incorrect user credentials and the browser or native wrapper took over and
completed the user authentication.

See also: login( ) method

260 OpenEdge® Development: Mobile Applications


xhr property

xhr property
A reference to the XMLHttpRequest object used to perform the request. In the case of
an asynchronous call, this property may not be available until after the
XMLHttpRequest object is created.

Data type: Object

Access: Read-only
Applies to: request object

This request object property is available only for the following events:

• afterCreate

• afterDelete

• afterFill

• afterInvoke

• afterUpdate

See also: fill( ) method, invocation method, saveChanges( ) method

OpenEdge® Development: Mobile Applications 261


xhr property

262 OpenEdge® Development: Mobile Applications

You might also like