PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

Eight Weeks of Prototype: Week 4, Event Handling in Prototype

Using Prototype to Fire and Handle Custom Events

In addition to being able to handle the native browser events such as click, mouseover, mouseout and other similar events, you can also define your own custom events. The difference between custom events and native events is that you must determine when these events should be fired, and then of course to fire them. Handling of custom events is almost identical to native events.

So the big question is, why would you ever need to use a custom event? What advantage does it provide over say, not using a custom event? Custom events allow different scripts on the same page to easily indirectly interact. If an action occurs on Script A, then this script can fire a particular event. If Script B is observing this event, then it knows the action has occurred.

Obviously this would be much clearer with an example. To demonstrate how custom events can be used we are going to create a page that contains essentially two items. The first is a list of items that the user can click on. The second is a status window that prints out what has happened.

Listing 15 shows the code that uses custom events. I'll list the code here then discuss it afterwards, including how to include extra data with your events and also how to name your custom events.

Listing 15 Using custom events (listing-15.html)
<html>
    <head>
        <title>Using custom events</title>
        <script type="text/javascript" src="/js/prototype.js"></script>
        <style type="text/css">
            #status { border : 1px solid #000; padding : 10px; }
        </style>
    </head>
    <body>
        <div>
            <h3>Items</h3>
 
            <ul id="myList">
                <li>Item 1</li>
                <li>Item 2</li>
                <li>Item 3</li>
                <li>Item 4</li>
            </ul>
 
            <div id="status">
                <h3>Status</h3>
            </div>
        </div>
 
        <script type="text/javascript">
            function onItemClicked(e)
            {
                var element = Event.element(e);
 
                var memo = {
                    name : element.innerHTML
                };
 
                document.fire('list:item_selected', memo);
            }
 
            function onCustomEvent(e)
            {
                var status = $('status');
                status.insert('<div>Selected: ' + e.memo.name + '</div>');
            }
 
            $$('#myList li').each(function(item) {
                item.observe('click', onItemClicked);
            });
 
            document.observe('list:item_selected', onCustomEvent);
        </script>
    </body>
</html>

In this example, we define two functions. The first (onItemClicked()) is used to handle the normal click event. The second (onCustomEvent()) is called when the list:item_selected event is triggered.

To create a custom event, it is simply a matter of firing the event using the document.fire() method. The first argument to this method is the name of the custom event, while the second (optional) argument contains any custom data you would like to be available from within the event object in the handler.

As you can see, we fire the list:item_selected event in the onItemClicked() method and pass to it the name of the list item that was clicked. This data is referred to as the event memo.

When you name a custom event you must namespace it by including a colon in the name. This is in order to prevent any naming conflicts with non-standard native events. In order to then observe this event you call the observe() method just as you would with normal events.

I've tried to keep the above example as simple as possible, so it may be difficult to see the real value in using custom events. Here's a practical example of where custom events are really useful. Consider an Ajax-powered address book that listed out all of your contacts. That is, you can view, add or delete contacts on the page, all handled in the background using Ajax.

If you were to add a new contact, your Ajax routine could fire an event such as user:addedonce it received confirmation from the server that the user was added. If the code that controls the list of users is observing this event, it can dynamically add the new user to the display in real-time (you can of course hold specific display information about the user in the event's memo field).

While technically the Ajax response could interact with the code that manages the display of the user list, using custom events it doesn't need to know anything about how that code works or even care whether or the display of contacts is there. This allows you to use the same "Add user" component on a different page that might not even display the list of users.

In This Article