In this chapter, we'll continue looking at client-side scripting, but we'll be looking at more advanced technologies that give much needed functionality and extensibility to client-side pages. This includes:
Each of these are subjects broad and deep enough to be books of their own, so what we are going to be doing here is focusing on small, well- tested examples that cover the major techniques required for you to be able to begin making use of these technologies. In reality, to achieve maximum gain from these technologies you'd have to read masses of documentation-a lot of which is very poorly written. We'll show you here what is possible and how to go about doing it. We'll have achieved what we set out to do if, by the time you have finished this chapter, you are able to make any sense of the official documentation!
Microsoft's documentation is available as a free download at www.microsoft.com/scripting .
Even though these are advanced applications and tools, the main thing you still need is a good text editor to manage these technologies. The following table lists the applications you need to make use of the technologies.
Technology | Requirements |
Scriptlets |
Internet Explorer 4 or later |
Behaviors |
Internet Explorer 5 or later |
HTML Components |
Internet Explorer 5 or later |
The Internet Explorer browser is a security aware application . Every component contained within the browser (flaws and bugs aside) is subject to the security settings defined for it. For detailed information about the security settings of your browser, refer to the documentation and help files. Typically, the zone containing the components -server should be Medium ( Medium-Low in IE5 and IE6) or Low . If the security level is more restrictive the components will not download on the client computer.
It is especially important to verify security settings when distributing an application that uses components. This is why these technologies are better suited for distribution in a corporate network setting than over the Internet to everyone. Asking a visitor to your site to change security settings in order to utilize something is, in today's security climate, absurd. For one thing, the security settings will be global. Secondly, how can they trust you?
Introduced in IE4, the scriptlet mechanism was the first browser technology to permit the design of components using DHTML. While developing a Web or an intranet project, you usually produce a lot of HTML and scripting functionalities. Without a technology to implement components , you're limited to reusing your code by cutting it from a source file and pasting it into another file (or you can include external scripting files using the src attribute of the < script > tag: a useful facility, not a component- based technology). Also, cutting and pasting code usually requires lot of adaptations to make the code work in the new context and there is enormous scope for things to go wrong and for errors to be introduced. On the other hand the usage of a component is straightforward. You include it in your context using its public interface made of properties, methods , and events-the usual stuff expected by an object-oriented programmer.
A scriptlet is a component developed using DHTML. What this actually means is that a scriptlet is an HTML file with a few extensions to allow the definition of properties, methods and events that permit its use as a component.
The Hello World Scriptlet
To quickly show what a scriptlet is, we'll introduce the classic application 'Hello, World!'. The application's task is just to output the 'Hello, World!' message using the technology under examination. To implement 'Hello, World!' two files are required:
The following code shows the content of the CLIENT_HELLOW.HTM file.
TYPE="text/x-scriptlet" DATA="hellow.htm" HEIGHT="0" WIDTH="0">
The scriptlet is identified by the name myScriptlet . This name has been used as the ID of an < OBJECT > tag included in the HTML file. The details of this tag are as follows :
TYPE="text/x-scriptlet" DATA="hellow.htm" HEIGHT="0" WIDTH="0">
Tip |
Note the HEIGHT and WIDTH parameters of the < OBJECT > tag have been set to zero. This is done so as to make the object invisible. There are cases where it might makesense to the object visible (say if the scriptlet contains visible objects as well) but that is not the case here. |
The following line calls the scriptlet code.
Document.All.myScriptlet.Hello
This line will require a scriptlet that exposes a Hello method. This very simple scriptlet is stored in the HELLOW.HTM file.
So, what does our scriptlet comprise? It is an HTML file encapsulating the scripting code inside a < script > tag, which, in our case, contains just one VBScript function defined as public_Hello .
There are several points for you to take note of from this example:
To run the scriptlet we simply run the client file (the file that contains the < OBJECT > tag. Figure 11-1 shows the scriptlet in action!
FIGURE 11-1
VBScript offers a very simple way to define which code is exposed by the scriptlet to the container: a simple to follow naming convention.
Tip |
It is important for you to note ( especially if you have used JScript) that JScript offers a further mechanism called 'Public Description Object' to define the public interface of a scriptlet. JScript is outside the scope of this book and, anyway, we don't need it to implement scriptlets. |
Further naming conventions:
Prefix | Used to Expose |
public_ |
Variables as read/write properties and procedurespar or functions as methods |
public_get_ |
Functions as readable properties |
public_put_ |
Functions as writable properties |
When a scriptlet member is exposed, its name in the host application does not have the prefix. Remember that the Hello function in the HELLOW.HTM scriptlet was defined as public_ Hello.
Sub public_Hello()
While the public_ prefix has been removed in the method call made by the host file CLIENT_HELLOW.HTM :
Document.All.myScriptlet.Hello ' and not ' Document.All.myScriptlet.public_Hello
Scriptlets use prefixes to expose their public interface, but the host applications don't use the prefixes to access that interface. This is using quite an ambiguous syntax to simply declare a public interface.
Scriptlets are a good mechanism to package reusable code into one module. The next example shows you the beginnings of a more complex example that exposes a few methods and a property.
The Cookies Manager
The Cookies Manager is a scriptlet that exposes the following interface.
Member Type | Name | Description |
Method |
SetCookieKey (Key, Value) |
Stores a value in a cookie and associates it with a specific key |
Method |
GetCookieKey (Key) |
Returns the value of a specific key in a cookie |
Method |
RemoveCookieKey (Key) |
Removes a specific key from a cookie |
Property |
KeyExists |
True if the cookie key exists. |
Usually checked after calling GetCookieKey or RemoveCookieKey |
Using this interface, the client can store, read, or remove a specific key stored in a cookie.
Tip |
An HTTP cookie is a small file stored on a client machine. By using cookies you can implement persistency among different sessions (so a user returning to the page will still find the values previously stored in the cookie). However, you cannot fully rely on this as many people do delete their cookies now on a regular basis. |
Here is the code of COOKIESMANAGER.HTM scriptlet.
We also need a new host application to display an example of using the Cookies Manager scriptlet. This is the code contained in the CLIENT_COOKIE.HTM .
TYPE="text/x-scriptlet" DATA="cookiesManager.htm" HEIGHT="0" WIDTH="0">
Let's take a quick run-through of what this application does.
Figure 11-2
Figure 11-3
Figure 11-4
Figure 11-5
How dose it work?
The first time you load the page the cookie storing your name doesn't exist. In this case, the following < div > tag will be used to display a button.
Once you've completed the process by entering a text string and then reloading the page, the same < div > will be dynamically filled with a new content by the VBScript code.
sValue = Document.All.myScriptlet.GetCookieKey("Name") If Document.All.myScriptlet.KeyExists Then Document.All.Main.InnerHTML = "Hello there" & sValue & _ "! Welcome back!" End If
Using the Cookies Manager , your name has been stored in a cookie (very originally called "Name" ).
The Cookies Manager script extends the "Hello, World!" example by showing the following:
When the scriptlet is used in a host document, it is only logical that the host document can be notified about events raised from the scriptlet. A scriptlet can raise two types of events:
Handlers have a one-to-one relationship with each other. This means that when one event handler is in the scriptlet and raises the event, another event handler is in the host document to capture the event raised by the scriptlet.
Standard DHTML Events
The standard DHTML events exposed by the scriptlet are:
The following example shows an HTML file that contains a simple implementation of an event handler in the scriptlet for the onclick event that is triggered when the user clicks on the image that will be displayed on the page.
Example
The previous sample shows how to do the following:
What happens if the scriptlet does not implement an event handler for a standard event using the BubbleEvent method? In this case the event will not be passed to the host application and will not be acted upon.
Tip |
In a COM development environment the scriptlet container object will expose all standard events at design time, even if the scriptlet does not handle all of them. |
In the preceding context the scriptlet container object is the HTML document. The Event object is accessed via the Window.Event property. The Event object properties will give additional information on the specific event.
Here is an example (for clarity and brevity we've omitted the HTML skeleton that surrounds this code) that shows how to access the event additional information using the Window.Event property.
Custom Events
Custom events are used to:
The following sample (again, free from HTML) shows how to notify a change in the internal state of the scriptlet.
This simple example demonstrates the following:
A special event is captured in the host document to run the host event handler: onscriptletevent . The following example shows this technique in action.
All the custom events are subsequently handled by the onscriptletevent . As a result, a Select Case structure is normally used in the onscriptletevent handler to customize the actions taken based on different events.
How Do You Know When a Scriptlet Is Ready?
In order to make sure everything works fine, the container object implements the property ReadyState and the event onreadystatechange that are used to ensure that specific code will be executed only when the scriptlet has been completely loaded into the container object.
The onreadystatechang e event is fired multiple times while the scriptlet is loading. The final time it is fired indicates the point at which the scriptlet file has been fully loaded and its scripts can be called. The ReadyState property is used to test the current state. This property is read-only and it is available only at runtime. The ReadyState property returns an integer value indicating the loading state of the scriptlet.
Value | Description |
1 , 2 |
Scriptlet is still loading |
3 |
Scriptlet has been loaded, but the page might not yet be fully functional |
4 |
Scriptlet is completely loaded and functional |
Specific extensions have been introduced into the Dynamic HTML Object Model to help programmers design and implement scriptlets. All these extensions are available in the DHTML Window.External object.
Properties | Methods |
Frozen |
BubbleEvent |
SelectableContent |
RasieEvent |
Version |
SetContextMenu |
Let's take a closer look at the properties and methods listed in the last table.
Frozen Property
Description |
This property indicates whether the scriptlet container is ready to handle events |
Syntax |
aVariable = Window.External.Frozen |
Remarks |
While this property is True , events will not be received by the scriptlet container. When the container is ready to receive events the variable is set to False . This property is read-only |
SelectableContent Property
Description |
This property specifies whether the user can select the contents of the scriptlet |
Syntax |
Window.External.SelectableContent = boolean |
Remarks |
By default, the value of this property is set to False , and the user cannot select objects in the scriptlet. If it is set to True then the user can select text or other objects contained in the scriptlet |
Version Property
Description |
Returns the version and platform of the scriptlet container object. For example ' 5.0 Win32 ' is the value returned by the Version property when the scriptlet is hosted by IE6 for Windows 98/NT/2000/XP |
Syntax |
ver = Window.External.Version |
Remarks |
Version is returned in the following format N.nnnn platform |
Where
N is an integer representing the major version number
nnnn is any number of characters (except a space) representing the minor version number
platform is the platform ( win32 , mac , alpha , and so on)
The version property can be used to determine whether the page is being used as a scriptlet or as a standalone Web page. The following code:
Mode = (TypeName(Window.External.Version) = "String")
If the value of Mode is True , the page is being used as a scriptlet, otherwise the page is being used as a standalone page
BubbleEvent Method
Description |
This method sends event notification for a standard event to the host document |
Syntax |
Window.External.BubbleEvent |
Remarks |
This method is used to pass a standard DHTML event from the scriptlet to the host document |
RaiseEvent Method
Description |
This method is used to pass a custom event notification from the scriptlet to the host document |
Syntax |
Window.External.RaiseEvent EventName , EventObject |
Parameters |
EventName -a string identifying the event that is being passed. |
EventObject -a variant type that typically includes a reference to the object on the scriptlet that triggered the event |
|
Remarks |
This method is used to notify the host document about a nonstandard event. The onscriptletevents event is strictly related to this method |
SetContextMenu Method
Description |
This method creates a context menu that is displayed when a user right-clicks a scriptlet in the scriptlet container object |
Syntax |
Window.External.SetContextMenu MenuDefinition |
Parameters |
MenuDefinition defines the command text and commands contained in the context menu |
A one-dimensional array in which the menu items are defined using sequences of two elements, n and n + 1 |
|
Element n is the command text. Shortcut keys are defined by preceding a letter with '&' |
|
Element n + 1 is the method to be called when the command is chosen |
|
You cannot pass parameters to the method |
|
Example-the following script defines a context menu with two commands: |
|
< script language="VBScript" for="Menu" event="onClick" > |
|
Dim MenuItems(4) |
|
MenuItems(0) = " &Cut text' |
|
MenuItems(1) = "CutText" |
|
MenuItems(2) = "Co &py text' |
|
MenuItems(3) = "CopyText" |
|
Window.External.SetContextMenu MenuItems |
|
< /script > |
This chapter shows examples of scriptlets that contain only code (no visible HTML tags). Originally scriptlets were introduced to contain HTML visible tags as well. You can actually use it by adopting the same techniques we've been looking at so far. The only thing to remember is not to set the WIDTH and HEIGHT parameters of the < OBJECT > tag to zero. If the scriptlet has visible parts then it will occupy a visible place in the layout of the HTML page that contains the component. The examples display thinking in 'behaviors terms'.
At the end of 1998, Microsoft deprecated the scriptlets technology. You can still use this technology but Microsoft suggests replacing it in your applications with HTC components (known as behaviors). As we will see later in this chapter, behaviors have a strong influence during the design of an application, suggesting the separation of the code that defines the behavior of an HTML tag from the tag itself (that's the reason why they're called behaviors!). We have chosen to present scriptlets as the original approach as it was these that evolved into behaviors (known as HTML components) and are still a widely used technology.
Tip |
Behaviors are not supported in IE4. |
Introduced with the advent of Internet Explorer 5.0, behaviors are a fascinating mechanism that have the potential to bring a new programming paradigm in the DHTML world.
The behaviors technology is based on a concept: the behavior. The previous sentence could appear to be a truism, but it introduces a major point. As we will see, Microsoft overused the term behavior in different contexts (to indicate a concept, a technology label, and a keyword). We are now focusing on the first and most important occurrence: the behavior concept.
Unlike scriptlets that were created to group HTML elements and scripts together in an external HTML file, the behavior concept emphasizes the separation of script from HTML elements.
The behavior concept is implemented as an encapsulated component that is associated to an HTML element or, more frequently, to a (CSS) class of HTML elements.
Currently two technologies allow us to implement behaviors:
HTML components are simply text files with an HTC extension containing code scripts (VBScript or JScript) while binary behaviors are built using compiled languages such as C++ or Visual Basic.
Tip |
Binary behaviors do not fall within the scope of this book; they have been introduced to further clarify the relationship between the behavior concept and an HTML component. |
When the encapsulated component implementing a behavior is applied to an HTML element, that component then extends the behavior of the HTML element (that's where the term behavior comes from).
There are two approaches you can follow to apply a behavior to an HTML element: Statically by using a CSS class, and Dynamically by using scripting.
Applying a Behavior Statically
In IE5 and IE6 you can define a CSS class using a new property, behavior .
Tip |
The property is currently a Microsoft proposal to W3C. |
The following code defines a simple CSS class that will be used to apply a behavior to HTML elements.
After the declaration of such a CSS class, your HTML file could contain several different tags, for example:
This is a div
In the last example, a behavior has been applied to two different HTML elements.
The behavior of both HTML elements will be extended by the code (either VBScript or JScript code) that is contained in the somebehavior.htc file.
The CSS property named behavior can be defined inline using the < style > attribute. In this case the programmer doesn't even need to declare a CSS class to apply the behavior. Also, if you wanted, a single specific element can be addressed. The following example demonstrates this technique:
another div
Applying a Behavior Dynamically
A behavior can be applied through scripting in one of two ways: using the AddBehavior method or modifying the Behavior property of the Style object. The following code shows both ways in action.
another div
Tip |
Note that the Behavior property still expects the syntax " url (somebehavior.htc) " while the AddBehavior method doesn't require this syntax. |
Remove a Behavior Attached Dynamically
Let's think about the lifecycle of the relationship between an attached behavior and the HTML elements. Behaviors attached employing CSS classes are automatically detached from the elements as soon as the element or elements are removed from the document tree. This is not the case when using any other method. Under these circumstances you will be required to use the RemoveBehavior method.
In all these cases it is not enough to just remove the elements themselves from the document tree. They will still maintain all the style sheet rules defined programmatically or by inline definitions (including the behavior rule itself).
So far, we have looked at what a behavior is as a concept and the ways that it can be used to augment and extend on HTML elements. As yet, we haven't examined any behavior implementation. We have already seen that behaviors could be implemented using VBScript through HTML components. It is time we looked at HTML components.
An HTML component is an encapsulated component, which implements a behavior. An actual HTC is simply a file with an HTC extension. An HTC file contains VBScript code that is wrapped by HTML tags that define the public interface of the component.
It is not too difficult to confuse HTML components with scriptlets. Microsoft has recommended that programmers replace scriptlets with HTML components because they are the newer and as such better evolution of this technology. HTML components are evolving into something that is very different and far removed from scriptlets themselves . The behavior concept (discussed earlier) is what makes the difference-and an enormous difference.
The main purpose of both scriptlets and HTML components is to make it easier for the programmer to reuse code. However, this produces the misconception that HTML components should replace scriptlets. Each of them in fact captures different code aspects and both of them should be used together in large projects that are component-based.
In contrast to scriptlets, the goal of HTML components is to extend HTML elements' behavior. Let's look at a few techniques that are used to extend HTML elements using HTML components:
Let's begin this journey by taking a look at a basic 'Hello, World!' HTML component to get a feeling for how this technology actually works. The HTML component is stored in the HELLOW.HTC file.
The component has one line of code more than the analogue scriptlet sample. One thing that's important to note is that the prefix ' public_ ' is not required (the prefix naming conventions are only required for scriptlets and are not required for HTML components).
In the case of this minimal sample, you will certainly find it more interesting to have a look at the HTML file that uses the component CLIENT_ HTC_HELLOW.HTM.
}
As you can see there is a total separation between scripting code (contained in one file) and HTML and CSS (contained in another).
If you think that we are exaggerating the minimalist nature of the actual HTML file, take a look at the following alternative for the client file ( CLIENT_HTC_HELLOW2.HTM).
This is an extremely minimalist file in terms of it being a complete HTML file. However, it can afford to be only four lines because the powerhouse is contained in the .htc file.
Enhancement 1-Adding Properties
An HTML component can expose properties to the containing document by using the < property > element.
Here we have an example that implements an HTML component, which has a public interface made of only one property called CryptedKey . The example captures the essentials of the technique to exposes properties. The HTML component is contained in a file named CRYPTED.HTC.
This sample shows you how to do the following:
The example uses the Xor function to crypt/decrypt the value of the property. Applying this crypt/decrypt transformation the example shows how it is possible to use read/write property functions that actually do something more than simply give access to an internal variable.
A client sample that uses the HTML component is shown next ( CLIENT_CRYPT.HTM ).
This div has been enhanced with the CryptEd property
The example applies the behavior to a < div > element, identified by the ' myDIV ' ID . This is done using the following line of code.
MsgBox Document.All.myDiv.CryptedKey
The HTML component has actually enhanced the < div > adding to it the CryptedKey property that behaves as implemented. To check this you could generate an error by choice, changing a letter in the same line, as in:
MsgBox Document.All.myDiv.CryptKey
If you now click on the button labeled Read Property you will see the error message shown in Figure 11-6.
What the error message is telling you is that the CryptKey property it is not supported by the object. This is further evidence that you can actually extend HTML elements using behaviors.
Overriding Standard Properties
It is possible to override the element's default behavior by specifying a name for the property that is the same as that of a property already defined for the element.
Notify the HTML Element that the Property Value has Changed
When the value of the property has changed, the HTML element can be notified by firing the onpropertychange event calling the FireChange method.
Figure 11-6
Function PutCK(ByVal newValue) cKey = newValue Xor 43960 oCryptedKey.FireChange End Function
The oCryptedKey identifier indicates the id of the < property > element that has been specified.
To verify that the event has fired effectively, modify the
definition in the client.
This div has been enhanced with a Crypted property
Enhancement 2-Adding Methods
To add new methods to an HTML element using an HTML component is easier than to adding properties.
As an example let's modify the CRYPTED.HTC component to expose a method named isplayCryptedValue , which displays the internal value of the CryptedKey property in a dialog. A further element named method is available to expose methods. The resulting CRYPTED.HTC code looks as follows .
For this new, modified code to work the host application will require some modification to use the DisplayCryptedValue method. The following is the code for the modified host application ( CLIENT_CRYPT2.HTM ).
This div has been enhanced with a Crypted property
Value">
Enhancement 3-Exposing Component Events
An HTML component is capable of defining its own events and then exposing them through the < event > element. This method of exposing custom events is clearly more powerful than the one offered by scriptlets (described earlier in this chapter). Actually, scriptlets are only capable of exposing one event- onscriptletevent . With HTML components you can expose any kind of event you want to the containing document. As an example we are going to enhance our CRYPTED.HTC code with an OnReadWarning event, which informs the container that somebody has accessed the CryptedKey property.
This code shows the technique to fire a component event in.
Dim oEvent Set oEvent = CreateEventObject() orw.Fire(oEvent)
The CreateEventObject function is required to create an event object and the event object becomes the parameter of the Fire method of the < event > element. The < event > element is identified by its id attribute ( orw ). The < event > element also defines the name of the exposed event as well.
It is again necessary to modify the client, but this time only one line of code needs to be changed.
This div has been enhanced with a Crypted property
To generate the event we launch the client application, assign a value to the property, and then read that value. The onreadwarning event will be raised and the application will inform you with the message shown in Figure 11-7.
Figure 11-7
Enhancement 4-Handling HTML Element Events
HTML components offer a further mechanism to enhance HTML elements. They can attach handlers for the HTML element's events using the < attach > element. We will modify the CRYPTED.HTC example to handle the onclick event of the HTML elements to which the behavior is attached.
The handler for the onclick event is declared in the following line.
This time, no modifications are required in the code for the host application.
You can easily test the handler. Click on the < div > element to run the handler. This will produce a dialog box shown in Figure 11-8.
Figure 11-8
Tip |
When the specified event fires on an element to which the behavior is attached, the behavior's handler is called after the element's event handler (if any). |
Attach Event Handlers through Scripting
Timing becomes a very critical issue when dealing with event handlers. Sometimes you need to attach an event handler that responds to specific events. It is possible to attach handlers through scripting using the AttachEvent method instead of the < attach > element.
The general technique to deal with dynamically attached event handlers is shown in the following lines of code.
A DetachEvent method and an ondetach event have both been introduced in the example above. Event handlers that are attached using the AttachEvent method have to call the DetachEvent method to stop them from receiving any sent notifications. The HTML component will be notified with the ondetach event from the page to actually detach all the handlers attached through scripting.
Multiple Behaviors
It is possible to apply multiple behaviors to an element either by using the AddBehavior method multiple times or using the syntax shown in the following example.
But what about conflicts? Conflicts can happen when more than one behavior is applied to one element. For any conflicts resulting from applying multiple behaviors to an element, the following resolution rule is defined.
Tip |
Each subsequent behavior takes precedence over the previous behavior in the order in which the behavior is applied to the element. |
Name Clashing Resolution and the COMPONENT Element
A further element can actually be helpful in cases where there are multiple behaviors. This is the < component > element. The < component > element allows us to give a name to the HTML component that can be used to access properties and methods through scripting (solving name clashing issues whenever multiple behaviors are applied to the same element).
After using the < component > element it is possible to access the component properties and methods using the component name.
Sub ReadProp() MsgBox Document.All.myDiv.Crypted.CryptedKey End Sub
This definitively solves the name clashing issue. Suppose we want to apply two behaviors (named, for example, bhone and bhtwo ) both of which define a Description property to the same element ( myDiv ), it is possible to access both properties.
MsgBox Document.All.myDiv.bhone.Title & Document.All.myDiv.bhtwo.Title
The goal of this section was to introduce all the fundamental techniques to start you on your way using behaviors and HTML components. Experimenting with the preceding code and concepts can only help to further your understanding of these topics.
The goal of this chapter is to give you an understanding of how much farther than a simple static Web page VBScript can take you. We've looked at sufficient code samples for you to be able to make use of many and reuse or adapt them to suit your own needs. We looked at the evolution of scriptlets into behaviors and their use through HTML components . With regard to scriptlets you saw how to:
We then moved on to look at behaviors and saw how to:
This then led us to learn that the goal of HTML components is to extend HTML elements' behavior. And, with regard to HTML components, we also covered:
Do remember that we've covered some enormous topics here. Whole volumes can (and have!) been devoted to the topics we have covered in this chapter and, so, if you want to go deeper and do more, refer to more specialized sources to further your learning. However, what we've provided here will give you a good foundation on which to build!
Introduction