Wednesday, September 29, 2010

jQuery triggering custom event (Observer pattern)


Introduction

We all know what basic events in JavaScript and jQuery are. They represent handlers that are triggered at specify event (click, timer, mouse move, etc.). But how do we create custom events that are triggered on our command, here comes jQuery to the rescue! Also doing this (calling custom events), we can simulate classic Go4 observer pattern (publish/subscribe).

Using jQuery is beneficiary, because, we are not concerned about various DOM levels, browser specific stuff (like: (event.target) ? event.target : event.srcElement;...), does IE 6,7,8 support event capture phase, and stuff like that. We basically create another abstraction level over various JavaScript implementations.

So, let the fun begin!

Live event handling

In our example we will use jQuery ability to manage event handler on the fly (as we manipulate the DOM by adding or removing elements). This means that we will proactively establish event handlers for elements that don't exist yet. jQuery provide this functionality with the live() method. Syntax for this method is similar like bind() or for example click() method.

Triggering events

In out example we will also need some method that will automatically invoke (trigger) event handlers on our behalf under script control. For this we will use the trigger method. This method does its best to simulate the event to be triggered. One curiosity is that it even populate instance of jQuery event (event object in jQuery style :) ), but because there is no real event, properties that report event-specific values such as the location of mouse x and y cordinates, have no value. Ok, let's move on.

Example

First jQuery part:

$(function() { //Wait until DOM is fully loaded .
    $('#addBox').click(function() {
        $('td.box:first-child').clone().appendTo('tr.boxLine');                
    });

    $('#paintBlue').click(function() {                
        $('td.box').trigger('paintThem');
    });

    $('td.box').live('paintThem', function() {
        $(this).css('background', 'blue');                
    });            
});

2-5: First we create simple click handler that add new box like element on the DOM. We create boxes using simple table and just adding new table data elements by coping them. Please see html part, and first picture where we add couple of boxes.

6-8: Here we trigger custom event named "paintThem". This is simple click event triggered by button. We need to trigger custom event on elements (in this case 'td.box') that posses custom event (but, also we can trigger standard events like: click, hover...).

10-12: The "real meat" of this whole story. Here we see a use of the live() method to proactively establish event handlers. The 'td.box' elements will be added dynamically to the DOM and live method will automatically establish handlers as necessary.
This way, we sat it up _once_ and jQuery will handle the details whenever an item that matches that selector (td.box) is create (or destroyed). Great stuff!

So as you can see, this example is not so fancy, it just paint red boxes to blue. But the way it does it is interesting. I can also walk trough all elements and paint them to certain color, but this approach is much cleaner and in some situations better (asynchronous refresh (AJAX) for example).

Then, html part. My apologies for this fuzzy looking html code (it's blogger fault! :) ).


Custom event is a very useful concept. Using it, we can attach code to an element as a handler for a custom event, and cause it to execute by triggering the event. The beauty of this approach, as opposed to directly calling code, is that we can register the custom handlers in advance, and by simply triggering the event, cause any registered handlers to be executed, without having to know they've been established.

Custom event concept in jQuery can be seen as limited version of Observer pattern. In this pattern (also know as publish/subscribe pattern) we subscribe an element to a particular event by establishing a handler for that element, and then when the event is published (triggered), any elements that are subscribe to that event will automatically invoke their handlers.

In this way we are creating loose coupling (and that is always a _good_ idea) in our JavaScript code. This make our code cleaner and meaner!

Custom trigger in action:

Adding boxes.


Triggering event to paint boxes in blue.

2 comments:

  1. Nice text. Simple but objective.
    Was looking for a Observer example for a friend and this helped. It's from 2010 but still nice.

    Thanks

    ReplyDelete
  2. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a Front end developer learn from JQuery Training in Chennai . or learn thru JQuery Training . or learn thru ES6 Online Training. Nowadays JavaScript has tons of job opportunities on various vertical industry.

    ReplyDelete