{"id":137,"date":"2016-04-20T16:57:45","date_gmt":"2016-04-20T16:57:45","guid":{"rendered":"http:\/\/www.digitaldatatactics.com\/?p=137"},"modified":"2017-11-08T23:24:50","modified_gmt":"2017-11-08T23:24:50","slug":"setting-up-an-event-based-rule-that-be-fired-directly-like-a-direct-call-rule","status":"publish","type":"post","link":"https:\/\/www.digitaldatatactics.com\/index.php\/2016\/04\/20\/setting-up-an-event-based-rule-that-be-fired-directly-like-a-direct-call-rule\/","title":{"rendered":"Setting up an Event-based Rule that be fired directly like a Direct Call Rule"},"content":{"rendered":"<p><span style=\"color: #ff0000;\"><strong>Update:<br \/>\n<\/strong>As proud as I am of this solution\/workaround, it may be far less needed now that you can use the\u00a0<em>dataelementchanged<\/em>\u00a0 condition to fire an Event Based Rule. Instead of using custom events, you can just have DTM listen for when your pageName Data Element has changed.\u00a0<\/span><\/p>\n<h2>The current limitations<\/h2>\n<p>If developers want to fire a DTM rule directly from their code (say, they want to make sure a beacon fires only after their data layer is ready), typically they would fire a Direct Call Rule, with its very specific syntax: <em>_satellite.track(&#8220;rule string here&#8221;)<\/em>. There are, however, some limitations to this method.<\/p>\n<p>Direct Call Rules:<\/p>\n<ul>\n<li>Don&#8217;t allow for multiple conditions (you can&#8217;t say &#8220;<em>if _satellite.track(&#8220;cart add&#8221;) is fired AND the current page has &#8220;\/products&#8221; in the URL<\/em>&#8220;)<\/li>\n<li>Don&#8217;t allow for multiple arguments (you can&#8217;t pass _satellite.track(&#8220;cart add&#8221;,&#8221;sku1&#8243;) to attach the added SKU to the rule)<\/li>\n<li>Don&#8217;t allow for firing s.clearVars() before your rule sets up your analytics variables (to clear out variables from previous beacons on the same DOM).<\/li>\n<li>Require very specific syntax- they MUST be &#8220;_satellite.track()&#8221;<\/li>\n<\/ul>\n<p>And unfortunately, both Direct Call Rules\u00a0and Event-based rules don&#8217;t &#8220;stack&#8221;- if a certain condition triggers multiple similar rules, each rule will fire its own beacon. This is different from Page Load Rules, where if multiple rules have conditions being met by the current page, they all wrap nicely into a single page view beacon.<\/p>\n<h2>An alternative<\/h2>\n<p>To get around some (but maybe not all) of these limitations, I&#8217;ve been playing with another possible option, where we use the Custom Event conditions of an Event Based Rule to accomplish nearly the same thing. After getting it set up, I can fire something like this:<\/p>\n<pre>digitalData.userAction(\"cart add\",\"sku1\")<\/pre>\n<p>&#8230;to fire an Event-Based Rule in place of a Direct Call Rule. There are a few things I need to do in DTM to make this <em>digitalData.userAction<\/em> work.<\/p>\n<h3>Set Up the Logic<\/h3>\n<p>First, I have to set up the logic in a Page Load Rule- set to fire on DOMReady (no need for it to be sooner)- that will merely hold the\u00a0following as a Sequential Javascript Third Party Tag:<br \/>\n<code><\/code><\/p>\n<pre>\/\/make sure digitalData is defined to prevent errors\r\nif(typeof digitalData==\"undefined\"){\r\n  digitalData={}\r\n}\r\n\r\n\/\/create fake DOM item to bind the event to\r\nvar fakeDiv = document.createElement('div');\r\nfakeDiv.setAttribute('id', \"dtmHolder\");\r\nfakeDiv.setAttribute('height','1');\r\nfakeDiv.setAttribute('width','1');\r\nfakeDiv.setAttribute('style','display:none');\r\ndocument.body.appendChild(fakeDiv);\r\n\r\n\/\/define custom event\r\ndigitalData.userAction=function(n,details){\r\n\r\n document.getElementById(\"dtmHolder\").addEventListener(\"dtmEvent\", function(e) {\r\n    console.info(\"Event is: \", e);\r\n  })\r\n\r\n  \/\/ First create the event\r\n  var dtmEvent = new CustomEvent(n, {\r\n    detail:\"\"\r\n  });\r\n\r\n  jQuery(\"#dtmHolder\").attr(\"detail\",details)\r\n  \r\n  \/\/ Trigger it!\r\n  document.getElementById(\"dtmHolder\").dispatchEvent(dtmEvent); \r\n}<\/pre>\n<p>(Update: note that this code should not run before the DOM is created- it will create an error if you try to run it at page top because you are trying to append something to a body that doesn&#8217;t exist yet).<br \/>\nNow, whenever a developer fires <em>digitalData.userAction(&#8220;string here<em>&#8220;<\/em>)<\/em>, you can listen for that string as the<em> Triggered Event Type<\/em> in a <em>Custom Event<\/em> Event Based Rule. Obviously, you can alter the above code if you want a function named something other than digitalData.userAction.<\/p>\n<h3>Set Up an Event Based Rule<\/h3>\n<p>The rule will need to be bound to the CSs selector of the tiny fake div (&#8220;#dtmHolder&#8221;) we created for the custom event to bind to:<\/p>\n<p><a href=\"http:\/\/digitaldatatactics.com\/wp\/wp-content\/uploads\/2016\/04\/2016-04-20_12-38-12.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-145\" src=\"\/\/digitaldatatactics.com\/wp\/wp-content\/uploads\/2016\/04\/2016-04-20_12-38-12.png\" alt=\"2016-04-20_12-38-12\" width=\"527\" height=\"288\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2016\/04\/2016-04-20_12-38-12.png 527w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2016\/04\/2016-04-20_12-38-12-300x164.png 300w\" sizes=\"(max-width: 527px) 100vw, 527px\" \/><\/a><\/p>\n<p>You can create as many of these rules as you want, for whatever different strings you pass into <em>digitalData.userAction()<\/em>where the &#8220;triggered event type&#8221; reflects that string.<\/p>\n<h3>Pass Additional Info<\/h3>\n<p>If you want to pass a second argument ( e.g.\u00a0<em>digitalData.userAction(&#8220;cart add&#8221;,&#8221;sku1&#8243;)<\/em>) I currently have that second argument \u00a0passing as a new attribute (&#8220;detail&#8221;) on the tiny invisible div, so you can access it off the &#8220;this&#8221; object directly in the rule:<a href=\"http:\/\/digitaldatatactics.com\/wp\/wp-content\/uploads\/2016\/04\/2016-04-20_12-41-52.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-146\" src=\"\/\/digitaldatatactics.com\/wp\/wp-content\/uploads\/2016\/04\/2016-04-20_12-41-52.png\" alt=\"2016-04-20_12-41-52\" width=\"373\" height=\"105\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2016\/04\/2016-04-20_12-41-52.png 373w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2016\/04\/2016-04-20_12-41-52-300x84.png 300w\" sizes=\"(max-width: 373px) 100vw, 373px\" \/><\/a><\/p>\n<p>You can give this a try at my <a href=\"http:\/\/jenniferkunz.com\/test\/DTMalternateDCR.html\">ugly test site<\/a>&#8211; open a developer console, turn on DTM debugging, and fire either\u00a0<em>digitalData.userAction(&#8220;cartAdd&#8221;,&#8221;sku123&#8243;)<\/em> or\u00a0<em>digitalData.userAction(&#8220;pageView&#8221;)<\/em>\u00a0to see two example rules at work.<br \/>\n<a id=\"clearVars\"> <\/a><\/p>\n<h3>Run ClearVars<\/h3>\n<p>This opens the ability to run s.clearVars on s.t() beacons in cases where multiple beacons may be firing on a single DOM. (As a reminder, if you&#8217;re using the old DCR route, there are some hack-ish options for doing this- we call it <a href=\"http:\/\/www.digitaldatatactics.com\/examples\/DCR.html\">daisy-chaining<\/a>).<\/p>\n<p>In an Event Based Rule, there IS a code block that runs before the Analytics tool, giving you a perfect opportunity to make sure you are starting with a &#8216;clean slate&#8217; of variables: the Conditions Custom Code block. Just create a new Rule Condition with &#8220;custom&#8221; criteria, then put &#8220;s.clearVars()&#8221; in the code block, followed by &#8220;return true&#8221; (so that DTM doesn&#8217;t think some condition didn&#8217;t pass):<\/p>\n<p><a href=\"http:\/\/digitaldatatactics.com\/wp\/wp-content\/uploads\/2016\/04\/2016-04-20_12-52-49.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-147\" src=\"\/\/digitaldatatactics.com\/wp\/wp-content\/uploads\/2016\/04\/2016-04-20_12-52-49.png\" alt=\"2016-04-20_12-52-49\" width=\"335\" height=\"178\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2016\/04\/2016-04-20_12-52-49.png 335w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2016\/04\/2016-04-20_12-52-49-300x159.png 300w\" sizes=\"(max-width: 335px) 100vw, 335px\" \/><\/a><\/p>\n<p>You can also apply additional conditions, like &#8220;only fire this &#8220;cart add&#8221; rule on certain pages&#8221;, by adding more criteria under Rule Conditions.<\/p>\n<h2>Conclusion<\/h2>\n<p>I&#8217;m very open to suggestions and feedback on this- maybe we can crowdsource a better way, but for now, this seems to be a reasonable alternative to Direct Call Rules. Let me know what you think!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Update: As proud as I am of this solution\/workaround, it may be far less needed now that you can use the\u00a0dataelementchanged\u00a0 condition to fire an Event Based Rule. Instead of using custom events, you can just have DTM listen for when your pageName Data Element has changed.\u00a0 The current limitations If developers want to fire &#8230; <a title=\"Setting up an Event-based Rule that be fired directly like a Direct Call Rule\" class=\"read-more\" href=\"https:\/\/www.digitaldatatactics.com\/index.php\/2016\/04\/20\/setting-up-an-event-based-rule-that-be-fired-directly-like-a-direct-call-rule\/\" aria-label=\"Read more about Setting up an Event-based Rule that be fired directly like a Direct Call Rule\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22,7,23],"tags":[19,8,30],"_links":{"self":[{"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/posts\/137"}],"collection":[{"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/comments?post=137"}],"version-history":[{"count":12,"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/posts\/137\/revisions"}],"predecessor-version":[{"id":292,"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/posts\/137\/revisions\/292"}],"wp:attachment":[{"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/media?parent=137"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/categories?post=137"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/tags?post=137"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}