I am new to Adobe Analytics and DTM.
On my website, an asynchronous API is creating a div on the page dynamically. This DIV has a special CSS class, let's say "wantedClass".
I want to create 2 rules :
A rule that fires once the DIV appears on the page, which i did like using Page Load Rules as following :
On this trigger, an event1 is fired in Adobe Analytics.
I picked onLoad because I read that this is the last one among the other options, and I want to make sure that the API async finished creating the DIV so this event would be fired.
A rule that fires once the DIV is clicked, which I did using Event Based Rules as following :
On this trigger, an event2 is fired.
What's happening when I test is :
Page loads, no event1 is fired
DIV clicked, no event2 is fired, BUT event1 is fired.
What am I doing wrong?
Any help would be appreciated;
1. Page loads, no event1 is fired
Async calls by their nature can happen after DOM Ready or window load (onLoad), so onLoad is not guaranteed to trigger after some API (async) ajax call is made and returns something.
Ideally, you should trigger something in the API's ajax success callback function. You can create and trigger a Custom Event which DTM can listen for in an Event Based Rule. Note: If you go this route, make sure you create/trigger on document.body or a decendant; DTM will not listen for custom events on document itself. Also, since I see you using jQuery syntax in your screenshot, if you go this route, also note that jQuery custom event functionality is NOT the same as native javascript custom events. So for example if you do $( document.body ).trigger( "someEvent" ), this does NOT push to something listening to
document.body.addEventListener('someEvent', function (e) { /* ... */ }, false);
DTM uses the above to listen for custom events. So TL;DR - don't use jQuery syntax to create or broadcast custom events if you intend on using DTM's built-in custom event listener.
Alternatively, within the API's ajax callback function, you can just do _satellite.track('dc_rule_value_here'); and create a Direct Call rule with 'dc_rule_value_here' as the string condition.
If you cannot add something to the API ajax callback function, the next best thing is to create a Data Element of Custom Code type, with the code you have in your screenshot condition (returning true or false if .wantedClass is found). Then, create an Event Based Rule of Data Element Changed type, with a condition reflecting what you return from the data element. This isn't ideal because this rule type works by polling the data element every 1 second for the duration of the page view. This isn't that big a deal in the grand scheme of things but it is not as efficient as other methods (and if you 0make it a practice to do this for a lot of rules, then it might become a problem). Note that you should also bake into your Data Element to only return true once, so that it doesn't keep triggering the EBR every 1s after its found (DTM does not have a native "fire only once" type config).
2. DIV clicked, no event2 is fired, BUT event1 is fired.
Not sure about this one. At face value, it sounds like the DTM rule itself is working, but there is a problem with the AA s.events being set. Could be that you simply typo'd and put event1 into the rule, though I'm sure you checked that.. right?
Could be you have other code (e.g. code within s.doPlugins callback) that is overwriting it. Or maybe it's some other rule entirely that is triggering, not the one above.
May be able to help further if you provide more details on how/where you actually set the event (including other places you may be setting both events), but it but kinda sounds like something I'd have to see this in action on a page to really get to the bottom of it :/
Related
Is there a way to track any form being filled on google tag manager? I looked at the options, and there doesn't seem to be a way to do this, I can capture events for form submission, but not when the form is being filled by an user. Is there an easy way to do this? I tried to capture the event with input being clicked by the user, but it triggers on every page load. Check if one of the input field in the form is being filled.
Well, you generally have two ways of doing it: ask your front-end devs to write the code and just send you a dataLayer event when it happens, or write the code on your own.
If you're not able to delegate it to the FE devs, then you will have to write it on your own. Consider what you want to do. The simplest thing from here would be detecting clicks on that one field, assuming that if a user clicked it, then they will fill it. Tracking like this is not perfect since there are other ways to fill a field without clicking/tapping it And also there will be cases when a user clicks it, but doesn't type anything. But this is probably what you want to do. For this, you only need to pick a right CSS selector and use built-in funcitonality of GTM.
If you actually want to track when the field changes input, you will have to write your own event listeners and with it, send yourself dataLayer events and then listen to those and send the event accordingly.
This is what you want to know about the change event: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event
You will also likely want to prevent event sent on every change, so make a blocking variable that you set after the listener callback fires once.
This is very messy. It's not likely worth it to go this route.
I have an id being pushed to my data layer via dataLayer.push() and there is no event key at the moment.
I know the best practice is to use an event key like 'event': 'idPush' and then in Google Tag Manager UI, have a trigger that activates when the custom event idPush occurs.
Is there is a way that I can still get the trigger to activate upon seeing a generic 'Message'?
I can't be 100% sure because I haven't read the GTM source code and I couldn't find any articles that talk about this, but I'm reasonably certain that this can't be done.
I tried:
creating a Custom Event trigger with a regex match of .* which would match anything, including nothing.
matching undefined, because according to the preview pane, the _event variable is set to undefined for Message events.
Unfortunately neither of these worked, and preview mode just says No tags were evaluated for the Message. This leads me to think that GTM only checks to see if any triggers should fire when an event is pushed into the dataLayer.
No. Until there was an event, GTM does not know about the content of the message - the message is just the debugger telling you that something has been added to the global dataLayer variable (which exists in the global namespace of the browser, not the confined namespace of GTM). The even is what updates GTM's internal state to make it aware of changes and additions to the dataLayer.
Depending on your use case you might be able to use a trigger type that creates it's own event - e.g. setting a visibility trigger to an element that you know will be at the viewport after your message, which will then take the new values of the dataLayer into account. Or create a custom HTML tag with a setInterval functions that periodically pushes an event to the dataLayer.
While these solutions may work, I do not think they are actually good. Finding a solution to change your page code will almost certainly be less headache in the long run than using a workaround.
You can attach two or more triggers to a tag. They are united with the OR rule, i.e. the tag starts when one of the triggers fires. How to unite the triggers with the AND rule, i.e. make a tag which starts when ALL the given triggers have fired?
Use case: I have a tag that must start when the page DOM is ready and the user location is determined (the location determination starts as soon as possible, before the DOM is ready). I made 2 triggers: «DOM ready» (built-in event) and «Location determined» (custom event fired by a JavaScript code).
P.S. Starting the location determination after the DOM is ready is a workaround, not an answer.
There is no "and" condition for triggers (and to combine two event based triggers would be impossible, since you cannot evaluate two events at the same time).
The easiest way would be to push a variable to the dataLayer on the "Location determined" event and then have a DOM Ready trigger that fires only when the variable is set (actually you don't event need an event on location determined - if you just push a value it will be accessible on the next event sent to the datalayer, in this case your DOM ready event).
I'm writing a realtime updating graph using Angular2. My graph is being updated through data coming via an http observable, and a setInterval command.
A weird thing I've noticed is that, when I route through angular to a different view on my app, the setInterval command on the previous component does not stop, causing the server for unnecessary load.
What would be the correct method to stop setInterval http requests on route changes in Angular2?
Any help would appreciated.
Events are managed very differently by browsers, basically they are processed by Event loop.
The browser has inner loop, called Event Loop, which checks the queue
and processes events, executes functions etc.
So whenever you add any asynchronous event like setTimeout/setInterval, they gets added to Event Loop with their handlers.
Basically whenever you wanted to stop/de-register those asynchronous event, you need to de-register them manually. Like here you need to call clearInterval method with that setInterval object reference, then only it will remove that async event from Event Loop.
You could use ngOnDestroy life-cycle hook where you can have your stuff before destroying your component.
//hook gets called before Component get destroyed or you can say disposed.
ngOnDestroy(){
clearInterval(intervalReference)
}
Extra stuff(Comparing with Angular 1)
The same kind of problem you can see in any Javascript Framework. In Angular 1 there is way to handle such kind of situation(I'm adding this stuff so that anyone from Angular 1 background can easily get this concept by comparing A1 with A2). While destroying controller instance angular internally emit's $destroy event over element & $scope of that element. So by having listener over $destroy event, we used to do stuff to ensure those object value/object/events should not available.
$scope.$on('$destroy', function(event){
//do stuff here
})
element.bind('$destroy', function(event){
//do stuff here
})
I'm trying to track form submissions by creating a data element and rule in Adobe DTM. I'm new to DTM and am having difficulty configuring the tag correctly. Here's a screenshot of my code: http://zeffective.d.pr/1hTHa. How should I create this rule in DTM to track email form submissions as an event in GUA (I've created a tool for GUA in DTM already).
There are several ways to do this (jQuery form submit, etc) but using an event-based rule should work just fine.
Something like this:
Event Type: Click
Element Tag or Selector: button.form-submit.disabled-submit // class name
Apply Event Handler Directly to Element
// Adobe Analytics Section
// Select s.tl (does not increment a PV)
// Set events or vars
You can also do this with a page rule that uses jQuery and listens for the form.submit.
Hope this helps.
Best way to set it up correctly is:
create event base rule,
chose event type click and check option delay link activation (this will avoid page reload before analytics call is made).
Apply event handler directly to element - leave this option unchecked.
Please do not set any other conditions as mentioned in comments above.
Choose analytics tool set s.tl and map your evars/props/events
Also, please check _sattelite.getVar("data element name") function to check that Data Elements are resolved properly.
Use browser addons like omnibug to check that calls are made as expected.
In section Javascript / Third Party Tags, for testing purposes you can add following java script:
console.log('new submission');
hope it helps.
If you have form validation happening I would not use an on click event in DTM. For form submissions, my preferred method is to use the form onsubmit handler and fire a direct call event to DTM after any other logic / validation happens.
_satellite.track('lead_form_submit');
Set up all your tracking logic in a Direct call rule that has a string to match what you pass to track. ie. 'lead_form_submit' or whatever you name it.