Thursday, September 4, 2008

Custom Events in ExtJS

I was kind of new to the idea of event driven applications, but after reading a little about it fell in love with it. I immediately had some applications in my work where it would solve particular problems I was having. Having never implemented this before, I didn't know where to start. Searching the ExtJS forum I uncovered some good information, but not enough to just jump right into it.

I thought I would blog about it while it was still fresh in my mind.

First you need to extend the Observable class for the class that you want to add a new custom event to. Then in a method called when the class is constructed, you need to add the new custom event. I needed to throw a custom event whenever the tab changed. As you can see from the code below, that a 'tabchange' event triggered a call to onTabChange function. This function then fires the 'myCustomEvent' event. That is all it takes to create a custom event. Of course, nothing will happen if there are not any listeners registered for that event.

Example.Events = function(config) {
this.initialize(config);
};
Ext.extend(Example.Events, Ext.util.Observable, {
initialize: function(config) {
this.addEvents('myCustomEvent');
this.panel = new Ext.TabPanel({
.....
};
this.panel.on('tabchange', this.onTabChange.createDelegate(this));

}
onTabChange : function(tabPanel, tab) {
var index = -1;
if (tab.getIndex) {
index = tab.getIndex();
}
this.fireEvent('myCustomEvent', index);
},
}

In my case, I had widgets that existed on tabs and they need to know when their tab was activated. So inside those widgets they needed to obtain a reference to the Example.Events object for our application, and then register as a listener and tell it which function to call back on. I did this in the widget constructor, as shown below.

in constructor:

var event= Example.Parent.getEvent();
event.on('myCustomEvent', this.tabSelected.createDelegate(this));
this.myTabIndex = event.getMyIndex();

The call back function:
tabSelected : function(index) {
if (index == myTabIndex) {
// Do something if your tab is activated
}
},


That's it. There is nothing more to it. And it works like a charm.

1 comment:

Aaron Conran said...

Great post Jeffrey. It's worth nothing that you could also use the inherited relayEvents method from your new Observable class as well. relayEvents is often useful when you want to 'throw' the event up your chain of objects.

In your case you could do the following:
this.relayEvents(this.panel, ['tabchange']);

Now your new class will pass the tabchange event along through any instance of the Example.Events class.