Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


DHTML Interfaces: Taking The Next Step : Page 2

A new kind of DHTML toolkit can provide developers with a better approach to code and widget reuse.

The Example Page, Step-by-Step
Now that you've tried the sample page, I'll explain why it's special. The first thing to note is the relative simplicity of the contents of the <body> tag:

<body onClick="addButton();" style="background-color: white;"> <h4>click anywhere in the document to spawn a new button widget</h4> </body>

Despite the fact that the page consists of nothing more than a single headline element and a function call, it's able to spawn and track an arbitrary number of button widgets. The sample page proves:

  • that you can create widgets after the page has fully loaded
  • widget creation is not dependent data sent from the server nor on initialization variables
  • widget creation can be fully event driven
The addButton() function does the heavy lifting. Stripped of comments and extraneous code, the function looks like this:

function addButton(){ var tmpButton = new buttonWidget('button', null, "alert('button ' + this.IDNum + ' clicked');"); tmpButton.generate(); document.body.appendChild(tmpButton.compNode); document.body.appendChild(document.createElement("br")); }

Four lines to spawn a widget, give it attributes, attach an event handler, add it to the document and add spacing isn't bad—and that's all end developers normally ever need to see or know about. The object constructor new buttonWidget() calls a constructor included from another script. You need to understand the constructor's arguments to make full use of the widget.

The first argument specifies the text or "label" for the new button widget. The second and third (both optional) arguments provide methods for defining the behavior of the widget. The second argument accepts a function pointer to a method to be evaluated when the button is clicked, or null if it is unused. The third argument is the string containing script that evaluated via the eval() function when the button is clicked. In this example, the code describes an alert():

alert('button ' + this.IDNum + ' clicked');

Figure 1: The hierarchy of objects in the framework.
Interestingly, the value of this.IDNum is not defined in the addButton() function or anywhere else in the global namespace. Instead, it's a member of the buttonWidget object itself. This works because code executed via eval() in the scope of an object inherits the scope of that object, and not the scope of the calling function. The code looks up a specific JavaScript object when we click on the button, and accesses the members of that object from an event fired from a DOM node. But what is IDNum? And how does the environment know which buttonWidget was clicked so it can obtain the right IDNum value?

To answer these questions, we'll need to look deeper into the framework and the button widget's responsibilities. By understanding how this simple button widget works, you can leverage the framework to build other widgets from a shared code base.

Here's how the framework adds the button widget to the page. First, it doesn't simply add the object returned from the constructor; instead, it adds one of its members, compNode. In other words, the return value from the constructor isn't a DOM node as you might expect, it's a JavaScript object, and compNode is a DOM node member of that object. Digging a little deeper, you'll find that there's an entire object hierarchy at work here, and that the buttonWidget class is actually a subclass of a base class that's part of the framework (see Figure 1).

First I'll show you the base class and you can see what it does, and then I'll show you the buttonWidget class and you can see how it uses the services provided by the base class to make the end developers' lives easier.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date