This behavior was based on the cool button script but it has been rewritten to use the power of DHTML behaviors. Since I haven't explained much about behaviors before I think it is about time to do so now. if you don't want to read about how this behavior was made jump straight down to the demo section.

Behavior pros and cons

The only real negative thing about behaviors is that it is an IE5 only technology but besides that it is all good. A very good thing about behaviors is that they are extremely easy to reuse and all you have to do is to add the behavior in the style declaration.

Creating your behavior

Behaviors are created in a special file type called HTML Components (.htc) (See the HTC Reference for detailed info). The file format is XML with a script block but there are problems about the format (See more) but these problems seldom leads to any problems.

Below is the format for the htc used to create this behavior (notice that all tags needs to be closed in XML):

<PUBLIC:COMPONENT>
   <PUBLIC:ATTACH EVENT="onmousedown" ONEVENT="buttonMouseDown()"/>
   <PUBLIC:ATTACH EVENT="onmouseup" ONEVENT="buttonMouseUp()"/>
   <PUBLIC:ATTACH EVENT="onmouseout" ONEVENT="buttonMouseOut()"/>
   <PUBLIC:ATTACH EVENT="onmouseover" ONEVENT="buttonMouseOver()"/>
   <PUBLIC:ATTACH EVENT="ondblclick" ONEVENT="buttonDblClick()"/>
   <PUBLIC:ATTACH EVENT="oncontentready" ONEVENT="buttonInit()"/>
   <PUBLIC:ATTACH EVENT="onpropertychange" ONEVENT="buttonPropertyChange()"/>

   <PUBLIC:PROPERTY NAME="buttontype"/>
   <PUBLIC:PROPERTY NAME="value"/>
   <PUBLIC:PROPERTY NAME="cooldisabled"/>

   <SCRIPT>
   
   // Code goes here
   
   </SCRIPT>
</PUBLIC:COMPONENT>

First we have the ATTACH element that is used to hook up events. When the element that has this behavior assigned to it receive an onmousedown event the function buttonOnMouseDown() is called. The element called PROPERTY is used to assign a property to the element with this behavior (almost like an expando property). The name of the property cooldisabled was chosen because IE5 has already a property called disabled for all its HTML elements.

There are two IE5 specific events attached as well. First is the oncontentready that is called when the entire content of the element has been loaded. This is really useful for behaviors since they can be initiated before the entire page has been loaded. The second new event is the onpropertychange and this is called as soon as a property (such as style, attribute or expando properties) has been changed. This is for example called when the user changes the cooldisabled property through scripting and this allows us to modify the look and feel of the button once this is changed.

Creating the code

The code is pretty basic and it is mostly style manipulations but there are some things worth mentioning. The first thing is that the current element is called element in the htc file and it is always in scope. This means that element.getAttribute() is equivalent to getAttribute() (just like the window element is in scope in a normal script tag. This can be though of like a global with statement). Another very important thing to remember is that document (window.document)refers to the XML document that builds up the htc file. To get the document that the element is included in use element.document (this is because window has higher priority than element in the scope.

To create the look of the disabled buttons the filters Mask and DropShadow are used. When a button is set to disabled the old onclick handler is backed up and the onclick handler is set to null. With the radio/checkbox buttons there is a special function attached to the onclick handler as well.

Catching the property changes

To make the behavior easy to use I would like the user to be able to just set the cooldisabled property to true and then the button would become disabled. This was done like I said before by hooking up the onpropertychange event. Below is part of the code of the function

function buttonPropertyChange() {
   var pName = event.propertyName;
   if (pName == "cooldisabled") {
      if (getBooleanCoolDisabled())
         disable();
      else
         enable();
   }
   else if (pName == "value") {
      // code for handling changed value
   }
   else if (pName == "buttontype") {
      // code for handling changed buttontype
   }
}

Custom style properties

IE5 allows the user to use custom style properties. To use them one just declares them in a normal way but when reading them you have to use the currentStyle object. (The style object only contains values directly assigned to an element.)

<style type="text/css">
<!--

#foo {customProperty: customValue}

-->
</style>

And then in the script...

alert("foo's customProperty = " + foo.currentStyle.customProperty);
// will give "foo's customProperty = customValue"

This is really usefull for behaviors since you can have global initiation varibles declared in the style element.

Usage

To include the behavior you assign it through a style declaration. There is also a custom style property called coolRadioBackgroundUrl that is used to tell the behavior where to find the background image used for pressed radio buttons

<style type="text/css">
<!--

.coolButton {behavior: url('coolbutton.htc'); coolRadioBackgroundUrl: url('../../images/tileback.gif');
            background: buttonface; cursor: default; font: icon;}
.coolButton img	{margin-right: 2px;}

-->
</style>

There are three different types of buttons. The first and simplest is a plain button. The second one is a button with the buttontype attribute set to radio (and no name attribute defined). This button also has a property called value and when this is set to true the button is pressed down. The third type also uses the buttontype="radio" but this also needs a name attribute assigned. If there are more than one button with the same name only one of these can be selected at the same time (therefor the name radio). All buttons listen to the attribute cooldisabled and once this is true the button gets disabled.

Demo

The first button is a simple button (no buttontype declared) that is disabled (by setting cooldisabled="true"). The second and third button changes the cooldisabled property of the first button.

Button Bold Italic
Set cooldisabled to true
Set cooldisabled to false

Below is two radio buttons (with no names) where one has value="true". Notice that the value property is not updated until after the onclick handlers.

Starting toggled
Starting not pressed
Set value to true
Set value to false
Toggle cooldisabled

You can also change the buttontype during runtime.

Starting normal Toggle buttontype

And now some radio buttons with the same name

There can be only one There can be only one
There can be only one There can be only one
There can be only one There can be only one

Cool Buttons
As a behavior
Behavior Demo Page

Author: Erik Arvidsson