Ext JS - Learning Center

Tutorial:Events Explained

From Learn About the Ext JavaScript Library

Jump to: navigation, search
Summary: This tutorial will explain what events are and how they are used in Ext.
Author: Jozef Sakalos, aka Saki
Published: May 18, 2008
Ext Version: 2.0+
Languages: en.png English cn.png Chinese it.png Italian

Contents

Historical Background

Most likely many of you who will read this article do not remember times of Fortran language and computers that were fed with tons of punch cards to have some job done.

The main purpose of computers at that time was to compute something really; that is not true anymore because computers very rarely are used for getting computational result at schools or scientific institutions.

How did it work at that time? If you wanted a computer to run a program, you went to a shelf with your punched cards, you found the drawer with the stack of them, fed them through card reader and the computer started your program.

First task was to ask for user inputs and once you filled them in the program computed the result, printed it and ended. Easy, straightforward, "single thread" job.

Events Introduced

With the invention of GUI and Mouse this concept of load-run-end just didn't work anymore - as we needed some infinite loop that would wait for user actions (mouse movement and clicks) and that would process them to execute the required actions.

It became clear that putting the code that processes these actions directly in that loop is the route to no where, so the Event driven programming was born.

Event Definition

Event is a message, a function call, generated by one (part of) program, the event source, that notifies another (part of) program, the event listener, that something happened. Events are generated as responses to user actions or to state changes of the event source.

The event source is independent of event listeners and it generates events also if nobody listens or even if there is no listener defined. The viewpoint of our infinite loop would be: "I'm informing everybody that user moved the mouse to position [x,y] and I do not care who listens, if anybody."

The viewpoint of the listener would be: "Let me know when user moves the mouse, I need to do something with it."

Events in Ext

There are two main "sorts" of events in Ext: DOM events and JavaScript, or software, events.

DOM Events

Browsers that display (X)HTML pages already have our "infinite loop" that watches user actions and fires events if these actions are occurring on DOM elements. Before Ext we were used to install event listeners on DOM elements this way:

<div id="mydiv" onclick="alert('You clicked me')">Click me!</div>

Ext.Element wraps DOM elements together with their events so now we install the same event handlers this way:

Ext.get('mydiv').on('click', function() {alert('You clicked me');});

It can be said that DOM events are "passed-through" from DOM through Ext.Element to listeners.

JavaScript Events

Now, DOM elements are not the only possible event sources; it is quite easy to implement event source logic and event listener installation to any JavaScript object. But, what could it be good for?

Imagine that you have a complex component such as grid. If you had only DOM events, the handling of user actions such as column move would be extremely difficult. You would need to listen to DOM elements, process mouse clicks, moves, calculate from where to where the column has been moved, etc. If would be much easier if grid component would do all this dirty work for you and, after everything has be done, just informed you: "User moved column 3 to position 1."

That is exactly what grid does: it fires JavaScript events that inform potential listeners what has happened to it. The same is true for another Ext components. Form validation events, Panel resize events, Tree expand/collapse events can serve as examples, to name a few.

How do I listen to events?

If you have an object of Ext class, for example Panel, and you need to do some action when panel resizes you would install a listener to implement your action:

// create panel
var myPanel = new Ext.Panel({...});
 
// install resize event listener
myPanel.on('resize', function(panel, w, h) {
    alert('Panel resized to ' + w + 'x' + h);
});
 
// you can also add an event listener to a component configuration.
var myPanel2 = new Ext.Panel({
    listeners: {
        resize: function(panel, w, h) {
            alert('Panel resized to ' + w + 'x' + h);
        }
    }
});

From this point on, whenever the panel myPanel is resized your function is called so you can do your actions.

How do I create an event source?

Event related functionality is implemented in the Ext.util.Observable class. To make your extension an event source, just extend Ext.util.Observable. Please note extending a class that is already a descendant of Observable (Panel, Grid, Form, Tree, etc), will make your extension the event source automatically.

Events fired by your extension are events fired by parent class(es).

Custom Events

It will often happen that you need to add a new custom event that isn't built-in to the Ext framework. So for example let's say you have two classes, Employee and Organization Chart, that you have implemented drag&drop assignment/dismissal of employees to/from a position. It would come in handy to fire both an assigned and dismissed event, wouldn't it?

In this example we will also create listeners for these events that will send e-mails to an employee informing them of any assignment change automatically!

So here is how we do it:

OrgChart = Ext.extend(Ext.Panel, {
    initComponent:function() {
        // call parent init component
        OrgChart.superclass.initComponent.apply(this, arguments);
 
        // add custom events
        this.addEvents('assigned', 'dismissed');
    }
 
    ,assign:function(employee, position) {
        // do whatever is necessary to assign the employee to position
 
        // fire assigned event
        this.fireEvent('assigned', this, employee, position);
    }
 
    ,dismiss:function(empoyee, position) {
        // do whatever is necessary to dismiss employee from position
 
        // fire dismissed event
        this.fireEvent('dismissed', this, employee, position);
    }
});

In the initComponent function we inform the Observable class that we are going to fire our new events so it can do all necessary setup.

Note: Even though we did not extend Observable directly, Panel (what we extended) did. Notice Panel's inheritance chain: Observable -> Component -> BoxComponent -> Container -> Panel.

Now in the assign and dismiss functions we fire our events after all assign/dismiss jobs have been done with the signature (arguments) of our choice.

When we call fireEvent, Observable looks if there are any listeners for this event and calls for all listeners with the arguments we supplied in the fireEvent call. If there is no listener it will do nothing.

Summary

  • event is a message sent (fired) by an event source to inform listeners that something happened
  • event source is an object that can fire events
  • event listener is a function that is called when event source fires an event
  • to listen to events we use on function to install an event listener
  • to create an event source we extend Observable class, addEvents and fireEvent

Enjoy firing your events and listening to them!

Further Reading

  • This page was last modified on 9 February 2009, at 18:26.
  • This page has been accessed 25,676 times.