Expand my Community achievements bar.

SOLVED

enters viewport condition in DTM

Avatar

Level 2

I am trying to set a rule to fire only when a <p> with the id of "ApplyFormError" shows, i'm using the enters viewport condition but it seems like the rule is firing before the element show.not when the element actually appears in the page
[img]entersviewportsettings.png[/img]

I want to know if my settings are correct? or if i should try a different thing???
smiley

1 Accepted Solution

Avatar

Correct answer by
Former Community Member

Yeah, there are definitely other ways - JavaScript is flexible, and so is DTM.
 

Probably the easiest way would be to add a Rule Condition that tests for something else that should also be true.

Before I give any examples - what information are you trying to capture with this event/rule?
I ask because all it is doing/will do is capture when a user has entered a valid birthdate in the top form, and is now viewing the top of the registration form on the bottom of the page.

Is that what you're after?
Or are you looking to capture other information?
e.g. capturing when someone tries to submit the form at the bottom of the page, but gets an error

If the intended purpose of this event is just to capture when someone is viewing the form on the bottom of the page, then you could add a Rule Condition similar to the following:

Criteria = Custom
Custom JavaScript =

(document.getElementById("page").style.display == "block")

This is effectively asking "Is the <div> containing all the registration form goodness on the bottom currently visible?"
[img]dtm-custom-script.png[/img]


Adding the above condition should resolve the issue of the event firing prematurely, but as I said, it may not serve the intended purpose. Let us know what you're trying to do, and we could provide some other suggestions.

View solution in original post

10 Replies

Avatar

Level 2
        Seems like it does not work :( the url is http://stage.mltapthefuture.com/Apply. This is what is see as soon as the page loads:

Avatar

Former Community Member

Hello, Yabagna, and welcome to the Marketing Cloud community.

Is it possible that you have more than one element in the page with the same ID? (e.g. a parent <div>)
If so, you'll need to remove the duplication (IDs need to be unique). You might have some luck with a more specific selector, e.g. p#ApplyFormError

Also, have you tried unchecking the "Apply event handler directly to element" option?
In most cases, it shouldn't be necessary to have this checked.

If that doesn't help, can you share a link to the page you are trying to implement this on?

If the page in question is not publicly accessible, or for some other reason you are unable to share, I'd recommend using a JavaScript debugger to determine if this event is firing; and if so, when.

Avatar

Former Community Member

Thanks for sharing a link to the page. It was helpful in determining what's going on.

The paragraph in question is hidden by default (because div#page has display:none set) - which, to a browser, means the element still exists and is still rendered (just not displaying). More to the point, hidden elements like this are rendered in the browser at the x/y coordinates of 0,0. Therefore, the reason the rule is firing is because 0,0 is always in the viewport when the page loads. Just one of those fun things about HTML/CSS/JavaScript and browsers. smiley

 

There are a few ways to achieve the desired behavior without changing much, but note that you'll need to make changes to your page's code (i.e. not just in DTM) to get there.

First, you should note that <p>s can't contain <div>s (invalid HTML), so at the very least, you need to change the <p> into a <div>. Here's a snippet of the invalid markup from your page:

        <p>If you’ve already registered, sign in using the box in the top right corner.</p> <p id="ApplyFormError" class="error"> <div class="validation-summary-valid" data-valmsg-summary="true"><ul><li style="display:none"></li> </ul></div> </p>

 

Instead of just changing the <p> to a <div>, I'd recommend changing to something like this:

<p>If you’ve already registered, sign in using the box in the top right corner.</p> <div id="error-container"></div>

And then change the invalidHandler function of $('#ApplyForm').validate (in your '/Scripts/desktop.js' file) to dynamically create the div#ApplyFormError (instead of inserting HTML and showing the element). e.g.:

$('#ApplyForm').validate({ debug: true, invalidHandler: function (form, validator) { $("#error-container").append("<div id='ApplyFormError' class='error'><p>Hey, you've left a field incomplete or incorrect. Give it another try.</p><div class='validation-summary-valid' data-valmsg-summary='true'><ul><li style='display:none'></li></ul></div></div>") },

(You could, of course, create the element in some other part of your various JavaScript files, but without being more familiar with your code, this seems a logical place to make the change.)
 

Once you do that, your 'enters viewport' rule should function as expected. (If you changed the condition to p#ApplyFormError as I suggested before, then you'll need to remove the p and save/approve the rule before it'll work with the above changes.)

Avatar

Level 2

Ok I understand that. The thing is that i can't do any changes on the code since an agency develop the site. I can't ask for any code change right now
Is there any other way I can get that rule to fire without having to change the js or the html code?
Thank you so much for taking some of your time to help me with this :)

Avatar

Correct answer by
Former Community Member

Yeah, there are definitely other ways - JavaScript is flexible, and so is DTM.
 

Probably the easiest way would be to add a Rule Condition that tests for something else that should also be true.

Before I give any examples - what information are you trying to capture with this event/rule?
I ask because all it is doing/will do is capture when a user has entered a valid birthdate in the top form, and is now viewing the top of the registration form on the bottom of the page.

Is that what you're after?
Or are you looking to capture other information?
e.g. capturing when someone tries to submit the form at the bottom of the page, but gets an error

If the intended purpose of this event is just to capture when someone is viewing the form on the bottom of the page, then you could add a Rule Condition similar to the following:

Criteria = Custom
Custom JavaScript =

(document.getElementById("page").style.display == "block")

This is effectively asking "Is the <div> containing all the registration form goodness on the bottom currently visible?"
[img]dtm-custom-script.png[/img]


Adding the above condition should resolve the issue of the event firing prematurely, but as I said, it may not serve the intended purpose. Let us know what you're trying to do, and we could provide some other suggestions.

Avatar

Level 2

We are trying to track when a user gets this error and count it as a page viewed.
I'm having the same issue trying to find out how to set a rule that differentiates pages that share the same url

for example to enter this site:  http://stage.mltapthefuture.com/ you have to add you age and submit it in order to see the homepage, however the homepage has the same url as the age gate page, which is http://stage.mltapthefuture.com/
How can i set a rule to track each of those pages separately?

Avatar

Former Community Member

As long as you are sending the title of the page (document.title), you should be able to differentiate the two.
When the age verification screen appears, the title is "Miller Lite Tap The Future - AV" and it changes to "Miller Lite Tap The Future - Home Page" after you've submitted a valid birthdate and the page shows the main content.

Assuming you're using Adobe Analytics, you could just update s.pageName with the new page title and then send a new image request (e.g. via s.tl).

Avatar

Level 2

Well that can be a good option! :)

Now how do i do to caputre that and translate it into a rule?
Should i create a event based rule with the condition "element exists" ? If so how can will the selector will be in this case?

Thank you for your time! you've really helpfull :D

Avatar

Former Community Member

It looks like the page markup is very similar on the home page as to what's on the Apply page, so you can use a similar rule to the one we discussed for the Apply page, and then add some JavaScript to the rule to update s.pageName to equal the new document.title (and send the page view for tracking).

That is, you would use the same Rule Condition (checking if the div#page is displaying) with an 'enters viewport' event. (You could use a different kind of event than 'enters viewport', but this type of event should work for your needs.) You could check for the #page div itself coming into view (by putting #page as the selector), or you could check for the navigation bar (by putting .container-top-nav-bar as the selector), or really anything else that exists inside of the div#page.
I don't know when the existing scripts on your site change the document.title to "Home Page", and you need to make sure your rule doesn't fire until after the document.title changes, so I'd recommend testing with this rule by setting the selector to different elements - try the two I suggested above first, but if neither works, then try a few more elements a little farther down on the page. The testing you do is just to ensure you get the timing right.

The last (and perhaps the most important) bit is to add the JavaScript to your rule as well - this is what will update the page title and then send the data for tracking. Again, you'll have to test this, but you could do something like:

s.pageName = document.title; s.t();

 

Just in case you need it, this is a helpful resource: https://microsite.omniture.com/t2/help/en_US/dtm/index.html#Troubleshooting

Avatar

Level 2

Unfortunately it did not work since the #AV and all of its elements are always in display block, However i noticed that all of the #AV content is removed when you go to the home page (i think it uses some kind of ajax to do it) and i tried to create an page load rule whit a script that evaluates if the #AV has any child, it work but the thing is that it only works when i update the page, and I need to work as soon as you see the home page. So i tried creating a event based rule with this conditions but seems that is not working. I'm missing something in the settings? Or is there a way to create a rule that fires without the need of updating the page and using this script condition ?
 

The following has evaluated to null or missing: ==> liqladmin("SELECT id, value FROM metrics WHERE id = 'net_accepted_solutions' and user.id = '${acceptedAnswer.author.id}'").data.items [in template "analytics-container" at line 83, column 41] ---- Tip: It's the step after the last dot that caused this error, not those before it. ---- Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)?? ---- ---- FTL stack trace ("~" means nesting-related): - Failed at: #assign answerAuthorNetSolutions = li... [in template "analytics-container" at line 83, column 5] ----