For not so long ago I wanted to track a client event for the DMS. In this case I wanted to know if a specific alert box has been closed.
I did some googling and found Sitecore Client Event Tracker on the Github. That was exactly what I needed.
I did some minor changes to it. Instead of passing a number of parameters to the javascript method, AnalyticsPageEvent, I changed it to take one parameter – a Json object.
function AnalyticsPageEvent(jsonData) { this.jsonData = jsonData; this.trigger = function () { var queryString = ''; if (!this.jsonData) { return; } queryString += '&' + 'jsonData' + '=' + JSON.stringify(this.jsonData); var url = '/components/Tracking/Presentation/ClientEventTracker.aspx' + '?ra=' + eventTracker.randomstring() + queryString; eventTracker.request(url); }; }
The Json object is a serialized class with a dictionary
namespace Sandbox.Framework.SitecoreSpecific.Model { [DataContract] public class InputData { [DataMember(Name = "requestParamAndValues")] public Dictionary<string, string> RequestParamAndValues { get; set; } public bool ContainsParamkey(InputDataKeys inputDataKeys) { return RequestParamAndValues != null && RequestParamAndValues.ContainsKey(inputDataKeys.ToString()); } public string GetValueByKey(InputDataKeys inputDataKeys) { string value; RequestParamAndValues.TryGetValue(inputDataKeys.ToString(), out value); return value; } public void SetValueByKey(InputDataKeys inputDataKeys, string value) { if (RequestParamAndValues.ContainsKey(inputDataKeys.ToString())) RequestParamAndValues[inputDataKeys.ToString()] = value; else RequestParamAndValues.Add(inputDataKeys.ToString(), value); } } }
The keys for the dictionary are defined in an enum
namespace Sandbox.Framework.SitecoreSpecific { public enum InputDataKeys { None = 0, IpAddress = 1, Coordinates = 2, Language = 3, Device = 4, Browser = 5, PageEventId = 6, PageEventName = 7, PageEventText = 8, PageEventKey = 9, PageEventData = 10, PageUrl = 11, EngagementPlan = 12, EngagementPlanState = 13 } }
The widget containing the alert box. The data-goal attribute contains the item id for the “Closed Alert box” event and the data-pageurl holds the path to actual page(in order for the tracker to find the correct page row).
<div class="alert alert-info fade in" data-pageurl="<%= HttpContext.Current.Request.Url.PathAndQuery %>" data-goal=" <%# Sandbox.Alert.Constants.Analytics.Goals.CloseAlertBox %> "> <button type="button" class="close" id="closeAlert" data-dismiss="alert">×</button> <asp:PlaceHolder runat="server" Visible="<%# !string.IsNullOrWhiteSpace(this.GetDataSourceOrContextItem().GetString(Sandbox.Spots.Constants.Fields.Alert.AlertHeader)) || Sitecore.Context.PageMode.IsPageEditorEditing %>"> <h4> <sc:Text runat="server" DataSource="<%# this.GetDataSourceOrContextItem().ID %>" Field="<%# Sandbox.Spots.Constants.Fields.Alert.AlertHeader%>" /> </h4> </asp:PlaceHolder> <sc:Text runat="server" DataSource="<%# this.GetDataSourceOrContextItem().ID %>" Field="<%# Sandbox.Spots.Constants.Fields.Alert.AlertText%>" /> </div>
The javascript for the widget:
var Sandbox = Sandbox || {}; jQuery(document).ready(function () { Sandbox.Alert.DomReady(); }); Sandbox.Alert = { DomReady: function () { jQuery("#closeAlert").click(function () { Sandbox.Alert.TrackCloseEvent(); }); }, TrackCloseEvent: function () { var dataContainer = jQuery(".alert alert-info fade in"); var requestParamAndValues = {}; requestParamAndValues["PageEventId"] = dataContainer.data("goal"); requestParamAndValues["PageUrl"] = dataContainer.data("pageurl"); var jsonObject = {}; jsonObject["requestParamAndValues"] = requestParamAndValues; var analyticsEvent = new AnalyticsPageEvent(jsonObject); analyticsEvent.trigger(); } };
The javascript for the tracking.
var eventTracker = false; function AnalyticsPageEvent(jsonData) { this.jsonData = jsonData; this.trigger = function () { var queryString = ''; if (!this.jsonData) { return; } queryString += '&' + 'jsonData' + '=' + JSON.stringify(this.jsonData); var url = '/components/Tracking/Presentation/ClientEventTracker.aspx' + '?ra=' + eventTracker.randomstring() + queryString; eventTracker.request(url); }; } function EventTracker() { this.request = function (url) { var script = new ClientEventScript(url, true); script.load(); }; this.randomstring = function () { var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var text = ""; for (var i = 0; i < 32; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)); } return text; }; } function ClientEventScript(src, async) { this.src = src; this.async = async; this.load = function () { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = this.src; script.async = this.async; var ssc = document.getElementsByTagName('script')[0]; ssc.parentNode.insertBefore(script, ssc); }; } eventTracker = new EventTracker();
The aspx page, ClientEventTracker, (which is requested from the EventTracker-method) will register the tracking
namespace Sandbox.Tracking.Presentation { public partial class ClientEventTracker : System.Web.UI.Page { protected void Page_Init(object sender, EventArgs e) { Context.Response.ContentType = "application/javascript"; TriggerEvent(this.Context); } private static void TriggerEvent(HttpContext context) { string jsonData = context.Request["jsonData"]; InputData inputData = ConvertJsonToObjectService.Convert<InputData>(jsonData); if (!inputData.ContainsParamkey(InputDataKeys.PageUrl)) return; if (!inputData.ContainsParamkey(InputDataKeys.PageEventId)) return; Tracker.StartTracking(); Tracker.CurrentPage.Cancel(); VisitorDataSet.PagesRow pageRow = Tracker.CurrentVisit.GetPages().FirstOrDefault(p => p.Url.Contains(inputData.GetValueByKey(InputDataKeys.PageUrl))); if (pageRow == null) return; PageEventItem pageEvent = null; if (!string.IsNullOrWhiteSpace(inputData.GetValueByKey(InputDataKeys.PageEventId))) pageEvent = new PageEventItem(Sandbox.Framework.SitecoreEnhancements.SitecoreItemRepository.Get(inputData.GetValueByKey(InputDataKeys.PageEventId))); if (pageEvent == null) return; pageRow.Register(pageEvent); Tracker.Submit(); } }
That’s all for now folks 🙂
Great reaading your post
LikeLike