{"id":1115,"date":"2012-05-17T17:17:54","date_gmt":"2012-05-17T15:17:54","guid":{"rendered":"http:\/\/doanduyhai.wordpress.com\/?p=1115"},"modified":"2012-05-17T17:17:54","modified_gmt":"2012-05-17T15:17:54","slug":"contextual-event-binding-with-html-5-data-attributes","status":"publish","type":"post","link":"https:\/\/www.doanduyhai.com\/blog\/?p=1115","title":{"rendered":"Contextual event binding with HTML 5 data attributes"},"content":{"rendered":"<p>Today we&#8217;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.<\/p>\n<p><!--more--><\/p>\n<blockquote><p>Please note that the demo application in this article can be found in a demo application on GitHub <a title=\"Contextual event binding with HTML 5 data attributes Demo\" href=\"https:\/\/github.com\/doanduyhai\/HTML5Tutorial\" target=\"_blank\">https:\/\/github.com\/doanduyhai\/HTML5Tutorial<\/a>\n<\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<h1>I One actor model<\/h1>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-one-actor-model.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-one-actor-model.png\" alt=\"event-listener-one-actor-model\" title=\"event-listener-one-actor-model\" width=\"359\" height=\"363\" class=\"aligncenter size-full wp-image-1116\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-one-actor-model.png 359w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-one-actor-model-297x300.png 297w\" sizes=\"(max-width: 359px) 100vw, 359px\" \/><\/a><\/p>\n<p>In the old days of web design, people used to put inline event handlers into their HTML tags:<\/p>\n<pre class=\"brush: xml; title: ; wrap-lines: false; notranslate\" title=\"\">\n...\n&amp;lt;a href=&amp;quot;#&amp;quot; onclick=&amp;quot;doSomething();&amp;quot; title=&amp;quot;click here to trigger action&amp;quot;&amp;gt;Click Me&amp;lt;\/a&amp;gt;\n...\n<\/pre>\n<p> In this model, the event binding is done in the HTML tag itself. The tag is playing two roles: <strong>data display<\/strong> and <strong>event listener<\/strong>.<\/p>\n<p> No need to say that this is an anti-pattern leading to a bloated HTML code.<\/p>\n<p>&nbsp;<\/p>\n<h1>II Two actors model<\/h1>\n<p> 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. <\/p>\n<p> <a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-two-actors-model.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-two-actors-model.png\" alt=\"event-listener-two-actors-model\" title=\"event-listener-two-actors-model\" width=\"595\" height=\"214\" class=\"aligncenter size-full wp-image-1118\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-two-actors-model.png 595w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-two-actors-model-300x108.png 300w\" sizes=\"(max-width: 595px) 100vw, 595px\" \/><\/a><br \/>\n In this model, the event binding is achieved by two actors:<\/p>\n<ul>\n<li>the <strong>DOM element<\/strong>, with a <strong>marker<\/strong> to be identified in the DOM tree. It is usually a dedicated <strong>style-less CSS class<\/strong> or an <strong>id<\/strong> attribute<\/li>\n<li>\nthe <strong>event listener<\/strong>, which listens to events and delegates the processing to an event handler<\/li>\n<\/ul>\n<pre class=\"brush: xml; title: ; wrap-lines: false; notranslate\" title=\"\">\n...\n&amp;lt;a id=&amp;quot;myLink&amp;quot; href=&amp;quot;#&amp;quot; title=&amp;quot;click here to trigger action&amp;quot;&amp;gt;Click Me&amp;lt;\/a&amp;gt;\n...\n&amp;lt;span class=&amp;quot;descriptionText&amp;quot;&amp;gt;This is a description text&amp;lt;\/span&amp;gt;\n...\n&amp;lt;script type=&amp;quot;text\/JavaScript&amp;quot;&amp;gt;\n\n\tjQuery('#myLink').click(doSomething);\n\tjQuery('.descriptionText').click(doSomethingElse);\n\n\tfunction doSomething() {...}\n\tfunction doSomethingElse() {...}\n&amp;lt;\/script&amp;gt;\n<\/pre>\n<p>&nbsp;<\/p>\n<h1>III Three actors model<\/h1>\n<p> HTML 5 has introduced a very convenient new feature: custom <strong>data-*<\/strong> attributes. It is now possible to embed custom data in HTML tags. A new event binding model is now possible: <strong>three actors model<\/strong>.<\/p>\n<p> <a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-three-actors-model.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-three-actors-model.png\" alt=\"event-listener-three-actors-model\" title=\"event-listener-three-actors-model\" width=\"630\" height=\"575\" class=\"aligncenter size-full wp-image-1123\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-three-actors-model.png 660w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-three-actors-model-300x274.png 300w\" sizes=\"(max-width: 630px) 100vw, 630px\" \/><\/a><\/p>\n<p> 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.<\/p>\n<ul>\n<li>the <strong>DOM element<\/strong>, with a <strong>marker<\/strong> to be identified in the DOM tree. It is usually a dedicated <strong>style-less CSS class<\/strong>, an <strong>id<\/strong> attribute. Now it can also be a <strong>custom data attribute<\/strong><\/li>\n<li>the <strong>event listener<\/strong>, which listens to events and delegates the processing to an event handler<\/li>\n<li>the <strong>custom data<\/strong> which is exposed to event listeners and passed to event handlers<\/li>\n<\/ul>\n<p>Let&#8217;s suppose we have table listing some books:<\/p>\n<pre class=\"brush: xml; highlight: [6,15]; title: ; wrap-lines: false; notranslate\" title=\"\">\n...\n\t&amp;lt;tr&amp;gt;\n\t\t...\n\t\t&amp;lt;td&amp;gt;Authors&amp;lt;\/td&amp;gt;\n\t\t&amp;lt;td&amp;gt;\n\t\t\t&amp;lt;a href=&amp;quot;#&amp;quot; data-authors=&amp;quot;Craig WALLS,Ryan BREIDENBACH&amp;quot;&amp;gt;Craig WALLS,Ryan ...&amp;lt;\/a&amp;gt;\n\t\t&amp;lt;\/td&amp;gt;\n\t\t...\n\t&amp;lt;\/tr&amp;gt;\n\t...\t\n\t&amp;lt;tr&amp;gt;\n\t\t...\n\t\t&amp;lt;td&amp;gt;Authors&amp;lt;\/td&amp;gt;\n\t\t&amp;lt;td&amp;gt;\n\t\t\t&amp;lt;a href=&amp;quot;#&amp;quot; data-authors=&amp;quot;Isaac ASIMOV&amp;quot;&amp;gt;Isaac ASIMOV&amp;lt;\/a&amp;gt;\n\t\t&amp;lt;\/td&amp;gt;\n\t\t...\n\t&amp;lt;\/tr&amp;gt;\n...\n<\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"brush: jscript; highlight: [2,4]; title: ; wrap-lines: false; notranslate\" title=\"\">\n\t...\n\tjQuery('[data-authors]').click(function(event)\n\t{\n\t\tvar authors = $(event.currentTaget).attr('data-authors');\n\t\tdisplayAuthorsDetails(authors);\n\t});\n\t...\n\t...\n\tfunction displayAuthorsDetails(authors) {...}\n\t...\n<\/pre>\n<p> In the above example, the <strong>&lt;a&gt;<\/strong> tag exposes the custom data attribute &#8220;<strong>data-authors<\/strong>&#8221; which contains a list of authors for a book.<\/p>\n<p> We use this custom data attribute as a selector to identify all <strong>&lt;a&gt;<\/strong> tags in the DOM tree (<strong>line 2<\/strong>) and bind a handler to the click event. The authors information is retrieved from the <strong>&lt;a&gt;<\/strong> tag and then passed to the event handler as argument (<strong>line 4<\/strong>).<\/p>\n<p> 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 <strong>hidden input element<\/strong>:<\/p>\n<pre class=\"brush: xml; highlight: [6,16]; title: ; wrap-lines: false; notranslate\" title=\"\">\n...\n\t&amp;lt;tr&amp;gt;\n\t\t...\n\t\t&amp;lt;td&amp;gt;Authors&amp;lt;\/td&amp;gt;\n\t\t&amp;lt;td&amp;gt;\n\t\t\t&amp;lt;input type=&amp;quot;hidden&amp;quot; value=&amp;quot;Craig WALLS,Ryan BREIDENBACH&amp;quot;\/&amp;gt;\n\t\t\t&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Craig WALLS,Ryan ...&amp;lt;\/a&amp;gt;\n\t\t&amp;lt;\/td&amp;gt;\n\t\t...\n\t&amp;lt;\/tr&amp;gt;\n\t...\t\n\t&amp;lt;tr&amp;gt;\n\t\t...\n\t\t&amp;lt;td&amp;gt;Authors&amp;lt;\/td&amp;gt;\n\t\t&amp;lt;td&amp;gt;\n\t\t\t&amp;lt;input type=&amp;quot;hidden&amp;quot; value=&amp;quot;Isaac ASIMOV&amp;quot;\/&amp;gt;\n\t\t\t&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Isaac ASIMOV&amp;lt;\/a&amp;gt;\n\t\t&amp;lt;\/td&amp;gt;\n\t\t...\n\t&amp;lt;\/tr&amp;gt;\n...\n<\/pre>\n<p>It is possible to have <strong>many custom attributes per DOM element<\/strong>, each of them bound to a distinct event handler.<\/p>\n<pre class=\"brush: xml; highlight: [2]; title: ; wrap-lines: false; notranslate\" title=\"\">\n...\n\t&amp;lt;div class=&amp;quot;tweet&amp;quot; data-tweetId=&amp;quot;123456&amp;quot; data-tweetAuthor=&amp;quot;duyhai&amp;quot;&amp;gt;\n\t\t...\n\t\t...\n\t&amp;lt;\/div&amp;gt;\n...\n<\/pre>\n<p>&nbsp;<\/p>\n<h1>IV Demo<\/h1>\n<blockquote><p>Please note that the demo application in this article can be found in a demo application on GitHub <a title=\"Contextual event binding with HTML 5 data attributes Demo\" href=\"https:\/\/github.com\/doanduyhai\/HTML5Tutorial\" target=\"_blank\">https:\/\/github.com\/doanduyhai\/HTML5Tutorial<\/a>\n<\/p><\/blockquote>\n<p> I&#8217;ve created a demo application displaying a simple page with a list of books.<\/p>\n<p> 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 <a href=\"http:\/\/twitter.github.com\/bootstrap\/javascript.html#tooltips\" title=\"http:\/\/twitter.github.com\/bootstrap\/javascript.html#tooltips\" target=\"_blank\">Twitter Bootstrap<\/a>). The event binding is done using the <strong>data-authors<\/strong> attribute as selector.<\/p>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-data-authors.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-data-authors.png\" alt=\"event-listener-data-authors\" title=\"event-listener-data-authors\" width=\"613\" height=\"236\" class=\"aligncenter size-full wp-image-1141\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-data-authors.png 613w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-data-authors-300x115.png 300w\" sizes=\"(max-width: 613px) 100vw, 613px\" \/><\/a><\/p>\n<p> It is possible to click on the magnifying glass icon to trigger an Ajax call to the server and retrieve all complete book details. <\/p>\n<p> Internally the link tag contains a <strong>data-isbn<\/strong> 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.<\/p>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-books.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-books.png\" alt=\"event-listener-books\" title=\"event-listener-books\" width=\"630\" height=\"229\" class=\"aligncenter size-full wp-image-1143\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-books.png 795w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-books-300x109.png 300w\" sizes=\"(max-width: 630px) 100vw, 630px\" \/><\/a><\/p>\n<p> On response from the server, we display a modal panel with all the book details:<\/p>\n<p><a href=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-book-details.png\"><img loading=\"lazy\" src=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-book-details.png\" alt=\"event-listener-book-details\" title=\"event-listener-book-details\" width=\"563\" height=\"537\" class=\"aligncenter size-full wp-image-1145\" srcset=\"https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-book-details.png 563w, https:\/\/www.doanduyhai.com\/blog\/wp-content\/uploads\/2012\/05\/event-listener-book-details-300x286.png 300w\" sizes=\"(max-width: 563px) 100vw, 563px\" \/><\/a><\/p>\n<p> Below is the Javascript code<\/p>\n<pre class=\"brush: jscript; highlight: [3,5,11,18]; title: ; wrap-lines: false; notranslate\" title=\"\">\n!function ( $ )\n{\n\tbindListeners('#booksTable');\n\t\n\tbindListeners('#bookDetails');\n\t\n}(window.jQuery);\n\nfunction bindListeners(selector)\n{\n\t$(selector).find('[data-authors]').each(function(index, element)\n\t{\n\t\tvar authors = $(element).attr('data-authors');\n\t\tcreateToolTip($(element),authors);\n\t\t\n\t});\n\t\n\t$(selector).find('[data-isbn]').click(function(e)\n\t{\n\t\tvar isbn = $(e.currentTarget).attr('data-isbn');\n\t\tdisplayDetails(isbn);\n\t\t\n\t});\n}\n\nfunction createToolTip($element, message)\n{\n\t$element.tooltip(\n\t{\n\t\t\ttitle: message\n\t});\n}\n\nfunction displayDetails(isbn)\n{\n\t$.ajax({\n\t\ttype: 'GET',\n\t\turl: 'book\/find\/'+isbn,\n\t\tdataType: 'json',\n\t\tsuccess: function(book) {\n\t\t\t...\t\t\n\t\t\t...\n\t\t}\n\t});\n}\n<\/pre>\n<p> It is quite straightforward. On page load complete, we call a generic <strong>bindListener()<\/strong> method, passing the target DOM element as argument (<strong>lines 3 &amp; 5<\/strong>).<\/p>\n<p> This function will select all elements having the appropriate custom attribute and for each of them, bind the corresponding event handler function (<strong>lines 11 &amp; 18<\/strong>).<\/p>\n<p> With this approach, it is possible to create a <strong>generic event binding function<\/strong> delegating the event handling to appropriate handlers. This function acts as a central dispatcher for event binding.<\/p>\n<p>&nbsp;<br \/>\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today we&#8217;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.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[26,13],"tags":[],"_links":{"self":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1115"}],"collection":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1115"}],"version-history":[{"count":0,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1115\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}