Contextual event binding with HTML 5 data attributes

Today we’ll see how to bind events along with the target context using the HTML 5 data attributes. This new event binding technique relies on the 3-actors model we introduce in this article.

Please note that the demo application in this article can be found in a demo application on GitHub https://github.com/doanduyhai/HTML5Tutorial

 

I One actor model

event-listener-one-actor-model

In the old days of web design, people used to put inline event handlers into their HTML tags:

...
<a href="#" onclick="doSomething();" title="click here to trigger action">Click Me</a>
...

In this model, the event binding is done in the HTML tag itself. The tag is playing two roles: data display and event listener.

No need to say that this is an anti-pattern leading to a bloated HTML code.

 

II Two actors model

After the DOM Level 2 Event Model specs were released, it is a best practice to move event listener out of HTML tags. This is the two actors model.

event-listener-two-actors-model
In this model, the event binding is achieved by two actors:

  • the DOM element, with a marker to be identified in the DOM tree. It is usually a dedicated style-less CSS class or an id attribute
  • the event listener, which listens to events and delegates the processing to an event handler
...
<a id="myLink" href="#" title="click here to trigger action">Click Me</a>
...
<span class="descriptionText">This is a description text</span>
...
<script type="text/JavaScript">

	jQuery('#myLink').click(doSomething);
	jQuery('.descriptionText').click(doSomethingElse);

	function doSomething() {...}
	function doSomethingElse() {...}
</script>

 

III Three actors model

HTML 5 has introduced a very convenient new feature: custom data-* attributes. It is now possible to embed custom data in HTML tags. A new event binding model is now possible: three actors model.

event-listener-three-actors-model

The first two actors is similar to the previous model. The new thing is that now it is possible for the event listeners and event handlers to retrieve the contextual custom data embedded in the event target.

  • the DOM element, with a marker to be identified in the DOM tree. It is usually a dedicated style-less CSS class, an id attribute. Now it can also be a custom data attribute
  • the event listener, which listens to events and delegates the processing to an event handler
  • the custom data which is exposed to event listeners and passed to event handlers

Let’s suppose we have table listing some books:

...
	<tr>
		...
		<td>Authors</td>
		<td>
			<a href="#" data-authors="Craig WALLS,Ryan BREIDENBACH">Craig WALLS,Ryan ...</a>
		</td>
		...
	</tr>
	...	
	<tr>
		...
		<td>Authors</td>
		<td>
			<a href="#" data-authors="Isaac ASIMOV">Isaac ASIMOV</a>
		</td>
		...
	</tr>
...

 

	...
	jQuery('[data-authors]').click(function(event)
	{
		var authors = $(event.currentTaget).attr('data-authors');
		displayAuthorsDetails(authors);
	});
	...
	...
	function displayAuthorsDetails(authors) {...}
	...

In the above example, the <a> tag exposes the custom data attribute “data-authors” which contains a list of authors for a book.

We use this custom data attribute as a selector to identify all <a> tags in the DOM tree (line 2) and bind a handler to the click event. The authors information is retrieved from the <a> tag and then passed to the event handler as argument (line 4).

This is a very convenient way to pass extra argument to event handlers. Before HTML 5 we had to rely on some hacks to do that, for example storing information in a hidden input element:

...
	<tr>
		...
		<td>Authors</td>
		<td>
			<input type="hidden" value="Craig WALLS,Ryan BREIDENBACH"/>
			<a href="#">Craig WALLS,Ryan ...</a>
		</td>
		...
	</tr>
	...	
	<tr>
		...
		<td>Authors</td>
		<td>
			<input type="hidden" value="Isaac ASIMOV"/>
			<a href="#">Isaac ASIMOV</a>
		</td>
		...
	</tr>
...

It is possible to have many custom attributes per DOM element, each of them bound to a distinct event handler.

...
	<div class="tweet" data-tweetId="123456" data-tweetAuthor="duyhai">
		...
		...
	</div>
...

 

IV Demo

Please note that the demo application in this article can be found in a demo application on GitHub https://github.com/doanduyhai/HTML5Tutorial

I’ve created a demo application displaying a simple page with a list of books.

For each book, the title, authors and availability information are displayed. Authors name are abbrievated but it is possible to have the full list displayed by putting the mouse over the link (tooltip component by Twitter Bootstrap). The event binding is done using the data-authors attribute as selector.

event-listener-data-authors

It is possible to click on the magnifying glass icon to trigger an Ajax call to the server and retrieve all complete book details.

Internally the link tag contains a data-isbn custom attribute, containing the ISBN of the book. This attribute is used as selector to bind with an event listener and passed to event handler as parameter to trigger Ajax call.

event-listener-books

On response from the server, we display a modal panel with all the book details:

event-listener-book-details

Below is the Javascript code

!function ( $ )
{
	bindListeners('#booksTable');
	
	bindListeners('#bookDetails');
	
}(window.jQuery);

function bindListeners(selector)
{
	$(selector).find('[data-authors]').each(function(index, element)
	{
		var authors = $(element).attr('data-authors');
		createToolTip($(element),authors);
		
	});
	
	$(selector).find('[data-isbn]').click(function(e)
	{
		var isbn = $(e.currentTarget).attr('data-isbn');
		displayDetails(isbn);
		
	});
}

function createToolTip($element, message)
{
	$element.tooltip(
	{
			title: message
	});
}

function displayDetails(isbn)
{
	$.ajax({
		type: 'GET',
		url: 'book/find/'+isbn,
		dataType: 'json',
		success: function(book) {
			...		
			...
		}
	});
}

It is quite straightforward. On page load complete, we call a generic bindListener() method, passing the target DOM element as argument (lines 3 & 5).

This function will select all elements having the appropriate custom attribute and for each of them, bind the corresponding event handler function (lines 11 & 18).

With this approach, it is possible to create a generic event binding function delegating the event handling to appropriate handlers. This function acts as a central dispatcher for event binding.

 
 

About DuyHai DOAN
Cassandra Technical Evangelist. LinkedIn profile : http://fr.linkedin.com/pub/duyhai-doan/2/224/848. Follow me on Twitter: @doanduyhai for latest updates on Cassandra

2 Responses to Contextual event binding with HTML 5 data attributes

  1. Enjoy the open spaces while you are out too. yet. take it up with the sponsoring organization.

  2. EDISON says:

    It is truly a nice and helpful piece of info. I am happy that you shared this helpful info with us. Please stay us informed like this. Thanks for sharing.

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

Follow

Get every new post delivered to your Inbox.

Join 45 other followers

%d bloggers like this: