Skip navigation.

Fun with Kinematic TypographyAll recent postsKeeping a Design Scrapbook

Build DOM with the MS AJAX Toolkit Common Library

Building DOM elements by hand is mind numbingly boring. It’s more fun to watch paint dry. Traversing DOM is just as boring, which is what prompted my JQuery post.

If you’re writing a MS AJAX client control or behavior, you have some powerful functionality in the common toolkit library, common.js. See how you need to declare an extender control to have this library available. Btw, applying the [RequiredScript (typeof(CommonToolkitScripts))] attribute is ignored on controls implementing the IScriptControl interface. I guess only bona fide extenders are supported.

The syntax

Luckily, the AjaxControlToolkit.CommonToolkitScripts singleton has a shortcut notation, $common, which is simply a “global” JavaScript variable.

The library has an interesting factory method of a sorts, createElementFromTemplate, which saves you typing boring code of creating DOM elements, filling in their properties, attaching events, and doing the same for children elements (if any).

The function takes three parameters:

  1. template (mandatory): an object literal describing the intended element, properties, events, child nodes (if any), etc.
  2. appendToParent (optional): A DOM element within which to append the newly created element. Note: the parent must be an instance of DomElement which you can obtain via $get('....').
  3. nameTable (optional): An object to use as the storage for the element using template.name as the key, as inline documentation states. I know it sounds confusing. It is. I’ll skip it in this post. Once I understand what it’s used for and how, I’ll write a follow-up post.

Let’s look at some examples.

Example 1

var el = $common.createElementFromTemplate ({nodeName : 'div'});

This creates a bare-bones div. Seems slower than just calling document.createElement('div') because of all kinds of checks inside createElementFromTemplate.

Example 2

Here’s an example from our project:

var el = this.get_element();
var new_id = el.id + '_checkall_';

var footer = $common.createElementFromTemplate ({
   nodeName : 'div',
   cssClasses : ['callout'],
   children : [
   {
      nodeName : 'input',
      properties : { 
         type : 'checkbox', 
         id : new_id
      },
      events : this._checkAll$delegate
      /*
      Declared as: 
      this._checkAll$delegate = { 
          click : Function.createDelegate (this, this._toggle) 
      }
     */
   },
   {
     nodeName : 'label',
     properties : { 
         htmlFor : new_id
     },
     content : document.createTextNode ('*blah*')
  }]
});

I’m emulating the CheckBox server control, i.e. a checkbox and a label when rendered. This sample creates a footer div with a CSS class of 'callout', and I’m putting two child nodes inside: a checkbox (nodeName : 'input') and a label (nodeName : 'label').

Pay attention to how both child nodes are initialized, especially the htmlFor property of the label (since you can’t use 'for' as an attribute).

Also note the appendToParent and nameTable are not set here. I’m passing only one parameter, template, in the object literal notation. If template has a children field, as shown above, the children are simply fed recursively to createElementFromTemplate.

Example 3

Once you create an element, you need to attach it. It’s not attached for you by default! There are two ways to do it as the following sample shows:

$common.createElementFromTemplate ({
    parent : pager,
    nodeName : 'span',
    properties : { innerHTML: '*blah*' }
});

Here I’m creating a span with some arbitrary content and attaching it to an element called pager. You can do the same thing by passing pager in the appendToParent parameter:

$common.createElementFromTemplate ({
    nodeName : 'span',
    properties : { innerHTML: '*blah*' }
}, pager);

Example 4:

Adding one or more CSS classes is fine and dandy, but how about setting CSS rules explicitly? You can throw an object literal in the properties field:

properties : {
    style : {
    height : '100px',
    width : '100px',
    backgroundColor : 'white'
    }
}

Syntax recap

So what fields may the template parameter hold?

  • nodeName: a DOM element to create.
  • parent: a container to append the element to.
  • properties: an object literal with properties to assign to the element.
  • cssClasses: an array (!) of CSS classes to assign to the element.
  • events: an object literal of event handlers, same notation as for $addHandlers.

    For example (taken from inline documentation):

    events : {
     click : function() { alert('foo'); },
     mouseover : function() { elt.backgroundColor = '#999'; },
     mouseout : function() { elt.backgroundColor = 'white'; }
    }
  • visible: hide or show the element upon creation.
  • opacity: self-explanatory, right? Must be in the 0…1 range (ex: 0.3).
  • children: an array (!) of objects for each node in the same literal notation as template itself.
  • content: content to stick inside the element.
  • name and contentPresenter: work in tandem with the nameTable parameter which I won’t discuss here.

Passing up on nameTable

I don’t fully understand what the last parameter, nameTable is for. Neither can I find a reasonable explanation anywhere.

Comments

No comments yet

Emails and Notifications

Would you like to be notified when somebody responds to this post? 

TrackBacks

Sorry, TrackBacks are not allowed.

Submit your comment

Please enter only text since all HTML tags except hyperlinks will be stripped. Hyperlinks will become live links. Any comments with flaming or offensive language will be deleted. Be courteous to other posters. Thank you.

Your name (required):
Your email (optional):
Your site's URL (optional):
Enter this number
Type in the number above:
Comment (required):