Events

The Mojo framework provides a way to respond to user actions. If you are familiar with the W3C event model, the HP webOS event model will hold few surprises for you. Events are actions applied to scene elements. Tapping on a button, for example, generates an event. To be functional, the button must have a handler, a method for handling the tap event. Elements specify which events they handle by registering themselves as listeners for those events.

Framework Event Types

Mojo includes the W3C event types, and also defines event types specific to webOS. The Mojo.Event section of the API documentation contains a complete list of event types, with descriptions and reference information.

Not all events are handled by widgets. The meaning of a non-widget event depends on the context in which the event occurs, and it must be handled accordingly.

Custom Event Types

You can define your own event types with the mojo.event.make() method, and propagate them to event handlers by calling the mojo.event.send() method.

Listening

When an event occurs, the framework notifies any code that is subscribed to handle the event. You can subscribe a DOM element to events by calling one of the following methods:

  • Mojo.Event.listen() or this.controller.listen()
  • .addEventListener()
  • observe()

Make sure to remove any event listeners when they are no longer needed, generally in your scene assistant's cleanup() method; otherwise, your application may leak memory. It is especially important to remove listeners in two cases:

  • when the listener is attached to a DOM node outside of the scene
  • when the listener is attached to a node within a closure

These cases can lead to a memory leak if listeners are not removed. The basic pattern looks like this:

this.element = ...some DOM node...;
this.element.addEventListener('whatever', someFunction.bind(this), false);

Even when the node is removed from the DOM, the cluster of objects is not garbage collected.

There is an issue with referencing elements by DOM ID. The Prototype $ and getElementById won't work across stage boundaries. If you have a multi-stage application, use this.controller.listen() if you pass an element by DOM ID, or this.controller.get() when you want to retrieve an element by DOM ID.

As in the standard HTML model, events bubble up the DOM tree; the parent DOM element receives the events that occur on any child elements. For widgets, you should observe events on the enclosing DIV element instead of on an element that is part of the widget implementation.

The following code snippets show how to subscribe to events using the Mojo.Event.listen() method, which is the preferred mechanism:

  • Define the HTML DOM element associated with an event and assign an ID to the element.

    <button id='okButton'>OK</button>
    
    
  • Provide a JavaScript method to handle the event.

    handleOk: function() {
      Mojo.Log.info("Received the OK");
    }
    
    

    This is the handler specified when the user subscribes to the event. The method is invoked by the browser when the event occurs. You should provide the event handling logic appropriate for the event and application context.

  • Subscribe to the event, using the element ID and specifying the event handler method.

    this.okButton = this.controller.get('okButton');
    Mojo.Event.listen(this.okButton, Mojo.Event.tap,
      this.handleOk.bind(this));
    
    

stopListening

Use one of the following methods to remove your listener from events:

  • Mojo.Event.stopListening() or this.controller.stopListening()
  • .removeEventListener()
  • stopObserving()

You should use the method that corresponds to the method used for listening to the event; in other words, use the Mojo method to stop listening if you used it for listening.

With any of these methods you must use the exact handler reference used in the listen method call. In the above example, the handler was specified as this.handleThanks.bind(this) which won't work in the stopListening method. Try this instead:

this.okButton = this.controller.get('okButton');
this.eventHandler = this.handleOk.bind(this);
Mojo.Event.listen(this.okButton, Mojo.Event.tap,
  this.eventHandler);
. . .
Mojo.Event.stopListening(this.okButton, Mojo.Event.tap,
  this.eventHandler);

Using Events with Widgets

Many widgets dispatch events. Applications can use these to better leverage the functionality built into the controls. Events are generally dispatched to the widget's element, the DIV defined in the scene's view HTML that has the x-mojo-element attribute.

For the list of widgets that propagate a particular event, refer to the event reference documentation in Mojo.Event.

For the list of events propagated by a widget, refer to the reference documentation for the particular widget in the API, specifically Mojo.Event, which indicates the widgets that each event is applied to.