How to use GTM trigger name in custom javascript conditional statement? - google-tag-manager

I'm wondering whether it is possible in a custom javascript variable in GTM (google tag manager) to find the "trigger name" that the variable is called by and use this in a conditional statement within the variable? I can find anything online about this? Is there something way of using the API maybe. I know we can get variable names with the curly braces. Anything like this for triggers?
Cheers

Usually triggers are based on built-in variables, and if you need to, you can reconstruct the trigger in your custom JS and then refer to it elsewhere.
For example, if you want to track a certain type of link click, you might start by creating the custom JS variable isTargetLink:
function() {
var targetLinkClass = 'relevant-css-selector'
if (targetLinkClass === {{click classes}}) {
return true;
}
}
You can then save this and refer to isTargetLink in another custom JS variable, e.g.
function() {
if ({{isTargetLink}}) {
// do something
}
}

Related

Can I replace dataLayer.push() with gtag()?

While trying to implement and understand the use of Google Tag Manager and Google Analytics I was wondering why there is talk about dataLayer.push() in some places while gtag() is used for similar operations in other places. They seems to be serving the same purpose even though the result is not exactly the same.
gtag() is defined as:
function gtag(){dataLayer.push(arguments)};
If I try the code I get a wrapping Arguments-object when using gtag. So I understand that there is a difference, but does this matter and should they be used for different purposes?
> dataLayer = []
> dataLayer.push({'event','login'})
[{'event','login'}]
> dataLayer = []
> gtag({'event','login'})
[Arguments({'event','login'})]
When should either one of them be used or could I resolve to only using one of them?
Well, there is no difference. gtag() is just a wrapper JS function around dataLayer.push(). However, gtag is preferable.
The reason for using gtag is to avoid any action that might pollute or change data inside dataLayer object by accident, which might affect analytic data.
Technically, they're the same, and you can use either ways.
Personally, when tagging events, I usually create my own function:
// definition
function gevent(name, data) {
gtag('event', name, data);
}
// sample
gevent('level_up', { userId: 123, prevLevel: 12, currLevel: 13 });
gevent('logout', { userId: 123 });

Google Tag Manager - Parse Dynamic Data Layer Variable

I want to parse a 'pushed' data layer string. I intend to use it to track click events and setup the appropiate funnels in Google Analytics, it looks as follows: products.view.19|view recent product|19
The first part (products.view.19) is the unique page identifier.
The second part (view recent product) is the action.
The last part is (19) is the action identifier, this way actions may be grouped and compared more easily.
So I did the following, I first created a trigger (it fires when a link has the tag 'data-trackclick' in it) which pushes the data value to a variable (variable for datalayer). However, now I want to split that variable in to 3 new variables, as described above. I selected 'javascript macro' for this but somehow it returns 'undefined'. The macro looks as follows:
function() {
var data = {{TrackClickData}};
var pieces = data.split('|');
if (pieces[0].length()) {
return pieces[0];
} else {
return data;
}
}
Obviously this didnt work since it would only run on the initial load and not (like I thought) when the macro was requested, so it should somehow be fired on the 'click' and then set the variables accordingly.
Is this possible to do? Or do I really have to add the dataLayer.push() in script tags?
A few things:
.length() is wrong, the property for array length is .length without the ()
if it exists, pieces[0] is not an array, then .length would return the string length, see How do you check for an empty string in JavaScript? for more standard way of checking for empty strings
Is this possible to do? There's virtually nothing you can't do with GTM, since you can write JavaScript code, you can do whathever you code allows you to do, and splitting a string to use parts of it as variables is certainly within the realm of possibilities.
My advise is to make your code work outside GTM first (eg test it in the browser console), then once it's all working, port it to GTM.

Fire macro only once in Google Tag Manager

I have a macro which remembers a previous clicked ID for the next event, which is quite handy and it works fine. When I use the macro in a firing rule, where the firing rule is not used, it also works good. However, when I use the firing rule for a Tag, it get's calculated twice and so it forget the previous clicked ID and only returns the current clicked ID. Is there a way to let this Macro only be calculated once?
Set a cookie in your macro
document.cookie="hasexecuted=true";
Create a second macro of the cookie type and name it e.g. "hasexecuted". Use it to check for the presence of the cookie. The cookie macro will be filled in with a value before any custom javascript values, so you can use it's return value in your custom macro function:
function() {
if({{hasexecuted == true}}) { return; }
....
}
Google Tag Manager does not have any memory all by itself so you need to implement your own storage and for such a simple thing a cookie might be easiest (if course this means a wee bit more overhead since cookie data is send to the server, so you might want to use localstorage or something like it).

Detect template change in Meteor

I'm looking to make an element flash on screen when the underlying collection is updated.
It seems to me that it would make to have an equivalent of Template.my_template.rendered = function(){} which is fired every time the template is updated.
Ideally, this function would not fire the first time the template is rendered.
This is seems like such an obvious use case, am I missing something?
For Meteor < 0.8
You should use Template.myTemplate.created to do something for the very first time. From the docs Template.myTemplate.rendered is fired everytime there is a change including the first time. If you want to limit it to only the second time and changes after that (I'm guessing this is what you want), you have to write some custom logic. Currently there is no Meteor api that supports that.
For Meteor-0.8
It seems like this API underwent some backwards incompatible changes in Meteor-0.8.
There is an elegant way to achieve this as described Adaptation to the new Meteor rendered callback here. Bascially you should modify whatever function you are attaching to the variables inside your Template's javascript by calling a helper function once. For example,
var renderCount = 1;
var myHelper = function () {
console.log("rendered #" + renderCount);
renderCount++;
};
Template.myTemplate.myVariable = function () {
myHelper();
return this.name;
};
Hope this helps. There is also another alternative approach in that same repo. You might like that one.
There is no simple solution; more discussion here: https://groups.google.com/forum/#!topic/meteor-talk/iQ37mTP3hLg

How to add default custom action to dashlet's title bar in Alfresco Share

Since some days ago I'm struggling to find out the best way to add a custom action in every dashlet's title bar by default.
At this stage, I know the actions are set up as a widget in every dashlet's webscript. For example, in docsummary.get.js:
var dashletTitleBarActions = {
id : "DashletTitleBarActions",
name : "Alfresco.widget.DashletTitleBarActions",
useMessages : false,
options : {
actions: [
{
cssClass: "help",
bubbleOnClick:
{
message: msg.get("dashlet.help")
},
tooltip: msg.get("dashlet.help.tooltip")
}
]
}
};
model.widgets = [docSummary, dashletResizer, dashletTitleBarActions];
Then, the widget is instanciated in when the page is rendered.
I have figured out the next approaches:
Augment the "actions" array of every widget instance with the action I need in a custom JS snippet, every time the page is rendered. I have performed some tests without success using techniques like this: http://acidmartin.wordpress.com/2012/03/19/getting-instance-names-of-a-javascript-object/
Modify the prototype of Alfresco.widget.DashletTitleBarActions by adding my custom action. I believe it doesn't work either as the "actions" object is always overridden when the widget is instantiated, as you can see in the code above pasted.
Create an extension module for every dashlet's webscript which adds the custom action for every Alfresco.widget.DashletTitleBarActions widget definition, similarly as Dave Drapper explains in his post http://blogs.alfresco.com/wp/ddraper/2012/05/22/customizing-share-javascript-widget-instantiation-part-1/
Get every dashlet div container and add the action required directly manipulating the DOM once the page is ready. It should work but is something I consider slightly dirty and inconsistent, hence I would like to avoid it.
Could anyone imagine a better and feasible solution??
Let's start with adding an action to a single existing dashlet. As you suggest in (3) you can define an extensibility module to change the behaviour of the dashlet by intercepting and modifying its model.
Creating an extensibility module is well covered on the blog article and follow-up posts, but the trick here is to provide a controller JavaScript extension which locates the DashletTitleBarActions widget and adds your action to it, e.g.
if (model.widgets)
{
for (var i = 0; i < model.widgets.length; i++)
{
var widget = model.widgets[i];
if (widget.id == "DashletTitleBarActions")
{
widget.actions.push({...})
}
}
}
What you put in the object literal depends on how your action is implemented. If you require some client-side behaviour (rather than say, a static link) then you will also need to bind that in using a CustomEvent - see the RSS Feed dashlet org/alfresco/components/dashlets/rssfeed.get.html.ftl for an example.
The down-side of an extensibility module is that you will need to define an explicit extension JS file for each dashlet. You could easily put the code above in a central file and then include it in each dashlet extension where it is needed, e.g.
<import resource="classpath:alfresco/site-webscripts/org/myco/utils/dashlet.utils.js">
I would take the road number 2 here.
The definition of this widget is in share.js file ({share.context}/js/share.js). For Alfresco 4.2, DashletTitleBarActions is defined at around line 1700. In the onReady handler of the widget, there's a loop that processes the actions.
// Reverse the order of the arrays so that the first entry is furthest to the left...
this.options.actions.reverse();
// Iterate through the array of actions creating a node for each one...
for (var i = 0; i < this.options.actions.length; i++)
{
As you can see, it reverses the order of actions parameter, and then adds starts to loop the actions. So depending if you want your action to be the first or last, you could probably edit this file and add your custom action:
myAction = {
"cssClass": "customCSS"
, "tooltip": this.msg("slingshot.messages.generic.tooltip")
, "eventOnClick": ...
...
}
this.options.actions.push(myAction);
// now move on with the rest of the loop
for (...)
Of course, that requires overwriting shares' own js file, and not extending it. If you can't do that, you would then have to include a custom JS file on each page where share.js is also included and make sure it's executed after share.js but before any of the widgets are ready, and overwrite the onReady method of the widget itself so that it does this.

Resources