Access datalayer from GTM - javascript

I have created the following tag in GTM (Google Tag Manager):
(function(window) {
if (typeof(dataLayer[dataLayer.length-1].count) !== "undefined"){
dataLayer.push({'count':dataLayer[dataLayer.length-1].count+1});
} else {
dataLayer.push({'count':1});
}
})(window);
Initially, when there is no "count" pushed to the dataLayer, the if statement returns false and { "count" : 1} is pushed. After that the value of count should be incremented with each push. My aim is just to count the number of clicks on certain button.
However, it seems "if" statement is never validated, thus every button click results in pushing "0"-s to the dataLayer. I know this is not the best solution, but still I can't find out why this is not working. Btw it's working when I run this code in browser console.

I had to use dataLayer.length-2 instead of dataLayer.length-1 to access count. This was caused by the fact that GTM pushes gtm.click to dataLayer after each click event

Related

Custom Javascript Variable Returns Different Value on History Change

I have setup a Custom JavaScript variable that works intermittently. The function is simply designed to return true or false if a text is contained on the page.
The below code works fine when the page is loaded directly from the URL bar and when executed in the developer tools console. When running the function in the console, the function indeed turns true. When the code is executed within debug mode in GTM, the value returns false when a history change event occurs.
function() {
var content = document.body.innerText;
var query = "text to search";
if (content.search(query) > -1 ) {
return true;
} else {
return false;
}
}
Any assistance/insight is very much appreciated!
To me this seems like expected behavior. Since you are talking about history changes, you are probably working with a single page application, or some other page where the DOM is changed after the initial page load.
Custom Javscript variables evaluate a function and return the result each time you reference it. How I imagine the flow of operations goes is this.
Page Loads (target text is in the page body) -> Custom JS evaluates on page view and returns true -> User presses some button -> DOM is modified to display new content (target text is removed and no longer present -> History change occurs -> Custom JS evaluates again, the text is no longer present so returns false.
If the target text is still present after the history change, then I can understand why we have some unexpected behavior. The history change trigger is based off of the push state api so what could be happening is that the pushState() function is called before the DOM is finished being modified. In this case, the text isn't present at time of the history change event even though it is shortly afterwards.
You could change the page so pushState() is only called after the DOM is done being modified, use a custom event as a trigger instead (again, pushing it after the DOM is done being modified), or use a different trigger like the element visibility trigger that will only fire after the new DOM elements you want to target appear on-screen.

how to put an 'if' statement in front of a change function

This question is for using javascript in Caspio Cloud's platform, so a few things might look different than normal. But basically, I need to put an 'if' statement that references a variable 'above' a change function that runs some other code and I can't figure it out.
The problem is that in Caspio's form the Virtual9 field will 'change' on the form's load, and so it runs the change js. I need to not run the change js onload and also only if the variable 'item' is null.
<script>
var item = document.getElementsByName("InsertRecordItemID")[0].value;
<!-- right here I need an if (item !== null) to then run the change function but that if it's not null to not run the change function{ -->
$("[name='cbParamVirtual9']").change(function(){
var itid = document.getElementsByName("cbParamVirtual9")[0].value;
document.getElementsByName("InsertRecordItemID")[0].value = itid;
}
);
</script>
I've tested the variables using alert windows and they are gotten correctly. I just need to make sure the change function doesn't run if the variable 'item' is null.
EDIT: To clarify, when the form loads the ItemID field may or may not be null (based on parameters that pass over).
If it is not null then the Virtual9 field (where the user makes a selection) will be hidden- because the ItemID already had a value and needs to not change.
However, if ItemID is null then Virtual9 will be visible and the user can make a change, thereby updating the ItemID field. The user may update Virtual9 multiple times (looking for the right record) so it needs to keep updating ItemID (even after it is no longer null in this case).
That's why I think the best solution is to disable the code ONLY for onload, if possible. So that the code runs on change of Virtual9 but not onload.

s.getPreviousValue plugin not working

On Page A, I have a s.tl() call on click of "Link A" where I am filling evar1 and triggering off an event1. This link A leads to Page B
Code on link click in page A
$(document).on('click','.nav.navbar-nav.subnav-breadcrumb a',function(){
if($(this).text().toLowerCase().indexOf('create group')!=-1){
s.events = "event1";
s.linkTrackEvents = "event1";
s.eVar1 = "Step 1";
s.linkTrackVars = "eVar1,events";
s.tl(true,'o','Step 1');
}
});
On pageload of Page B, in the do Plugins sections, I try to get the value of eVar set in the prev s.tl() call by the following code
function s_doPlugins(s) {
console.log(s.getPreviousValue(s.eVar1,'cookie_name','event1')
}
However, I get the value as 'undefined'. Does getPreviousValue() plugin not work on previous s.tl() calls? What am I doing wrong here?
As mentioned in the documentation, since you are using the 3rd argument of s.getPreviousValue(), it will only store and trigger if the specified event is set (in both your case and doc example, that is event1).
Since you are setting event in the link click, s.getPreviousValue() triggers because s_doPlugins gets called on all s.t() and s.tl() calls, so at that point you should see the value in your cookie_name cookie (look in s_pers cookie if you are using combined cookie plugin).
However, on the next page (Page B) event1 isn't set, so when s_doPlugins gets called for the on-page s.t() call, s.getPreviousValue() will not update/return previous value.
In other words, when you specify an event in the 3rd argument, the plugin only triggers when the specified event is present in s.events. Basically first thing it does is check if 3rd arg exists then go through s.events and see if it's in there. If it's not, that's it, function ends with no return value (and that's why you get undefined returned).
I'm not sure what you're actually trying to accomplish but in my experience there aren't many use cases for specifying an event in the 3rd argument.

Show current tab URL in extension's popup

I want to store the current tab url in the following <input> field:
<input type="text" id="pdurl" value=>
The code I wrote in popup.js is the following:
chrome.tabs.query({active : true, currentWindow: true}, function (tabs) {
var tab = (tabs.length === 0 ? tabs : tabs[0]);
var activeTabUrl = tab.url;
});
document.getElementById("pdurl").innerHTML = var activeTabUrl;
I already have the tabs permission set in manifest file.
Your code is totally wrong. There are some serious problems, which would have been easy to avoid checking the popup console for errors. Here they are:
First of all chrome.tabs.query is an asynchronous method. This means that the code is evaluated and queued to be executed; when it executes, the callback function (which you're specifying as second argument) is called and executed. This means that the last line you wrote will always fail because the variable you want to use still doesn't exist (the query function hasn't still finished working).
You are creating a useless (and wrong (because you're assigning an array to it)) variable inside the callback: there's no need of your tab variable, because querying an active tab in the current window always returns a single tab, so you just need to use tabs[0].
Your activeTabUrl variable is defined with the var keyword, which will make it private, and you won't be able to use it outside the function (which is what you're trying to do in the last line, althought it's still wrong).
In the last line you are trying to assign the variable you created in the callback function to the innerHTML of your input: this statement is so wrong on so many levels I don't even know where to start: first of all if you want to actually see something in the text input you have to modify its value; secondly: the variable is not defined; plus, the var statement in your assignment makes it syntactically wrong; fourth: even doing all of the three previous conditions right you still are out of the callback.
Stated the above, this is the correct code for what you're trying to do:
chrome.tabs.query({active : true, currentWindow: true}, function (tabs) {
document.getElementById("pdurl").value = tabs[0].url;
});
I strongly recommend you to take a look at some JavaScript tutorial, and to check the console for errors* before asking questions like this one.
* Errors in the popup of an extension are shown in the popup console, which you can open right clicking on the extension's icon and choosing "Inspect popup".

Conditional Statement Determined by Previous Page or Firing off a .click without clicking

I was wondering if this were possible.
I have a very complicated script, that runs on .click.
I want to run the same script without the user clicking as-well - in the instance that the user clicks to a new page with the correct content open - I have done this a thousand times but in this case the normal wont work..
so my question is, can you have a conditional statement that will do something (run a function) if the user has come from a specific page?
or
set off the .click function if in the query string say URL.client_id is present..?
You could do something like:
// evaluate id
if(URL.client_id) // or whatever you're passing through here
{
runFunction();
}
$('#element').click(function()
{
runFunction();
});
function runFunction()
{
console.log("runFunction called");
}

Categories

Resources