let popup_datalayer = (formID, eventType = 'open', buttonPosition = 'middle') => { let dataLayerObject = { 'event': `popup_${eventType}`, 'formName': 'N/A', 'formType': 'N/A', 'buttonLocation': 'N/A' } //nfForms is an array which holds information about all forms present on //the page. This is initialized by Ninjaform after all forms are ready. if (formID && nfForms) { for (let nfForm of nfForms) { if (nfForm.id === formID) { formName = nfForm.settings.title; } } if (formName) { dataLayerObject['formName'] = formName; dataLayerObject['formType'] = 'ninja form'; dataLayerObject['buttonLocation'] = buttonPosition; } } window.dataLayer = window.dataLayer || []; window.dataLayer.push(dataLayerObject); } /** * Returns an unescaped version of DL props string. example - The heading block of wordpress escapes the double * Quotes. This causes the JSON string parser to fail on the unescaped quote value. This function checks if the * DL Props string contains escaped Quotes and converts those back to ' " '. * Note: This function unescapes only double quote("). * @param {string} DL_props_string - eg ' {"key1":"value1"} ' * @returns {string} - return unescaped string * */ const nlsn_unescape_quotes = (DL_props_string) => { if (!DL_props_string.includes('"')) { return DL_props_string; } return DOMPurify.sanitize(DL_props_string.replaceAll('"','"')); }; /** * Generic onclick datalayer trigger function * This function can be used to add event listener to an html element * which has data-dl-event attribute. */ function add_datalayer_event_to_targets() { let data_layer_elements = document.querySelectorAll('[data-dl-event]'); data_layer_elements.forEach((data_layer_element) => { // Before adding event listner check if an event listener is // already added to the element. 'dl-event-present' attribute // keeps track of event listener if (data_layer_element.hasAttribute("dl-event-present")) { return; } data_layer_element.addEventListener('click', (e) => { let element = e.currentTarget;// avoid e.target because it tries to extract the attributes of clicked element let event_name = element.getAttribute('data-dl-event'); let event_props = element.getAttribute('data-dl-props'); if (event_name === "" || event_name === null || event_props === "" || event_props === null){ return; } event_props = JSON.parse(nlsn_unescape_quotes(event_props)); let data_layer_object = {}; data_layer_object['event'] = event_name; for (const prop in event_props) { data_layer_object[prop] = event_props[prop]; } window.dataLayer = window.dataLayer || []; window.dataLayer.push(data_layer_object); // This will stop the click event from propagating to parent element // use case: After the category tag (in insights card) datalayer event is triggered, the below line // will stop propagation of click event and will prevent triggering datalayer event set in parent element. e.stopPropagation(); }) // add an attribute to element after datalayer event listener is // attached to the element. This is done to mitigate duplicate event trigger issue. data_layer_element.setAttribute("dl-event-present", "true"); }) } jQuery(document).one('nfFormReady',function ($) { add_datalayer_event_to_targets(); //execute the function after at least one form is loaded as NF takes a while to load }); document.addEventListener("postsLoaded",add_datalayer_event_to_targets); // execute the function after postsLoaded( load more )event /** * Ninja Form submission datalayer scripts */ /** * Get the value of a field containing specific key(set inside Ninja form) * @param {Object} form_fields_by_key- Submitted field values * @param {String} field_key_str - key string to search for */ const get_nf_field_value = (form_fields_by_key, field_key_str) => { let field_keys = Object.keys(form_fields_by_key); let field_key = field_keys.find((key) => key.startsWith(field_key_str)); if (!field_key){ return 'N/A'; } let NF_field_value = form_fields_by_key[field_key].value; let return_val = null; //special cases // speak with sales,remember me checkbox if ((field_key_str === 'speak_with_sales' || field_key_str === 'remember_me' || field_key_str === 'newsletter') && Array.isArray(NF_field_value)) { return_val = (NF_field_value.length > 0) ? 'true' : 'false'; } // inquiry type else if (field_key_str === 'inquiry_type' && ( NF_field_value === '' || NF_field_value === false)) { return_val = 'N/A'; } else { return_val = form_fields_by_key[field_key].value; } if (return_val === '' || return_val === null) { return_val = 'N/A'; } return return_val; }; /** * Bind a data layer event to form submit button * datalayer_infos is an array of objects which holds all datalayer fields for each form. Each object expects form_name, event_name, datalayer_fields * each object in datalayer_fields has two properties field_name and key * field_name : property name in the datalayer * key : ninja form label of the input field from where value has to be extracted */ function bind_form_data_layer_event() { const datalayer_ninjaforms_json = [ { form_identifier_class: 'datalayer-report-download', event_name: 'report_download_form', datalayer_fields: [ { field_name: 'industry', key: 'industry' }, { field_name: 'company', key: 'company' }, { field_name: 'jobTitle', key: 'job_title' }, { field_name: 'speakWithSalesCheckbox',key: 'speak_with_sales' }, { field_name: 'inquiryType', key: 'inquiry_type' }, { field_name: 'newsCheckbox', key: 'newsletter' }, { field_name: 'location', key: 'location' }, { field_name: 'campaignTag', key: 'campaigns_taxonomy_term' }, { field_name: 'reportFileName', key: 'form_attachment_1_url' }, { field_name: 'reportName', key: 'form_attachment_1_title' }, { field_name: 'pardotId', key: 'hidden_pardot_id' }, { field_name: 'salesforceId', key: 'custom_val_N/A' }, { field_name: 'websiteLeadId', key: 'custom_lead_id' }, { field_name: 'rememberMe', key: 'remember_me' }, ], }, { form_identifier_class: 'datalayer-contact-us', event_name: 'contact_us_form', datalayer_fields: [ { field_name: 'industry', key: 'industry' }, { field_name: 'company', key: 'company' }, { field_name: 'location', key: 'location' }, { field_name: 'areaOfInterest', key: 'area_of_interest' }, { field_name: 'inquiryType', key: 'inquiry_type' }, { field_name: 'newsCheckbox', key: 'newsletter' }, { field_name: 'pardotId', key: 'hidden_pardot_id' }, { field_name: 'salesforceId', key: 'custom_val_N/A' }, { field_name: 'websiteLeadId', key: 'custom_lead_id' }, { field_name: 'campaignTag', key: 'campaigns_taxonomy_term' }, ], }, { form_identifier_class: 'datalayer-newsletter', event_name: 'email_subscription_form', datalayer_fields: [ { field_name: 'newsletterName', key: 'custom_val_Newsletter' }, { field_name: 'pardotId', key: 'hidden_pardot_id' }, { field_name: 'salesforceId', key: 'custom_val_N/A' }, { field_name: 'websiteLeadId', key: 'custom_lead_id' }, ], } ]; nfRadio.channel('forms').on('submit:response', (form) => { //This is a fallback variable which contains all datalayer ninjafrom fields //in case the variable/js object in content_area is invalid or inaccesible. let errlog = form['errors']; if (Object.keys(errlog).length === 0) { const datalayer_infos = (typeof datalayer_ninjaform === 'undefined') ? datalayer_ninjaforms_json : datalayer_ninjaform; datalayer_infos.forEach((datalayer_info) => { if (form.data.settings.wrapper_class.toLowerCase().includes(datalayer_info.form_identifier_class.toLowerCase())) { //initialize event key and event value for datalayer object let data_layer_object = { 'event': datalayer_info.event_name, 'formName': form['data']['settings']['title'], 'formId': form['data']['form_id'], 'formtype': 'ninja form', }; let field_info = datalayer_info.datalayer_fields; //store all datalayer fields in an array field_info.forEach((field) => { let datalayer_field_key = field.field_name; // datalayer property name let datalayer_field_value; if (field.key.startsWith('custom_val')) { datalayer_field_value = field.key.substr(11); // extract the string after custom_val } else { let nf_key = field.key; // label of the ninjaform field datalayer_field_value = get_nf_field_value(form.data.fields_by_key, nf_key); // datalayer property value } data_layer_object[datalayer_field_key] = datalayer_field_value; }); if ( data_layer_object['event'].toString() === "contact_us_form" && data_layer_object['areaOfInterest'].toString() === "sales" && data_layer_object['inquiryType'].toString() === "false" ) { data_layer_object['inquiryType'] = get_nf_field_value(form.data.fields_by_key, ['sales_inquiry']).toLowerCase(); } window.dataLayer = window.dataLayer || []; window.dataLayer.push(data_layer_object); //close the form embeded in a gated pop-up let form_conatiner_modal = document.getElementById(`nf-form-${form['data']['form_id']}-cont`).closest('div[x-data]'); if (form_conatiner_modal === null || !(form_conatiner_modal.getAttribute('id').startsWith('modal'))) { return }; //for forms used independently or outside a pop-up block document.dispatchEvent(new CustomEvent(`${form_conatiner_modal.getAttribute('id')}`+'-gating',{bubbles : true})); //form cookie let rememberMe = get_nf_field_value(form.data.fields_by_key, 'remember_me'); if ( rememberMe === 'true') { document.cookie=`nlsn-pop-up|${form['data']['form_id']}=${form_conatiner_modal.getAttribute('id')}; max-age=604800`;//set cookie for 7 days } } }) } else { let data_layer_object = {}; let pardotId = get_nf_field_value(form.data.fields_by_key, ['hidden_pardot_id']); let websiteLeadId = get_nf_field_value(form.data.fields_by_key, ['hidden_lead_id']); data_layer_object['event'] = 'form_submit_failure' ; data_layer_object['formName'] = form['data']['settings']['title']; for(key in errlog) { var errobj = errlog[key]; for(var errkey in errobj) { var errmsg = errobj[errkey]; data_layer_object['failureReason'] = errmsg; } } data_layer_object['pardotID'] = pardotId ?? 'N/A'; data_layer_object['salesforceId'] = 'N/A'; data_layer_object['websiteLeadId'] = websiteLeadId; window.dataLayer = window.dataLayer || []; window.dataLayer.push(data_layer_object); } }) } jQuery(document).one('nfFormReady', () => { bind_form_data_layer_event(); }) /* * Ninjaform field on chanage datalayer triggers */ let formInfos = {}; let formInfoAggregator = Marionette.Object.extend({ initialize: function () { // stores the form id and form name after form intialization let formsChannel = Backbone.Radio.channel('forms'); this.listenTo(formsChannel, 'init:model', this.storeFormData); }, storeFormData: function (model) { let formID = model.get('id'); let formTitle = model.get('title'); let form_fields = model['attributes']['fields']['models']; let formLeadID = ""; for (let form_field of form_fields) { let field_key = form_field['attributes']['key']; if (field_key.startsWith('hidden_lead_id')) { formLeadID = form_field.attributes.value; break; } }; formInfos[formID] = { title: formTitle, leadID: formLeadID }; } }); let formStartDatalayerController = Marionette.Object.extend({ initialize: function () { // push datalayer when a field's value changes let fieldsChannel = Backbone.Radio.channel('fields'); this.listenTo(fieldsChannel, 'change:modelValue', this.dataLayerPush); }, dataLayerPush: function (model) { let fieldValue = model.get("value"); let fieldLabel = model.get('label'); let formInfo = formInfos[model.get('formID')]; if (formInfo) { let formName = "title" in formInfo ? formInfo['title'] : "no_title"; let formLeadID = "leadID" in formInfo ? formInfo['leadID'] : "no_lead_id"; if ( formName !== undefined && fieldLabel !== "" && fieldValue !== '' && model['attributes']['type'] !== 'hidden' ) { let dataLayerObj = { 'event': 'form_field_start', }; // define event name dataLayerObj['formName'] = formName; dataLayerObj['formFieldName'] = fieldLabel; dataLayerObj['pardotID'] = pardotId ?? 'N/A'; // should already be initialized at this point. present in wp_head hook dataLayerObj['salesforceId'] = 'N/A'; // should already be initialized at this point. present in wp_head hook window.dataLayer = window.dataLayer || []; let dataLayerEvents = window.dataLayer; let eventPresent = false; // avoid trigger form_field_start event more than once on the same form for (let dataLayerEvent of dataLayerEvents) { if (('event' in dataLayerEvent === true)) { if ( (dataLayerEvent['event'] === 'form_field_start') && (formName !== "no_title") && (dataLayerEvent['formName'] === formName) ) { eventPresent = true; } } } if (!eventPresent) { window.dataLayer.push(dataLayerObj); } } } }, }); jQuery(function () { new formInfoAggregator(); // some NF fields (default) values are populated during pageload using jQuery. A delay/timeout ensures that // form_start datalayer event doesn't trigger during these default field value assignment. setTimeout(function () { new formStartDatalayerController(); }, 1500); }); ; !function(e){"object"==typeof exports&&"undefined"!=typeof module||"function"!=typeof define||!define.amd?e():define("inert",e)}((function(){"use strict";var e,t,n,i,o,r,s=function(e,t,n){return t&&a(e.prototype,t),n&&a(e,n),e};function a(e,t){for(var n=0;na;)o(e,n=r[a++])&&(~u(p,n)||f(p,n));return p}},function(t,r,n){var e=n(10),o=n(55),i=n(57);n=function(t){return function(r,n,u){var c,f=e(r),a=i(f),p=o(u,a);if(t&&n!=n){for(;p"+t+""}var u,c=e(42),f=e(64),a=e(59),p=e(48),s=e(66),y=e(39),l=(e=e(47),"prototype"),v="script",b=e("IE_PROTO"),g=function(){try{u=new ActiveXObject("htmlfile")}catch(t){}var t;g="undefined"==typeof document||document.domain&&u?function(t){t.write(i("")),t.close();var r=t.parentWindow.Object;return t=null,r}(u):((t=y("iframe")).style.display="none",s.appendChild(t),t.src=String("javascript:"),(t=t.contentWindow.document).open(),t.write(i("document.F=Object")),t.close(),t.F);for(var r=a.length;r--;)delete g[l][a[r]];return g()};p[b]=!0,r.exports=Object.create||function(r,n){var e;return null!==r?(o[l]=c(r),e=new o,o[l]=null,e[b]=r):e=g(),n===t?e:f(e,n)}},function(t,r,n){var e=n(5),o=n(41),i=n(42),u=n(10),c=n(65);t.exports=e?Object.defineProperties:function(t,r){i(t);for(var n,e=u(r),f=c(r),a=f.length,p=0;p0&&!(s>=n[t-1].priority);t--);t===n.length?n[t]=l:n.splice(t,0,l),u.__current.forEach((n=>{n.name===o&&n.currentIndex>=t&&n.currentIndex++}))}else u[o]={handlers:[l],runs:0};"hookAdded"!==o&&n.doAction("hookAdded",o,i,c,s)}};var i=function(n,t,o=!1){return function(i,c){const s=n[t];if(!e(i))return;if(!o&&!r(c))return;if(!s[i])return 0;let u=0;if(o)u=s[i].handlers.length,s[i]={runs:s[i].runs,handlers:[]};else{const n=s[i].handlers;for(let t=n.length-1;t>=0;t--)n[t].namespace===c&&(n.splice(t,1),u++,s.__current.forEach((n=>{n.name===i&&n.currentIndex>=t&&n.currentIndex--})))}return"hookRemoved"!==i&&n.doAction("hookRemoved",i,c),u}};var c=function(n,t){return function(r,e){const o=n[t];return void 0!==e?r in o&&o[r].handlers.some((n=>n.namespace===e)):r in o}};var s=function(n,t,r=!1){return function(e,...o){const i=n[t];i[e]||(i[e]={handlers:[],runs:0}),i[e].runs++;const c=i[e].handlers;if(!c||!c.length)return r?o[0]:void 0;const s={name:e,currentIndex:0};for(i.__current.push(s);s.currentIndex