Get element text through GTM Custom JavaScript Variable - javascript

I have two groups of links all with the same class names, the only difference is the text in the .
I need to get the text for the clicked link and pass it to GA through GTM.
<div class="item-set">
<header>Section Title One</header>
<section class="products">
<div class="list">
<img src="/ProductImages1.jpg">
</div>
<div class="list">
<img src="/ProductImages2.jpg">
</div>
<div class="list">
<img src="/ProductImages3.jpg">
</div>
</section>
</div>
<div class="item-set">
<header>Section Title Two</header>
<section class="products">
<div class="list">
<img src="/ProductImages1.jpg">
</div>
<div class="list">
<img src="/ProductImages2.jpg">
</div>
<div class="list">
<img src="/ProductImages3.jpg">
</div>
</section>
</div>
I have created a custom javascript variable
function() {
$('section.products div.list').click(function() {
return $(this).closest('.item-set').find('header').text();
});
}
But the bleep thing isn't working as I expect (or at all). It returns "undefined".
Any assistance is greatly appreciated.

You shouldn't bind to click event in JS variable. You should use JS variables in GTM only for receiving values
The correct way to achieve your goal is:
1) Enable built-in variable Click Element (if you already have it, you can skip this step)
2) Create trigger, which will fire when you clicking on your links
CSS selector on the screenshot is .item-set .list a
3) Create JS variable
Code is: function() {
return $({{Click Element}}.closest('.item-set')).find('header').text();
}
3) Create a tag, which will send data to GA
Here you can use your variable form step 3 {{Click List Header}}

Maybe you are not capturing/storing the return $(this).closest('.item-set').find('header').text(); from the function?
When you for example immediately invoke your function and click a div, the text of the <header> will be logged to the console.
(function() {
$('section.products div.list').click(function(e) {
e.preventDefault(); // to prevent the default action of the click
console.log($(this).closest('.item-set').find('header').text());
return $(this).closest('.item-set').find('header').text();
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item-set">
<header>Section Title One</header>
<section class="products">
<div class="list">
<img src="/ProductImages1.jpg">
</div>
<div class="list">
<img src="/ProductImages2.jpg">
</div>
<div class="list">
<img src="/ProductImages3.jpg">
</div>
</section>
</div>
<div class="item-set">
<header>Section Title Two</header>
<section class="products">
<div class="list">
<img src="/ProductImages1.jpg">
</div>
<div class="list">
<img src="/ProductImages2.jpg">
</div>
<div class="list">
<img src="/ProductImages3.jpg">
</div>
</section>
</div>

Related

TypeError: Cannot read properties of null (reading 'addEventListener') javascript

I am trying to add a button but it is showing me this error.
here is my html code
<div card-container>
<template class="mainTemplate">
<div class="cards">
<div class="card">
<img data-image src="" alt="">
<div data-title class="header"></div>
<div data-body class="body"></div>
<button data-button class="btn">read more</button>
<p data-paragraph class="fullText"></p>
</div>
</div>
</template>
</div>
here is the javascript code
let showDitail = document.querySelector(".btn");
showDitail.addEventListener("click", showMore);
function showMore(){
alert("e")
}
You're using the <template> tag, which is an element that holds html markup but it's not rendered on page load.
In order to render its contents, one has to handle the <template> element via javascript, using the html structure as - in fact - a template for filling another structure (a table, a divs grid, etc.).
Since the sub-elements of <template> are not part of the DOM yet, let showDitail = document.querySelector(".btn"); will result in null. That's why you cannot bind events to it.
Either change the tag to something else (a div maybe), or handle the template properly via javascript.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template
let showDitail = document.querySelector(".btn");
showDitail.addEventListener("click", showMore);
function showMore(){
alert("e")
}
<div card-container>
<div class="mainTemplate">
<div class="cards">
<div class="card">
<img data-image src="" alt="">
<div data-title class="header"></div>
<div data-body class="body"></div>
<button data-button class="btn">read more</button>
<p data-paragraph class="fullText"></p>
</div>
</div>
</div>
</div>

add data- attributes by reading values from DOM

I have the below html structure and I'm trying to get the text of h tags and add as a data- attribute in the corresponding tags:
<div class="content">
<div class="body">
<h1>foo</h1>
<p>para-test1</p>
<p>para-test2</p>
<div class="link">
anchor1
anchor2
anchor3
</div>
</div>
</div>
<div class="content">
<div class="body">
<h1>bar</h1>
<p>para-test3</p>
<div class="link">
anchor4
</div>
</div>
</div>
So 'foo' should be set as a data attribute value for anchor 1,2,3 elements and
'bar' should be set as a data attribute value for anchor 4. Something like this:
<a data-custom="foo" href="#">anchor1</a>
<a data-custom="foo" href="#"">anchor2</a>
<a data-custom="foo" href="#">anchor3</a>
<a data-custom="bar" href="#">anchor4</a>
I tried to iterate over the elements and I'm struck at the second loop.
$(".content .body").each(function() {
$(this).find(".link").attr("data-hN", $(this).next(":header").text());
});
You have an extra double quote two times in your HTML. But, fixing that and foregoing JQuery (which is overkill for such a trivial task), see comments inline below:
// Loop over the links
document.querySelectorAll("div.link > a").forEach(function(item){
// Set the current link data-custom attribute to the nearest
// .body ancestor and the first heading element within that text
item.dataset.custom = item.closest(".body").querySelector(":first-child").textContent;
console.log(item);
});
<div class="content">
<div class="body">
<h1>foo</h1>
<p>para-test1</p>
<p>para-test2</p>
<div class="link">
anchor1
anchor2
anchor3
</div>
</div>
</div>
<div class="content">
<div class="body">
<h1>bar</h1>
<p>para-test3</p>
<div class="link">
anchor4
</div>
</div>
</div>

Enclose whole div in an <a>

I have a div which I want to surround with an <a href>. I have the jQuery to add the <a href> after the div but I struggle to set it before and close it after the div.
This is the jQuery code I have:
$('.box_service').each(function() {
var link = $(this).html();
$(this).contents().wrap('');
});
It results in this HTML:
<div class="row">
<div class="box_service">
<a href="example.com">
<div class="inner-row"></div>
</a>
</div>
</div>
However my goal is this structure:
<div class="row">
<a href="example.com">
<div class="box_service">
<div class="inner-row"></div>
</div>
</a>
</div>
I can't enter the div before because there are more boxes in this row so I would add the <a href> to everything in there
The issue is due to your call to contents() which means you're wrapping the elements inside .box_service, not that element itself. Remove that method call.
Also note that each() is redundant, you can do what you require in a single line:
$('.box_service').wrap('');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="box_service">
Box service #1
<div class="inner-row">Inner row #1</div>
</div>
</div>
<div class="row">
<div class="box_service">
Box service #2
<div class="inner-row">Inner row #2</div>
</div>
</div>
.content will wrap the contents of your div, you want to wrap the div with <a> so call wrap on the div not on contents.
$('.box_service').each(function() {
var link = $(this).html();
$(this).wrap('');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="box_service">
<div class="inner-row"></div>
</div>
</div>
$('.box_service').each(function() {
var link = $(this).html();
$(this).wrap('');
});
You just need to remove contents() in between $(this).wrap() because contents() mean that you are wrapping the children of $(this).
Remove .contents() in order to wrap around each element with the class box-service:
$('.box_service').each(function() {
$(this).wrap('');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="box_service">
<a href="example.com">
<div class="inner-row"></div>
</a>
</div>
</div>
$('.box_service').wrap('');

Switch Content of Div onclick

I've got two divs - each with one image inside. If I click on the image inside the second div I want this image to become the content of the first div (like a gallery).
It's important that I don't replace the links inside the img tag, so document.IMG1name.src=document.IMG2name.src isn't a possibility.
I tried it with innerhtml, but it doesnt work:
<div id="container1">
<img src="blablabla">
</div>
<div id="container2"; onclick="document.getElementById('container1').innerHTML=document.getElementById('container2').innerHTML"><img src="../funnycat.jpg">
</div>
mm... your code works fine, just close img tags and remove semicolon:
<div id="container1">
<img src="blablabla" />
</div>
<div id="container2" onclick="document.getElementById('container1').innerHTML=document.getElementById('container2').innerHTML"><img src="https://www.google.es/logos/doodles/2013/holiday-series-2013-3-4504416610680832-hp.jpg" />
</div>
here you have a demo: http://jsfiddle.net/HLs86/
HTML
<div class="pricing_table" id="monthly">
<ul>
<li>Basic</li>
<li>Subscribe Now</li>
</ul>
<ul style="background-color:#CCCCCC;">
<h2>Monthly Plans</h2><a class='plansSwitch' href='#yearly'>Click here to switch to the "Yearly Plans"</a></ul>
</div>
<div class="pricing_table" id="yearly">
<ul>
<li>Basic</li>
<li>Subscribe Now</li>
</ul>
<ul style="background-color:#CCCCCC;">
<h2>Yearly Plans</h2><a class='plansSwitch' href='#monthly'>Click here to switch to the "Monthly Plans"</a></ul>
</div>
JS
var $plansHolders = $('#monthly, #yearly').hide();
$('#monthly').show();
$('.plansSwitch').click(function() {
var href = $(this).attr('href');
$plansHolders.hide();
$(href).show();
});
you just need to add javascript: on your onclick action like this
<div id="container1"></div>
<div id="container2" onclick="javascript:document.getElementById('container1').innerHTML=document.getElementById('container2').innerHTML"><img src="http://i.imgur.com/0fS8dCsb.jpg"/>
</div>
there is example

How i can select specific div from multiple divs in jquery

I have something like this, and i need to show every div called "plink" just in the main div of each parent, so i tried to fadeIn ".plink" but its doing the same function for all the divs of "plink"
<script>
$(document).ready(function(){
$('.plink').hide();
$('.project').mouseover(function(){
$(this).next('.plink').fadeIn(400);
});
$('.project').mouseleave(function(){
$(this).next('.plink').fadeOut(200);
});
});
</script>
<div class="project">
<div class="plink">
<div class="go"></div>
<div class="goplus"><img src="images/more.png" border="0"/></div>
</div>
<div class="pic"><img src="images/portfolio_pic2.png" border="0" alt="projectname"/></div>
<div class="title">Test1</div>
</div>
<div class="spacer_project"></div>
<div class="project">
<div class="plink">
<div class="go"></div>
<div class="goplus"><img src="images/more.png" border="0"/></div>
</div>
<div class="pic"><img src="images/portfolio_pic.png" border="0" alt="projectname"/></div>
<div class="title">test2</div>
</div>
You can use find() instead of next()...
$(this).find('.plink').fadeIn(400);
because this is your .project div then you need to "find" the child elements that you are looking for. Using next() means you will get the very next element if it matches the selector (i.e. it is check to see if the next .project div matches the .plink selector)
I would go the FIND route like musefan suggested. Here is the solution code:
http://jsfiddle.net/bx7YC/
<div class="project">
<div class="plink">
<div class="go">go</div>
<div class="goplus">goplus</div>
</div>
<div class="pic">pic</div>
<div class="title">Test1</div>
</div>
<div class="spacer_project"></div>
<div class="project">
<div class="plink">
<div class="go">go</div>
<div class="goplus">goplus</div>
</div>
<div class="pic">pic</div>
<div class="title">Test2</div>
</div>​
$('.plink').hide();
$('.project').mouseover(function(){
$(this).find('.plink').fadeIn(400);
});
$('.project').mouseleave(function(){
$(this).find('.plink').fadeOut(200);
});​
I replaced the broken img links with simple text for the jsfiddle.

Categories