Sencha Inc. | HTML5 Apps

Blog

Advanced Plugin Development with Ext JS

November 11, 2009 | Nige "Animal" White

When creating a cross browser RIA, choosing a framework with a plethora of components is where most of us look first. There comes a time, however, when the framework might not have the specific component or functionality we need. Here, selecting a framework that enables you the flexibility to enhance and expand its offering becomes very important. Fortunately, Ext JS has all the rich UI functionality that most applications require coupled with a vibrant community creating impressive extensions. However, sometimes, you will want to add extra capabilities to a component for which an extension is not available. Ext's elegant design allows us to explore our creativity by adding new features to existing widgets. We will explore several ways to approach this advanced task.

What is an Ext Plugin?

An Ext Plugin is a class (It could also be a singleton object) which is configured into a Component in the plugins config option. All plugins must implement a method named init which is called by the Component, passing itself as the sole parameter at initialization time right at the beginning of the Component's lifecycle, before it has been rendered.

Upon gaining control, a plugin must initialize itself to add capabilities and processing to its client Component.

This is usually done by augmenting certain methods of the client Component by specifying new functions to run either before or after the base Component's method. This is done using Ext's additions to all JavaScript functions, createInterceptor or createSequence. Each of these functions will be explained individually as they become relevant.

Approaches to Adding Functionality

When an application developer needs to enhance, or change the functioning of an existing Ext Component there are several options open each of which has advantages and disadvantages.

For example, Ext's form Fields receive the fieldLabel configuration when used in a Container with a layout of form. Imagine that we want to eliminate this requirement and allow Fields to manually render their own labels. Ext is flexible enough that we can add this functionality in many different ways.

There are three possible options:

Component configuration (Option 1)

The developer may choose to configure the input Fields with listeners on published events which use the published interface of the TextField class to achieve the requirement. This may be done by using the listeners configuration or setting up event handlers after the component is instantiated with the on method.

In a one-off situation, this might be the easiest option, but as soon as the requirement needs to be repeated in different situations, code duplication can arise. In this case, it's immediately obvious that we cannot add such complex new processing into each configuration of every Field.

Another disadvantage is that events may be programmatically suspended, or may be cancelled by existing event handlers rendering the added listeners inoperative.

Create a subclass (Option 2)

In a subclass, the developer overrides the template methods (more of which later) which provide the structure and lifecycle flow of the Component. The equivalent template method in the superclass is called either before or after the additional functionality is performed.

A possible implementation of a self labeling TextField class.

The disadvantage here is that forking off a subclass at any level in the hierarchy to add capabilities to a class, "strands" any existing subclasses of the augmented class. They are left without access to the extra functionality.

In this case, we've created an enhanced TextField which renders its own label, but this leaves subclasses like TriggerField, TextArea and NumberField unable to take advantage of the added functionality.

Another disadvantage is that if there are two subclasses of a base class which both implement some new capabilities, and a developer wants to use both sets of new capabilities, this is not possible.

Create a plugin (Option 3)

This option offers the most flexibility in terms of code reuse because if carefully written, a plugin for one class is usable by subclasses of that class. Also, multiple plugins may be used in a Component. This obviously requires that the plugins do not conflict with each other.

Implementing a Plugin

Before we dive into an implementation, let's examine how a plugin can entwine its required functionality around the existing functionality in an Ext Component without using events.

We avoid using events because there is no guarantee that our plugin's listener would be called before or after other event handlers. Other listeners might stop the event by returning false, or events may be programatically suspended.

Instead, we augment methods within the host Component which allows our plugin to gain control at important points in the component lifecycle.

The Template Method Pattern

Ext JS's Component class hierarchy uses the Template Method pattern to delegate to subclasses, behaviour which is specific only to that subclass.

The meaning of this is that each class in the inheritance chain may 'contribute' an extra piece of logic to certain phases in the Component's lifecycle. At each phase, a class implements its own special behaviour while allowing the other classes in the inheritance chain to continue to contribute their own logic. The template methods are analogous to events, they perform internal processing at defined points in Component lifecycles which loosely correspond to events.

An example is the render function. Instead of having to override it and duplicating its complex code, it provides you with hooks or Template Methods which each subclass can implement. The two hooks that are executed during the render process are onRender and afterRender. Every subclass implementor can add class-specific processing to any template method. By calling the hook on the superclass and up the entire inheritance hierarchy, we allow each class to contribute its own behavior while keeping the inheritance chain in tact.

The diagram above illustrates the execution of the onRender template method up the entire inheritance chain within a Component. When the render method is executed it will call this.onRender which is the implementation within the current subclass (if implemented). For example, if a subclass of Panel called MyPanel is being rendered, MyPanel.onRender is called. This method performs the special processing that makes the class different from the Panel class and calls the superclass version which calls its superclass version etc. Each class contributes its specific functionality, and control eventually returns to the render function.

There are several Template Methods in the Ext JS Component lifecycle which provide useful points to implement class-specific logic.

The Template Methods available to all Component subclasses are:

  • onRender Allows addition of behaviour to the rendering phase. After calling the superclass's onRender, the Component's Element will exist. Extra DOM processing may be performed at this stage to complete the desired structure of the control.
  • afterRender Allows addition of behaviour after rendering is complete. At this stage the Component's Element will have been styled according to the configuration, will have had any configured CSS class names added, and will be in the configured visibility and the configured enable state.
  • onAdded Allows addition of behaviour when a Component is added to a Container. After calling the superclass's onAdded, the Component will hold a reference to its parent Container in its ownerCt property.
  • onRemoved Allows addition of behaviour when a Component is removed from a Container. After calling the superclass's onRemoved, the Component will have no ownerCt reference.
  • onShow Allows addition of behaviour to the show operation. After calling the superclass's onShow, the Component will be visible.
  • onHide Allows addition of behaviour to the hide operation. After calling the superclass's onHide, the Component will be hidden.
  • onDisable Allows addition of behaviour to the disable operation. After calling the superclass's onDisable, the Component will be disabled.
  • onEnable Allows addition of behaviour to the enable operation. After calling the superclass's onEnable, the Component will be enabled.
  • onDestroy Allows addition of behaviour to the destroy operation. After calling the superclass's onDestroy, the Component will be destroyed.

Further Ext classes down the hierarchy add their own Template methods which are appropriate to their own capabilities. To learn more about adding functionality within template methods read the Creating New UI Controls article in the Learn section of our website.

Hooking into Template Methods

A plugin needs to insert some extra processing either before or after its client Component's template method executes. To do this, we need to understand how to create function interceptors and function sequences.

Interceptors

An interceptor function is a function which a developer uses to perform some functionality before an existing function performs its own functionality. As an example, let's insert some functionality before Observable's fireEvent method so that we can log all Ext events to the Firebug console. (Warning: there will be lots!)

 
// A class's methods are stored in its <b>prototype</b>, so grab that.
var o = Ext.util.Observable.prototype;
 
// This is the function we will be executing <b>before</b> the real fireEventMethod.
// It will be passed all the same argments, and has the same scope (this reference).
// Log the firer, the event name, and the arguments to the console.
 
function fireEventInterceptor(evt) {
    var a = arguments;
    var msg = "fired the following event {0} with args";
 
    console.log(this);
    console.log(String.format(msg, evt));
    console.log(Array.prototype.slice.call(a, 1, a.length)); 
}
 
// Set the class's fireEvent to be our interceptor.
o.fireEvent = o.fireEvent.createInterceptor(fireEventInterceptor);
 

It's that simple. Our function always gets called before Ext's original fireEvent method.

Sequences

A sequence is a function which gets executed after an existing function.

Our plugin implementation uses sequences to add its own processing after the processing of the Field has taken place.

A FieldLabeler Plugin

In this case, the plugin is a singleton. It cannot be instantiated. It is specified simply using:

 
plugins: [ Ext.ux.FieldLabeler ]
 

It augments several of its client Field's template methods with its own methods. These execute as if they were member methods of the Field. Their this reference is the Field itself, so they can perform any processing which may be necessary at that particular lifecycle phase. This is why a singleton may be used - all contextual information is in the client Component.

The three methods we augment within our plugin are:

  • onRender
    Our added code renders extra DOM elements.
  • onResize
    Our added code ensures the extra DOM elements are sized properly
  • onDestroy
    Our added code ensures the extra DOM elements are cleaned up.

By implementing this functionality as a plugin rather than a subclass we have eliminated the problem of our downstream plugins not receiving the added functionality. This plugin is capable of being integrating with TriggerField, TextArea and NumberField without a problem.

Take a look at the example of this plugin in action here. The source has been comprehensively documented and is available here.

Summary

We explored different ways to implement custom functionality and specifically how to create reusable plugins without creating a fragile class hierarchy. Using plugins to augment Ext's baseline functionality is one of the best approaches when you want to be able to mix and match functionality. The most important concept to grasp is that we can provide additional functionality by augmenting existing methods within a component that are guaranteed to be executed during a components lifecycle. We encourage you to take a look at the thousands of plugins available on the Ext Forums. We hope that our post and community inspire you to take the plunge into Ext plugin development.

There are 36 responses. Add yours.

Tweets that mention Ext JS - Blog -- Topsy.com

5 years ago

[...] This post was mentioned on Twitter by extjs and Basilakis, Michael Benson. Michael Benson said: EXT Plugin Development. http://tr.im/ELFo [...]

Steffen

5 years ago

Great article Nigel!

I probably should print out Ext’s function methods (http://www.extjs.com/deploy/dev/docs/?class=Function) which I sometimes forget that they exist and stick them to my wall.

Cheers,
Steffen

Sergei

5 years ago

Your articles on Ext JS are the most informative, consistent and clear, recommended to every Ext developer who really wants to understand the framework. Thanks, Nigel, and looking forward to reading more stuff from you.

Robert Sanchez

5 years ago

Nigel, after reading your article I must say you have a grasp on JS like none other!! aha. Thanks for the very informative article and keep ‘em comin!

David Davis

5 years ago

Great post Nigel!

eastxing

5 years ago

Excellent tutorial, informative and clear, thanks!

james k

5 years ago

Great post! Huge eye opener.  To be honest, after reading this I feel I have so much more to learn.  I’m moving from script kiddie to JavaScript developer.  Can anyone share how long this journey takes?

Nickolay

5 years ago

Very well written, kudos to the author

links for 2009-11-12 « pabloidz

5 years ago

[...] Advanced Plugin Development with Ext JS (tags: extjs) [...]

Mats

5 years ago

Great stuff mr Animal smile

Juan Mendes

5 years ago

Thanks Animal, for this great article. Great insight into the three approaches of customizing widgets. The problem with component configuration (code duplication) becomes obvious as you try to reuse it. However, the problems with subclassing are mores subtle but were thoroughly well explained here. I do currently used the subclassing approach most often but will start looking into plugins when possible.

Rothariger

5 years ago

Great article…


thanks a lot!

Praveen Ray

5 years ago

Animal, you Rock!

Crysfel

5 years ago

Excellent post!!

thanks :D

justin

5 years ago

Very impressive. I read it a few times to make sure I didn’t miss anything.  Javascript and the additions Ext has brought to the language make you want to code only in Ext JS.

Bundaberg Web Developer

5 years ago

Great article Nigel.
Keep them coming.
If this was in a magazine - I’d buy the whole magazine just for the article!

Crysfel

5 years ago

Very delicious article.

Charles

5 years ago

Nigel, since you are recommending that a plug-in should augment the methods of the host Component and these methods run within the scope of the host Component, then any additional values needed by the plug-in will be added onto the host.  Does that give you any qualms?  I guess I was debating in my own mind whether it were safer to maintain a plug-in’s values within its own scope separate from the host thinking this would protect the host variables from inadvertent obliteration by the plug-in or visa versa making the plug-in more resistant to any future Ext updates should Ext add variables of the same name later.

ExtJS – ?????????? [???????? ?????] «

5 years ago

[...] ??????? ??????????? ???????? ???????? ? ExtJS (Advanced Plugin Development with Ext JS). ?????????, ???? ??????? ?? ?????. ? ??????, ? ?????? [...]

Animal

5 years ago

Charles, that is a very good point. There are ways to protect the plugin’s context within the host Component. But perhaps that warrants a thread in the “Open Discussion” folder of the forum at extjs.com.

Parkash

5 years ago

Hey i am an eclipse RCP developer is it possible to create modular web application using EXT JS any ideas ????

Tipitip

5 years ago

What I’m doing wrong.

1. var comp = new myCompGrid({})
  ....
  var pnl = new Panel({
    items: comp
  })
———>height 100%

2. var pnl = new Panel({xtype:“myCompGrid”}
———>height 20px

derekl

5 years ago

Hi all,

What is the significance, is it recommended and helpful of using namespace definition as pertains to developing ext plugin?

I am looking at one example, are there more examples of well-developed plugins available?

Thanks,

Derek

greg

5 years ago

@derekl

Look at the Forums.  There are 1000’s of plugins there.  Great Article Nige, loved it.

Alex - ajaxBlender

5 years ago

This is a really good article for ExtJS programmers, especially for those who are using the framework to develop complex UI’s. Thanks for posting it. This is a good one to share!

Americo

5 years ago

Very nice article. Clean concise and to the point. Love it.

frank

4 years ago

I just made a translation to this great article into Chinese, which url is:
http://blog.csdn.net/zhangxin09/archive/2010/02/22/5317109.aspx
???????????

oya-dantel

4 years ago

What is an Ext Plugin?
An Ext Plugin is a class (It could also be a singleton object) which is configured into a Component in the plugins config option. All plugins must implement a method named init which is called by the Component, passing itself as the sole parameter at initialization time right at the beginning of the Component’s lifecycle, before it has been rendered.

Upon gaining control, a plugin must initialize itself to add capabilities and processing to its client Component.

Dantel Örnekleri

4 years ago

What is an Ext Plugin?
All plugins must implement a method named init which is called by the Component, passing itself as the sole parameter at initialization time right at the beginning of the Component’s lifecycle, before it has been rendered.

Upon gaining control, a plugin must initialize itself to add capabilities and processing to its client Component.

Diyet

4 years ago

Upon gaining control, a plugin must initialize itself to add capabilities and processing to its client Component.

Pua

4 years ago

I’m also interested in how
namespace definition ties in
here.


?

Shemika Hoard

4 years ago

Thanks for this information. Advanced Plugin Development with Ext JS — Ext JS Blog — JavaScript Framework and RIA Platform was a wonderful read. My sister has been wondering about this topic for a while.

??

4 years ago

I just made a translation to this great article into Chinese, which url is:
http://blog.csdn.net/zhangxin09/archive/2010/02/22/5317109.aspx

Siki?

4 years ago

Very delicious article.

Rick

4 years ago

Nigel, you have some great information here.  I’ve been getting back into coding after years of being away from it so this is a great place for me to start picking up some good knowledge.  Definitely going to bookmark this site.  Thanks!

Rick

djones

3 years ago

The links for the example and source are down?

Comments are Gravatar enabled. Your email address will not be shown.

Commenting is not available in this channel entry.