diff --git a/core/lib/core.ts b/core/lib/core.ts index 0362e8148..ad5c87e9f 100644 --- a/core/lib/core.ts +++ b/core/lib/core.ts @@ -786,7 +786,7 @@ export function trackerCore(base64: boolean, callback?: (PayloadData) => void) { }, /** - * Track the value of a form field changing + * Track the value of a form field changing or receiving focus * * @param formId The parent form ID * @param elementId ID of the changed element @@ -800,7 +800,8 @@ export function trackerCore(base64: boolean, callback?: (PayloadData) => void) { * * @todo make `nodeName` enum */ - trackFormChange: function ( + trackFormFocusOrChange: function ( + schema: string, formId: string, elementId: string, nodeName: string, @@ -811,7 +812,7 @@ export function trackerCore(base64: boolean, callback?: (PayloadData) => void) { tstamp?: Timestamp): PayloadData { return trackSelfDescribingEvent({ - schema: 'iglu:com.snowplowanalytics.snowplow/change_form/jsonschema/1-0-0', + schema: 'iglu:com.snowplowanalytics.snowplow/' + schema + '/jsonschema/1-0-0', data: removeEmptyProperties({ formId: formId, elementId: elementId, diff --git a/core/tests/unit/core.js b/core/tests/unit/core.js index d7dfacc51..5316e5ad7 100644 --- a/core/tests/unit/core.js +++ b/core/tests/unit/core.js @@ -400,6 +400,37 @@ define([ compare(tracker.trackRemoveFromCart(sku, name, category, unitPrice, quantity, currency), expected); }, + "Track a form focus event": function () { + var formId = "parent"; + var elementId = "child"; + var nodeName = "INPUT"; + var type = "text"; + var elementClasses = ["important"]; + var value = "male"; + + var inputJson = { + schema: 'iglu:com.snowplowanalytics.snowplow/focus_form/jsonschema/1-0-0', + data: { + formId: formId, + elementId: elementId, + nodeName: nodeName, + type: type, + elementClasses: elementClasses, + value: value + } + }; + + var expected = { + e: 'ue', + ue_pr: JSON.stringify({ + schema: unstructEventSchema, + data: inputJson + }) + }; + + compare(tracker.trackFormFocusOrChange('focus_form', formId, elementId, nodeName, type, elementClasses, value), expected); + }, + "Track a form change event": function () { var formId = "parent"; var elementId = "child"; @@ -428,7 +459,7 @@ define([ }) }; - compare(tracker.trackFormChange(formId, elementId, nodeName, type, elementClasses, value), expected); + compare(tracker.trackFormFocusOrChange('change_form', formId, elementId, nodeName, type, elementClasses, value), expected); }, "Track a form submission event": function () { diff --git a/src/js/forms.js b/src/js/forms.js index 11177e713..e18cac1b9 100755 --- a/src/js/forms.js +++ b/src/js/forms.js @@ -119,12 +119,14 @@ object.getFormTrackingManager = function (core, trackerId, contextAdder) { /* * Return function to handle form field change event */ - function getFormChangeListener(context) { + function getFormChangeListener(event_type, context) { return function (e) { var elt = e.target; var type = (elt.nodeName && elt.nodeName.toUpperCase() === 'INPUT') ? elt.type : null; var value = (elt.type === 'checkbox' && !elt.checked) ? null : elt.value; - core.trackFormChange(getParentFormName(elt), getFormElementName(elt), elt.nodeName, type, helpers.getCssClasses(elt), value, contextAdder(context)); + if (event_type === 'change_form' || (type != 'checkbox' && type != 'radio')) { + core.trackFormFocusOrChange(event_type, getParentFormName(elt), getFormElementName(elt), elt.nodeName, type, helpers.getCssClasses(elt), value, contextAdder(context)); + } }; } @@ -162,7 +164,8 @@ object.getFormTrackingManager = function (core, trackerId, contextAdder) { lodash.forEach(innerElementTags, function (tagname) { lodash.forEach(form.getElementsByTagName(tagname), function (innerElement) { if (fieldFilter(innerElement) && !innerElement[trackingMarker]) { - helpers.addEventListener(innerElement, 'change', getFormChangeListener(context), false); + helpers.addEventListener(innerElement, 'focus', getFormChangeListener('focus_form', context), false); + helpers.addEventListener(innerElement, 'change', getFormChangeListener('change_form', context), false); innerElement[trackingMarker] = true; } });