In 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, you have two tasks:
- To write non-generated JavaScript
- 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.
When you write the JavaScript,
you 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.
The current topic describes the use of egl.defineClass.
For details on defining a new widget, see Extending the Rich UI
widget set.
Structuring your general-use JavaScript code
If
you are making general logic available —for example, a random number
generator—place your JavaScipt file in a subdirectory of the WebContent
folder. The file invokes the JavaScript function
egl.defineClass.
Here is the outline:
egl.defineClass(
'packageName', 'className',
'superclassPackageName', superclassName,
{
"constructor": function()
{ },
"otherFunction": function(parameterList)
{ }
}
);
The italicized details are as follows:
- packageName
- The name of the package in which the EGL external type will reside.
The package name is case sensitive and is required.
- className
- An identifier that you are assigning as the JavaScript class
name. The class is a predefined collection of functions, and 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; and
if you specify this value, you must also specify superclassName.
- 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; and if you specify this
value, you must also specify superclassPackageName.
- parameterList
- 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 any 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 file RandomNumberGenerator.js,
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);
}
}
);
Writing the external type
In relation to JavaScript, the EGL External Type stereotype
is
JavaScriptObject, as shown in the following
example:
package randomNumber;
import com.ibm.egl.rui.JavaScriptObject;
import com.ibm.egl.rui.JavaScriptProperty;
ExternalType RandomNumberGenerator type JavaScriptObject
{
relativePath = "randomnumber",
javaScriptName = "RandomNumberGenerator"
}
upperLimit int {@JavaScriptProperty{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
part-level properties:
- relativePath
- The location of the JavaScript file
in relation to the WebContent folder.
- javaScriptName
- The name of the JavaScript file.
- includeFile
- Identifies other CSS, JavaScript,
or HTML 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,
as described in
Extending the Rich UI widget set with DoJo:
<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 runtime.
As shown in the example of an external type,
a field in that type can include the following field-level property:
- @JavaScriptProperty
- This complex property is required if you want to access, from
your EGL code, a JavaScript global field (a
field of the form this.myField). 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,
@JavaScriptProperty 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 { @JavaProperty{} };
The
property fields in
@JavaScriptProperty 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 that 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.
Relationship of EGL and JavaScript data
types
Table 1. EGL and JavaScript data
typesEGL 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 with 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. It 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 once 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 containing the desired value for the BigDecimal. Numbers
in String form must have at least one digit and might not contain
a blank. They might have a leading sign, might have a decimal point,
and might 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 ) -- The parameter obj is any object. 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. Returns false is the argument is not a BigDecimal, or is
a BigDecimal with a different value or scale.
- 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.