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
LikeLiked by 1 person