Skip to content

Commit

Permalink
✨ amp-form: form data in analytics with submit-success/error (#16028)
Browse files Browse the repository at this point in the history
* amp-form: form data in analytics when amp-form-success and amp-form-error

* linting corrections, documentation

* touchup
  • Loading branch information
nbonnotte authored and cvializ committed Jun 20, 2018
1 parent 567401b commit c6d016a
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 8 deletions.
13 changes: 7 additions & 6 deletions extensions/amp-form/0.1/amp-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,10 @@ export class AmpForm {
* Triggers 'amp-form-submit' event in 'amp-analytics' and
* generates variables for form fields to be accessible in analytics
*
* @param {string} eventType
* @private
*/
triggerFormSubmitInAnalytics_() {
triggerFormSubmitInAnalytics_(eventType) {
const formDataForAnalytics = {};
const formObject = this.getFormAsObject_();

Expand All @@ -309,7 +310,7 @@ export class AmpForm {
}
formDataForAnalytics['formId'] = this.form_.id;

this.analyticsEvent_('amp-form-submit', formDataForAnalytics);
this.analyticsEvent_(eventType, formDataForAnalytics);
}

/**
Expand Down Expand Up @@ -438,7 +439,7 @@ export class AmpForm {

const p = this.doVarSubs_(varSubsFields)
.then(() => {
this.triggerFormSubmitInAnalytics_();
this.triggerFormSubmitInAnalytics_('amp-form-submit');
this.actions_.trigger(
this.form_, 'submit', /* event */ null, trust);
// After variable substitution
Expand Down Expand Up @@ -536,7 +537,7 @@ export class AmpForm {
handleXhrSubmitSuccess_(response) {
return response.json().then(json => {
this.triggerAction_(/* success */ true, json);
this.analyticsEvent_('amp-form-submit-success');
this.triggerFormSubmitInAnalytics_('amp-form-submit-success');
this.setState_(FormState_.SUBMIT_SUCCESS);
this.renderTemplate_(json || {});
this.maybeHandleRedirect_(response);
Expand All @@ -559,7 +560,7 @@ export class AmpForm {
}
return promise.then(responseJson => {
this.triggerAction_(/* success */ false, responseJson);
this.analyticsEvent_('amp-form-submit-error');
this.triggerFormSubmitInAnalytics_('amp-form-submit-error');
this.setState_(FormState_.SUBMIT_ERROR);
this.renderTemplate_(responseJson || {});
this.maybeHandleRedirect_(error.response);
Expand Down Expand Up @@ -587,7 +588,7 @@ export class AmpForm {
for (let i = 0; i < varSubsFields.length; i++) {
this.urlReplacement_.expandInputValueSync(varSubsFields[i]);
}
this.triggerFormSubmitInAnalytics_();
this.triggerFormSubmitInAnalytics_('amp-form-submit');
}

/**
Expand Down
99 changes: 99 additions & 0 deletions extensions/amp-form/0.1/test/test-amp-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -1814,6 +1814,105 @@ describes.repeated('', {
});
});

it('should trigger submit-success analytics event with form data', () => {
return getAmpForm(getForm()).then(ampForm => {
const form = ampForm.form_;
form.id = 'registration';

const emailInput = createElement('input');
emailInput.setAttribute('name', 'email');
emailInput.setAttribute('type', 'email');
emailInput.setAttribute('value', 'j@hnmiller.com');
form.appendChild(emailInput);

const unnamedInput = createElement('input');
unnamedInput.setAttribute('type', 'text');
unnamedInput.setAttribute('value', 'unnamed');
form.appendChild(unnamedInput);

let fetchResolver;
sandbox.stub(ampForm.xhr_, 'fetch').returns(new Promise(resolve => {
fetchResolver = resolve;
}));
sandbox.stub(ampForm, 'analyticsEvent_');
const event = {
stopImmediatePropagation: sandbox.spy(),
target: form,
preventDefault: sandbox.spy(),
};
ampForm.handleSubmitEvent_(event);
expect(ampForm.state_).to.equal('submitting');
fetchResolver({json: () => Promise.resolve()});

const expectedFormData = {
'formId': 'registration',
'formFields[name]': 'John Miller',
'formFields[email]': 'j@hnmiller.com',
};

return ampForm.xhrSubmitPromiseForTesting().then(() => {
expect(ampForm.state_).to.equal('submit-success');
expect(ampForm.analyticsEvent_).to.be.calledWith(
'amp-form-submit-success',
expectedFormData
);
}, () => {
assert.fail('Submit should have succeeded.');
});

});
});

it('should trigger submit-error analytics event with form data', () => {
return getAmpForm(getForm()).then(ampForm => {
const form = ampForm.form_;
form.id = 'registration';

const emailInput = createElement('input');
emailInput.setAttribute('name', 'email');
emailInput.setAttribute('type', 'email');
emailInput.setAttribute('value', 'j@hnmiller.com');
form.appendChild(emailInput);

const unnamedInput = createElement('input');
unnamedInput.setAttribute('type', 'text');
unnamedInput.setAttribute('value', 'unnamed');
form.appendChild(unnamedInput);

let fetchRejecter;
sandbox.stub(ampForm.xhr_, 'fetch')
.returns(new Promise((unusedResolve, reject) => {
fetchRejecter = reject;
}));
sandbox.stub(ampForm, 'analyticsEvent_');
const event = {
stopImmediatePropagation: sandbox.spy(),
target: form,
preventDefault: sandbox.spy(),
};
ampForm.handleSubmitEvent_(event);
expect(ampForm.state_).to.equal('submitting');
fetchRejecter();

const expectedFormData = {
'formId': 'registration',
'formFields[name]': 'John Miller',
'formFields[email]': 'j@hnmiller.com',
};

return ampForm.xhrSubmitPromiseForTesting().then(() => {
assert.fail('Submit should have failed.');
}, () => {
expect(ampForm.state_).to.equal('submit-error');
expect(ampForm.analyticsEvent_).to.be.calledWith(
'amp-form-submit-error',
expectedFormData
);
});

});
});

it('should trigger amp-form-submit after variables substitution', () => {
return getAmpForm(getForm()).then(ampForm => {
const form = ampForm.form_;
Expand Down
7 changes: 5 additions & 2 deletions extensions/amp-form/amp-form.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,10 @@ You can configure your analytics to send these events as in the example below.
</amp-analytics>
```

The `amp-form-submit` event fires when a form request is initiated. The `amp-form-submit` event generates a set of variables that correspond to the specific form and the fields in the form. These variables can be used for analytics.
The `amp-form-submit` event fires when a form request is initiated.
The `amp-form-submit-success` event fires when a successful response is received, that is when the response has a status of `2XX`. Any other status triggers the `amp-form-submit-error` event.

All three events generate a set of variables that correspond to the specific form and the fields in the form. These variables can be used for analytics.

For example, the following form has one field:

Expand All @@ -210,7 +213,7 @@ For example, the following form has one field:
<input type="submit" value="Comment" />
</form>
```
When the `amp-form-submit` event fires, it generates the following variables containing the values that were specified in the form:
When the `amp-form-submit`, `amp-form-submit-success`, or `amp-form-submit-error` event fires, it generates the following variables containing the values that were specified in the form:

* `formId`
* `formFields[comment]`
Expand Down

0 comments on commit c6d016a

Please sign in to comment.