Form Engagement Tracking With Google Tag Manager

November 10, 2014

Do you know how people are completing forms on your site? Are there certain fields that get skipped frequently or that cause users to drop off?

Almost two years ago, I wrote a post showing how to use a simple script to track form abandonment in Google Analytics with event tracking. I’ve gotten a lot of great user feedback (and requests) about that script, and wanted to share an updated version that is a little more elegant.

This new version more effectively handles fields that are completed or skipped. I’ve also modified this script and included instructions for how to add it to your site through Google Tag Manager.

Use this script to see which fields get the most completions, but also use it to compare to the amount of forms that get submitted successfully. If you find that people are starting to complete the form but failing to submit it, you may need to look into ways to improve the user experience.

The updated script

<script>
(function($) {
$(document).ready(function() { 
 $('form :input').blur(function () {
 if($(this).val().length > 0 && !($(this).hasClass('completed'))) {
 // The if statement above checks to see if there is a value in the form field and if that field does NOT have the class "completed".
 // If those conditions are met, we push information to the dataLayer that tells GTM the form field was completed, along with the
 // event category (form name), event action (field name), and event label (completed).
 dataLayer.push({'eventCategory': 'Form - ' + $(this).closest('form').attr('name'),
   'eventAction': 'completed',
   'eventLabel': $(this).attr('name'),
   'event': 'gaEvent'});
 // Once we fire an event for this form field that is completed, we need to add the class "completed" to this form field to prevent it from firing again
 // if the user mouses in and out of this field more than once.
 $(this).addClass('completed');
 } 
 else if(!($(this).hasClass('completed')) && !($(this).hasClass('skipped'))) {
 // If the first if statement didn't match, it means that either the form field was empty or it had the class of "completed." Here, the else if statement checks
 // to see if it doesn't have the class "completed" AND doesn't have the class "skipped." In other words, if the form field is empty and we haven't already fired
 // an event to GA to indicate that the field was skipped. If this is the case, we will push information to the dataLayer that tells GTM the form field was
 // skipped, along with the event category (form name), event action (field name), and event label (skipped).
 dataLayer.push({'eventCategory': 'Form - ' + $(this).closest('form').attr('name'), 
   'eventAction': 'skipped', 
   'eventLabel': $(this).attr('name'), 
   'event': 'gaEvent'});
 // Once we fire an event for this form field that is skipped, we need to add the class "skipped" to this form field to prevent it from firing again
 // if the user mouses in and out of this field more than once.
 $(this).addClass('skipped');
 }
 });
});
})(jQuery);
</script>

What does this script do?

This is a simple listener script that uses jQuery to “listen” for certain events on the page. Specifically, it listens for a user’s cursor to exit an input field, either by tabbing to the next field or clicking out of the field.

When that happens, this script checks to see if any text was entered. If there is text, it pushes an update to the data layer that includes a category with the name of the form, an action of “completed” and a label that is set to the name of the form field.

Note: This process of using a data layer push to trigger a generic event can be reused for other tracking opportunities!

If the field is left blank when the cursor exits, it fires a similar event, but sets the action field to “skipped”.

What’s new?

The biggest change is that I’ve built in some logic to only fire an event once per field completion and once per field skip. With the original script, if a user’s cursor entered and exited a form field 10 times, it would fire 10 events to Google Analytics. Now, there will be at most 2 events fired per form field (one if they skip a field and a second if they complete it).

The next change is that this script is updated to work with Google Tag Manager. Instead of firing an event directly into Google Analytics, we’re now pushing that information to the dataLayer, and using Google Tag Manager to handle the event tracking.

Here are the steps to make this work in GTM:

Step 1:

Create Custom HTML Tag named Listener – Form Fields. Copy and paste the above script into this tag. The rule/trigger to fire this tag can be set to All Pages if you have forms across many pages of your site.

Alternatively, you could create a new rule to only fire this tag on pages where you have forms that you want to track, like the screenshot below. In that case, your rule may look like {{url path}} matches RegEx page1|page2|page3.

form pages rule

Step 2:

Create macros/variables that record the values from the script that are pushed to the dataLayer for event category, event action, and event label. Create three data layer variable macros that pull the values that we’re passing from the dataLayer. Create one for “eventCategory”, “eventLabel”, and “eventAction.”

event category macro

Step 3:

Create a new Google Analytics tag and name it GA – Event. You’ll need to fill in the appropriate property ID. Choose the track type of Event, and use the following settings:

event tag

Step 4:

Create a rule/trigger that listens for the custom event that we’re passing from our script. Use this as the Firing Rule for the Tag we just created.

blog-formtracking-rule

Now that everything is set up, you can preview and debug these new tags and macros to make sure they’re working as expected without any conflicts. Then create a new version of the container and publish!

Things to keep in mind:

  • Just like the old version, this script requires jQuery. Make sure you include jQuery before your GTM container script (i.e. in the <head> section of your page).
  • This script pulls in the name attribute of the form as well as each of the form fields. It uses these values for the event category and label, respectively. Make sure you use descriptive names instead of something like field1 or field2. If you already have descriptive IDs on each form field, you could use those instead. Just replace $(this).attr(‘name’) with $(this).attr(‘id’) in the form tracker script.
  • You may also want to track submissions of the form. This can be done easily with a form submit listener tag in GTM. This form tracking basics in GTM post will help explain the basics (as well as advanced topics) of tracking form submissions.