Openedge Development Mobile Applications Product - 59edeacf1723ddc769c559a4
Openedge Development Mobile Applications Product - 59edeacf1723ddc769c559a4
Openedge Development Mobile Applications Product - 59edeacf1723ddc769c559a4
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
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
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
• Purpose
• Audience
• Organization
• Typographical conventions
• OpenEdge messages
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 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”
Walks through the process of creating a simple Mobile App directly from an
OpenEdge data model.
Describes the requirements and tools for building Mobile services, including the
AppServer coding and Mobile interface annotations required to define Mobile
resources.
Describes how to access Mobile services from JavaScript, including how to build
Mobile Apps that access these services.
Describes options for deploying Mobile services and the Mobile Apps that access
them.
For the latest documentation updates see the OpenEdge Product Documentation
Overview page on PSDN:
http://communities.progress.com/pcom/docs/DOC-16074.
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.”
• 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.
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.
Typographical conventions
This manual uses the following typographical conventions:
Convention Description
Convention Description
SMALL, BOLD Small, bold capital letters indicate OpenEdge key functions
CAPITAL LETTERS and generic keyboard keys; for example, GET and CTRL.
Syntax:
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.
Syntax
FOR is one of the statements that can end with either a period or a colon, as in this
example:
Syntax
In this example, the outer (small) brackets are part of the language, and the inner
(large) brackets denote an optional item:
Syntax
Syntax
{ &argument-name }
In this example, EACH, FIRST, and LAST are optional, but you can choose only one of
them:
Syntax
In this example, you must include two expressions, and optionally you can include
more. Multiple expressions are separated by commas:
Syntax
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
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" ] ... }
Syntax
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
OpenEdge messages
OpenEdge displays several types of messages to inform you of routine and unusual
occurrences:
• 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.
• Returns to the Procedure Editor, so you can correct an error in a procedure. This
is the usual action taken after compiler messages.
OpenEdge messages end with a message number in parentheses. In this example, the
message number is 200:
If you encounter an error that terminates OpenEdge, note the message number before
restarting.
• Choose Help→ Messages and then type the message number to display a
description of a specific OpenEdge message.
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.
OpenEdge-install-dir/bin/pro
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.
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
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
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].
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.
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.
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
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
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
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.
[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
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.
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.
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.
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 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.
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.
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:
• Android devices, including numerous smart phones and tablets made by a variety
of manufacturers
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.
• Run-time architecture
• Deployment options
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.
Figure 1: OpenEdge Mobile run-time architecture for native and Web apps
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 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).
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.
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.
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.
Figure 3: Accessing AppServer data and business logic from Mobile Apps
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.
Built-in
operation Required parameter list for the implementing ABL routine1
For information on coding and annotating these ABL routines, see Chapter 3, “Creating
Mobile Services.”
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.
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.”
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.
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.
• 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.
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.”
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.
For more information on building Mobile Apps, see Chapter 4, “Creating Mobile Apps
using JSDOs.”
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.”
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
• Troubleshooting
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.
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.
2. Enter the user name and password associated with your Progress account.
Click OK.
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.
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.
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.
3. Go to the Database tab, and select the Show all radio button.
3. In the body of the include file, copy and paste the following code:
4. Save the file in your working directory and close the file.
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.
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.
DATASET dsCustomer:FILL().
BUFFER eCustomer:DETACH-DATA-SOURCE().
RETURN.
3. On the Modify a Mobile Service page, select the check box next to the
dsCustomer.cls file. Click Finish.
1. In the Project pane, expand the Pages folder and click the home page.
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.
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;
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);
3. Click Upload a file and browse to the MyMobileService.json file. The file is
located in your workspace folder in \MyMobile\WebContent.
6. Click Close.
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.
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.
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.
20. Click on the Design tab and expand the Events tab at the bottom of the page.
22. Click on the Data tab and expand the Events tab at the bottom of the page.
1. In the Server view in Developer Studio, right click restmgr1 and choose Start.
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.”
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.
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.
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.
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.
2. Check the JavaScript associated with the Load event of the home page.
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.
General
Open the Windows Firewall and make sure port 8980 is open.
This chapter describes options and procedures for starting Mobile development and
creating and testing Mobile services, as follows:
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.
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.
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):
• 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.
For more information on getting started with the Mobile App Builder, see
Chapter 4, “Creating Mobile Apps using JSDOs.”
Before configuring and managing OpenEdge servers from Developer Studio, you need
to configure a connection to OpenEdge Explorer or OpenEdge Management.
1. From the main menu, select Window→ Preferences. The Preferences window
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.
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 installs with default instances for some servers that are appropriate for
Mobile development:
• 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.
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.
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.
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.
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.
• 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.
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.
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.
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.
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.
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).
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.
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.
Built-in
operation Prescribed ABL parameter list1
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.
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( )
USING Progress.Lang.*.
CLASS dsCustomer:
{"dsCustomer.i"}
END METHOD.
END METHOD.
END METHOD.
/* 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.
*/
FINALLY:
BUFFER eCustomer:DETACH-DATA-SOURCE().
RETURN.
END FINALLY.
END METHOD.
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.
Following is the dsCustomer.i include file for the simple Business entity class.
• 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.
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.
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.
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.
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.
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.
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.”
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]
• 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.
/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.
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:
For more information on logging into a Mobile Web Application from a Mobile App, see
Chapter 4, “Creating Mobile Apps using JSDOs.”
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.
/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:
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.
– Create — POST
– Read — GET
– 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)
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.
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).
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:
• JSDO overview
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.
• 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.
• 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).
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.
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.”
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.
• Properties of a JSDO
• 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.
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.
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.”)
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
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 ) { ... } );
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:
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.
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:
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.
These methods are always called on the JSDO and execute asynchronously.
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”)
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.
These methods are called on a JSDO table reference and always execute
synchronously.
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.
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.
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.
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.
So, each asynchronous method has a set of unique 'before*' and 'after*' events
defined to fire for it as follows:
• fill( ):
• saveChanges( ):
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.
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.
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.
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.”
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.
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
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”.
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).
• 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.
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.
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.”
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.
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 ...
}
} ]
}
});
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.
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.
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.
The ABL routine associated with a read operation must have the following signature:
DATASET dsOrderEntry:FILL( ).
BUFFER ttCustomer:DETACH-DATA-SOURCE( ).
RETURN.
END METHOD.
The following example illustrates calling fill( ) on the JSDO to load records from the
database into local storage:
• 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.
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.
If an error occurs on the server, the record is automatically deleted from the
JSDO’s local storage.
The signature of the ABL routine associated with a create operation must have a
DATASET or TABLE input-output parameter.
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);
<...>
dsOrderEntry.saveChanges();
• 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.)
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.
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.
If an error occurs on the server, the record automatically reverts to its original
state in the JSDO’s local storage.
The signature of the ABL routine associated with an update operation must have a
DATASET or TABLE input-output parameter.
The following example illustrates calling assign( ) on a table reference in the JSDO
to update a record:
/* subscribe to event */
dsOrderEntry.subscribe('afterUpdate', onAfterUpdate);
Delete operation
To delete an existing record from local storage on the client, you call the remove( )
method.
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.
The signature of the ABL routine associated with a delete operation must have a
DATASET or TEMP-TABLE INPUT-OUTPUT parameter.
/* subscribe to event */
dsOrderEntry.subscribe('afterDelete', onAfterDelete);
• Calls findById( ) to retrieve the record to be deleted, and then calls remove( )
on this JSRecord object.
/* subscribe to event */
dsOrderEntry.subscribe('afterSaveChanges', onAfterSaveChanges);
dsOrderEntry.saveChanges();
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];
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 */
}
}
}
};
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.
The following example shows a method that might be designated as an invoke method,
which can be called on the JSDO:
END METHOD.
dsOrderEntry.subscribe('afterInvoke', 'GetCreditInfo',
onAfterInvokeGetCreditInfo);
dsOrderEntry.GetCreditInfo ( { piCustNum : 10 } );
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 */
}
}
}
};
However, you need to gather some information to determine how best to configure and
code the user login sequence.
• The Web server authentication model that the Mobile Web application will
use:
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.”
• 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:
• 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.
• /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.
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.
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.
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.
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
• iUI
• User interface based on HTML and JavaScript where list views are built directly
using the <li> element
Note: For complete information on the methods of the UIHelper class, see
Appendix C, “OpenEdge JavaScript Class Properties, Methods, and Events
Reference.”
<!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>
var customers;
var uihelper;
var forminitialized = false;
$(document).ready(function() {
var session = new progress.data.Session();
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.
• 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( ):
• Call progress.ui.UIHelper.setFieldTemplate( ).
Alternatively, you can define the layout for the detail page using HTML instead of
calling getFormFields( ).
<div data-role="fieldcontain">
<label for="{__name__}">{__label__}</label>
<input id="{__name__}" name="{__name__}" placeholder="" value=""
type="text" />
</div>
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>'
});
For example:
progress.ui.UIHelper.setItemTemplate('<li data-id="{__id__}"><a
href="#{__page__}" >{__format__}</a></li>');
progress.ui.UIHelper.setFieldTemplate('<input id="{__name__}"></input>');
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.”
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.
• Deployment overview
• Security considerations
Deployment overview
There are three options for packaging and deployment of a Mobile App:
• iOS App
• Android App
Table 3 lists the terminology used in this chapter to describe the considerations for
deployment of different types of mobile applications.
Term Description
Mobile Web The Mobile App and/or Mobile services deployed to a web server
application
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)
1. In Developer Studio, right-click on the name of your project in the Project Explorer
view and choose Export→ Mobile Web Application.
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.
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.
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.
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.
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.
c. Click Upload a file and locate the certificate. Once the upload is complete,
click Back to files list.
c. Click Upload a file and locate the provisioning profile. Once the upload is
complete, click Back to files list.
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.
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.
https://developer.apple.com/devcenter/ios/index.action
Apple Developer
https://developer.apple.com/programs/register/
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
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
https://developer.apple.com/ios/manage/overview/index.action
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.
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#
http://developer.apple.com/library/ios/#technotes/tn2250/_index.html
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.
6. The launcher icon is the visual representation of your app on the mobile device.
To upload an icon:
c. Click Upload a file and locate the icon file. Once the upload is complete, click
Back to images list.
e. Click Upload a file and locate the provisioning profile. Once the upload is
complete, click Back to files list.
b. Click Upload a file and locate the Keystore. Once the upload is complete,
click Back to files list.
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.
During development, there are several ways to get the newly created APK on an
Android device for testing. One
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.
http://developer.android.com/index.html
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 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
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.
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
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.)
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.
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.
• 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.
• 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.
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.
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.
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.
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.
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) 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.
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.
The following sections present a brief description of JavaScript data types and how
they map to data types in 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.
The data type of a primitive value is determined by the format of the value:
• 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.
Non-standard
data type Representation
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:
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.
CHARACTER String
CLOB1 String
COM-HANDLE Number
DECIMAL Number
HANDLE Number
INT64 Number
INTEGER Number
LONGCHAR3 String
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.
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
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)
Methods
Table 9: JSRecord object methods
Brief description
Member (See also the reference entry)
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)
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.
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.
Syntax
events : {
'event' : [ {
[ scope : object-ref , ]
fn : function-ref
} ] [ ,
'event' : [ {
[ scope : object-ref , ]
fn : function-ref
} ] ] ...
}
event
object-ref
function-ref
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:
});
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
Brief description
Member (See also the reference entry)
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.
Brief description
Member (See also the reference entry)
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
Brief description
Member (See also the reference entry)
assign( ) method (JSDO Updates field values for the specified temp-table
class) 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
Events
Table 13: progress.data.JSDO events
Brief description
Member (See also the reference entry)
The JSDO can subscribe to the events listed in Table 13 in either of two ways:
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:
function onAfterFill() {
uihelper.eCustomer.clearItems();
jsdoOrderEntry.eCustomer.foreach(function(jsrecord) {
uihelper.eCustomer.addItem();
});
uihelper.eCustomer.showListView();
}
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
record
• jsdo.table-ref
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
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
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)
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.
Properties
Table 15: progress.data.Session properties
Brief description
Member (See also the reference entry)
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
Methods
Table 16: progress.data.Session class-instance methods
Brief description
Member (See also the reference entry)
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:
// create Session
pdsession = new progress.data.Session();
// 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' } );
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
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 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
Methods
Table 18: progress.ui.UIHelper class-level methods
Brief description
Member (See also the reference entry)
setItemTemplate( ) method Specifies the format for items in all list views
created during the JavaScript session
Brief description
Member (See also the reference entry)
assign( ) method (UIHelper Updates the working record in JSDO local storage
class) with the values currently displayed on the detail
page form
Brief description
Member (See also the reference entry)
setDetailPage( ) method Specifies the HTML page that contains the form in
which item details are displayed
Example The sample Mobile app shown below is followed by the code for its index page
(index.html) and client logic (customers.js):
var customers;
var uihelper;
var forminitialized = false;
$(document).ready(function() {
var session = new progress.data.Session();
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 •
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)
See also fill( ) method, invocation method, progress.data.JSDO class, saveChanges( ) method
• add( ) method
• addCatalog( ) method
• addItem( ) method
• addRecords( ) method
• afterCreate event
• afterDelete event
• afterFill event
• afterInvoke event
• afterSaveChanges event
• afterUpdate event
• async property
• authenticationModel property
• batch property
• 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
• 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
• unsubscribe( ) method
• useRelationships property
• userName property
• xhr property
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.
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.
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:
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.
Syntax
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
cat-user-name
cat-password
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:
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:
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}' )
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.
Syntax
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.
{
dsCustomerOrder: {
eCustomer: [
// Record objects ...
],
eOrder: [
// Record objects
]
}
}
{
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:
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" ]
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:
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].
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.
The following parameters appear in the signature of the event handler function:
Syntax
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.
Example:
/* subscribe to event */
myjsdo.subscribe('afterCreate', onAfterCreate);
. . .
myjsdo.saveChanges();
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.
The following parameters appear in the signature of the event handler function:
Syntax
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.
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();
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.
The following parameters appear in the signature of the event handler function:
Syntax
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();
};
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.
The following parameters appear in the signature of the event handler function:
Syntax
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);
}
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 */
}
}
}
};
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.
The following parameters appear in the signature of the event handler function:
Syntax
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
request
A reference to the request object returned after all requested operations complete.
For more information, see the description of the request object.
Example:
/* subscribe to event */
myjsdo.subscribe('afterSaveChanges', onAfterSaveChanges);
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];
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 */
}
}
}
};
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.
The following parameters appear in the signature of the event handler function:
Syntax
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.
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();
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.
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
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:
$('#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.
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.
async property
A Boolean that indicates, if set to true, that the Mobile operation was executed
asynchronously on the Mobile App.
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
authenticationModel property
A string constant that specifies the type of authentication that the server requires from
the Mobile App. Valid values are:
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.
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.
Access: Read-only
Applies to: request object
This request object property is available only for the following events:
• afterSaveChanges
• beforeSaveChanges
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.
The following parameters appear in the signature of the event handler function:
Syntax
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);
. . .
myjsdo.saveChanges();
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.
The following parameters appear in the signature of the event handler function:
Syntax
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();
};
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.
The following parameters appear in the signature of the event handler function:
Syntax
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();
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.
The following parameters appear in the signature of the event handler function:
Syntax
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);
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.
The following parameters appear in the signature of the event handler function:
Syntax
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);
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.
The following parameters appear in the signature of the event handler function:
Syntax
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 );
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.
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.
clearItems( ) method
Clears the items from a list view.
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.
data property
An object containing the data for a temp-table record associated with a JSRecord
object.
Access: Read-only
Applies to: JSRecord object
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)
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.
Syntax
[table-ref.]display ( )
table-ref
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:
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.
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:
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
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.fill();
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.
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
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.
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.
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.
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.
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:
$('#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.
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.
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.
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.
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.
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
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.
Your funcRef can terminate the foreach( ) loop be returning false. If the
function does not return false, the loop continues.
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:
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.
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.
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.
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
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:
getFormRecord( ) method
Returns a JSRecord object for the record shown on the form on the detail page.
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.
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.
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
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.
getListViewRecord( ) method
Returns a JSRecord object for a specified item in a list view.
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
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.
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.
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.
Syntax
op-name
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
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
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.
This request object property is available only for the following events:
• afterCreate
• afterDelete
• afterUpdate
• beforeCreate
• beforeDelete
• beforeUpdate
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.
Syntax
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.
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
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:
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.
• 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.”
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.
loginHttpStatus property
Returns the specific HTTP status code returned in the response from the most recent
login attempt on the current Session object.
Access: Read-only
Applies to: progress.data.Session class
See also: login( ) method
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.
Access: Read-only
Applies to: progress.data.Session class
Possible login return values include the following numeric constant values:
For a more specific status code returned in the HTTP response, you can check the
value of the loginHttpStatus 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".
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.
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.
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:
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.
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.
Access: Writable
Applies to: progress.data.JSDO class
Note: To set this property, you must pass its value to the JSDO constructor.
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.
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
params
• verb — The HTTP operation (GET, PUT, etc.) to be performed by the request.
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:
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.
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
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.
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.
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
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:
$('#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.
response property
Returns an object whose properties contain data from a Mobile built-in or invoke
operation executed on the AppServer.
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 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
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
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.
After execution, the working record for each temp-table referenced by the JSDO is not
set.
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
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 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.
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:
$('#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.
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.
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.
• 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:
// 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");
CustomerSvc /SportsApp/rest/CustomerSvc
ItemSvc http://itemhost:8080/SportsApp/rest/ItemSvc
Note: To return a corresponding list of URIs for the loaded JSDO catalogs, read the
catalogURIs 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.
Access: Read-only
Applies to: progress.data.Session class
See also: loginTarget property, login( ) method
setDetailPage( ) method
Specifies the HTML page that contains the form in which item details are displayed.
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
• name — The id propety of the HTML div (or other) element that contains the
form page
For example:
uiHelper.eCustomer.setDetailPage({
name: 'cust-detail-page',
fieldTemplate: '<input id="{__name__}"></input>'
});
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.
Syntax
progress.ui.UIHelper.setFieldTemplate( ‘string’)
string
An HTML string.
• 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:
As shown in the preceding example, the template uses the following substitution
parameters:
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( ).
Syntax
progress.ui.UIHelper.setItemTemplate( ‘string’)
string
An HTML string.
• 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:
As shown in the preceding example, the template uses the following substitution
parameters:
setListView( ) method
Defines a list view for a given table.
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
• 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.
• 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
});
showListView( ) method
Displays the specified table’s list view on the Mobile App device or browser.
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.
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.
Syntax
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.
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).
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.
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.
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:
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.
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.
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.
Syntax
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
• 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
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).
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.
userName property
Returns the user ID passed as a parameter to the most recent call to the login( )
method on the current Session object.
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.
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.
Access: Read-only
Applies to: request object
This request object property is available only for the following events:
• afterCreate
• afterDelete
• afterFill
• afterInvoke
• afterUpdate