Dojo in XPages – 17: Getting Event Information from Event Handlers

In the last post, we looked at how to dynamically attach event handlers to DOM elements with Dojo. In this post, we’ll take a look at the information available to the event object that is available to the event handler.

Dojo in XPages Series

Dojo in XPages — All Blog Posts

Getting The Event Object

If you add a parameter to the event handler that you attach to any DOM element via Dojo, you will have a handle to an Event object containing informomation about the event.

Here’s an example:

dojo.on(dojo.byId('myDiv'), 'click', function(e) {
  // do something
});

Event Coordinates

The layerX and layerY properties provide the coordinates of the event (such as a click) relative to the event target and the pageX and pageY properties provide the coordinates of the event relative to the page.

If the element flows inline on the page, then the layer and page coordinates generally seem to be the same. If the element is absolutely positioned on the page, then the layer properties are relative to the “layer” that is absolutely positioned.

You can test these properties with code like this:

dojo.on(dojo.byId('myDiv'), 'click', function(e) {
  console.log('clicked div');
  console.log('layerX: ' + e.layerX);
  console.log('layerY: ' + e.layerY);
  console.log('pageX: ' + e.pageX);
  console.log('pageY: ' + e.pageY);
});

To see the difference in the layer properties, change the div from something like this:

<div id="myDiv"
  style="height:100px; width:100px; background-color:red;">
</div>

…to this (specifying the positioning):

<div id="myDiv"
  style="height:100px; width:100px; background-color:red; position:absolute; top:50px; left:50px;">
</div>

target vs currentTarget

The target property is the DOM element that originally received the event. The currentTarget property is the DOM element whose event handlers are currently being processed. They will be the same if you click on one element and the event does not trigger any other handlers.

Here’s an example of how they can be different. If you have a div on the page with the id of myDiv and you run the code below to attach a click event handler to both that div and the page body, you can click on the div and it will fire the click event on both the div and the page body (since they’re both listening for the click event).

In this case the event handler for the div will fire first and will show both the target and currentTarget to be myDiv. Then the body‘s event handler will run and it will show the target to be myDiv, because that was the element that first received the event.

dojo.query('body').on('click', function(e) {
  console.log('clicked page body');
  console.log('target: ' + e.target.id);
  console.log('currentTarget: ' + e.currentTarget.id);
});

dojo.on(dojo.byId('myDiv'), 'click', function(e) {
  console.log('clicked div');
  console.log('target: ' + e.target.id);
  console.log('currentTarget: ' + e.currentTarget.id);
});

Event Bubbling

As we saw in the previous example, the click event will be fired for both the div and the body that have handlers.

If desired, you can stop this bubbling behavior with the stopPropagation() method of the event.

dojo.on(dojo.byId('myDiv'), 'click', function(e) {
  console.log('clicked div');
  console.log('target: ' + e.target.id);
  console.log('currentTarget: ' + e.currentTarget.id);
  e.stopPropagation();
});

This prevents the event from being passed on to the body‘s event handler.

The preventDefault() method of the event object will prevent default behavior from firing after the event handler. For example, if you have a link, but you attach a handler to the click event and then call e.preventDefault(), the link will not be opened.

This code will log a console message and disable any link on the page:

dojo.query('a').on('click', function(e) {
  console.log('clicked link');
  e.preventDefault();
});

Reading Key Presses

Another useful piece of information to trap with event handlers is a keystroke. The charCode() method will return a character code for a printable character and the keyCode() method will return a character code for a non-printable character, which is very handy to trap special keys.

This code will display the charCode or keyCode for anything typed into an edit box named inputText1. It will also trap the Enter key and prevent it from automatically submitting the page.

dojo.query('[id$=inputText1]').on('keypress', function(e) {
  console.log('keypress');
  console.log('charCode: ' + e.charCode);
  console.log('keyCode: ' + e.keyCode);
  
  // Stop [Enter] from submitting form
  if (e.keyCode == 13) {
    console.log('trapping [Enter] key');
   e.preventDefault();
  }
});

If you want your keyCode-checking code to be a little more readable, you can include the dojo.keys module and compare the keyCode to a list of constants. (See this page for more information.)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: