The inimitable Craig Sullivan gave me an idea for a continuation to my latest post on form abandonment tracking. In this short tutorial, I’ll show you how to track the time users spend on your form fields. We’re going to use the User Timings hit type, and we’ll send the data for just one form. With small modifications, you can expand the script to cover multiple forms on a page.
This simple solution tracks the time the user spends on each form field by measuring the distance between the focus
event and the blur
or change
event. The first one occurs when a form field is entered, and the latter depends on if a value changed (change
) or no change was registered (blur
).
The timing object that is sent to GA looks like this:
Timing Category - Comment Form Field Timing
Timing Variable - Form field name
attribute value
Timing Label - ‘blur’ or ‘change’ depending on how the field was exited
Timing Value - Time spent in the field in milliseconds
Note! Timings are counted against the 500 hits / session limit in Google Analytics. That’s why you have to be careful when implementing this. I suggest you only implement it on one form and for a short time, and then see if users’ sessions are getting miscalculated thanks to them surpassing the 500 hit limit. There are some additional limitations per property as well, but they only count towards the timing hits and not all hits in the session.
The Simmer Newsletter
Follow this link to subscribe to the Simmer Newsletter! Stay up-to-date with the latest content from Simo Ahava and the Simmer online course platform.
The Custom HTML Tag
The Custom HTML Tag looks like this:
<script>
(function() {
var form = document.querySelector('#commentform');
var fields = {};
var enterField = function(name) {
fields[name] = new Date().getTime();
}
var leaveField = function(e) {
var timeSpent;
var fieldName = e.target.name;
var leaveType = e.type;
if (fields.hasOwnProperty(fieldName)) {
timeSpent = new Date().getTime() - fields[fieldName];
if (timeSpent > 0 && timeSpent < 1800000) {
window.dataLayer.push({
'event' : 'fieldTiming',
'timingCategory' : 'Comment Form Field Timing',
'timingVariable' : fieldName,
'timingLabel' : leaveType,
'timingValue' : timeSpent
});
}
delete fields[fieldName];
}
}
if (form) {
form.addEventListener('focus', function(e) { enterField(e.target.name); }, true);
form.addEventListener('blur', function(e) { leaveField(e); }, true);
form.addEventListener('change', function(e) { leaveField(e); }, true);
}
})();
</script>
To fire this Tag, I suggest you create a Page View Trigger which only fires this Tag on pages where your form exists.
Next, change the very first variable var form = document.querySelector('#commentform');
to select the form you want to track. On my site this happens to be a form with ID #commentform.
Whenever a focus
event is detected, a hash table is updated with the form field name and the time when the field was entered.
Then, when the field is exited, and either a blur
or change
is recorded, the time spent in the field is calculated, and then the field name is deleted from the hash table. If you don’t delete the field, a change
event would send the timing twice, because when the user edits the value of a field and leaves it, a change
is dispatched first, and then a blur
.
Anyway, feel free to change the value of the ‘timingCategory’ variable in the dataLayer.push()
. I use ‘Comment Form Field Timing’, as that’s what I’m doing here.
Finally, if the form selector you use in the very first variable declaration of the script works, the three listeners are attached to the form with their respective callbacks.
This is the script itself. We’ll wrap up the setup in the next chapter.
Timing Tag, Trigger, and Data Layer Variables
To make the setup work, we need a Timing Tag, a Custom Event Trigger and four Data Layer Variables.
Data Layer Variables
Create the Data Layer Variables first. You need four Variables with the following settings:
Name: {{DLV - timingCategory}}
Data Layer Variable Name: timingCategory
Name: {{DLV - timingVariable}}
Data Layer Variable Name: timingVariable
Name: {{DLV - timingLabel}}
Data Layer Variable Name: timingLabel
Name: {{DLV - timingValue}}
Data Layer Variable Name: timingValue
Custom Event Trigger
The Trigger is a Custom Event Trigger with the following settings:
Name: Event - fieldTiming
Fire On / Event name: fieldTiming
Timing Tag
Finally, you need to create the Timing Tag. Create a new Tag of type Google Analytics, and set the following settings:
Name: UA - Timing - Form Field Timing
Tracking ID: UA-XXXXXX-Y (substitute with your property ID)
Track Type: Timing
Var: {{DLV - timingVariable}}
Category: {{DLV - timingCategory}}
Value: {{DLV - timingValue}}
Label: {{DLV - timingLabel}}
Attach the Trigger you created in the previous section to this Tag.
And now you’re set to go! Each interaction with the fields in your form should now send the Timing hit. You can find the results in Google Analytics, by going to Behavior -> Site Speed -> User Timings.
Summary
Like I mentioned, this is a very simple solution. It just measures the time spent on each form field, and reports this as a User Timing hit to Google Analytics. You might want to tweak it a little to be more robust, and you have to be mindful of the 500 hits / session limitation that GA imposes on sessions.
You can do some cool stuff with the data, such as building a histogram where it’s easier to visualize the problematic fields. It would be also interesting to see if long time spent on a field correlates with form abandonment.