Building Components from Web Pages

by Rick Dobson

Fortunately for developers, Microsoft continues to embellish the functionality of Internet Explorer 4.0. Scriptlets, introduced in the latest version of IE 4.0, represent another significant feature enhancement that markedly upgrades the capability of developers to build customized solutions.

You may recall from our first treatment of this topic that scriptlets enable developers to build custom components with Dynamic HTML (DHTML). A scriptlet encapsulates DHTML code for re-use by you or others. These encapsulated DHTML components run inside another web page or any application that runs COM objects. The application that runs the scriptlet serves as a host for the encapsulated component.

This article reviews the basics of scriptlet architecture to give you a firm grasp of how to apply it in any situation. We'll describe two approaches for building scriptlets. Then we'll explore scriptlet functionality and reinforce one approach with a pair of custom scriptlets, each of which reveals how to activate scriptlets from a host. We'll close with a mention of how to pass events from scriptlets to a host.

An overview of scriptlets

A scriptlet is a web page that functions inside another web page or other COM object container, such as VB or Word. The power that DHTML delivers to Web-page development creates a special incentive for sharing its code in multiple situations. Scriptlets serve this precise function.

One way to portray the significance of scriptlets is to review briefly the functionality that DHTML delivers. First, there are the three D's: dynamic styles, dynamic content, and dynamic positioning. Recall that these factors allow you to change the style, content, and positioning of objects on a web page—on the fly. Filters and transitions add basic multimedia effects like those you can achieve with Power Point.

DirectAnimation is a subset of DirectX that lets DHTML developers easily create more elaborate multimedia effects. Finally, data binding lets you dynamically link web pages to data sources. Scriptlets allow you to put any combination of these features into a COM object with the simplicity of DHTML coding. This is the first time that Microsoft has given the power of COM programming to millions of HTML content developers.

Figure A shows the major architectural elements required for putting a scriptlet to work. The scriptlet itself is a web page. It typically contains some combination of exposed memory variables that represent expressions, property functions, or method functions. A property function can return the current value or set the current value for an object within a web page. Typically, a method function performs an action on an object within a web page. Exposed memory variables and functions offer a programming interface for manipulating a scriptlet's functionality.

A scriptlet can also contain unexposed memory variables and functions. Users can modify even unexposed object properties and methods so long as they offer a user interface, such as a button.

Figure A: This graphic shows the major architectural features of a scriptlet application.

Another web page or Win 32 application, such as a Word document, can serve as host. The host must have a scriptlet container object that points at the scriptlet. The container object references the scriptlet through a URL that points at the scriptlet. Code inside the host references the container object that represents the scriptlet in a web page.

The scriptlet container object permits developers to accomplish three tasks: First, developers can activate scriptlet functions. Second, developers can manage the appearance of a scriptlet in a host by setting its property values. Third, developers can determine how a host should interact with a scriptlet through an examination of its property values.

Two ways to design a scriptlet

There are two design strategies for building scriptlets. First, developers can create a Public_Description object. This JScript object provides runtime access to exposed properties and methods in a scriptlet. (At the time of this writing, there is no VBScript equivalent.) Second, you can use default naming conventions that work equally well in JScript and VBScript.

Both the Public_Description object and the default naming conventions offer benefits for developers. The Public_Description object has a couple of desirable attributes: It groups all the exposed expressions, property functions, and method functions in one area; and it offers alias naming for exposed properties and methods. Until Microsoft revises VBScript to offer a Public_Description object, the default naming conventions strategy has one important benefit: These conventions expose properties and methods in either JScript or VBScript. If Microsoft releases the Public_Description object in VBScript, this benefit goes away.

The Public_Description object has two parts—the declaration statement and the constructor function. The declaration statement creates the object and assigns a name to it. The constructor function defines names for exposed properties and methods. The following lines provide a generic layout for the specification of a Public_Description:

<SCRIPT LANGUAGE="JavaScript">
   var Public_Description = new CreateScriplet();

   Function CreateScriptlet(){
      // statements here define properties and methods
   }
</SCRIPT>

The constructor function has four basic statement types.  The first describes an exposed property based on an expression. Its syntax is the line

This.PropertyName = expression;

This function creates a read-write property. PropertyName represents the alias for the expression on the right.

Two additional statements can jointly or independently define a property. Both link the property definition to functions so developers can trigger an action when the property is set or read. The syntax for these statements is

This.get_PropertyName = function;
This.put_PropertyName = function;

The get_PropertyName function returns a property value, and the put_PropertyName function sets a property value. Using the statements together defines a read-write property. Using the get_PropertyName function by itself defines a read-only property, while inserting just the put_PropertyName function specifies a write-only property.

The final type of constructor statement defines a method. Methods perform an action, and the constructor statement references a method to accomplish the action. This statement's syntax is

This.method = methodFunction;

When defining exposed properties and methods with default naming conventions, always use a prefix to mark exposed expressions and functions. Use the public_ prefix for read-write properties that depend on an expression. Recall that you must use this approach with VBScript. Its syntax is

var public_PropertyName = expression

Use the public_ prefix as well when you define a method based on a function, like so:

function public_MethodName(param)

Note that the parameter is optional.

Property functions use either or both of these two prefixes: public_get_ and public_put_ with the syntax:

function public_get_PropertyName()
function public_put_PropertyName(param)

Use the public_get_ function by itself to create a read-only exposed property. The public_put_ function by itself creates a write-only property. The param argument for the public_put_ function lets a developer specify a value for setting the property. Using both functions together creates a read-write property.

Using a scriptlet in a host application

Using a scriptlet in a host application requires one or two steps. First, define a scriptlet container object by using either a single Object tag or a pair of Object tags bracketing PARAM tags. Then, you can reference the exposed properties and methods in the scriptlet. Use the ID for the scriptlet container object followed by a period and either the property or the method name.

The second step is required only if you want to define controls in the host that programmatically interact with the scriptlet. If the scriptlet exposes controls or it includes animation, such as a rotating logo, then you don't necessarily need the second step.

An Object tag for a scriptlet can require three attributes: ID, TYPE, and DATA. You must use the ID tag whenever you have to refer back to the scriptlet to reference an exposed property or method.

The TYPE attribute is essential. Set this attribute to "text/x-scriptlet". This setting identifies the object as pointing at a scriptlet. The DATA attribute references the location for the scriptlet. This attribute will generally take the form:

http://servername/scriptletfilename.htm

When the scriptlet is in the same folder as its host application, you can simply reference the scriptlet's file name. If you use PARAM tags inside an Object block, then set the value for the PARAM named URL to the scriptlet's location.

There are four variations for programmatically referring to a scriptlet's exposed methods and properties. These variations are the same no matter which method a developer uses to define a scriptlet. Table A summarizes the syntax. Scriptlet1 designates a scriptlet's object ID setting, and X is a value that the host accepts from the scriptlet or sends to the scriptlet.

Table A: Syntax for referencing a scriptlet in a host application

For Syntax
Expression X = Scriptlet1.PropertyName
Scriptlet1.PropertyName = X
Property Get Function X = Scriptlet1.PropertyName
Property Put Function Scriptlet1.PropertyName = X*
Method Scriptlet1.Method
X* designates property value

Two sample scriptlets

Now let's look at a couple of sample scriptlets that build on one another. They show progressively more complicated scriptlet functionality. Both samples complement and extend those in last month's scriptlet article, "Scriptlets: A New and Powerful Way to Web Computing" (January 1998), and at the SBN Scriptlets Gallery  You can download the scriptlets from the address

 http://www.microsoft.com/gallery/files/scriptlets/

Our first sample illustrates how to use a scriptlet with no exposed properties or methods. The second demonstrates how to use exposed methods. The other examples demonstrate how to create and use exposed properties. In combination, these resources illustrate the full range of options for using scriptlets on web pages.

Figure B shows a scriptlet inside a host application at three different points in time. The top panel shows the scriptlet at load time. The host application contains nothing but the scriptlet, which appears as a red rectangle with a button and a text message. The red rectangle identifies the boundary of the scriptlet's window.

Figure B: Our first sample scriptlet toggles color and text together.

After clicking the button, the display looks like the middle panel in Figure B. Three characteristics change as the display transitions from the top to the middle panel. First, the scriptlet's background color changes from red to blue. Second, the message changes. Third, the window title changes from Sample1 to Constructor3. Scriptlets can control the window title of their host.

A second click of the button presents the bottom panel in Figure B. This display changes the message again, and the scriptlet background color goes back to red.

Successive clicks alternate the display between the middle and the bottom panels. However, clicking too rapidly can cause the scriptlet to ignore a click. This reaction demonstrates that the scriptlet becomes unavailable while it processes a click. One of the scriptlet extensions to the DHTML object model allows developers to discern when a scriptlet is unavailable to detect new notifications, such as a mouse click.

Listing A presents the DHTML that implements the scriptlet in Figure B. The Public_Description object declares a new scriptlet named MyScriptlet. Since MyScriptlet does not programmatically expose any properties or methods, its Public_Description object has no constructor statements. The trailing function statement is empty, but you must nevertheless include it to complete the Public_Description object.

Listing A: Constructor3.htm

<HTML>
<HEAD>
<TITLE>Sample1</TITLE>
<SCRIPT>
public_description = new MyScriptlet;
function MyScriptlet(){
}
function TColor( ){
//Cannot use Red to test a value
   if (window.document.bgColor == "#ff0000"){
      window.document.bgColor = "Blue";
      window.document.title = "Constructor3";}
   else{ 
      window.document.bgColor = "Red";
      window.document.title = "Constructor3";}}
function TMessage( ){
   if (document.all.MyMessage.innerText != "This is my story")
      document.all.MyMessage.innerText = "This is my story";
   else
      document.all.MyMessage.innerText="This is my song";}

function ToggleBoth( ){
   TColor();
   TMessage();
}
</SCRIPT>
</HEAD>
<BODY BGCOLOR="Red" >
<INPUT TYPE=button VALUE="Toggle from Scriptlet" ONCLICK="ToggleBoth()">
<DIV ID=MyMessage STYLE="font-size=30">First Message<DIV>
</BODY>
</HTML>

The INPUT button in the scriptlet invokes the ToggleBoth function when a user clicks it. This function, in turn, calls the TColor and TMessage functions. TColor toggles the background color for the document and changes the window title to Constructor3. The TITLE tags in the HEAD block initially set the title to Sample1. The TMessage function generally toggles the message between "This is my story" and "This is my song". When the message in the DIV block is neither of these, it initializes it to "This is my story". This latter action causes the message to transition from the message in the top panel to that in the middle panel.

Listing B shows the DHTML for the host in Figure B. Notice that it contains a single OBJECT tag. This is the scriptlet container object. You can optionally use an OBJECT tag pair when you prefer PARAM tags. The ID setting is not strictly necessary in this case since there are no exposed properties and methods.

Users manipulate the scriptlet by clicking a button on it instead of interacting with the host. Remember, the TYPE and DATA settings are mandatory. The TYPE setting declares the object a scriptlet container object; the DATA setting points the container object at an htm file in the same virtual directory as the host application.

Listing B: Container.htm

<HTML>
<BODY>
<OBJECT ID=scriptlet1 HEIGHT=100 WIDTH=250 
STYLE="position:absolute;top=75;left=0"
TYPE="text/x-scriptlet"   DATA="Constructor3.htm">
</BODY>
</HTML>

The OBJECT tag's HEIGHT, WIDTH, and STYLE settings define the size and location of the scriptlet container in the host application. You can optionally set a scrollbar property to let users scroll to portions of a scriptlet that extend beyond the scriptlet container window.

Figure C presents a second scriptlet sample that extends the initial one. This scriptlet exposes its TColor and TMessage functions as methods. The two buttons in the host activate these exposed methods. Figure C shows the display immediately after a click to the button labeled Toggle Just Message From Host. Notice the scriptlet displays the "This is my story" message on a red background. This was impossible in the scriptlet example from Figure B, since the color and message toggled together and the initial button click assigned the "This is my story" message to a blue background.

Figure C: Our second sample scriptlet uses exposed methods.

Listing C shows the DHTML for the scriptlet in Figure C. Its Public_Description object function includes two constructor statements. The first exposes the TColor function as the ToggleColor method. The second exposes the TMessage function as the ToggleMessage method. As an aside, this second scriptlet simplifies the TColor function from the first scriptlet sample. There's still a ToggleBoth function, but it's not exposed. This arrangement demonstrates that you can selectively expose functions. You can also expose functions differently for a host application from its native scriptlet application.

Listing C: Constructor4.htm

<HTML>
<HEAD>
<SCRIPT>
public_description = new MyScriptlet;
function MyScriptlet(){
   this.ToggleColor = TColor;
   this.ToggleMessage = TMessage;
}
function TColor( ){
//Cannot use Red to test a value
   if (window.document.bgColor == "#ff0000")
      window.document.bgColor = "Blue";
   else 
      window.document.bgColor = "Red";}
function TMessage( ){
   if (document.all.MyMessage.innerText != "This is my story")
      document.all.MyMessage.innerText = "This is my story";
   else
      document.all.MyMessage.innerText="This is my song";}

function ToggleBoth( ){
   TColor();
    TMessage();
}
</SCRIPT>
</HEAD>
<BODY BGCOLOR="Red" >
<INPUT TYPE=button VALUE="Toggle from Scriptlet" 
ONCLICK="ToggleBoth()">
<DIV ID=MyMessage STYLE="font-size=30">First Message<DIV>
</BODY>
</HTML>

Listing D reveals the DHTML for the host in Figure C. It contains two INPUT buttons in addition to the OBJECT tag. A SCRIPT block includes two VBScript functions that fire in response to button clicks. One button and function combination changes just the message, and the other button and function team up to modify just the background color. Both functions reference the scriptlet container object by its ID setting, followed by a period, and the name of an exposed scriptlet method. The method names are the same ones in the Public_Description object from Listing C.

Listing D: Container2.htm

<HTML>
<BODY>
<INPUT TYPE=button ID=Color VALUE="Toggle Color from Host" STYLE="width:250">
<INPUT TYPE=button ID=Message VALUE="Toggle Just Message from Host" STYLE="width:250">
<OBJECT ID=scriptlet1  HEIGHT =100 WIDTH=250 STYLE="position:absolute;top=75;left=0"
TYPE="text/x-scriptlet"   DATA="Constructor4.htm">
</OBJECT>
<SCRIPT LANGUAGE=VBScript>
Sub Color_onclick()
scriptlet1.ToggleColor
End Sub
Sub Message_onclick()
scriptlet1.ToggleMessage
End Sub
</SCRIPT>
</BODY>
</HTML>
Scriptlets can propagate!

A scriptlet can propagate events to a host. When a scriptlet notifies a host of an event, the host can respond to the event.

Scriptlets can notify hosts about two types of events. First, standard DHTML events can propagate from a scriptlet to a host. When a scriptlet notifies a host about a standard event, however, the host doesn't know which object generated the event. Second, scriptlets can raise custom events. When a scriptlet passes a custom event to a host, it can notify the host of the event type and origin.

Eight standard events propagate from a scriptlet to a host. These are onclick, ondblclick, onkeydown, onkeypress, onkeyup, onmousedown, onmousemove, and onmouseup. To pass a standard event, there must be an event handler, and the handler must include a bubbleEvent method. This method applies to the external object within the window object. The external object allows access to an additional object model from host applications in IE 4. In this situation, the scriptlet's host application receives the event passed it by the bubbleEvent method.

Developers can access the passed event like any other host event. The event belongs to the scriptlet's container object. If a scriptlet passed the onkeyup event for an INPUT text box within it, a host could access keystrokes typed in the text box with the following VBScript expression:

Scriptlet1.event.keyCode

Scriptlet1 is the ID setting for the scriptlet container object that points to the scriptlet.

Passing custom events has several advantages. First, you can convey more information to the host application. Second, you can pass a greater variety of built-in events. Third, you can create your own events.

Call the raiseEvent method in the scriptlet to pass a custom event. This event belongs to the external object. The raiseEvent method has the following syntax

window.external.raiseEvent(eventName, eventObject)

The eventName argument is a string. Use it to denote the event name. The eventObject is a variant that references the object triggering the event.

Use the onscriptletevent event in the host application to process a custom scriptlet event. The event takes two arguments that correspond to those for the raiseEvent method.

Summary

This article demonstrates how to use scriptlets to develop applications. We describe two different approaches to performing this task. Keep in mind that Microsoft recommends the Public_Description object when you use Jscript. The other approach, based on default naming conventions, has the advantage of working with both VBScript and JScript.

With either approach, you can expose scriptlet properties and methods to a host. This host can be another web page or any Windows application—such as Word—that can handle components.

A scriptlet doesn't have to expose methods or properties to function successfully as a component. This article illustrates that a scriptlet can open its functionality through controls, such as buttons, that reside within it. You can also use a scriptlet to display a slick animation, such as one achieved with DirectAnimation.

Conclusion

Scriptlets are extremely flexible development tools. In addition to exposing methods and properties, they can pass events to their host. You can pass either standard or custom events from a scriptlet to its host. When you do this, the host can process events in addition to, or instead of, the scriptlet that originates the event.

Rick Dobson, Ph.D. is president of CAB, Inc. a consultancy offering database, Internet, and Office development services. Rick is Microsoft Certified to train developers in Access and Office 97 development. He's a contributing editor for Microsoft Interactive Developer and a frequent contributor to Byte. You can reach Rick online at RickD@cabinc.win.net or by fax at (502) 426-3743.

Copyright © 1998, ZD Inc. All rights reserved. ZD Journals and the ZD Journals logo are trademarks of ZD Inc. Reproduction in whole or in part in any form or medium without express written permission of ZD Inc. is prohibited. All other product names and logos are trademarks or registered trademarks of their respective owners.