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
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.
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.
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.
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.
On response from the server, we display a modal panel with all the 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.
HTML Attributes are property of the elements which may have values and these attribute values are always enclosed in quotes. It’s providing to the browser with some additional information about an elements how the elements should appear or behave. HTML elements can contain one or more attributes, attribute names and attribute values are case-insensitive and separated by an equals (=) sign.
[HTML Attributes](http://www.willvick.com/HTML/HTMLAttribute.aspx)
[HTML Attributes Examples](http://www.willvick.com/HTML/HTMLExampleAttribute.aspx)
[Youtube – HTML Tutorial – Attributes](http://www.youtube.com/watch?v=ucOXvaCEZgg)
Enjoy the open spaces while you are out too. yet. take it up with the sponsoring organization.
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.