(function($) {
var eventIds = {
fieldCompleted: "2ca692cb-bdb2-4c9d-a3b5-917b3656c46a",
fieldError: "ea27aca5-432f-424a-b000-26ba5f8ae60a"
};
function endsWith(str, suffix) {
return str.toLowerCase().indexOf(suffix.toLowerCase(), str.length - suffix.length) !== -1;
}
function getOwner(form, elementId) {
var targetId = elementId.slice(0, -(elementId.length - elementId.lastIndexOf(".") - 1)) + "Value";
return form.find("input[name=\"" + targetId + "\"]")[0];
}
function getSessionId(form) {
var formId = form[0].id;
var targetId = formId.slice(0, -(formId.length - formId.lastIndexOf("_") - 1)) + "FormSessionId";
var element = form.find("input[type='hidden'][id=\"" + targetId + "\"]");
return element.val();
}
function getElementName(element) {
var fieldName = element.name;
if (!endsWith(fieldName, "value")) {
return getFieldGuid(fieldName) + "Value";
}
return fieldName;
}
function getElementValue(element) {
var value;
if (element.type === "checkbox" || element.type === "radio") {
var form = $(element).closest("form");
var checkboxList = form.find("input[name='" + element.name + "']");
if (checkboxList.length > 1) {
value = [];
checkboxList = checkboxList.not(":not(:checked)");
$.each(checkboxList, function () {
value.push($(this).val());
});
} else {
value = element.checked ? "1" : "0";
}
} else {
value = $(element).val();
}
if (value && Object.prototype.toString.call(value) === "[object Array]") {
value = value.join(",");
}
return value;
}
function getFieldGuid(fieldName) {
var searchPattern = "fields[";
var index = fieldName.toLowerCase().indexOf(searchPattern);
return fieldName.substring(0, index + searchPattern.length + 38);
}
function getFieldName(element) {
return $(element).attr("data-sc-field-name");
}
$.fxbFormTracker = function (el, options) {
this.el = el;
this.$el = $(el);
this.options = $.extend({}, $.fxbFormTracker.defaultOptions, options);
this.init();
},
$.fxbFormTracker.parse = function (formId) {
var $form = $(formId);
$form.track_fxbForms();
var isSessionExpired = parseInt($("[name$='.IsSessionExpired']").val());
if (isSessionExpired) {
alert($.fxbFormTracker.texts.expiredWebSession);
}
},
$.extend($.fxbFormTracker,
{
defaultOptions: {
formId: null,
sessionId: null,
fieldId: null,
fieldValue: null,
duration: null
},
prototype: {
init: function () {
this.options.duration = 0;
this.options.formId = this.$el.attr("data-sc-fxb");
},
startTracking: function () {
this.options.sessionId = getSessionId(this.$el);
var self = this;
var inputs = this.$el.find("input:not([type='submit']), select, textarea");
var trackedInputs = inputs.filter("[data-sc-tracking='True'], [data-sc-tracking='true']");
var trackedNonDateInputs = trackedInputs.not("[type='date']");
if (trackedInputs.length) {
inputs.not(trackedInputs).on("focus",
function () {
self.onFocusField(this);
});
trackedInputs.on("focus",
function () {
self.onFocusField(this, true);
}).on("blur",
function () {
self.onBlurField(this);
});
trackedNonDateInputs.on("change",
function () {
self.onBlurField(this);
});
}
},
onFocusField: function (element, hasTracking) {
if (!hasTracking) {
this.options.fieldId = "";
return;
}
var fieldId = getElementName(element);
if (this.options.fieldId !== fieldId) {
this.options.fieldId = fieldId;
this.options.duration = $.now();
this.options.fieldValue = getElementValue(element);
}
},
onBlurField: function (element) {
var fieldId = getElementName(element);
var timeStamp = $.now();
if (!endsWith(fieldId, "value")) {
var owner = getOwner(this.$el, fieldId);
if (!owner) {
return;
}
element = owner;
}
var duration = this.options.duration ? Math.round((timeStamp - this.options.duration) / 1000) : 0;
var value = getElementValue(element);
var fieldChanged = this.options.fieldId !== fieldId;
if (fieldChanged) {
this.options.fieldId = fieldId;
this.options.duration = $.now();
duration = 0;
}
if (fieldChanged || this.options.fieldValue !== value) {
this.options.fieldValue = value;
var fieldName = getFieldName(element);
var clientEvent = this.buildEvent(fieldId, fieldName, eventIds.fieldCompleted, duration);
var validator = this.$el.data("validator");
var validationEvents = [];
if (validator && !validator.element(element)) {
validationEvents = this.checkClientValidation(element, fieldName, validator, duration);
}
this.trackEvents($.merge([clientEvent], validationEvents));
}
},
buildEvent: function (fieldId, fieldName, eventId, duration) {
var fieldIdHidden = getFieldGuid(fieldId) + "ItemId";
fieldId = $("input[name=\"" + fieldIdHidden + "\"]").val();
return {
'formId': this.options.formId,
'sessionId': this.options.sessionId,
'eventId': eventId,
'fieldId': fieldId,
'duration': duration,
'fieldName': fieldName
};
},
checkClientValidation: function (element, fieldName, validator, duration) {
var tracker = this;
var events = [];
$.each(validator.errorMap,
function (key) {
if (key === element.name) {
var clientEvent = tracker.buildEvent(key, fieldName, eventIds.fieldError, duration);
events.push(clientEvent);
}
});
return events;
},
trackEvents: function (events) {
$.ajax({
type: "POST",
url: "/fieldtracking/register",
data: JSON.stringify(events),
contentType: "application/json"
}).done(function (data, textStatus, jqXhr) {
if ((jqXhr.statusText === "OK" || jqXhr.statusText === "success") && jqXhr.responseText !== "") {
alert(jqXhr.responseText);
}
});
}
}
});
$.fn.track_fxbForms = function (options) {
return this.each(function () {
var tracker = $.data(this, "fxbForms.tracking");
if (tracker) {
tracker.startTracking();
} else {
tracker = new $.fxbFormTracker(this, options);
$.data(this, "fxbForms.tracking", tracker);
tracker.startTracking();
}
});
};
$("form[data-sc-fxb]").track_fxbForms();
})(jQuery);