YUI 3.x Home -

YUI Library Examples: Event: Using Custom Events

Event: Using Custom Events

The Custom Event framework is one of the principle communication mechanisms in YUI. An object can be augmented with EventTarget, enabling it to be both a host and a target for Custom Events. Custom Events fire from their host and optionally bubble up to one or more targets. This allows you to make the interesting moments of your applications broadly available within a module, within a set of modules, or throughout a complex interface populated with rich elements.

In this example, a simple Custom Event is illustrated: testEvent. This Custom Event is hosted on a Publisher object and bubbles up to a BubbleTarget object.

An
illustration of the relationship between the Custom Event, its host, and its
Bubble Target.

Custom Events, like DOM events, can be stopped (stopPropagation) and their default behavior can be suppressed (preventDefault).



  1. Custom Event log messages will appear here.

Source Code

The full source code for this example follows. Read through the comments and code to get an understanding of how you can make use of Custom Events in your own application development.

  1. //Create a YUI instance:
  2. YUI().use('node', function(Y) {
  3.  
  4. //Shortcut for our logging div:
  5. var logger = Y.one("#log");
  6.  
  7. //Our BubbleTarget object is an object to which our Custom Event
  8. //will be allowed to bubble. It needs itself to be an EventTarget,
  9. //so we'll use augment to make it an EventTarget:
  10. var BubbleTarget = function() {
  11. Y.log("Host constructor executed.", "info", "example");
  12. }
  13. //Augment BubbleTarget to make it an EventTarget:
  14. Y.augment(BubbleTarget, Y.EventTarget);
  15.  
  16. //Create an instance of BubbleTarget:
  17. var bubbleTarget = new BubbleTarget();
  18.  
  19. //Now we'll subscribe to the "publisher:testEvent" -- note
  20. //that we can do this even before this event is published:
  21. bubbleTarget.on("publisher:testEvent", function(e) {
  22. Y.log("publisher:testEvent fired on the BubbleTarget object.", "info", "example");
  23. });
  24.  
  25. //Now we'll create the constructor for the Publisher, which
  26. //is the direct host of our Custom Event. It will also be an
  27. //EventTarget, so we'll extend it as well:
  28. var Publisher = function(bubbleTarget) {
  29.  
  30. //We'll specify now that Custom Events hosted by Publisher
  31. //should bubble to the bubbleTarget instance passed into the
  32. //the Publisher's constructor:
  33. this.addTarget(bubbleTarget);
  34.  
  35. //Here we publish the Custom Event. Note that it's not
  36. //necessary to publish the event at all if you don't have
  37. //options you wish to configure -- firing the event or
  38. //subscribing to it will create it on the fly if necessary:
  39. this.publish("publisher:testEvent",
  40. {
  41. emitFacade: true,
  42. //the defaultFn is what you want to have happen
  43. //by default when no subscriber calls preventDefault:
  44. defaultFn: function() {
  45. Y.log("defaultFn: publisher:testEvent's defaultFn executed.", "info", "example");
  46. },
  47. //You can prevent the default function from firing by
  48. //calling preventDefault from a listener (if the Custom
  49. //Event's preventable option is set to true, as it is by
  50. //default). If the default is prevented, the preventedFn
  51. //is called, allowing you to respond if necessary.
  52. preventedFn: function() {
  53. Y.log("preventedFn: A subscriber to publisher:testEvent called preventDefault().", "info", "example");
  54. },
  55. //The stoppedFn is called if a subscriber calls stopPropagation or
  56. //stopImmediatePropagation:
  57. stoppedFn: function() {
  58. Y.log("stoppedFn: A subscriber to publisher:testEvent called stopPropagation().", "info", "example");
  59. }
  60. }
  61. );
  62. Y.log("Publisher constructor executed.");
  63. }
  64. //Augment Publisher to make it an EventTarget:
  65. Y.augment(Publisher, Y.EventTarget);
  66.  
  67. //Create a Publisher instance:
  68. var p = new Publisher(bubbleTarget);
  69.  
  70. //We've already subscribed to the event on the bubbleTarget, but
  71. //we can also subscribe to it here on the Publisher instance.
  72. //We'll see the event fire here before it bubbles up to the
  73. //bubbleTarget:
  74. p.on("publisher:testEvent", function(e) {
  75. Y.log("publisher:testEvent subscriber fired on the publisher object.", "info", "example");
  76. if(Y.one("#stopPropagation").get("checked")) {
  77. //we will stopPropagation on the Custom Event, preventing
  78. //it from bubbling to the bubbleTarget:
  79. e.stopPropagation();
  80. }
  81.  
  82. if(Y.one("#preventDefault").get("checked")) {
  83. //we will preventDefault on the Custom Event, preventing
  84. //the testEvent's defaultFn from firing:
  85. e.preventDefault();
  86. }
  87. });
  88.  
  89. //We can tie our testEvent to an interface gesture -- the click of a
  90. //button, for example.
  91. Y.on("click", function(e) {
  92. //clear out the logger:
  93. logger.set("innerHTML", "");
  94. p.fire("publisher:testEvent");
  95. }, "#fire");
  96.  
  97. //write out log messages to the page:
  98. Y.on("yui:log", function(e) {
  99. var s = logger.get("innerHTML");
  100. logger.set("innerHTML", s + "<li>" + e.msg + "</li>");
  101. });
  102.  
  103. });
//Create a YUI instance:
YUI().use('node', function(Y) {
 
    //Shortcut for our logging div:
    var logger = Y.one("#log");
 
    //Our BubbleTarget object is an object to which our Custom Event
    //will be allowed to bubble.  It needs itself to be an EventTarget,
    //so we'll use augment to make it an EventTarget:
    var BubbleTarget = function() {
        Y.log("Host constructor executed.", "info", "example");
    }
    //Augment BubbleTarget to make it an EventTarget:
    Y.augment(BubbleTarget, Y.EventTarget);
 
    //Create an instance of BubbleTarget:
    var bubbleTarget = new BubbleTarget();
 
    //Now we'll subscribe to the "publisher:testEvent" -- note
    //that we can do this even before this event is published:
    bubbleTarget.on("publisher:testEvent", function(e) {
        Y.log("publisher:testEvent fired on the BubbleTarget object.", "info", "example");
    });
 
    //Now we'll create the constructor for the Publisher, which 
    //is the direct host of our Custom Event.  It will also be an
    //EventTarget, so we'll extend it as well:
    var Publisher = function(bubbleTarget) {
 
        //We'll specify now that Custom Events hosted by Publisher
        //should bubble to the bubbleTarget instance passed into the
        //the Publisher's constructor:
        this.addTarget(bubbleTarget);
 
        //Here we publish the Custom Event.  Note that it's not
        //necessary to publish the event at all if you don't have
        //options you wish to configure -- firing the event or 
        //subscribing to it will create it on the fly if necessary:
        this.publish("publisher:testEvent",
            {
                emitFacade: true,
                //the defaultFn is what you want to have happen
                //by default when no subscriber calls preventDefault:
                defaultFn: function() {
                    Y.log("defaultFn: publisher:testEvent's defaultFn executed.", "info", "example");
                },
                //You can prevent the default function from firing by
                //calling preventDefault from a listener (if the Custom
                //Event's preventable option is set to true, as it is by
                //default).  If the default is prevented, the preventedFn
                //is called, allowing you to respond if necessary.
                preventedFn: function() {
                    Y.log("preventedFn: A subscriber to publisher:testEvent called preventDefault().", "info", "example");          
                },
                //The stoppedFn is called if a subscriber calls stopPropagation or
                //stopImmediatePropagation:
                stoppedFn: function() {
                    Y.log("stoppedFn: A subscriber to publisher:testEvent called stopPropagation().", "info", "example");
                }
            }
        );
        Y.log("Publisher constructor executed.");
    }
    //Augment Publisher to make it an EventTarget:
    Y.augment(Publisher, Y.EventTarget);
 
    //Create a Publisher instance:
    var p = new Publisher(bubbleTarget);
 
    //We've already subscribed to the event on the bubbleTarget, but
    //we can also subscribe to it here on the Publisher instance.
    //We'll see the event fire here before it bubbles up to the 
    //bubbleTarget:
    p.on("publisher:testEvent", function(e) {
        Y.log("publisher:testEvent subscriber fired on the publisher object.", "info", "example");
        if(Y.one("#stopPropagation").get("checked")) {
            //we will stopPropagation on the Custom Event, preventing
            //it from bubbling to the bubbleTarget:
            e.stopPropagation();
        }
 
        if(Y.one("#preventDefault").get("checked")) {
            //we will preventDefault on the Custom Event, preventing
            //the testEvent's defaultFn from firing:
            e.preventDefault();
        }
    });
 
    //We can tie our testEvent to an interface gesture -- the click of a
    //button, for example.
    Y.on("click", function(e) {
        //clear out the logger:
        logger.set("innerHTML", "");
        p.fire("publisher:testEvent");
    }, "#fire");
 
    //write out log messages to the page:
    Y.on("yui:log", function(e) {
        var s = logger.get("innerHTML");
        logger.set("innerHTML", s + "<li>" + e.msg + "</li>");
    });
 
});

Copyright © 2009 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings