With EGL, your Rich UI application can access
non-generated JavaScript™.
You might be making general logic available—for example, to provide
a random number generator—or you might be referencing a non-EGL widget—for
example, to allow use of a Dojo widget inside your code.
In either case, your tasks are twofold:
- To develop an EGL external type that makes the JavaScript logic available to a Rich UI
application. The JavaScript is
said to be the implementation of the external type.
- To write a non-generated JavaScript class,
unless the external type references a built-in JavaScript class such as Math or Number.
If your external type is implemented by a JavaScript source file, the next statements
apply:
- When you define the external type, set the relativePath property,
which indicates the location of the JavaScript source file in relation to
the WebContent folder.
- When you write the JavaScript code,
do as follows:
- Invoke an EGL-specific function, whether egl.defineClass,
for general logic, or egl.defineWidget,
for a widget definition. In each case, the JavaScript is solely for use by EGL and
is likely to be invoking other JavaScript that
is available to you.
- Ensure that the name of the JavaScript source
file is the same as the JavaScript class
name and that the source-file extension is .js.
If your external type is implemented by a built-in JavaScript class, do not set the relativePath property
of the external type.
Regardless of how you implement the external type, if the name
of the JavaScript class
is different from the name of the external type, you must set the javaScriptName property
to the name of the class.
To avoid errors at run time, avoid using multiple versions of the
same runtime library in a given Rich UI application.
This topic describes the use of egl.defineClass.
For details about defining a new widget, see “Extending the Rich UI
widget set.”
Structure of general-use JavaScript code
If you are making
general logic available—for example, a random number generator—place
your JavaScript file in
a subdirectory of the WebContent folder. The file invokes the
egl.defineClass JavaScript function:
egl.defineClass(
'packageName', 'className',
'superclassPackageName', superclassName,
{
"constructor": function()
{ },
"otherFunction": function(parameterList)
{ }
}
);
The parameters are as follows:
- packageName
- The name of the package in which the custom JavaScript resides. The package name
is required, is case sensitive, and identifies the WebContent subfolder.
Include dots in place of a forward slash for every subfolder under
the first. For example, if your JavaScript is
in the WebContent/myPkg/test folder, the packageName
value is myPkg.test.
- className
- An identifier that you are assigning as the JavaScript class name. The class is a
predefined collection of functions. The name must be the name of the
EGL external type JavaScriptName property,
which defaults to the name of the external type. The class name is
case sensitive and is required.
- superclassPackageName
- Optional. The name of the package in which the EGL external type
for a super class resides. The package name is case sensitive. If
you specify this value, you must also specify the superclassName value.
- superclassName
- Optional. The name of a super class, which is also the name of
an EGL external type that makes the superclass available to EGL source
code. The superclass name is case sensitive. If you specify this value,
you must also specify superclassPackageName value.
- otherFunction
- A function that is in addition to the one named "constructor,"
which is described later. You can specify any number of additional
functions.
- parameterList
- A list of function parameters
The function named "constructor" is optional
and, if present, runs as soon as you declare an EGL variable of the
external type. That function cannot have parameters and can be in
any position in the list of functions.
You can define multiple
classes in a single JavaScript file,
but the convention is to include only one class, with the same name
as the file. For example, here is the code in the
RandomNumberGenerator.js file,
which makes available a random number generator:
egl.defineClass(
'randomNumber', 'RandomNumberGenerator',
{
"constructor" : function()
{
this.upperLimit = 100;
},
"setUpperLimit" : function(limit)
{
this.upperLimit = limit;
},
"getUpperLimit" : function()
{
return this.upperLimit;
},
"generateRandomNumber" : function()
{
return Math.floor(Math.random()*this.upperLimit);
}
}
);
The external type stereotype
In relation
to JavaScript, the EGL
External type stereotype is
JavaScriptObject,
as shown in the following example:
package client;
ExternalType RandomNumberGenerator type JavaScriptObject
{
relativePath = "randomnumber",
externalName = "RandomNumberGenerator"
}
upperLimit int {@Property{getMethod = "getUpperLimit",
setMethod = "setUpperLimit"}};
function generateRandomNumber() returns(int);
end
The external type can include the
extends clause,
to reference an external type that represents a super class, as in
the following example outline:
ExternalType MyType extends OtherType type JavaScriptObject
end
The external type also can include the following
type-level properties, each of which takes a string:
- relativePath
- The location of the JavaScript file
in relation to the WebContent folder. The property setting is optional.
If the JavaScript file
is stored directly in the WebContent folder and not in a subfolder,
set the relativePath property to an empty
string. In any case, do not include a file name in the property value.
When
the external type is implemented by a JavaScript file, you must set the relativePath property.
When the external type is implemented by a built-in class, do not
set the property.
- externalName
- Specifies the name of the JavaScript class.
Do not specify the file extension .js, which
is assumed.
The property setting is optional. If you do not specify
a value, the name of the JavaScript class
is assumed to be the name of the external type.
You might use
the
externalName property to access a JavaScript class for which
the name is an EGL reserved word. For example, the following external
type makes possible the access of a JavaScript class named
add,
which is in the
WebContent/part1/part2/add.js file:
ExternalType SumType type JavaScriptObject
{relativePath = "part1/part2", externalName = "add" }
;
end
- includeFile
- Identifies an HTML file or other CSS or JavaScript files that are made available
at run time. The path specified in includeFile is
relative to the WebContent directory. An example is "JS/myFile.js".
The
following file might be used if you were using the external type to
reference a Dojo widget:
<script type="text/javascript" src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js">
</script>
<style type="text/css">
@import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/dijit.css";
@import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
@import "http://o.aolcdn.com/dojo/1.0.0/dojo/resources/dojo.css"
</style>
<script>
dojo.require("dijit.form.Button");
dojo.require("dijit.form.Slider");
</script>
That file loads the Dojo widget library
and Dojo CSS files and starts the Dojo run time.
As shown in the example of an external type,
a field in that type can include the following field-level annotation:
- Property
- This annotation is required if you want to access, from your EGL
code, a JavaScript global
field (a field of the form this.myField). If you
want to assign a value from your EGL code, the JavaScript must define the field in the
function named "constructor". However, you can retrieve a value from
the JavaScript field regardless
of where the field is defined in the JavaScript.
In general,
Property identifies JavaScript functions that
get and set the JavaScript field
value. You can use this property without specifying function names
if the names of the functions are built with the word
get or
set followed
by the variable name. For example, if the variable is
UpperLimit and
the JavaScript class includes
functions named
getUpperLimit() and
setUpperLimit(),
you only need to add the complex property, as in this example:
UpperLimit INT { @Property{} };
The
fields in the
Property are as follows:
- getMethod
- A string (enclosed in quotation marks) containing the name of
the get method for the specified variable (do not include parentheses).
The method has no parameters, and its return value has the same type
as the field.
- setMethod
- A string (enclosed in quotation marks) containing the name of
the set method for the specified variable (do not include parentheses).
The method has one parameter that has the same type as the field.
By convention the setMethod does not have a return value, but no error
condition results if the method returns a value.
If you specify only one of the two property
fields, EGL assumes that the unspecified function is not available.
An error does not occur unless an expression causes invocation of
the function that is assumed to be missing.
JavaScript field names are case sensitive,
as is the field name in the external type.
Note: After you make any change to the JavaScript
file, you must re-save the corresponding EGL external type and then
refresh the Rich UI handler that uses the external type. The requirement
is a consequence of the generator's use of Asynchronous Module Definition
(AMD) technology, which improves runtime performance.
Relationship of EGL and JavaScript data types
Table 1. EGL and JavaScript data
types
EGL type |
JavaScript type
(case-sensitive) |
STRING |
String |
BOOLEAN |
Boolean |
SMALLINT, INT, FLOAT, SMALLFLOAT |
Number |
BIGINT, DECIMAL, MONEY, NUM |
egl.javascript.BigDecimal (as described in a
later section) |
DATE, TIME, TIMESTAMP |
Date |
EGL arrays are passed to JavaScript as JavaScript arrays. If an EGL type (such
as an array) is set to null, the JavaScript code
receives a JavaScript null.
egl.javascript.BigDecimal
The supplied JavaScript class egl.javascript.BigDecimal
can precisely represent numbers that have a very large number of digits.
This class also has methods for performing mathematical operations
with BigDecimals.
The native numeric type in JavaScript is the Number class, which
is a floating-point representation of numbers. The class is imprecise
and cannot represent many values. Rounding errors might occur when
you do math with values of the Number class.
A BigDecimal
object cannot be changed after it has been created. For example,
to add two BigDecimal values, write the code as follows:
var result = bigDecimal1.add( bigDecimal2 );
The
result is lost if you write the code as follows:
bigDecimal1.add( bigDecimal2 );
The
egl.javascript.BigDecimal constructor takes one argument, which is
a String that contains the wanted value for the BigDecimal. Numbers
in String form must have at least one digit and cannot contain a blank.
They can have a leading sign, can have a decimal point, and can be
in exponential notation. Here are some valid arguments:
- "0"
- "12"
- "-76"
- "12.70"
- "+0.003"
- "17."
- ".5"
- "4E+9"
- "0.73e-7"
Here are JavaScript methods
that use objects of egl.javascript.BigDecimal (such objects are identified
as
bd, and Number objects are identified as
n):
- abs() returns the absolute value of the BigDecimal
- add(bd) returns the sum of the current object and the argument.
- compareTo(bd) returns -1 if the current object is less
than the argument, 1 if the current object is greater than the argument,
or 0 if they are equal.
- divide(bd) returns the result of dividing the current object
by the argument.
- divideInteger(bd) returns the integer part of the result
of dividing the current object by the argument.
- equals(obj) returns true if the argument, which can be
any object, is a BigDecimal with the same value and scale (number
of decimal digits) as the current object. This method returns false
if the argument is not a BigDecimal, or is a BigDecimal with a different
value or scale. The obj parameter is any object.
- max(bd) returns the current object or the argument, whichever
is greater.
- min(bd) returns the current object or the parameter, whichever
is smaller.
- movePointLeft(n) returns a BigDecimal that is equivalent
to the current object (a Number), but with the decimal point shifted
to the left by the specified number of positions.
- movePointRight( n) returns a BigDecimal that is equivalent
to the current object (a Number), but with the decimal point shifted
to the right by the specified number of positions.
- multiply(bd) returns the result of multiplying the current
object by the argument.
- negate() returns the negation of the current object.
- pow(bd) returns the result of raising the current object
to the specified power. The power must be in the range -999999999
through 999999999 and must have a decimal part of zero.
- remainder(bd) divides the current object by the argument
and returns the remainder.
- setScale(n, mode) returns a BigDecimal with the
given scale (number of decimal digits). The argument n is
a Number, and the optional argument mode is a constant, as
described later.
If
n is larger than the current scale, the
method adds trailing zeros to the decimal part of the number. If
n is
smaller than the current scale, the method removes trailing digits
from the decimal part of the number, and
mode indicates how
to round the remaining digits. Here are the possible values of
mode:
- The default (egl.javascript.BigDecimal.prototype.ROUND_UNNECESSARY)
indicates that no rounding is necessary.
- egl.javascript.BigDecimal.prototype.ROUND_CEILING causes rounding
to a more positive number.
- egl.javascript.BigDecimal.prototype.ROUND_DOWN causes rounding
toward zero.
- egl.javascript.BigDecimal.prototype.ROUND_FLOOR causes rounding
to a more negative number.
- egl.javascript.BigDecimal.prototype.ROUND_HALF_DOWN causes rounding
to the nearest neighbor, where an equidistant value is rounded down.
- egl.javascript.BigDecimal.prototype.ROUND_HALF_EVEN causes rounding
to the nearest neighbor, where an equidistant value is rounded to
the nearest even neighbor.
- egl.javascript.BigDecimal.prototype.ROUND_HALF_UP causes rounding
to the nearest neighbor, where an equidistant value is rounded up.
- egl.javascript.BigDecimal.prototype.ROUND_UP causes rounding away
from zero.
- scale() returns the number of digits after the decimal point,
as a Number.
- signum() returns -1 if the number is negative, zero if the number
is zero, and 1 if the number is positive.
- subtract(bd) returns the result of subtracting the parameter
from the current object.
- toString() returns a String representation of the BigDecimal object.
The following constants are also defined by BigDecimal:
- egl.javascript.BigDecimal.prototype.ZERO is BigDecimal with the
value zero.
- egl.javascript.BigDecimal.prototype.ONE is a BigDecimal with the
value one.
- egl.javascript.BigDecimal.prototype.TEN is a BigDecimal with the
value ten.
JavaScriptObjectException
If a non-generated JavaScript function is invoked
by way of an external type and if the function throws an error, the
invocation causes an EGL JavaScriptObjectException.
Like every EGL exception, the JavaScriptObjectException has message and messageID fields.
If
a JavaScript error object
is caught, the message field is set from
the equivalent field of the error object. Otherwise, the message field
receives a string that is equivalent to the value thrown by the JavaScript function.
Here
is the additional field in
JavaScriptObjectException:
- name
- If a JavaScript error
object is caught, the name field is set
from the equivalent field of the error object. Otherwise, the name field
receives an empty string.