One of the features of the prototype library that I like to use is the Enumerable class.  Although highly debatable in regards to the legitimate necessity for such class, I like the simplicity and beauty of using Prototype’s enumerable class.

So, when using Ext as a base library (not using the Prototype adapter) for JavaScript DOM manipulation I looked into the enumeration methods available, such as Ext.each().  Here is a quick overview of how I used Ext.each to traverse members of a collection of HTML nodes.  I decided to split this up into main topics; first I will talk about why I like to use the enumerable class, and then show you a simple example of using the Ext.each() method.

Why use enumerable methods?

You might be asking yourself, why?  Great question.  Yes, I can traverse over nodes using several looping operators such as for().  However, using Ext’s traversal methods allows me to call other methods and maintain context over this.

Prototype’s enumerable class is inherited from Rails, and allows for ease of implementing helpers in Ruby that generate JavaScript code or coding in rjs (JS templating engine providing element and collection proxies), which is translated into JavaScript code when delivered to the client.  Therefore, Prototype’s Enumerable class implementation is basically borrowed from the Ruby Enumerable API; lending the elegant use of blocks (anonymous functions in JS) to apply a snippet of code to a sequence of objects.

Still not convinced about enumerables?  Well, lets compare two snippets of code that check all checkboxes within a form dependent upon the checked status of a single checkbox - think of the ‘ole ‘check all’ checkbox.

Without using enumerables, I might do the following (still using prototype library):

?View Code COLDFUSION
1
2
3
4
5
6
7
function checkAll(formid,ctrl){
  var checkboxes = $(formid).getInputs('checkbox');
  var state = $(ctrl).checked;
   for (var i=0;i<checkboxes.length;i++){
     checkboxes[i].checked = state;
  }
}

With Prototype’s enumerables, I would be able to accomplish this in one line (thanks to method chaining):

?View Code COLDFUSION
1
2
3
function checkAll(formid,ctrl){
  $(formid).getInputs('checkbox').each(function(checkbox){checkbox.checked=$(ctrl).checked;});
}

Using Ext.each() method

So, lets dive in and look at the Ext.each() method.  The method syntax looks like this:

eachArray/NodeList/Mixed array, Function fn, Object scope ) : void

Basically, for each element in the Array/NodeList/Mixed array argument, the function specified in the second argument is called passing in each item in the array as the first argument, bound to the object scope specified.  The following example using Ext.query() (using CSS selection) to obtain all elements with the class name ‘addlink’, and change the behavior of the link.  This is an unobtrusive method to applying behavior to HTML elements after the page loads:

?View Code COLDFUSION
1
2
3
4
5
6
7
8
9
10
11
12
13
function addEventListeners(){
    var links = Ext.query('.addlink');
    if (links.length){
     Ext.each(links,function(el){
         var element = Ext.get(el);
         element.on('click', function(){
             ColdFusion.navigate(this.href,'editwindow');
             ColdFusion.Window.onShow('editwindow',windowShowHandler.createCallback('Add user','editwindow'));
             ColdFusion.Window.show('editwindow');
         },this,{stopEvent:true});
     });
    }
}

Lets take a look at this closely.  After obtaining a nodelist of elements whose class attribute contains the string ‘addlink’, I am traversing the list of nodes passing the individual node into an anonymous function.  Inside the anonymous function, I am adding an event listener to the click event, and preventing the default action from occurring.

Example

Lets look at the <cfwindow> example.  Notice that if you click the link below the grid ‘Add user’, a <cfwindow> is appropriately opened up with the form.  Now, disable JS and reload the page.  You should now notice that clicking the ‘Add user’ link does not open a cfwindow tag, rather it keeps the traditional behavior specified by the href attribute in the <a>tag.  Sidenote:  Of course, the <cfgrid> no longer works with JS disabled, so this isnt really a practical example, but at least shows how unobtrusive JavaScript fails gracefully.

This entry was posted on Friday, April 4th, 2008 at 3:50 pm.
Categories: Javascript.

No Comments, Comment or Ping

Reply to “Enumerating with Ext.js”