Our first example is a Scriptlet with a user interface. All it does is appear to 'type' a message onto the screen. The main page contains a text box and buttons that can be used to control the Scriptlet:
You can run or download this page, typetext.htm
, from our Web site at http://rapid.wrox.co.uk/books/0707
.
The Scriptlet itself is a Dynamic HTML page, which produces white mono-spaced text on a black background:
<html>
<head>
<script language=jscript>
...
... script goes here
...
</script>
<style>
BODY {background-color:black; color:white; font-family:"Courier New",Monospace;
font-size:12pt; font-weight:bold}
</style>
</head>
<body>
<div id=objDiv style="position:absolute; top:5; left:5; width:100; height:100">
<p id=objPara></p>
</div>
</body>
</html>
The main page, typecomp.htm
, that uses this Scriptlet contains all the descriptive text, instructions, text box, and buttons. It also contains a <OBJECT>
tag that inserts the Scriptlet page typetext.htm
:
<html>
<head>
<title>Using Visible Scriptlet Components</title>
</head>
<body onload="startCode()">
<h3>Using Visible Scriptlet Components</h3>
<object id=myTypist width=400 height=100 type="text/x-scriptlet"
data="typetext.htm" style="position:relative;">
</object>
...
... rest of page goes here
...
</body>
</html>
As you can see, the Scriptlet simply contains standard HTML that the IE4 parsing engine can display within the window defined by the <OBJECT>
tag in the main (original) page.
Of course, to be able to manipulate the Scriptlet, the original page has to have a way of accessing it. Scriptlets define an interface, which the page that contains them can use to reference the public properties, methods and events supported by the Scriptlet – in the same way as it would with any other ActiveX control.
A property is simply a variable within the control. Any variable that has public_
prefixing the variable name will be exposed as a property that can be accessed by the scriptlet's container. This is the easiest way to declare a property and set the default value of it:
<script language=jscript>
//public property variables
public_property1 = "Hello"
If you have any experience programming controls for Windows, then you know that COM also allows us to define a function that behaves like a property. This is especially useful if we need to perform input validation or other calculations before we set the value inside the control. The Scriptlet architecture allows us to declare a function for the put
and get
operations of a property. When the code in the container tries to place a value into a property, it calls the function that has public_put_
prefixing the property name – for example, here is the definition for a property named roomSize
:
//private internal 'member' variable
var m_roomSize = 0
function public_put_roomSize(newvalue)
{
if ((newvalue > 0) & (newvalue < 99)) m_roomSize = newvalue
}
The variable m_roomSize
is a private internal variable that will be used inside the Scriptlet's code sections. It cannot be accessed from outside the Scriptlet, and so can only be set using the public_put_roomSize
function (i.e. the roomSize
property). This allows us to validate the new value proposed by the user and reject any unsuitable ones, as we've done in the code above.
Likewise, when the code in the container tries to get
the value of a property, it calls the function that has public_get_
prefixing the property name. In this case, we can just return the value of the internal variable m_roomSize
:
function public_get_roomSize()
{
return m_roomSize
}
By providing both the put
and get
functions, we produce a property that is read/write to the outside world. If we want our property to be read-only or write-only, we define just the put
or the get
function, as appropriate.
Keep in mind also that we can only define a property using one of the two outline methods we've discussed here. If we use the put
and get
functions method then we cannot have a variable in our Scriptlet which has public_
prefixing a property name that we are also using for the put
and get
functions.
A method is declared simply by adding the prefix public_
to the name of the function or subroutine that carries out the method:
function public_rollsOfWallpaper(intLengthEach)
{
... some code to calculate the result ...
intNumberOfRolls = ...
return intNumberOfRolls
}
Any functions or variables within our Scriptlet not named with the public_
prefix will only be accessible to code within the Scriptlet, and not from the containing page. Like all routines, we can pass values into the routine as parameters (such as intLenghtEach
above), and we return the value, if there is one, just like we would from any other function. Of course, the function does not have to return a value if it's only required to carry out some direct action within the Scriptlet.
The interface of a Scriptlet can also be defined in another way, using the JavaScript public_declaration
object. We'll see how this is done later in the chapter. We'll also see how events are declared and implemented.
In the main (container) page, we can use the properties and methods of the Scriptlet just like we would with any other ActiveX control or integral HTML object:
MyScriptlet.roomSize = 42; 'set the roomSize property
alert(MyScriptlet.roomSize); 'retrieve the roomSize property
alert(MyScriptlet.rollsOfWallpaper(33)); 'call the rollsOfWallpaper method
Our Typing Scriptlet, typetext.htm
, provides four properties and one method:
messageText
(write only) is used to set the text of the message to be 'typed'.typeStatus
(read only) returns the current status of the 'typing' process.height
and width
(write only) are used to set the size of the typing area.stopTyping()
stops the current 'typing' process.
You can see how these properties and methods are defined by the interface in the code section below. This is the entire script section of the typetext.htm
Scriptlet:
<script language=jscript>
//private internal 'member' variables
var m_messageText = " ";
var m_typeStatus = "Idle";
//other internal variables
var timer = null;
var nPosition = 0;
var nLength = 0;
//--------------------------------------------
//put routine for text (write only)
function public_put_messageText(newString)
{
nPosition = 0;
if (newString.length > 0)
{
m_messageText = newString;
nLength = m_messageText.length;
timer = setInterval("typeText()", 200);
m_typeStatus = "Typing";
}
else
{
nLength = 0;
m_messageText = "";
clearInterval(timer);
document.all("objPara").innerHTML = "";
m_typeStatus = "Idle";
}
}
//-------------------------------------------
//get routine for typeStatus (read only)
function public_get_typeStatus()
{ return m_typeStatus }
//--------------------------------------------
//put routine for height (write only)
function public_put_messageHeight(newValue)
{
if ((newValue > 9) & (newValue < 1000))
document.all("objDiv").style.pixelHeight = newValue
else
alert("messageHeight must be between 10 and 999");
}
//--------------------------------------------
//put routine for width (write only)
function public_put_messageWidth(newValue)
{
if ((newValue > 9) & (newValue < 1000))
document.all("objDiv").style.pixelWidth = newValue
else
alert("messageWidth must be between 10 and 999");
}
//-------------------------------------------
// public method for the component
function public_stopTyping()
{
clearInterval(timer);
m_typeStatus = "Stopped";
}
//-------------------------------------------
//private internal routines
function typeText()
{
if (nPosition < nLength)
{
nPosition++;
document.all("objPara").innerHTML = m_messageText.substr(0, nPosition);
}
else
{
clearInterval(timer);
m_typeStatus = "Complete";
}
}
</script>
As you will be able to see from the code, the Scriptlet works by using the setInterval
method of its own window
object, and simply changing the text that is displayed in the <DIV>
tag objDiv
each time the interval occurs. At the same time, it sets appropriate values for the internal m_typeStatus
variable, which provides the read-only typeStatus
property. This simple example should prove that the architecture of scriptlets is relatively simple, and indicate how they allow us to create custom client-side controls quickly and easily.
So, using scriptlets is as simple as using an ActiveX control. All we have to do is place an <OBJECT>
tag within our HTML page that will contain the Scriptlet, and then we can use the scriptlet just as we would use any other ActiveX control:
<object id=myTypist width=400 height=100 type="text/x-scriptlet"
data="typetext.htm" style="position:relative;">
</object>
The only differences between a scriptlet <OBJECT>
tag, and an <OBJECT>
tag that defines an ActiveX control, are the values of the type
and data
attributes, and the lack of a ClassID
(or GUID). The type
attribute defines the MIME type that Internet Explorer should use when parsing the Scriptlet code; the MIME type for scriptlets is "text/x-scriptlet"
. The data
attribute defines the location of the scriptlet code, as a standard URL. This is similar to the codebase
attribute used for ActiveX controls.
Notice that there are no parameters declared using <PARAM>
tags. This is because scriptlets do not currently support parameters, however Microsoft is working on adding support for parameter tags for a future release of Internet Explorer.