diff --git a/README.md b/README.md index 0acbbae3..c400290d 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,36 @@ Properties - text - `View Account` - href - `/account` +Setting custom properties with `data-ahoy-click-` attributes: + +```html +Extra +``` + +Properties + +- tag - `a` +- text - `Extra` +- href - `/my_product` +- properties - `{product_id: "123", cat: "456"}` + +Setting custom properties from JSON with `data-ahoy-click-json` attribute: + +```html +Extra JSON +``` + +JSON + +Properties + +- tag - `a` +- text - `JSON` +- href - `/link1` +- properties - `{some_flag: true, some_count: 42}` + +JSON allows typing and nesting extra properties, but requires HTML escaping. HTML escaping is automatic in many templating systems like ERB. + ### Submits ```javascript diff --git a/src/index.js b/src/index.js index 59bca9c2..e8ea6677 100644 --- a/src/index.js +++ b/src/index.js @@ -333,6 +333,28 @@ function createVisit() { } } +function extraClickProperties(element) { + let prefix = "data-ahoy-click-"; + let jsonAttribute = prefix + 'json'; + + if (element.hasAttribute(jsonAttribute)) { + return JSON.parse(element.getAttribute(jsonAttribute)); + } + + let properties = {}; + + let attributeNames = element.getAttributeNames(); + for (let i = 0; i < attributeNames.length; i++) { + let attributeName = attributeNames[i]; + if (attributeName.startsWith(prefix)) { + let propertyName = attributeName.substring(prefix.length).replace("-", "_"); + properties[propertyName] = element.getAttribute(attributeName); + } + } + + return properties; +} + ahoy.getVisitId = ahoy.getVisitToken = function () { return getCookie("ahoy_visit"); }; @@ -419,6 +441,11 @@ ahoy.trackClicks = function () { let properties = eventProperties(e); properties.text = properties.tag == "input" ? target.value : (target.textContent || target.innerText || target.innerHTML).replace(/[\s\r\n]+/g, " ").trim(); properties.href = target.href; + + let extraProperties = extraClickProperties(target); + for (var propName in extraProperties) { + properties[propName] = extraProperties[propName]; + } ahoy.track("$click", properties); }); }; diff --git a/test/ahoy_test.js b/test/ahoy_test.js index f5b2d034..1bcd0343 100644 --- a/test/ahoy_test.js +++ b/test/ahoy_test.js @@ -84,12 +84,12 @@ test('View tracking', (t) => { }); test('Click tracking', (t) => { - t.plan(6); + t.plan(7); fauxJax.install(); fauxJax.once('request', function(request) { const event = JSON.parse(request.requestBody).events[0]; - const properties = event.properties + const properties = event.properties; t.equal(request.requestMethod, 'POST', 'Should use POST method'); t.equal(request.requestURL, '/ahoy/events', 'Should POST to correct URL'); @@ -97,6 +97,7 @@ test('Click tracking', (t) => { t.equal(properties.id, 'ahoy-test-link', 'Should set event id property'); t.equal(properties.section, 'Header', 'Should set event section property'); t.equal(properties.text, 'Home', 'Should set event text property'); + t.equal(properties.properties, undefined, 'Should not set extra properties'); request.respond(200, {}, '{}'); fauxJax.restore(); @@ -105,3 +106,28 @@ test('Click tracking', (t) => { ahoy.trackClicks(); document.getElementById('ahoy-test-link').click(); }); + +test('Click tracking extra properties', (t) => { + t.plan(8); + + fauxJax.install(); + fauxJax.once('request', function(request) { + const event = JSON.parse(request.requestBody).events[0]; + const properties = event.properties; + + t.equal(request.requestMethod, 'POST', 'Should use POST method'); + t.equal(request.requestURL, '/ahoy/events', 'Should POST to correct URL'); + t.equal(event.name, '$click', 'Should set event name property'); + t.equal(properties.id, 'ahoy-test-link-extra', 'Should set event id property'); + t.equal(properties.section, 'Header', 'Should set event section property'); + t.equal(properties.text, 'Extra', 'Should set event text property'); + t.equal(properties.properties.foo, 'bar', 'Should set extra property "foo"'); + t.equal(properties.properties.the_answer, '42', 'Should set extra property "the_answer"'); + + request.respond(200, {}, '{}'); + fauxJax.restore(); + }); + + ahoy.trackClicks(); + document.getElementById('ahoy-test-link-extra').click(); +}); diff --git a/test/template.html b/test/template.html index 76875128..f87d2c4b 100644 --- a/test/template.html +++ b/test/template.html @@ -3,4 +3,8 @@