Introduction to HTML Components

HTML components are part of a little-known web technology that make it possible for you to embed self-contained, completely independent User Interface components into a page. For example, suppose you have a standard toolbar you want in every page of a given application. Using components you can render this toolbar wherever you like in the page with one custom HTML tag. Another example is a web-based text editor. We use an HTML component to implement such an editor in Nexus, our Web Portal product.

Restrictions of Components

Currently, components are a Microsoft-centric technology, so they are only supported by IE. You can read more about them at Microsoft's developer's site (http://msdn.microsoft.com).

Components and Behaviors

You may see the term 'behaviors' associated with 'HTML components'. A 'behavior' is really just the functions that an HTML component can perform. You can associate behaviors with a custom HTML tag, or with a Cascading Style Sheet style. I prefer to use an HTML tag. It makes your code a little clearer as to where you are using the HTML component. In either case (CSS or HTML tag), components are still a Microsoft-only implementation. In other words, Microsoft have written proprietary extensions to the CSS-2 specification in order to support their unique technology.

Why Would You Want To Use Components

There are many ways to construct pages comprised of components that are independent of one another. Some of these are:

All of these approaches require a second trip to the server to deliver content, if variables from the server are required. In the case of frames and iframes, you will often confront problems with presentation (for example, how do you dynamically size the IFRAME container to match the size of its content?). In contrast, HTML components have these advantages:

So, you can think of an HTML component as a self-contained object with a public interface such as properties (parameters) and methods (functions) and private contents, such as the UI rendering and private functions.

How To Implement Components

To implement a component you need to do the following:

Example Of How To Code And Use A Simple HTML Component

This example is about as simple as you can get. Let's say we want to show today's day of week, month and year anywhere on our page. We could do this with java-script by modifying the contents of a div once the page has loaded. Using an HTML component is a little cleaner, though, because all the code can be self-contained. In addition, there's no need to invoke a java-script function or to dynamically modify the HTML contents. Further, the component becomes relatively context-independent- meaning we simply have to code a custom HTML tag to invoke it, and not have to attach it to some specific existing HTML tag.

Coding the Container Page

Here's our container page (explanation to follow):


<HTML XMLNS:TODAY>

<HEAD>

  <TITLE>Todays Date Implementation</TITLE>

  <?IMPORT namespace="TODAY" implementation="TodayInfo.htc">

</HEAD>

<BODY>

Normal page content goes here.

<br>  

	<TODAY:MY_TODAY></TODAY:MY_TODAY> 

<br>This appears after inclusion of the HTC

</BODY>

</HTML>

Explanation:

This line: <HTML XMLNS:TODAY> uses a special keyword, XMLNS. The XMLNS keyword means 'XML Namespace'. A namespace is a container for the definition of a set of custom XML tags. For example, you could create a namespace called 'INVOICE' and then define a set of custom XML tags that define the various pieces of an invoice. In this instance, we chose the name TODAY to give a unique name to a namespace that defines the implementation of our HTML component. We could have called it anything we liked.

This line: <?IMPORT namespace="TODAY" implementation="TodayInfo.htc"> uses the same namespace as we defined in the <HTML> tag (TODAY) to define the actual implementation of this namespace. In English, we can understand this as: 'implement the XML namespace called TODAY by using the contents of the HTML component file 'TodayInfo.htc'. Note that the HTC is expected to be found in the same path or directory as our HTML file. You can, however, use absolute or relative paths just like you would for included CSS, java-script, Image files etc.

This line: <TODAY:MY_TODAY></TODAY:MY_TODAY> defines a custom tag that actually renders content according to what TodayInfo.htc is designed to do. The TODAY: prefix tells the browser that this tag is a custom one that uses the previously defined XML namespace called TODAY. The element name MY_TODAY must match a line of code that you specify in the TodayInfo.htc, which I'll explain in more detail later on. Meanwhile, that line looks like this:


  <public:component tagName="MY_TODAY">

	

The example custom tag in the container page is the simplest possible. We could also include keywords on the tag which can be passed as parameters to the HTML component. For example, suppose we want to control the color of the text that displays today's date. We could pass that as a parameter, like this:

<TODAY:MY_TODAY COLOR="red"></TODAY:MY_TODAY> 
. The HTC file would contain code to receive this parameter. I'll explain passing parameters and making function calls to HTML components in detail in a later article.

Code For The HTML Component

Below is the initial code listing for the HTML component:

 

<!-- "TodayInfo.htc" -->

<head>

    <public:component tagName="MY_TODAY">

        <public:defaults viewLinkContent />

      	<public:attach event="oncontentready" onevent="WriteToday()"/>

    </public:component>

    

<script type="text/java-script">

function WriteToday()

{



var d=new Date();

var weekday=new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");

var monthname=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");



var dynhtml = weekday[d.getDay()] + " " + d.getDate() + ". " + monthname[d.getMonth()] + " "+ d.getFullYear();



document.getElementById("qdinfo").innerHTML = dynhtml; 

}

</script>

</head>

<body>

<div>Today is: <span id="qdinfo"></span></div>

</body>

The document is very similar to a normal HTML document except it does not have a <html></html> tag pair. Instead, within the <head></head> tag pair there are statements that define the HTC component attributes. In our example we have the component definition and just two statements within it. These are written in XML according to Microsoft's specifications (see MSDN's HTC Reference page. Here's what they mean.


  <public:component tagName="MY_TODAY">

        

    </public:component>

Define the start and end of the component's public definition. The tagName of MY_TODAY matches to the value we specified for the component in the container page listed earlier.

  <public:defaults viewLinkContent />

The default for this property is false (same as coding: <public:defaults viewLinkContent="false" />). This means any HTML within the component belongs to a completely separate DOM tree than the container page. This prevents problems with accessing document nodes in the master document and provides more effective 'encapsulation'.

   <public:attach event="oncontentready" onevent="WriteToday()"/>

This statement means that when the 'oncontentready' event is fired for the component, the java-script function called "WriteToday()" is executed. Microsoft explains it thus: "When the oncontentready notification fires, the content of the custom element has been successfully parsed and built. An HTC file should attach a function to this event if it is to set any properties that apply to the custom element or its contents." In other words, it's like the onLoad event in a body tag for a conventional page. Note that it applies to the HTC component itself, not the readiness of the content of the container page.

The rest of the code is pretty straightforward. First, we render some static HTML that writes the phrase "Today is:" in the body of the component's page. Once the page is rendered, the onContentReady event fires and "WriteToday()" populates the inner contents of the span tag with today's date. That's it!

Adding Style To Our Component

You'll notice we've used both static HTML and java-script to render dynamic HTML in our example. Now let's make the component look a little nicer by using CSS. Here's an improved version of our component:


<!-- "TodayInfo.htc" -->

<head>

    <public:component tagName="MY_TODAY">

        <public:defaults viewLinkContent />

        <public:defaults viewInheritStyle="false" />

        <PUBLIC:ATTACH event="oncontentready" onevent="WriteToday()"/>

    </public:component>

    

<style>

		div { border: 1px blue solid;  margin:3px; padding-left: 2px; padding-right: 2px; text-align: center; font: normal 12px/20px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;	color: #616B76;}

</style>		



<script type="text/java-script">

function WriteToday()

{



var d=new Date();

var weekday=new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");

var monthname=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");



var dynhtml = weekday[d.getDay()] + " " + d.getDate() + ". " + monthname[d.getMonth()] + " "+ d.getFullYear();



document.getElementById("qdinfo").innerHTML = dynhtml; 

}

</script>

</head>

<body>

<div>Today is: <span id="qdinfo"></span></div>

</body>

The changes we've made are as follows: