Lottery scams

guilablepat Consolidate your debt
[email protected]

Scam Email received 5/17/2019

Email From:

[email protected]

Sender Name:

National Debt Consolidation

Other emails used:


Email Subject:

guilablepat Consolidate your debt

guilablepat Consolidate your debt – [email protected]

Contact December 6, 2018 32 Google Tag Manager Debugging and Testing Tips Google Tag Manager debugging is an art of its own. Checking the Preview and Debug mode to see if the tag was fired is just the tip of the iceberg. In fact, there are many more things/techniques you need to follow in order to be sure that everything is working properly (or just to find the reason that is causing some nasty bugs). In this guide, I’ve collected a list of Google Tag Manager debugging and testing tips (and some tools) to help you better understand what and where you should check. Some of them are overlapping, therefore, in the end, it’s up to you which ones to use. Let’s start, shall we? Before we continue This list is definitely far from being complete, therefore, I ask for your input. If you see some very useful debugging technique missing, please let me know in the comments or contact me via other channels(e.g. social media, email, or contact form). Also, there’s still a high chance that I still don’t know or just forgot to include something, so any input from my audience is appreciated. Let’s move to Google Tag Manager Debugging Tips I’ve written down a bunch of tips/suggestions/ideas and then split them into categories: Debugging tips related to the GTM Preview and Debug mode Tips related to the built-in browser tools Google Tag Manager debugging tips related to browser extensions Other GTM debugging tips Table of contents Debugging tips related to the GTM Preview and Debug mode #1. If the orange box does not appear, GTM Preview console also won’t #2. If you share a link to the Preview and Debug mode, always try to enter the destination link too #3. To exit the shared Preview and Debug mode, you need to revisit the shared URL and click EXIT or delete the 3rd party cookie #4. Preview and debug mode may not always work and there are many causes for that #5. Preview mode can be minimized. It can also remain like that after a page reloaded. #6. Preview and Debug mode resets after the page refreshes #7. The left side of the Preview and Debug mode displays changes in the Data Layer #8. If you want to use a particular data (from the Data Layer) in a GTM tag, make sure that this data is available as a variable on that particular Data Layer event #9. Keep an eye on the Errors tab #10. Check what values were sent to a 3rd party tool by click on a tag #11. The Summary shows how many times each tag was fired #12. View trigger conditions by clicking on a tag #13. Preview and Debug mode does not show everything relating to firing conditions #14. Missing Pageview Event? The Data Layer is set incorrectly Google Tag Manager debugging with built-in browser tools #15. Check the browser’s JavaScript console for errors #16. View the Data Layer by entering “dataLayer” in the console #17. “Tag Fired” ≠ data was properly sent to a 3rd party tool #18. Check if there are more website elements matching the same CSS Selector #19. google_tag_manager.dataLayer methods Google Tag Manager debugging with browser extensions #20. Inject your Google Tag Manager container with extensions like Tag Manager Injector or dataLayer Inspector+ #21. dataLayer inspector+ #22. Block already existing GTM containers in order to inject your own. Fresh and clean. #23. Da Vinci Tools #24. GA Debugger #25. GA debug mode setting in GTM #26. Use Tag Assistant recordings to debug Google Analytics implementation #27. Non-standard Google Analytics implementation is not a problem #28. Google Tag Manager debugger #29. Use helpers/debugging plugins tailored to specific tools Other GTM debugging tips #30. Don’t see the data in GA Real-time reports? There are several possible reasons #31. Not every GA interaction is visible in the real-time reports #32. It is possible to test GTM implementation (web) on a mobile device Part I: GTM debugging with the Preview and Debug mode In this part, I’ll dive a bit deeper into the standard GTM Functionality. #1. If the orange box does not appear, GTM Preview console also won’t If you hit the Preview button in the top right corner of your GTM interface and the orange box (see below) did not appear, that’s a good indicator that the 3rd party cookie (from was not stored in your browser. This means that the Preview and Debug console will not appear either. There might be several reasons for that. For example, your browser’s privacy settings block 3rd party cookies or you’re using a more aggressive privacy-related browser extension that also blocks GTM’s 3rd party cookies. A solution for that? Change 3rd party cookie settings to accept them, whitelist cookies, whitelist in your browser privacy extension, etc. Since there are many browsers and extensions, I leave this task (to find out) for you. Also, this issue is one of the more popular reasons why GTM Preview and Debug mode is not working for you. #2. If you share a link to the Preview and Debug mode, always try to enter the destination link too There are two main reasons why you want to share your Preview and Debug mode: show someone how you implemented changes in the container (say, for the QA purposes) get help from someone to debug a particular issue for you. The latter point is the reason why I included this “tip” in this list at all. If you want to get GTM help faster from someone (for example, in the GTM community on Facebook), do your best to provide as much information as you can. This also includes the URL of the page where the issue should be debugged. I’ve had too many times when a person sends me a link to the P&D mode without actually entering the destination URL where I should check. I’m not a psychic to read your mind So even though this tip is not directly related to YOUR debugging, it will make the job easier for the person who wants to help you and debug. #3. To exit the shared Preview and Debug mode, you need to revisit the shared URL and click EXIT or delete the 3rd party cookie If you clicked someone’s shared link of the Preview and Debug mode and keep seeing the debug console at the bottom of your browser screen even after the debugging job/task is already done, you have two options: Revisit the link of the shared P&D mode and click the Exit preview and debug mode. Or delete the 3rd party cookie that belongs to #4. Preview and debug mode may not always work and there are many causes for that There are many reasons why GTM Preview and Debug mode does not work on your (client’s) website. In fact, I’ve listed at least 15 reasons and solutions to them. The list contains (but is not limited to): Wrong container Heavy caching Content Security Policy (CSP) AdBlockers etc. #5. It can also remain like that after a page reloaded. If GTM is taking too much of space in your screen, you can resize it by dragging its top border. If you want, feel free to minimize it by clicking a little icon in its top right corner. If you refresh a page, the debug console will appear in your screen again (regardless of its previous state). Fortunately, this can be fixed with a Chrome Extension Da Vinci Tools. This handy plugin implements various enhancements in GA, GTM, Data Studio. One of them is “Remember minimized” feature that keeps the Preview and Debug console minimized even after the page was reloaded. #6. Preview and Debug mode resets after the page refreshes This happens because the P&D console displays what is happening in the dataLayer, which is wiped out after the page refreshes. So if you have some click or other interaction tracked in the debug console and want to see what kind of variables were available at that moment, you won’t be able to do that after the page refreshes… unless you apply one of the following techniques/tools: Want to track a link? CTRL + Click (on Windows) or CMD + Click (on Mac) will help. These commands will open the link in a new tab while the data in the previous tab is still preserved. After you do a click or submit a form, quickly hit the ESC button on your keyboard. Success is not guaranteed but still worth trying. Even though the page refreshes, you can still preserve Data Layer’s information in your browser. This can be done by enabling “Preserve log” setting in the browser’s JavaScript console and then combining it with extensions like dataLayer Inspector+. Here’s how you can preserve log in Google Chrome: Once you do that, enable dataLayer Inspector+ by clicking its icon and then ticking the checkbox: After that, you’ll start seeing some magic in your browser’s JS console. Alternatively, you can use GTM Debugger or Data Layer Checker extensions that preserve data in the Data Layer without Preserve Log feature. Enter a Custom Script in browser’s JavaScript Console and it will block the page from reloading (read the tip #2 here) Automatically pausing the page upon the beforeunload event. By going to your browser’s developer tools, you can set the page to pause when it intends to reload. During the pause, you can inspect the Data Layer in the browser’s JavaScript console. This advanced technique is also explained in Simo Ahava’s guide (read the tip #3) Implement this Simo Ahava’s solution to persist the data in the Data Layer across pages. Personally, my favorites are tips #1 and #4. #7. The left side of the Preview and Debug mode displays changes in the Data Layer Click any interaction to inspect what happened in the Data Layer in that exact moment: what data was (un)available. Every dataLayer.push is visible in this stream. If the push has an event key, then that very exact key name will be visible in the stream. If there is no event key, then the dataLayer.push will be displayed as a message. #8. If you want to use a particular data (from the Data Layer) in a GTM tag, make sure that this data is available as a variable on that particular Data Layer event Take a look at the screenshot below. There are several interactions in the Data Layer: userInfo (custom dataLayer.push) Page view DOM Ready Window Loaded formSubmission (another custom dataLayer.push) With the userInfo event, there was some user-related data pushed to the Data Layer, including pricingPlan. Now, if you want to pass the value of pricingPlan with the formSubmission event to a 3rd party tool, like Google Analytics or Facebook Pixel, you need to make sure that the value of the pricing plan is actually available in the Data Layer. You can easily check that by: choosing the formSubmission event in the Preview and Debug mode (because you want to fire a tag upon this event) and going to the Variables tab. If the variable contains some actual value (not an undefined, NaN, etc.) on that Data Layer event, you can definitely use the variable in a tag to send its value to a 3rd party tool. Keep in mind that custom data in the Data Layer is not by default available in the Variables tab of the Preview console. Now, if the userInfo dataLayer.push occurs after the formSubmission dataLayer.push, the pricingPlan value will not be available and will not be sent to GA or anywhere else. And that is one of the most common mistakes among GTM beginners: not checking if the variable is actually available at the moment when a tag is fired). If a variable is not available in the Variables tab at all, then go to the Data Layer tab and see if the needed data is there. If yes, either enable a proper built-in GTM variable or create a Data Layer Variable. To sum up: if you want to use a particular data from the Data Layer in your tag, make sure that it is available there. If a particular key is pushed to the Data Layer only after a click, then it will definitely not be available with the Page View event (because the Page View happens sooner than the click). #9. Keep an eye on the Errors tab This feature is pretty new in GTM and isn’t used too often (at least from my experience). But if you notice any number in the tab (rather than 0), click it and see what is the cause. This tab displays if a GTM Tag Template failed to fire due to an error. Here’s a quick guide about it. #10. Check what values were sent to a 3rd party tool by clicking on a tag Choose an event in the Preview and Debug mode’s event stream and click the tag that fired on that event. If needed, expand the table to see what configuration was of that particular tag and what data was sent to a 3rd party tool (like Google Analytics). #11. The Summary shows how many times each tag was fired This is useful if you planned a particular tag to fire only once but, in fact, it was triggered several times by multiple triggers. P.S. You can prevent a tag from firing multiple times in its Advanced Settings. Choose Once per page. #12. View trigger conditions by clicking on a tag If you want to find out why a particular tag did or did not fire, choose an event in the Preview and Debug console’s event stream and click the tag that has fired (or not). Scroll down to see all the linked firing and blocking triggers. Take a closer look at icons. If a trigger has a green check icon, that means that this trigger activated the tag. You can also see green and red icons next to every condition of tags. If the condition was met, the icon will be green. This helps you identify possible reasons why one or another tag has fired (or not). #13. Preview and Debug mode does not show everything related to firing conditions There is a chance that such a situation has already happened to you once (or will happen in the future). A tag has fired even though conditions in your triggers were not met. Or the opposite, all conditions were met but the tag did not fire. Why do such things happen? As for November 2018 (and many years before), not everything (related to tag firing conditions) is displayed in the Preview and Debug mode. I’m talking about Tag Sequencing and Tag Firing Options. If you set a tag to fire before or after another tag (via Tag Sequencing), this will not be visible in the Preview console, under Firing Triggers section. You can only see it in the GTM UI by opening a particular tag and scrolling down to Triggering section. Anyway, as a result, you might start thinking that your tags are firing even when they shouldn’t but that’s not true. It’s just that the Preview console does not display the Tag Sequencing (that’s a feature request right here). Speaking of tags not firing even though they should, another setting that may prevent that is Tag Firing Options. You may have set a tag to fire only once per page load. This means that a tag (which has already fired) will not fire anymore even if all the conditions are met. That setting can be found under tag’s Advanced Options. #14. Missing Pageview Event? The Data Layer is set incorrectly. Every time a page loads, at least 3 Data Layer events are visible in the Preview and Debug mode: Page view (gtm.js) DOM Ready (gtm.dom) Window Loaded (gtm.load) And it always should be like that. At least 3. However, sometimes the Data Layer is implemented incorrectly on a website which causes the Page view (gtm.js) event to break. This happens because a developer places the following Data Layer snippet below the Google Tag Manager container: 123 So whenever you are debugging Google Tag Manager implementation, keep an eye on whether all three Pageload-related events appear in the Preview and Debug mode. A solution for this? At least ask a developer to place the Data Layer code above the GTM container. But even a better option is to use dataLayer.push instead of dataLayer=. Then the position of the snippet is not that important anymore. I’ve published a guide explaining this issue so feel free to read more about it. SUBSCRIBE & GET THE ULTIMATE LIST OF 120+ GOOGLE TAG MANAGER RESOURCES. A TO Z. Please wait… You have successfully subscribed. Go check your inbox. Please enter your email address Please enter a valid email address Unexpected error occurred! Part II: Google Tag Manager debugging with built-in browser tools Making use of the standard browser functionality for developers. #15. Check the browser’s JavaScript console for errors Since I’m mainly using Google Chrome to work with Google Tag Manager, here’s how you can enable JS console there. In the top right corner of the browser, click three dots, then navigate to More tools > Developer tools. A pane will appear at the bottom of the screen (or in the sidebar, this depends on your preferences). Switch to console, click Clear Console and refresh the page. If you notice any red errors, consult with your developer whether they are critical. The variety of errors is huge so don’t think I can give you some tips on how to act is the most standard cases. If you notice that an error that is originating from gtm.js, then take a deeper look at it (because that something cause by Google Tag Manager). One of the most common is this one: 404 not found for GET: GET 1 404 not found for GET: GET It is not critical but, nonetheless, you can fix it by reading this guide. #16. View the Data Layer by entering “dataLayer” in the console Even if you don’t have the access to website’s Google Tag Manager container and cannot enable the Preview and Debug mode, you can still check what is happening in the Data Layer. This is very useful if you’re asked to quickly debug a particular issue but, for some reason, cannot get the access to the GTM container right away. To do that, open your browser’s JavaScript console and enter dataLayer. What you’ll see is the list of all the information which was pushed into the Data Layer. Click the triangle to expand the Data Layer and then click any other triangle to expand that particular dataLayer.push to see what’s happening. #17. “Tag Fired” ≠ data was properly sent to a 3rd party tool Even though a tag is displayed among “Fired” in the GTM Preview and Debug mode, this does not mean that the data was sent to another tool (e.g. Google Analytics or Facebook Pixel) as you expected. It is pretty common among beginners to assume that if a tag has fired, the job is done here. Even if that happened, the request might end with an error (404, 502, etc.). Or maybe the request was indeed sent properly but the values of your variables were undefined. So how can you make sure that the data reached its destination as you intended? There are several options: Check real-time reports if they exist in your tool of choice. For example, in GA real-time reports you can debug page views, events, conversions. When your tag is fired in the Preview and Debug mode, go check the real-time reports and see if the data is actually displayed here. Keep in mind that custom dimensions, custom metrics, e-commerce data are not available there. As for the Facebook Pixel, you can also check their real-time data in Facebook Analytics. Go to, open your Pixel’s reports and in the left sidebar choose Event Debugging. This is where you can check what data was recently picked up by Facebook. Check the Network tab in your browser’s Developer Tools. In developer tools, go to the Network Tab to see the list of requests that your browser has made on that page. You can locate a specific type of request by using the filter feature. For example, if you’re debugging Facebook Pixel requests, enter to see the requests sent by Facebook Pixel. If status codes are 200, this means that everything is great. Sometimes internal redirects are possible so 307 status code is also fine, as long as you see other requests getting the 200 OK. Read Simo Ahava’s guide where he explains this topic more in-depth. Use helpers (browser extensions) tailored to debugging of particular tools/platforms. I will not dig deeper into this topic a bit later (in one of the upcoming chapters in this blog post). But when I say “helpers”, I’m talking about Facebook Pixel Helper, Twitter Pixel helper, GA Debugger, etc. #18. Check if there are more website elements matching the same CSS Selector If you’re actively tracking clicks and other interactions by using element IDs, CSS Classes, or Matches CSS Selector operators in GTM, you’ll find this one useful. By employing HTML element attributes and/or operator in their GTM triggers, people are often assuming that those attributes/CSS Selectors are pretty unique and apply only to those elements that they wish to track. Well, usually that’s not how things work. The problem with this approach is that people cannot be 100% positive that those classes, IDs, etc. are unique enough to rely on. What if you want to track clicks of one element with a CSS class btn-bt? How can you be sure that you’re not setting a trigger that will cause many false positives? In fact, there is a decent chance that there are more elements on that page/website with a similar CSS class. So if you’re checking your analytics reports and wondering why there was a click tracked on a certain page (even though the page does not contain THAT SPECIAL ELEMENT), this tip is for you. Let’s continue with the aforementioned example, CSS class btn-bt. In order to know the number of elements that utilize this class, open the JavaScript console in your browser’s developer tools and enter the following command: document.querySelectorAll(“your_css_selector”) document.querySelectorAll(“your_css_selector”) Replace the your_css_selector with the actual CSS selector you wish to test against. In our case, the selector is “.red-block”. document.querySelectorAll(“.btn-bt”) document.querySelectorAll(“.btn-bt”) Hit enter. What you’ll see is the list of all the elements on a page that use this class. In the example below, I got 2 elements. You can tell that from the number next to the NodeList and if you click the triangle next to it, you’ll see the list of all HTML elements that use that btn-bt CSS class). To make use of this method you need to possess at least some basic knowledge of CSS selectors. Simo Ahava’s guide is very useful here. How many elements do you see after you launch this command? Is that the result you expected? If not, then try narrowing down the CSS Selector to pick the item you are actually interested in. The most common CSS Selectors for beginners are: .class #id parentElement > directChildElement parentElement descendant And if you want to dig a bit deeper, read Simo’s guide. #19. google_tag_manager.dataLayer methods If you want to access values stored in Google Tag Manager’s data model from outside GTM, you can use the google_tag_manager interface. google_tag_manager.dataLayer.set(‘key’, ‘value’) sets the value of keyName to someValue in GTM’s data model. This is the equivalent to using dataLayer.push({‘key’: ‘value’}); google_tag_manager.dataLayer.get(‘key’) fetches the value stored in GTM’s data model for variable name key. google_tag_manager.dataLayer.reset() clears GTM’s data model and removes all stored keys. As for debugging, the most useful here is google_tag_manager.dataLayer.get(‘key’) because you can quickly find out what should be the correct value of your Data Layer variable (without having the need to constantly update the actual variable in the GTM UI and refresh the preview mode). I bet that this still looks confusing to some of my readers. No worries! A bit more visual explanation of this can be found in MeasureSchool’s video (starts @1:07) and @5:07 you’ll learn about one of the ways where you can apply this in practice. Too many Google Tag Manager debugging tips at once? No worries. Just bookmark this guide and come back at your earliest convenience. Part III: Google Tag Manager debugging with browser extensions A whole bunch of time-savers that will make your work much easier. #20. Inject your Google Tag Manager container with extensions like Tag Manager Injector or dataLayer Inspector+ When you create a new Google Tag Manager container, a developer must add its code to website’s source code to make it work. But what if he/she is currently busy and can do that only after a couple of days? With injector extensions, you can emulate your GTM container on any website and then continue working/configuring GTM without any disruptions. For sake of simplicity, I’ll demonstrate Tag Manager Injector. Install the extension from the Chrome Store and click its icon. Enter your GTM container’s ID. Click Start. What this extension does is it injects your Google Tag Manager container on all tabs of the browser (if you want to narrow down in which tabs should the container be injected, use the Include Domains feature and enter only those hostnames to which you actually want to inject the container. So after you enable the Preview and Debug mode, you’ll start seeing the debugging panel at the bottom of the screen. Even though the container code is not actually added by a developer to the website’s source code, you can successfully debug and configure your tags, triggers, and variables. Once the developer actually implements the container code, your GTM configuration will be already ready. Another situation where I use it is when someone asks for help to debug a particular issue. I just inject my own GTM container and do configurations that are needed to replicate the issue and resolve it. Keep in mind: Using Tag Manager Injector, dataLayer Inspector+ or any other injecting extension will work only within the boundaries of your browser. Calm down, you are not hacking the actual website. You’re just playing in your sandbox. If there is already some GTM container added directly in a website and you have injected your own container, you WILL NOT see the content of the original container. I’m talking about tags, triggers, variables, their configuration. On the other hand, you will be able to see what’s in the Data Layer. But that’s it. #21. dataLayer inspector+ AnalyticsPros have created an amazing browser extension that can be used as a Swiss army knife in Google Tag Manager debugging and testing. Not only can it inject your GTM container but there are also other goodies at your disposal. If you want to learn more about its full capabilities, read this guide and this one. To name a few out of many awesome (and very helpful) features: Visually visible requests to Google Analytics in browser’s JavaScript console. Google Analytics Duplicate hit identification. Useful if you don’t want to mess your bounce rate. Timing. You can tick the checkbox to see you how long it takes GTM to process a hit from the dataLayer push to the eventCallback. Validations (for example missing keys in an E-commerce object. See the screenshot below) Previously mentioned: Data in the Data Layer is preserved across multiple pages (see tip #6). One more useful feature became a separate tip in this blog post. Continue reading. #22. Fresh and clean. This tip is related to the aforementioned dataLayer Inspector+. I did not want it to blend with just a mention of the extension so I created it as a separate tip. Here’s the situation. Someone asks for your help to debug an interaction with the GTM on a particular website, which already has its own Google Tag Manager container. For some reason, you cannot quickly get access to the original container so you decided to inject your own (for testing purposes). Even though you cannot see in your Preview and Debug mode original container’s content, you’re still able the monitor what’s happening in the Data Layer and play around with the website itself. The original container is actively using the Data Layer and keeps pushing some data that is messing around with your container. This just makes the debugging inconvenient as you’re seeing events that should not be seen in your container. What’s the solution? You could temporarily block the original container’s script so that it would not interfere with your debugging efforts. Luckily, dataLayer Inspector+ offers a neat feature called Block & Swap Script. Open dataLayer Inspector+ > Inspect > Advanced Options > Block & Swap Script and paste the old GTM container’s ID. The plugin will be looking for all the scripts on a page that contain that string (your GTM Container ID) and will block them. That way, the original container will not mess with your debugging. Again, this is happening only within the boundaries of your browser, therefore, you’re not affecting other visitors. #23. Da Vinci Tools Another Swiss army knife that became a default in my Google Tag Manager stack is Stéphane Hamel’s Da Vinci Tools. It’s a handy and neat Chrome extension that tweaks and adds useful enhancements to your Google Tag Manager interface (GA and Data Studio too!). Here are my favorite features related to debugging: Ability to copy the data from the Data Layer tab in the GTM Preview and Debug mode. Have you noticed that, by default, it’s impossible to copy anything from the Preview mode’s Data Layer tab? Well, not anymore. Da Vinci got you covered. After you install the plugin, the Copy option will be back! Tidy GTM Preview (e.g. tag blocks are enriched with icons) Remembers if the Preview and Debug pane is minimized (and keeps it that way after the page is refreshed) Exit the Preview and Debug mode directly from the debug pane Also, I’ve seen Stéphane mentioning somewhere that in the long run, he plans to add debugging features similar to the WASP extension, which (surprise!) was also developed by him. #24. GA Debugger This extension is useful if you want to dig deeper into what data was passed onto Google Analytics. Once installed and enabled, it enables GA’s debug mode what starts displaying the data in the browser’s JavaScript console (among other Developer Tools). To enable it, simply click the extension’s icon and you’ll see the ON badge. This indicated that the GA Debug mode is enabled and you can start checking the data. After the extension is enabled, open browser’s JavaScript console and refresh the page. You’ll start seeing all the requests that were sent to GA. Even though the info might look a bit too technical, this is definitely worth checking out as it (more or less) clearly displays all the parameters that were passed to Google Analytics. Every GA hit (e.g. pageview, event, etc) is visible as a separate table with all the parameters and their values. By default, browser’s console is cleared every time the page reloads. So if you want to preserve what was captured, enable Preserve Log setting: #25. GA debug mode setting in GTM Even though this tip should have probably been mentioned in one of the other chapters of this post, I thought that it would be more appropriate to mention this right after presenting the GA Debugger extension. Alternatively to GA Debugger, you can also see the GA payload data in the console just by enabling the following setting in the GA Settings Variable that is being used by your Google Analytics tag. Once enabled, it will display the very same data as it was with the GA Debugger extension. To make this data visible only when you have enabled GTM Preview and Debug mode, enable the built-in variable called Debug Mode. It returns true if you’re currently in the Preview and Debug mode. That variable then should be inserted into the Debug Mode field of your Google Analytics Settings Variable or GA tags. So while you’re in the GTM preview mode, the GA debug mode will be enabled too. And when you exit the preview mode, the Debug Mode variable will return false, therefore the GA data will stop being logged in browser’s console. Nice and clean. #26. Use Tag Assistant recordings to debug Google Analytics implementation First things first, Google Tag Assistant is a Chrome Extension that helps you validate the tracking code on your website and troubleshoot common problems and makes the entire process much easier and faster. It enables you to record a typical user flow, it keeps track of all the hits you send, checks them for any problems, and gives you a full report of interactions. In case of any issues or potential improvements, it will let you know about them. By default, Tag Assistant is in the “sleep mode”, meaning that it does not check anything that’s happening on a page. In order to activate it, click the blue tag icon and then Enable. Now refresh the page. If any of Google’s products are implemented on that page, you’ll start seeing a particular number within that blue tag icon which represents the count of tags found. A great, yet often underused feature is session recordings. Recording a flow produces a report of all hits that were sent via marketing tags. This lets you validate that a particular tracking tag on your site works as expected. For example, if you own an e-commerce site, you could run through the pages and steps required to select an item, place the order, and submit payment. After the recording is complete, you can review all events/pageviews/etc. that were passed through and see what particular data was sent, what errors occurred, where they happened, etc. To start recording a flow, click the Tag Assistant icon and then RECORD button. The actual recording will start after you refresh the page. During the entire session, a red dot will be attached to the blue tag icon. To stop recording, click the icon, the red STOP RECORDING button and the summary of the session will be displayed. Click Show Full Report. This report will give you more insights into what happened during that recording session. Two types of reports are at your service: Tag Assistant Report. And Google Analytics Report. The Tag Assistant report shows all the tags that fired on all the pages you visited during the recording session. The controls in the left-hand panel let you do the following: Filter tags Switch between detailed and basic views Show/hide ignored requests. The main body of the page contains Recording summary (of what happened during the session) and recorded pages. Click every page to expand its details and tags that were fired. Keep in mind that these tags are listed alphabetically (and not in their sequence). The 2nd report (Google Analytics Report) will show an emulation of how Google Analytics will process the hits. The tab will recognize the account ID for this site and will allow you to see the full report (if you have access to that account). In it, you’ll see multiple data points collected by Google Analytics including acquisition data, behavior data, and conversions data. If you notice some issue in the report that needs to be fixed in the GA account (say, you had to configure a Cross-domain tracking’s Referral Exclusion List in your Google Analytics account), feel free to do that. After you’re done, just go back to the Google Tag Manager’s report and hit the Update report button in the top left corner. The plugin will check the entire recording session against your new GA Property settings and will let you know if the issue was fixed. That’s a real time saver! #27. Non-standard Google Analytics implementation is not a problem So you implement Google Analytics tags via Google Tag Manager, open the Tag Assistant and see that GA tag’s color is blue, not green. Click it and you’ll get a message “Non-standard implementation” under the “Where to optimize?” section. There’s nothing to worry about. Turns out, Tag Assistant always displays GA implementation as Non-standard if it was added via GTM. Case closed. #28. Google Tag Manager debugger Yet another amazing GTM-related Chrome extension, this time developed by David Vallejo. It adds an additional tab to your Chrome browser’s Developer Tools that eases your Google Tag Manager debugging process. First of all, the extension clearly displays (in a pretty readable manner) the data that was pushed to the Data Layer and the current data that is stored there. If you want to copy the Data Layer (e.g. to send the snippet to a developer (to report a bug)), you can do with with a couple of clicks. If Enhanced E-commerce data was sent to Google Analytics, an additional tab will activate within the interface of the plugin. It displays all the E-commerce steps completed in the exact order they occurred. Each step can be expanded and checked in greater detail. If the number of products is too overwhelming, feel free to use the search field. And if the website (that you’re working on) tracks A LOT of interactions, it might be a good idea to filter them out and track only particular types of GA hits. At this moment, David is actively updating/improving the extension thus I’m sure that you’ll find some new features there pretty soon. I still catch myself discovering something new (and pleasant/convenient) there. #29. Use helpers/debugging plugins tailored to specific tools I’m talking here about Facebook Pixel Helper, Twitter Helper, and other similar plugins tailored to specific tools. These browser extensions let you easily debug what kind of data was passed to 3rd party tools and whether that data was formatted properly. For example, once you install the Facebook Pixel helper and load a page where the pixel is present, you’ll notice that extension’s icon has become active. Click it to see the detailed view of what was captured and what was transferred to Facebook’s servers. If tracking issues occur, the extension will display that in a readable manner. Once you fix the problem, refresh the preview and debug mode. then the page and revisit the plugin’s report once again to check if that helped. Part IV: Other GTM/GA debugging tips Everything else that I could not find a place to. #30. Don’t see the data in GA Real-time reports? There are several possible reasons So you’re debugging Google Analytics implementation, checking real-time reports but, for some reason, cannot see the data coming in. Why? There’s a chance that you (or someone else) inserted the GA Settings Variable in the GA Tracking ID field (which you shouldn’t) GA filters are involved (most often IP-related filters are the ones to blame) You forgot to clear quick filters in real-time reports An opt-out extension is enabled in your browser Events are set to non-interaction hit: true. Such events are visible only if you switch to the “Last 30 minutes” option in your real-time event reports Privacy-related extensions (like Ghostery) are blocking your GA trackers or GTM You’re sending data to the wrong GA property You’re checking User ID view in GA but you’re not passing the actual User ID with events/page views to GA Maybe GA isn’t installed on a page at all? I have posted an in-depth guide explaining these reasons and how to solve them. #31. Not every GA interaction is visible in the real-time reports Real-time reports show you the most common interactions, page views, and events. Unfortunately, if you wish to see e-commerce data, social interactions, timing hits in GA, you’ll need to wait for them to appear in our actual reports. So if you wish to debug them beforehand, you’ll need to use browser extensions or GA debug mode to see what data was passed to GA and whether it was formatted properly. But in order to check if the data has actually reached the destination, you have no other choice rather than wait. #32. It is possible to test GTM implementation (web) on a mobile device If you want to check what’s happening in the Preview and Debug mode while being on a mobile device, just enable the P&D mode on your desktop/laptop, click Share Preview and copy the generated link (don’t forget to enter the Destination URL for easier access). Send that shared preview’s link to a chat/email/whatever so that you could open it via a mobile device. That’s it! Now you’ll see the Preview and Debug mode. Of course, it won’t be the most pleasant experience but it still possible to work. Pro tip: consider enabling Desktop view in your mobile browser to see more of the debug console. In order to exit the debug mode, revisit the shared preview link and click Exit. Update: Jean (in the comments of this blog post) also suggested an alternative solution: It is possible to test GTM implementation (web) on a mobile device You can simply activate the Toggle Device Mode in Chrome Dev console or Ctrl + Shift + M (while the Console is open). I use it to check that my tags fire only on mobile. Google Tag Manager Debugging: Final words Whew! That was a long one! As you can see there a lot of things to know and/or try when it comes to Google Tag Manager debugging. Although some of these tips are related purely to Google Analytics, GA is the most common 3rd party tool that’s being configured within GTM. So I guess it’s fair enough. Anyway, the key takeaway here (especially for beginners) should be that that GTM debugging consists not only of checking if a tag has fired. That’s just a beginning. You also need to make sure that: The data/request was sent successfully (e.g. via Network tab or some browser extension) And it is properly displayed in the 3rd party tool (e.g. Facebook Pixel, Google Analytics, etc.) And also there are a lot of different testing/debugging tools you can choose from. So pick the ones you find the most suitable/convenient go hunt those bugs! The list of these tips is definitely far from complete. So whenever I remember something else (that is useful) or if you have some GTM debugging tricks up your sleeve, feel free to share it in the comments and I’ll probably add it to the guide. Julius Fedorovicius In Google Tag Manager Tips 2 COMMENTS Jean Dec 7 2018 Reply #32. It is possible to test GTM implementation (web) on a mobile device You can simply activate the Toggle Device Mode in Chrome Dev console or Ctrl + Shift + M. I use it to check that my tags fire only on mobile. Thank you for the great tips. Julius Fedorovicius Dec 9 2018 Reply Thanks for the suggestion! I’ll add it to the list. Leave a comment Cancel reply Your email address will not be published. Required fields are marked *Comment Name * Email * Website Save my name, email, and website in this browser for the next time I comment. Notify me when new comments are added. Hi, I’m Julius Fedorovicius and I’m here to help you learn Google Tag Manager and GA (but mostly GTM). Join other 50000+ monthly readers and 10000+ newsletter subscribers in this exciting journey. Read moreEssential resources Popular articles GTM Form Tracking: 7 Effective Methods dataLayer.push: The Guide GTM vs Google Analytics 99 Things You Can Do with GTM Common GTM Mistakes Data Layer: Ultimate Guide 60+ Custom JavaScripts for GTM Analytics Mania Google Tag Manager Course Google Tag Manager Recipes Google Tag Manager Resources Google Tag Manager Community Follow Analytics Mania Subscribe to newsletter RSS feed Recent Posts Low Bounce Rate in Google Analytics isn’t Good. Here’s How to Fix it 32 Google Tag Manager Debugging and Testing Tips Support for it is also really good now.To make it work, behind the scenes we select the content to be copied, then run the copy command on that text and then finally remove the selection. ️‍♂️ Recommended course ⤵Wes Bos’ ES6 for Everyone!A Working ExampleI recently implemented this for the style guide, to allow to easily copy color codes. Try it by clicking on the color values to copy to clipboard:#FAE042 rgba(250,224,66,1)#EFBB35 rgba(239,187,53,1)#DFA612 rgba(223,166,18,1) Can’t copy, hit Ctrl+C!Here’s the markup:

Can’t copy, hit Ctrl+C!

And here’s the simple script to make the copy to clipboard feature possible:const aioColors = document.querySelectorAll(‘.color span’); aioColors.forEach(color => { color.addEventListener(‘click’, () => { const selection = window.getSelection(); const range = document.createRange(); range.selectNodeContents(color); selection.removeAllRanges(); selection.addRange(range); try { document.execCommand(‘copy’); selection.removeAllRanges(); const original = color.textContent; color.textContent = ‘Copied!’; color.classList.add(‘success’); setTimeout(() => { color.textContent = original; color.classList.remove(‘success’); }, 1200); } catch(e) { const errorMsg = document.querySelector(‘.error-msg’); errorMsg.classList.add(‘show’); setTimeout(() => { errorMsg.classList.remove(‘show’); }, 1200); } }); }); Note that you’d probably want to transpile this JavaScript code using Babel because it uses a lot of new features like the const keyword and arrow functions.Oh, and by the way, the layout is made super easy thanks to CSS grid:.colors { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 1rem; text-align: center; margin-bottom: 2rem; } @media (max-width: 600px) { .colors { grid-template-columns: 1fr 1fr; } }Breaking It DownWe first get all the span elements that contain the color values:const aioColors = document.querySelectorAll(‘.color span’);querySelectorAll return a nodeList, which is an array-like object. We then iterate over each node and add a click event listener:aioColors.forEach(color => { color.addEventListener(‘click’, () => { // … }); }); Iterating over a nodeList using forEach is not yet supported across the board. For wider support, you can convert the nodeList to a real array with something like and then call forEach.The magic happens next with the following code:const selection = window.getSelection(); const range = document.createRange(); range.selectNodeContents(color); selection.removeAllRanges(); selection.addRange(range);This gets a selection object, then creates a range where we select the contents our our span element. We then make sure that the global selection doesn’t contain any range yet, and add our new range to the selection.Next we’re ready to try and copy the selection to the clipboard using document.execCommand(‘copy’):try { document.execCommand(‘copy’); selection.removeAllRanges(); const original = color.textContent; color.textContent = ‘Copied!’; color.classList.add(‘success’); setTimeout(() => { color.textContent = original; color.classList.remove(‘success’); }, 1200); } catch(e) { // … }We then remove the selection range on our selection object to deselect the text, and setup a success message that disappears after 1.2 seconds.In case of failure, we keep the selection active, and display a message to tell the user to hit Ctrl + C:try { // … } catch(e) { const errorMsg = document.querySelector(‘.error-msg’); errorMsg.classList.add(‘show’); setTimeout(() => { errorMsg.classList.remove(‘show’); }, 1200); }More Fun With execCommandexecCommand can execute a cut, copy or a paste command, but it can also do a lot more. If you have have an element that has its contenteditable attribute set to true, or if your whole document has designMode turned on (document.designMode = ‘on’), you can run commands to change the selected text.Try it out by selecting some text in the paragraph below and the buttons: Hello! Bold Delete Color SizeHere’s the markup for the paragraph:


And the code for executing the commands looks like this:// select our button elements const boldBtn = document.querySelector(‘.bold-btn’); const deleteBtn = document.querySelector(‘.delete-btn’); const colorBtn = document.querySelector(‘.color-btn’); const sizeBtn = document.querySelector(‘.size-btn’); // add our event listeners boldBtn.addEventListener(‘click’, () => { document.execCommand(‘bold’); }); deleteBtn.addEventListener(‘click’, () => { document.execCommand(‘delete’); }); colorBtn.addEventListener(‘click’, () => { document.execCommand(‘styleWithCSS’, false, true); document.execCommand(‘foreColor’, false, ‘hotpink’); }); sizeBtn.addEventListener(‘click’, () => { document.execCommand(‘styleWithCSS’, false, true); document.execCommand(‘fontSize’, false, ’28px’); }); The first argument to execCommand is the name of the command, the second is a boolean to specify if the default user interface should be shown or not, and the third argument is the value for the command.Testing For Command SupportIf the browser supports execCommand, you can test for support of specific commands using document.queryCommandSupported:document.queryCommandSupported(‘copy’); // true document.queryCommandSupported(‘something’); // falseBrowser Support Can I Use document-execcommand? Data on support for the document-execcommand feature across the major browsers from ✨ get theweekly newsletter more js Tricks with JavaScript Destructuring Custom-Styled JavaScript Console Logging Don’t Be Afraid of the JavaScript Stack Trace ↑ Tweet It ✖ Clear Search Results Searching…Sponsored by #native_company# — Learn More #native_title# #native_desc##native_cta# Write for Us About Credits Contact PrivacySupport us on Patreon! • AdvertiseNote that we link to certain 3rd party products via affiliate links.Code snippets licensed under MIT, unless otherwise noted. Content & Graphics © 2018 LLC /*! loadCSS. Scott Mitchell shows how your ASP.NET pages and controls can add client-side code. (27 printed pages) Download the source code for this article. Contents Introduction Creating a Base Class as the Foundation for Adding Client-Side Script Adding Client-Side Script from the Code-Behind Class Executing Client-Side Code in Response to User Action Implementing Common Client-Side Functionality Conclusion Related Books Introduction When working with dynamic Web-based scripting technologies, like classic ASP or PHP, developers must have a keen understanding of the logical, temporal, and physical separation between the client and the server. For a user’s action to trigger the execution of server-side code, for example, a developer working with classic ASP must explicitly cause the user’s browser to make a request back to the Web server. Creating such interactions can easily consume much development time and lead to unreadable code. Microsoft ASP.NET helped ease the burden of tying user events to execution of specific server-side code through the use of Web Forms, which blur the lines between client and server. Using ASP.NET and a minimum of effort, a developer can quickly create a Web page that has a variety of interactive user interface elements—buttons, drop-down lists, and so on—which, based on the end user’s actions, can cause selective server-side code to run. For example, with ASP.NET to add a drop-down list that performs some action whenever the selected drop-down list item is changed, all you need to do is add a DropDownList Web control, set its AutoPostBack property to True, and create a SelectedIndexChanged event handler for the drop-down list. Accomplishing this same functionality with classic ASP would require you to write oodles of intricate HTML, client-side JavaScript, and server-side script code; with ASP.NET, the necessary script code and server-side event model are provided for you. While Web Forms in ASP.NET greatly simplify running server-side script when client-side actions are performed, such power, if misused, can lead to unacceptable performance. While Web Forms hide the complexities involved, each time server-side code needs to be executed, the end user’s browser must make a request back to the Web server by resubmitting the form. When submitting the form, all form fields—textboxes, drop-down lists, check boxes, and so on—must have their values sent back as well. Additionally, the page’s view state is sent back to the Web server. In total, each time the Web page is posted back, potentially several kilobytes of data will need to be sent back to the Web server. Frequent postbacks, then, can quickly lead to an unusable Web application, especially for those users still stuck on dial-up. The need for frequent postbacks can be reduced by pushing functionality to the client. Note ASP.NET Web Forms emit a hidden form field titled VIEWSTATE, which contains a base-64 encoded representation of the changed state of the Web controls in the Web Form. Depending on the Web controls present, the view state can range anywhere from a few dozen bytes, to tens of kilobytes. To learn more about view state check out my article Understanding ASP.NET View State. With classic ASP, adding data-driven, custom client-side script was simple, albeit not very readable. To display a popup window in classic ASP that loads a URL based on some ID field, for instance, you would type in the appropriate client-side script, using the <%=id%> syntax to insert the value of the ID field. ASP.NET allows you to create such data-driven client-side script with some assorted methods in the Page class. This article examines techniques for adding client-side script to your ASP.NET Web pages. Client-side script is, as its name implies, script code that runs in the visitor’s browser. We’ll see how to accomplish common client-side tasks, such as displaying alerts, confirm boxes, and popup windows. (One of the main uses of client-side script—form field validation—is a bit of a moot topic with ASP.NET, since the validator Web controls provide client-side form validation out of the box.) The focus of this article will be on the server-side classes, methods, and techniques for injecting client-side script; we will not be examining the actual client-side script in detail, as this information is covered in numerous other articles and sites around the Web. Creating a Base Class as the Foundation for Adding Client-Side Script One of the major differences between classic ASP and ASP.NET is the programming model of each technology. ASP pages are atomic, procedural scripts interpreted on each page visit. ASP.NET, however, is a fully object-oriented programming technology. All ASP.NET Web pages are classes with properties, methods, and events. All Web pages are derived, either directly or indirectly, from the Page class in the System.Web.UI namespace; the Page class contains the base functionality of an ASP.NET Web page. One of the concepts of object-oriented programming is that of inheritance. Inheritance allows you to create a new class that extends the functionality of another class. (If class B inherits class A, it is said to extend class A; class A is said to be the base class.) When using the code-behind model for creating ASP.NET Web pages, you can quite clearly see that the code-behind class inherits the Page class: Public Class WebForm1 Inherits System.Web.UI.Page … End Class By having your code-behind class inherit the Page class, it automatically receives the functionality inherent in the Page class, such as the Request, Response, Session, and ViewState objects, as well as common events, like Init, Load, Render, as so on. As we’ll see in this article, if you have a need for some common functionality to be available for all ASP.NET Web pages, one approach is to create a class that derives from the Page class and has additional methods and properties to accomplish these desired enhancements. Then, to have an ASP.NET Web page utilize these enhancements, all we need to do is update the Inherits statement in the page’s code-behind class to use the class that extends the Page class. In this article we’ll create a class, called ClientSidePage, that derives from the Page class and provides extra methods to help with performing common client-side tasks. By having a code-behind class inherit ClientSidePage, rather than Page, adding script code will be as simple as calling a method and passing in a few parameters. Specifically, this class will contain methods for: Displaying a modal, client-side dialog box. Setting the focus to a specific form field on page load. Using a modal confirm dialog box to determine if a user wants to postback the form or not. Displaying popup windows. Before we delve into the ClientSidePage class, let’s first examine the pertinent methods in the Page class for injecting client-side script into a Web page. Once we’ve covered these Page methods, we’ll jump into extending their functionality with the ClientSidePage class, and see how to tie everything together and use the extended class in an ASP.NET Web page. Adding Client-Side Script from the Code-Behind Class All ASP.NET Web pages must be derived directly or indirectly from the Page class in the System.Web.UI namespace. The Page class contains the base set of methods, properties, and events required for a functioning Web page. Among the class’s many methods are a few methods designed for injecting client-side script into the rendered HTML. These methods are called from the code-behind class and can therefore be used to emit data-driven client-side script. The pertinent Page class methods for emitting client-side script follow. The base class is derived from the System.Web.UI.Page class, so you can access the Page class’s public methods by calling them directly from your code-behind class. Note To access the Page class’s methods, you can either type in the method name directly, or utilize IntelliSense in Microsoft Visual Studio .NET by entering MyBase. (for Microsoft Visual Basic .NET), this. (for C#), or Page. (for either C# or Visual Basic .NET). If you are using Visual Basic .NET as your programming language of choice, be sure to configure Visual Studio .NET to not hide advanced members, or you won’t see these client-side script methods. (To show advanced members, go to Tools | Options | Text Editor | Basic and uncheck Hide advanced members.) RegisterClientScriptBlock(key, script) The RegisterClientScriptBlock method adds a block of client-side script after the Web Form’s rendered
element, before any Web controls contained within the Web Form. The key input parameter allows you to specify a unique key associated with this script block, whereas the script parameter includes the complete script code to emit. (This script parameter should include the actual ") The above will add the specified script content within the page's , but before the content within the form. When the page is rendered in the user's browser they will see a client-side alert box displayed upon page load, as shown in Figure 1. ...
Figure 1. Result of the client-side JavaScript Note One potentially undesirable side effect of the above example is that the alert box will be displayed right after the browser received the
tag. The browser will suspend rendering of the Web page until the user clicks the alert box's OK button. This means that the user will see a white browser page until they click OK. If you want to have the page displayed completely before displaying the alert box, you can have the JavaScript inserted at the end of the element using the RegisterStartupScript method, which we'll discuss next. RegisterStartupScript(key, script) The RegisterStartupScript method is quite similar to the RegisterClientScriptBlock method. The main difference is the location where the client-side script is emitted. Recall that with the RegisterClientScriptBlock the script is emitted after the start of the element, but before the form's contents. RegisterStartupScript, on the other hand, adds the specified script at the end of the form, after all form fields. Use RegisterStartupScript to place client-side script that interacts with the rendered HTML elements. (Later we'll look at an example of setting the focus to a form field upon page load; to accomplish this you'll use the RegisterStartupScript method.) Like RegisterClientScriptBlock, the script blocks added by RegisterStartupScript need a unique key value. Again, this key value is primarily used by custom control developers. Not surprisingly, there is an IsStartupScriptRegistered(key) method as well, which returns a Boolean value indicating if a script block with the specified key has already been registered or not. Note For more information on using RegisterStartupScript and RegisterClientScriptBlock in creating custom, compiled server controls, read an earlier article of mine: Injecting Client-Side Script from an ASP.NET Server Control. RegisterArrayDeclaration(arrayName, arrayValue) If you need to create a client-side JavaScript Array object with some set values, use this method to add a value to a specific array. For example, when using validation controls in an ASP.NET Web page, an Array object (Page_Validators) is built that contains references to the set of validation controls on the page. When the form is submitted, this array is enumerated to check if the various validation controls are valid or not. To add the values 1, 2, and 3 to a client-side Array object named FavoriteNumbers, you'd use the following server-side code: RegisterArrayDeclaration("FavoriteNumbers", "1") RegisterArrayDeclaration("FavoriteNumbers", "2") RegisterArrayDeclaration("FavoriteNumbers", "3") This code would emit the following client-side script: Notice that each array value passed in must be a string; however, the client-side script rendered sets the values of the Array object as the contents of the string. That is, if you wanted to create an Array with the string values "Scott" and "Jisun", you'd use: RegisterArrayDeclaration("FavoriteFolks", "'Scott'") RegisterArrayDeclaration("FavoriteFolks ", "'Jisun'") Notice that the second input parameters are strings that contain 'Scott' and 'Jisun'—text delimited by a single apostrophe. This would render the following client-side script: RegisterHiddenField(hiddenFieldName, hiddenFieldValue) In classic ASP there was often the need to pass around various bits of information from one page to another. A common way of accomplishing this was using hidden form fields. (A hidden form field is a form field that is not displayed, but whose value is sent on the form's submission. The syntax for creating a hidden form field is .) The need for passing information around by custom hidden form fields in ASP.NET is greatly reduced since the state of the controls in the page is automatically persisted. If, however, you find that you need to create a custom hidden form field, you can do so through the RegisterHiddenField method. The RegisterHiddenField method accepts two input parameters: the name of the hidden field and the value. For example, to create a hidden form field with the name foo and the value bar, use the following code: RegisterHiddenField("foo", "bar") This would add a hidden form field within the page's element, like so: ...
Understanding How Client-Side Elements Are Rendered The Page class contains two internal methods responsible for rendering client-side script registered in the methods discussed above: OnFormRender and OnFormPostRender. (A method marked internal can only be called by other classes in the same assembly. Therefore, you cannot call the Page's internal methods from the code-behind classes in your ASP.NET Web application.) Both of these methods are called in the HtmlForm class's RenderChildren method. The HtmlForm class, in the System.Web.UI.HtmlControls namespace, represents a Web Form; that is, the server-side form in an ASP.NET Web page—
—is loaded as an instance of the HtmlForm class during the page's instantiation stage. Since the client-side script registered by the Page class's assorted methods is rendered in the OnFormRender and OnFormPostRender methods, and since these methods are only called by the HtmlForm class, the client-side script you programmatically add by these methods is only rendered if the Web page contains a Web Form. That is, any script elements you programmatically add through any of the discussed methods above will only be emitted in the page's final markup if the ASP.NET Web page contains a server-side form (a
). A Web Form on an ASP.NET Web page is rendered by first adding the starting
element. Following that, the Web Form's RenderChildren method is called, which contains three lines of code: Page.OnFormRender(...) MyBase.RenderChildren(...) Page.OnFormPostRender(...) The call to the Page class's OnFormRender method adds the following markup: Any hidden form fields added by calls to RegisterHiddenField. The base-64 encoded view state in a hidden form field named __VIEWSTATE. Any script blocks added by calls to RegisterClientScriptBlock. The second line of code in the Web Form's RenderChildren method calls the base class's RenderChildren method, which renders the contents within the Web Form. After rendering all of the form's contents, a call is made to the Page class's OnFormPostRender method, which adds the following client-side content: Any Array objects added by the RegisterArrayDeclaration method. Any script blocks added by calls to RegisterStartupScript. Finally, after the Web Form's RenderChildren method completes, the closing form tag (
) is rendered. Figure 2 illustrates this rendering process graphically. Note Figure 2 assumes you are somewhat familiar with the ASP.NET page life cycle. If you are interested in learning more about the page life cycle, consider reading Understanding ASP.NET View State, focusing on the section titled, "The ASP.NET Page Life Cycle." Figure 2. Page rendering in ASP.NET Examining the Rendering Order of Script Blocks Upon first glance at the register methods of the Page class, it might seem that the order with which the registered elements are rendered in the Web page correspond to the order with which they were added in the code. That is, imagine that you had the following two lines of code in your ASP.NET Web page's code-behind class: RegisterClientScriptBlock("showSaveMessage", _ "") RegisterClientScriptBlock("showSaveMessage", _ "") You wouldn't be too surprised when you found that the page rendered the following client-side script blocks (assuming the value of someDataDriveValue was Sam): The user visiting this page would see an alert box saying "Hello, Sam!" Based on this test, you might then assume that it was always the case that the order the script blocks were emitted in the HTML page was the order they were specified in the server-side code. However, this would be an incorrect assumption, and one that could cause your pages to break. For example, imagine that the script blocks added above were emitted in the HTML page in the reverse order. Then you'd have: This would display an alert box reading "Hello, !", since the variable name has not yet been assigned a value. Clearly, there are times when the order with which script blocks are emitted is very important. The register methods of the Page class—RegisterClientScriptBlock, RegisterStartupScript, RegisterArrayDeclaration, and RegisterHiddenFields—all write the supplied script content to an internal HybridDictionary. A HybridDictionary is a data structure found in the System.Collections.Specialized namespace, and is designed for storing items in a dictionary where the number of items in the dictionary is not known. For a small collection of items, a ListDictionary is the most efficient data structure, but for larger dictionaries, a Hashtable is more efficient. A HybridDictionary splits the difference—it starts by storing items using a ListDictionary. Once the ListDictionary has its ninth item added, the HybridDictionary switches from using a ListDictionary to using a Hashtable. While this approach is ideal for performance, it can wreck havoc if you are using several script blocks where the order of the script blocks is important. That's because while a ListDictionary maintains the order with which the elements were added, a Hashtable does not. So, if you add eight or fewer items to any one of the particular register methods, the items will be emitted in the order with which they were added. However, if you add a ninth item, the order that the script is emitted will be seemingly random. Note The ListDictionary stores its elements using a linked list, while the Hashtable stores its elements in an array, where the contents are ordered by the hashed value of a sting key. A thorough discussion on linked lists and hashtables is far beyond the scope of this article. For more information, including an analysis of their performance, consider reading An Extensive Examination of Data Structures, specifically Part 2 and Part 4. If you plan on having cases where there may be more than eight client-side elements added using a particular register method, and the order with which the elements appear matters, you might want to take a look at Peter Blum's free RegisterScripts library. RegisterScripts provides greater control over the order with which the client-side elements are emitted, and also provides the option to not have to manually add the ") End Sub Public Function GetAlertScript(ByVal message As String) As String Return "alert('" & message.Replace("'", "'") & "');" End Function End Class Notice that this class is derived from the System.Web.UI.Page class. The DisplayAlert method simply uses the RegisterClientScriptBlock method to display the supplied message in an alert box. Since this method may be called multiple times by a single page, each call uses a GUID (Globally Unique Identifier) for its key. The string being passed to the alert function is delimited by apostrophes, any apostrophes in message must be escaped (JavaScript escapes apostrophes as '). To use this code in your ASP.NET Web application, you will need to add a new class to your ASP.NET application. In Visual Studio .NET, right click on the ASP.NET Web application project name in the Solution Explorer and choose to add a new class. Then, cut and paste the above code into the class. Next, in your ASP.NET Web pages where you want to utilize this code, you'll need to modify the code-behind class so that it inherits from the ClientSidePage class rather than from Page. The following code shows a sample code-behind class derived from ClientSidePage and that uses the DisplayAlert method. Public Class WebForm1 Inherits ClientSidePage Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load DisplayAlert("Hello, World!") End Sub ... End Class Note that the ClientSidePage class not only has the DisplayAlert method, which generates a full client-side ... Form fields ... ... Form fields ... The client-side function CSP_focus accepts a string parameter, the ID of the form field to set to focus, and retrieves the HTML element from the DOM. The retrieved element's focus() function is then called. At the bottom of the Web page, after all of the form fields have been specified, we need to call the CSP_focus method passing in the ID of the form field where we want the focus set. The following method, GiveFocus(Control), uses the RegisterClientScriptBlock and RegisterStartupScript methods to generate the needed client-side script. Public Sub GiveFocus(ByVal c As Control) RegisterClientScriptBlock("CSP-focus-function", _ "") RegisterStartupScript("CSP-focus", _ "") End Sub To use the GiveFocus method from an ASP.NET Web page whose code-behind class inherits ClientSidePage, simply call GiveFocus in the Page_Load event handler and pass in the Web control that should have its focus set on page load. For example, to set the focus to the TextBox Web control TextBoxControl, use the following Page_Load event handler: Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load GiveFocus(TextBoxControl) End Sub Opening a Popup Window While popup windows have gotten a bad rap on the Internet as a nefarious tool for advertisers, popup windows are used in many Web applications to a good end. For example, you might want a page that displays a list of database items in a DataGrid, with a link to edit each particular item. Rather than using the DataGrid's in-line editing capabilities, you might want to have a popup window opened when the user opts to edit a DataGrid, where the popup window contains a list of text boxes with the editable fields of the DataGrid. (One reason you might want to do this is because there may be a very large number of editable fields, but you only want to show the most pertinent fields in the DataGrid, thereby eliminating the possibility of using the DataGrid's built-in editing features.) To display a popup window, use the JavaScript function, which takes a number of optional input parameters, the three germane ones being: The URL to load in the popup window. A string name for the popup window. The features for the popup window, such as its height and width, whether or not the window is resizable, and so on. A thorough discussion of the function is beyond the scope of this article; to learn more refer to the technical documentation. Like the method to display the alert box, the ClientSidePage class contains two methods for displaying a popup window—one that renders a self-contained ") End Sub Public Function GetPopupScript(ByVal url As String, _ ByVal options As String) As String Return "var w =""" & _ url & """, null, """ & options & """);" End Function Public Sub CloseWindow(Optional ByVal refreshParent As Boolean = False) RegisterClientScriptBlock("CSP-close-popup", _ "") End Sub Public Function GetCloseWindowScript(Optional _ ByVal refreshParent As Boolean = False) As String Dim script As String If refreshParent Then script &= "window.opener.location.reload();" End If Return "self.close();" End Function An example of this code in action can be seen in the code download for this article. There you'll find a sample Web page that has a DataGrid listing the files in the same directory as the ASP.NET Web page. This DataGrid has two columns: a TemplateColumn that displays a hyperlink that, when clicked, opens a popup window showing the contents of the selected file; and the name of the file (see Figure 3). Figure 3. DataGrid with popup window The DataGrid's markup utilizes the GetPopupScript method, as shown below: "> View File The ASP.NET Web page ViewFile.aspx opens the file whose name is specified in the querystring, and displays its contents (see Figure 4). Figure 4. Displaying the contents of Web.config in a popup window Note Popup windows are best suited for intranet applications only, because a number of Internet users utilize some sort of popup blocking software, such as Google Toolbar. In fact, with the Microsoft Windows XP Service Pack 2, Microsoft Internet Explorer will be configured to block popups by default. However, popups will still work when a user visits a site in the Trusted Sites or Local Intranet zones. For more information on the popup blocking features for Internet Explorer in the Windows XP Service Pack 2, be sure to read Changes to Functionality in Microsoft Windows XP Service Pack 2. Confirming Before Postback Earlier in this article, we looked at how to display a client-side alert box, which is a modal dialog box with an OK button. JavaScript offers a more interactive flavor of the alert box called a confirm dialog box. The confirm dialog box is displayed using the confirm(message) function and has the effect of displaying a dialog box with the text specified by the message input parameter along with OK and Cancel buttons. The confirm(message) function returns true if the user clicks OK and false if they click Cancel. Typically confirm dialog boxes are used to ensure that the user wants to continue before submitting a form. When an HTML element is clicked to submit a form (such as a submit button), if that HTML element fires a client-side event handler that returns false, the form submission is canceled. Commonly the confirm dialog box is used in a Web page as follows:
When the user clicks the "Click Me to Submit the Form" button, they'll see a confirm dialog box that asks them if they are sure they want to submit the form (see Figure 5). If the user clicks OK, confirm() will return true and the form will be submitted. If, however, they click Cancel, confirm() will return false and the form's submission will be canceled. Figure 5. Results of the Confirm JavaScript Imagine you had a DataGrid with a column of buttons labeled "Delete." Upon clicking this button, the form will postback and the selected record will be deleted. In this instance, you might want to double-check that the user really wanted to delete this record. Here would be a great place to use a client-side confirm dialog box. You could prompt the user with a dialog box stating something like: "This will permanently delete the record. Are you sure you want to continue?" If the user clicks OK, the form will postback and the record will be deleted; if they click Cancel, the form will not be posted back, and hence the record will not be deleted. To add the client-side JavaScript necessary to display a confirm dialog box on button's click, simply use the Attributes collection to add a client-side onclick event handler. Specifically, set the onclick event handler code to: return confirm(message);. In order to provide such functionality for a DataGrid's ButtonColumn, you'll need to programmatically reference the Button or LinkButton control in either the DataGrid's ItemCreated or ItemDataBound event handlers and set the onclick attribute there. For more information, see Confirmation with AutoPostBack DropDownLists While confirm dialog boxes are typically used when a button is clicked, they can also be used when a drop-down list is changed. For example, you might have a Web page that automatically posts back when a particular DropDownList Web control is changed. (The DropDownList Web control has an AutoPostBack property that, if set to True, causes the form to postback whenever the DropDownList's selected item is changed.) Intuitively you might think adding a confirm dialog box for a DropDownList is identical to adding such a dialog box for a Button Web control. That is, simply set the DropDownList's client-side onchange attribute to something like: return confirm(...);. using: DropDownListID.Attributes("onchange") = "return confirm(...);" Unfortunately, this won't work as desired because an AutoPostBack DropDownList's onchange attribute will be set to a bit of JavaScript that causes a postback, namely a call to the client-side __doPostBack function. When setting the onchange attribute programmatically yourself, the end result is that the rendered client-side onchange event handler has both your code and the call to __doPostBack: Noting this, what we really want to happen is have the __doPostBack function called if confirm returns true, because then the page will be posted back. We can accomplish this by setting the onchange event by the Attributes collection to: if (confirm(...)), which will render the following markup, which is what we are after: At first glance this will seem to have the desired effect. If a user selects a different item from the drop-down list, a confirm box appears. If the user clicks OK, the form will postback; if the user clicks Cancel, the form's postback is halted. The problem, though, is that the drop-down list retains the item the user selected to initiate the drop-down list's onchange event. For example, imagine the drop-down list loads with item x being selected, and then the user chooses item y. This will trigger the drop-down list's client-side onchange event, which will display the confirm dialog box. Now, imagine that the user hits Cancel—the drop-down list will still be selected on item y. What we want is to have the selection reverted back to item x. To accomplish this we need to do two things: Write a JavaScript function that "remembers" the selected drop-down list item. In the drop-down list's client-side onchange event, if the user clicks Cancel, you need to revert the drop-down list back to the "remembered" value. Step 1 entails creating a global script variable for the drop-down list and a function that runs when the page loads that will record the drop-down list's value. Step 2 requires changing the client-side onchange attribute for the drop-down list to look like: if (!confirm(...)) resetDDLIndex(); else __doPostBack(); Where resetDDLIndex is a JavaScript function that reverts the drop-down list's selected value back to the "remembered" value. The client-side script for this needs to look like the following: This necessary script can be easily generated by creating a helper method in the ClientSidePage class. Public Sub ConfirmOnChange(ByVal ddl As DropDownList, ByVal message As String) 'Register the script block If Not IsStartupScriptRegistered("CSP-ddl-onchange") Then RegisterStartupScript("CSP-ddl-onchange", _ "") End If ddl.Attributes("onchange") = _ "if (!confirm('" & message.Replace("'", "'") & _ "')) resetDDLIndex(); else " End Sub To use this, simply call this method for each AutoPostBack DropDownList on the Web page that you want to display a confirm dialog box for when its selected item changes. Confirming When Exiting Without Saving In most every data-driven Web application I've created there's always been some page where users can edit particular bits of information from the database. A very simple example might be a page with a series of TextBox and DropDownList Web controls, with the database data populated within these controls. The user can make any suitable changes and click the Save button to persist their changes to the database. When I create these pages, I usually end the page with two Button Web controls: a Save button and a Cancel button. The Save button saves any changes back to the database, while the Cancel button exits the page without persisting any changes. While two buttons may seem like a perfect design, sometimes users accidentally click the Cancel button when they meant to click the Save button, thereby losing any changes they made to the data. To prevent this from happening, you can use a confirm box on the Cancel button that only appears if any of the textboxes or drop-down lists on the Web page have been changed. That is, if the user makes any changes to the data and then clicks Cancel, a confirm box will prompt them to see if they are sure they want to exist without saving. (If the user just clicks Cancel without changing any data, no such confirm box is shown.) This user experience can be accomplished by a bit of client-side JavaScript. Basically, it entails a JavaScript global variable, isDirty, that is initially false but is set to true whenever any of the form fields' onchange events fire. There's also a JavaScript function that displays a confirm dialog box if isDirty is true. The Cancel button's onclick client-side event handler is wired up to return the result from this JavaScript function. The following HTML illustrates this concept: Name: This script can be easily generated by moving its generation to the ClientSidePage class. Specifically, we can create the following three methods: Protected Sub RegisterOnchangeScript() If Not IsClientScriptBlockRegistered("CSP-onchange-function") Then RegisterClientScriptBlock("CSP-onchange-function", _ "") End If End Sub Public Sub MonitorChanges(ByVal c As WebControl) RegisterOnchangeScript() If TypeOf c Is CheckBox Or TypeOf c Is CheckBoxList _ Or TypeOf c Is RadioButtonList Then c.Attributes("onclick") = "isDirty = true;" Else c.Attributes("onchange") = "isDirty = true;" End If End Sub Public Sub ConfirmOnExit(ByVal c As WebControl, ByVal message As String) RegisterOnchangeScript() c.Attributes("onclick") = _ "return CSP_checkForChange('" & message.Replace("'", "'") & "');" End Sub To create a Web page that exhibits this behavior, we simply need to have its server-side code-behind class derive from ClientSidePage and in the Page_Load event handler have a call to MonitorChanges for each Web control that needs a client-side onchange event and a call to ConfirmOnExit for each Button, LinkButton, and ImageButton that, when clicked, should display a warning if the user has made changes and is exiting the page. Note Notice that the MonitorChanges method uses the onclick client-side event instead of onchange for the CheckBox, CheckBoxList, and RadioButtonList Web controls. This is because these controls wrap a tag or around the check box or series of check boxes or radio buttons. In my tests with Internet Explorer, I found that the onchange event, when applied to the or
, was not picked up when a check box or radio button was clicked, but the onclick event was raised. Figure 6 shows an example ASP.NET Web page with two TextBox Web controls, a DropDownList Web control, and a CheckBox Web control. As the Page_Load event handler below shows, all of these Web controls are being monitored for changes. The Cancel button, btnCancel, is configured so that if it's clicked after changes have been made, a confirm dialog box will be displayed. Figure 6. Dialog with confirmation Public Class ConfirmOnExit Inherits ClientSidePage Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load 'Specify what controls to check for changes MonitorChanges(name) MonitorChanges(age) MonitorChanges(favColor) MonitorChanges(chkSilly) ConfirmOnExit(btnCancel, _ "You have made changes to the data since last saving." & _ " If you continue, you will lose these changes.") End Sub ... End Class Note The client-side onchange event does not work in older versions of Netscape. Also, Internet Explorer 5.0 has had some reported problems with the onchange event (which were fixed in Internet Explorer 5.01, SP 1). Furthermore, this approach won't work as desired with DropDownList Web controls with AutoPostBack set to True, as the postback will reset the value of isDirty. There are a couple of workarounds for this problem, such as using a hidden form field that indicates whether or not the postedback form data is dirty to begin with or not. I leave implementing this as an exercise for the reader. Creating a Client-Side MessageBox Control While confirm dialog boxes are a great way to prevent accidental clicks and to potentially reduce the number of postbacks to the Web server, there are certain scenarios where you might want to display a confirm dialog box and be able to determine on the server-side whether or not they clicked OK or Cancel. (Recall that with the confirm dialog box, if the user clicks Cancel, the form is not posted back.) Furthermore, the alert and confirm boxes in JavaScript are rather limited in their appearance. Fortunately client-side VBScript offers a richer message box experience through its MsgBox function. In a past project, I had a need for a client-side, modal message box that would cause a postback no matter what button was clicked. In response, I built a custom compiled ASP.NET server control that met these requirements. In addition, the client-side message box uses VBScript's MsgBox function to provide a richer message box experience. Note VBScript only works as a client-side scripting language in Microsoft's Internet Explorer browser. To account for this, my server control only uses VBScript if the visiting browser is Internet Explorer. Non-Internet Explorer browsers are sent JavaScript. A thorough discussion of this custom server control could warrant an entire article in itself, so rather than focus on the inner workings of the control, let's examine how to use the MessageBox control in an ASP.NET Web page. (The complete source for the control, as well as a sample ASP.NET Web page using the control, is available in this article's download.) To use the MessageBox control in an ASP.NET Web page, first add the MessageBox control to the Visual Studio .NET Toolbox. This can be accomplished by right-clicking on the Toolbox and choosing to Add/Remove Items from the Toolbox, and then browsing to the MessageBox assembly. To add the client-side message box to a Web page, simply drag it from the Toolbox onto the Designer. Figure 7 shows the MessageBox control in the Visual Studio .NET Designer. Figure 7. Displaying a modal messagebox The MessageBox class has a number of properties that you can configure to tweak the appearance of the message box: Buttons. Specifies what buttons are displayed. The options are defined in the ButtonOptions enumeration and can be: OkOnly, OkCancel, AbortRetryIgnore, YesNoCancel, YesNo, or RetryCancel. DisplayWhenButtonClicked. The ID of the Button Web control that, when clicked, will display the client-side message box. Use this property if you want the message box displayed due to a specific button being clicked. Icon. The icon displayed in the message box; the options are defined in the IconOptions enumeration. The legal values are: Critical, Question, Exclamation, and Information. Prompt. The text displayed within the message box. Title. The title of the message box. Once you have added the MessageBox control to an ASP.NET Web page, the next challenge is having it displayed due to some client-side action. The DisplayWhenButtonClicked property allows you to specify the ID of a Button Web control on the page that, when clicked, will cause the message box to be displayed. Alternatively, you can have the message box displayed by calling the client-side function mb_show(id), where ID is the ID of the MessageBox control. Regardless of what button configuration you choose to display in the message box, when any button is clicked, a postback ensues and the MessageBox control's Click event fires. You can create an event handler for this event by simply double-clicking on the MessageBox in the Designer. The event handler's second input parameter is of type MessageBoxClickedEventArgs, which contains a ButtonClicked property that returns information on what message-box button the user clicked. The MessageBox control is useful in situations where you want to quickly present the user with a modal dialog box that, regardless of the user's choice, results in a postback. To see the MessageBox control in action, check out the MsgBoxDemo.aspx page in the source code download. Conclusion This article began with a look at common uses of client-side script in a Web page, and then turned to examine the methods and techniques for injecting client-side script into an ASP.NET Web page. As we saw, the Page class contains a number of methods designed for programmatically inserting client-side script blocks from the server-side code-behind class. These methods are also commonly used from custom, compiled server controls, as discussed in an earlier article of mine: Injecting Client-Side Script from an ASP.NET Server Control. In addition to adding script blocks, client-side functionality often must be tied to a client-side event raised by some HTML element. To programmatically specify a Web control's client-side event handler through the server-side code-behind class, use the Attributes collection, which is available as a property to all Web controls. The second half of this article applied the topics covered in the first half, showing how to implement common client-side functionality in an ASP.NET Web page. We saw how to extend the Page class so that from a code-behind class we could easily display an alert box, set the focus upon page load to a specific Web control, how to display a popup, and how to display a confirm dialog box. We also looked at creating a custom server control that used VBScript to provide a richer client-side message box user experience that caused a postback regardless of the button clicked. Happy Programming! Special Thanks To... Before submitting my article to my MSDN editor, I have a handful of volunteers help proofread the article and provide feedback on the article's content, grammar, and direction. Primary contributors to the review process for this article include Maxim Karpov, Carlos Santos, Milan Negovan, and Carl Lambrecht. If you are interested in joining the ever-growing list of reviewers, drop me a line at [email protected] Related Books ASP.NET Data Web Controls Kick Start ASP. NET: Tips, Tutorials, & Code Programming Microsoft ASP.NET About the author Scott Mitchell, author of five books and founder of, has been working with Microsoft Web technologies for the past five years. National Debt Consolidation - [email protected]

The above email is a scam. If you still think is legitimate, but you’re still concerned, then follow these steps:

Ten Minutes 10 minutes.

How to check if you received a scam email

  1. Google the details.

    Do a Google search for the persons name/company name that the email has come from.

  2. Confirm the details.

    Visit their website and look for a phone number or email address. Search for the website yourself. Do not assume the details in the email are valid.

  3. Confirm using the information you have found

    Using the details you have researched, call or email the business and ask them to verify the information within the email.

  4. Check if the email has been sent to multiple people

    Google snippets of the email text to see if the same format has been used in the past. eg "Army officer from Syria but now living with the United Nations on asylum"

Most of us know someone who is vulnerable to these types of attacks. Fortunately, if you’re aware of the presence of these scams, and armed with some basic knowledge on identifying them, you can greatly reduce your chances people you know becoming a victim. Please help them by sharing this information on Facebook or Twitter using the #telltwo and #takefive hashtags.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button

Adblock Detected

Please consider supporting us by disabling your ad blocker