Adobe DTM Capturing ID from Class - adobe

I'm new to Adobe DTM so please be gentle with me! What I'm trying to do is to have a Data element hold the value of the ID of a clicked button of class "b1".
<button type="button" class="b1" id="value 1">button 1</button>
<button type="button" class="b1" id="value 2">button 2</button>
How should my Data Element be set-up since I don't want any initial value in it?
How do I structure the Event rule to capture the value of the clicked button?
I do know that I have to set the tag/selector to .b1 with event type of "click" in the condition but how do I source the "ID" value of the clicked button and assign to the Data Element.
Thanks,
Bill

Example...
Create an Event Based Rule, name it whatever you want.
Within Conditions, for the Event Type select "click".
For Element Tag or Selector put "button.b1" (no quotes). This is basically the equivalent of a css (or e.g. jQuery) selector you'd use for targeting button elements that have class "b1".
Note: You may or may not need to checkmark the Apply event handler directly to element option, depending on how your site is setup and what all is already hooked to the elements.
Now, under Rule Conditions Criteria, choose "Data > Custom" and click the "Add Criteria" button, which will then show a Custom codebox section.
Within that codebox, enter the following:
var id=this.id||'';
_satellite.setVar('b1_button_id',id);
return true;
So the way this works is that within a condition, this should be a reference to the button that was clicked. So we use that, along with DTM's _satellite.setVar() method to set a data element called "b1_button_id" to the value of the button's id attribute. Then we return true to ensure that the condition is always true, so that this condition will not prevent the rule from triggering.
From there, in any of the sections of the rule, you can reference the data element with either %b1_button_id% syntax (like in one of the form fields for setting a var through DTM) or you can use _satellite.getVar('b1_button_id') within any of the custom code blocks in the rule.
Note: data elements created on-the-fly with the .setVar() method only persist for the duration/scope of the rule being evaluated. DTM does not have an officially documented way of creating or updating persistent data elements or setting any other features that you have available from the actual Rules > Data Elements section, but there are some workarounds depending on what you want to do.
Another Note: You didn't specifically mention a need for this, but since it may be a next step that might come up.. as mentioned, within the context of a condition, this is a reference to the element for the event (in this case, the "click" event). If for some reason you need to reference this within a codebox in the Javascript / Third Pary Tags section, be aware that this will remain in context if you do NOT check the Execute Globally option, but if you DO check that option, then this will no longer be a reference to the event element.
If you need a reference to this AND you need the code to be executed globally, then you can create a data element following the instructions above, except just use this as the value, e.g.
_satellite.setVar("this_reference",this)
Then, within the codeblock you can use _satellite.getVar("this_reference") to get it.

Related

Google Tag Manager - collect data attributes without using the datalayer

I'm trying to collect the value of data attributes when clicking on the element containing it but I would like to do it without using the datalayer.
I'm currently using the datalayer by pushing the data attribute into the datalayer with javascript, everything works but it's annoying to always modify the code, I'd like to do the same without using javascript.
My code looks like this:
link label
In Google Tag Manager, I have created an "automatic event variable" (not sure it is called like this in English, my GTM is in French) using the name "Generic_Dataset_product" where I select "element attribute" and as an attribute, I have tried multiple things without success like data-product, gtm.data-product, product, ...
To use this variable I have created a simple trigger that detects clicks on class "link_class" and associated an event (event_category, event_action, event_label) where I add the collected variables with the right name {{Generic_Dataset_product}}. Instead of seeing the expected value, I see "track_event".
Is there a way to collect data this way? I want to use the "automatic event variables" to collect content from src, data attributes, and other elements in the code as there are no predefined variables for this in GTM.
Thanks
Getting arbitrary attributes of clicked elements in GTM is a trivial task. And there are many ways of doing it. I prefer CJS cuz I often need to do mutations and sanitizing there. Your problem is that you're not debugging it properly.
First, make a trivial CJS variable like so:
function(){
return {{Click Element}}.getAttribute("data-shop");
}
Now open your preview debugger and actually go inspect all variables GTM sets on your click. Including your new CJS var as well as your auto-event vars. If you don't find what you're looking for from there, come back here and show us screenshots from the actual debugger and let's debug from there.
Here's how you enable {{Click Element}}:
There is no reason to avoid the datalayer. The datalayer already contains the clicked element, and the data attributes are properties of that element, so you can address them via dot notation like this:
This saves you custom javascript (which is something you might want to avoid if you ever plan to implement a proper content security policy, since custom scripts require the use of eval).

Get text of clicked button in Google Analytics

I want to be able to know exactly which element from a class has been clicked. I enabled the text option in Tag Manager:
But it's still not visible in the click object. But it wouldn't pick it up, since the tag containing the text is nested in the clickable element. Can I add a custom HTML attribute to be able to identify which element has been clicked?
<div class="card-content"> //<---- clickable element
<i aria-hidden="true" class="card-icon material-icons">business</i>
<h3 class="card-title">Company details</h3> //<--- clicked text
</div>
The best way to figure it out is to use the "Preview & Debug":
Activate it
Go to the page where you want to test (you should see now a new box at the bottom)
Click on the element
Check the variables in the debug box. Especially check the click.element data.
My guess is that since there is no "real" text in the div box, just children tags, no text can be discovered.
There are different options to solve it:
add the text as data-attribute to the div and use the click.element data
use a data-layer push event
if you know JS you can use the click.element data in a JS variable and traverse down to the h3
If you are going to keep your code as it is, you could create a custom variable, using Custom JavaScript.
In order to do so you need to first create the custom variable, choosing the Custom JavaScript type:
This code should do the job (I tested id)
function() {
return {{Click Element}}.closest('.card-content').getElementsByClassName('card-title')[0].innerText;
}
The custom variable will return the text inside .card-title.
To test the custom variable, you may create a dumb HTML tag with a console.log script, replacing Inside TXT with the name you gave to your custom variable:
<script>console.log( {{Inside TXT}} )</script>
The trigger should be a Click All Elements.
When previewing this tag, the captured text should appear in your console, as well as in the debugger panel.
Reading again your question, I wonder if you are going to have several .card-title items inside the .card-content. In that case, this custom variable will not work. Let me know what is the case.
Also, the code could be simpler, but I am not really sure on how is it really going to work in your site, so this one seems more reliable, since it works clicking anywhere in the element.
EDIT:
In order to test it, after you click an element, a new "Click" will appear in the left pane (Summary). There, in the Variables tab, you will see the variables captured by the click. The data will be stored under the variable name you gave to the variable.

Unable to get current click value through Adobe Launch

I created a click event in adobe launch which will capture the value of the link and send it to analytics. I have created a data element for saving the value and in my DOM I am saving value in local storage.
Local storage code:
$('.card').click(function() {
var name = $(this).text();
localStorage.setItem('productName', name);
});
My problem is when I click the first link no value got saved, but after when I click second link it saves the value of first link and on third link saves value of second link and so on. I want to save current link value in evar3 variable.
Data element:
Rule:
Set variables:
Thanks,
Harshit
I'm scratching my head a little bit about why your jQuery selector doesn't match your Rule selector, but that's probably not immediately related or relevant, considering you said you are seeing data pop, in general, so at face value, I'm going to ignore that.
But in general, it sounds like your jQuery code is getting executed after the Rule is evaluated, so it's effectively one step behind. I'm not sure there's much if anything you can do about that if you aim to keep two separate click event listeners like this.
You're going to have to restructure to have one chain off the other (which I don't think is actually feasible with jQuery > Launch as-is. Maybe if you write two separate custom code blocks with promise chaining but that kind of sidesteps Launch and IMO is over-complicating things to begin with (see below)). Better yet, merge them into a single click event listener. On that note..
Why do you have two separate click event listeners? Is the sole reason for this to pass off the link text? Because you can reference the clicked element in the Launch Rule itself.
You should be able to reference %this.innerText% in the Set Variables fields. Or you can reference this object in custom code boxes within the Rule.
IOW at face value I don't see why you need or should be creating/using that jQuery listener or pushing to local storage like that.
Update:
You commented the following:
I tried with %this.innerText% it is also not showing current values. I
am pushing the value first to local storage because my link values are
generating on runtime through an API. They are not hardcoded. I am
also trying to figure out why my rule is getting fired before my
jquery is evaluated. But when I check in console using
_satellite.getVar('Product Name'); it shows me the correct value, but in debugger console value is wrong. Can you show me the way you want
to create rule to getting it fired correctly ? Thanks,
Okay so your link values are generated runtime through an API call? Well okay now that sounds like where the (timing) issue is, and it's the same issue in principle I mentioned you prolly had between the jQuery and Launch code. Assuming you can't change this dynamic link functionality, you have two options:
1. Explicitly trigger a launch rule (direct call rule) in a callback from the API code that's generating the link values.
This is the better method, because you won't have race condition issues with your API vs. link tracking code. The biggest caveat about this method though is that it requires requires you to actively add code to the site, which may or may not be feasible for you.
I have no idea what your code for generating the link looks like, but presumably it's some ajax call and generated from the success callback. So in the callback, you'd add a line of code something like this:
_satellite.track('product_image_click', {
text : elem.innerText
});
Again, I don't know what your API code that generates the link looks like, but presumably you have within it some element object you append to or update the DOM, so for this example, I will refer to that as elem.
'product_image_click' - This is the value you use for the direct call rule identifier in the interface, e.g. :
And then _satellite.track() call also includes an object payload in 2nd argument that you can pass to the direct call rule. So in the code above, I set a property named text and give it a value of elem.innerText.
Then, within the direct call rule, where you set variables, the data you passed can be referenced from event.details object within custom code box (e.g. event.details.text), or using % syntax within the interface fields (e.g. %event.details.text%).
2. Make use of setTimeout to delay evaluating the link click.
The one advantage of this method over option #1 is that it is passive. You don't have to add code directly to your site to make it work.
However, this is the shadier option, because you don't really know how long it will take for your link to be generated. But generally speaking, if you can determine it takes on average say 250ms for the link generation API to do its thing, and you set the timeout to be called at say 300-500ms, then you will probably be okay most of the time. However, it's never a 100% guarantee.
In addition, if clicking on the link ultimately redirects the visitor to another page, then this solution will likely not work for you at all, since the browser will almost certainly have navigated before this has a chance to execute. Because of this, I normally I wouldn't even mention this as an option, but since you mentioned this link involves an API that generates the link values when clicked, I figured maybe this isn't a navigation / redirect link, so maybe this is an option you can go for, if you can't do option #1.
First, create a direct call rule the same as shown in option #1. This will be the rule that receives the link text and makes the Adobe Analytics (or whatever other marketing tag) calls.
Then, create a separate rule as a click event, similar to what you are currently trying to do (listening for the link click, based on your css selector). In this rule, you won't be setting any AA variables. Instead, add a custom js box with code like this:
var elem = this;
(function (elem) {
window.setTimeout(function() {
_satellite.track('product_image_click', {
text : elem.innerText
});
}, 500);
})(elem);
So when the rule is triggered, it will create a setTimeout callback to call the first rule, passing the link text in the payload. And.. hopefully the 500ms timeout shown in the code example is enough time for the API to do its thing. You may be able to adjust it up or down.
Rather than defining it in Data Element I would say its better to keep it directly in the Rule itself. Please try with this %this.#text%.
Let me know if this helped.

Is it possible to create a variable in google tag manager that refers to form name?

I am trying to create a trigger for a particular form. What is the correct way to refer to form if i have no id?
Untested, but you should be able to create a DOM type variable, change the selection method from the default "id" to "CSS selector" and use that to address the form in question:
The actual selector might need a bit tweaking (and obviously you'd want to substitute the real name of the form in the square brackets), but basically that is the way to go.
You then create a form submit trigger, set it to "fire on some forms" and use the variable created above to filter the trigger for that specific form.

In GTM, how do I use a CSS Selector on a Click Element trigger?

I want to create a "Click Element" trigger with a CSS selector... basically I want to set a trigger on a specific element, rather than all elements. So I create a trigger called "Click - All Elements" and then "Some clicks"... but it asks me to attach a variable to it??
So I tried to create an Auto-Event Variable with type "Element"... but then "element" in the data layer just returns the URL that element links to, rather than the entire element (it's returning "http://example.com/signup", rather than the actual HTML element)
This doesn't make any sense. All I want is to set a trigger on a specific CSS selected element. Please help!
To check for a CSS selector in a trigger, you need to create a variable that looks for your specific CSS selector. To do this, you need a variable called "DOM-element" to specify to your click trigger with the "Some clicks" option.
Instructions:
If you go to the section with variables, click the "NEW"-button to create a new variable. Once the right hand side pans out, open the "Variable configuration" and click on the one called "DOM-element". In the drop-down, you can select CSS-selector. Insert the value you'd like to check for in your trigger, and this should do as you ask.
So I'm assuming you have multiple elements that have the same class, and yet you only want to target one with your click element trigger? If you can add IDs or data elements instead of just relying on a class, you can still do it using a "Click" event and "matches css selector" in your "Fires On" setting.
So if you had the following element:
<a id="whatever" href="whatever">My Link</a>
Since IDs are unique you would just use the following selector "matches css selector":
#whatever
With data attribute on specific element, you can target all elements with specific classes, but limit it based on a unique identifier you set in a data attribute:
So if you had the following element:
<a href="whatever" data-mytrack='4'>My Link</a>
You would use the following selector for "matches css selector":
a[data-mytrack='4']
I'm using like this, and it works.
Trigger Configuration

Resources