everbridge-gtm/LinkedIn - Demo Form Autofill.html
2021-01-11 16:58:24 -05:00

164 lines
6.9 KiB
HTML

<style>
.liAutoFill {
text-align: center;
margin: 0px 10px;
}
</style>
<script>
(function () {
var fillScript = document.createElement('script'), // the LI autofill script (client-side)
liAutoFillScript = document.createElement('script'),
iframeHolderDiv = document.createElement('div'), // so we can style location of button
autoFillLocation = document.querySelector("form[id^='mktoForm_']"), // will only find first Marketo form on a page
firstRow,
mktoForm,
hiddenLinkedInInputs = document.createDocumentFragment(), // since we're creating multiple nodes, just do the add once
hiddenInputCreator = function (tagName, onChangeHandler) {
var newInput = document.createElement('input');
newInput.style.position = 'absolute';
newInput.style.left = '-999em';
newInput.setAttribute('name', tagName + '-flag');
newInput.setAttribute('type', 'text');
newInput.setAttribute('id', tagName + '-flag');
newInput.style.display = 'none';
newInput._value = newInput.value;
Object.defineProperty(newInput, 'value', {
get: function () {
return this._value;
},
set: function (v) {
this._value = v;
onChangeHandler(v);
},
});
hiddenLinkedInInputs.appendChild(newInput);
fillScript.setAttribute('data-field-' + tagName, tagName + '-flag');
},
linkedInAutofillClicked = false;
// style the holder div
// 1/17/21 - disabled because not being set, trying
// to move to after add to DOM
// iframeHolderDiv.style.textAlign = 'center';
// iframeHolderDiv.style.margin = '10px 0px';
// required by LinkedIn
fillScript.setAttribute('type', 'IN/Form2');
// You don't need any of these fields if they're
// named the same thing as the ones returned from LinkedIn.
// Unfortunately means you can't disable them, either...
// LinkedIn will set them automatically if it finds them
// in your form so you need to map them to 'pseudo-hidden'
// fields (like way offscreen). HIDDEN FIELDS WON'T WORK.
/*fillScript.setAttribute('data-field-firstname', 'FirstName');
fillScript.setAttribute('data-field-lastname', 'LastName');
fillScript.setAttribute('data-field-phone', 'Phone');
fillScript.setAttribute('data-field-company', 'Company');
fillScript.setAttribute('data-field-title', 'Title');*/
// 'Pseudo-hide' input fields to give us a place to store
// the email address and country LI provides to us. We do this for 2
// reasons:
// [1] To keep the main email field from being filled
// We *could* autofill email, but if they don't use a business
// address (few do) then submit will reject it. Better to make them
// just fill it to start with. We will also use this to trigger the GA
// autofill event.
// [2] To allow us to map the ISO country code LinkedIn provides us
// to the [sigh] full-text version of the country our select element
// requires
hiddenInputCreator('email', function (newValue) {
// fire the GA event for autofill
console.log('%s value changed to %s', this.ID, newValue);
// this sets the flag to ID an autofill event. We are
// gating this on email since it's the only guaranteed
// field that we can't see on screen so can't be set by
// a user directly...
linkedInAutofillClicked = true;
});
hiddenInputCreator('country', function (newValue) {
// console.log('%s value changed to %s', this.ID, newValue);
// map to the country we have in our select dropdown
var newCountry = {{JS - ISO Country Code to EVBG Country Name}}(newValue);
// sets the value in the form the user can see
if (typeof MktoForms2 !== 'undefined') {
mktoForm.setValues({
Country: newCountry
});
}
});
hiddenInputCreator('state', function (newValue) {
// only set state if we're in the US
if(mktoForm.getValues()['Country'] === "United States"){
mktoForm.setValues({
State: newValue.toUpperCase()
});
}
});
// build LI autofill script
liAutoFillScript.src = 'https://www.linkedin.com/autofill/js/autofill.js';
liAutoFillScript.type = 'text/javascript';
liAutoFillScript.defer = true; // as opposed to default 'async'
// add the iframe to the holder div
iframeHolderDiv.setAttribute('class', 'liAutoFill');
iframeHolderDiv.appendChild(fillScript);
autoFillLocation.prepend(iframeHolderDiv);
autoFillLocation.append(liAutoFillScript);
// moved from above to ensure it's in DOM before adding styles
// iframeHolderDiv.style.textAlign = 'center';
// iframeHolderDiv.style.margin = '10px 0px';
if (typeof MktoForms2 !== 'undefined') {
MktoForms2.whenReady(function (form) {
// need the id of the form so we can hook up autofill
// doing this way will work on any Marketo form
fillScript.setAttribute('data-form', 'mktoForm_' + form.getId());
firstRow = document.querySelector('form .mktoFormRow');
mktoForm = form; // so we can use it above
firstRow.appendChild(hiddenLinkedInInputs); // fragment vaporizes leaving input elements
form.onSubmit(function (form) {
// tell GA about it, but only if we know they autofilled
if (linkedInAutofillClicked) {
var values = form.getValues(),
eventData = {
category: 'LinkedIn Form AutoFill',
// will automatically set dlv-action which we'll pass to form id to name mapper in event submit in GTM
action: 'mktoForm_' + form.getId() + ' [LinkedIn AutoFill]',
label: [
values.Company,
values.Industry,
values.Title,
values.Country,
values.State,
'{{Page Path}}',
'gclid:' + '{{JS - GA Client ID}}',
].join(' | '),
};
// 'eventData' automatically maps to the GTM variables 'dlv - category', 'dlv - action', etc.
window.dataLayer.push({
event: 'formLinkedInAutoFill', // MUST FIX WHEN EXPANDING AS EVENT ONLY FIRES ON DEMO PAGE
eventData: eventData,
eventCallback: function () {
// this just prints that we've sent it
console.log('event submitted: %O', eventData);
},
}); // populated on the GTM side
}
return false;
});
});
}
})();
</script>
<!-- what LinkedIn recommends which doesn't allow any customization -->
<!--<script type="IN/Form2" data-form="mktoForm_1248" data-field-firstname="FirstName"
data-field-lastname="LastName" data-field-phone="Phone" data-field-company="Company"
data-field-title="Title"></script>-->