Skill Tracer
Skills › Marketing Skills › conversion-tracking › forminator.js

forminator.js

63 lines · skills/conversion-tracking/assets/snippets/forminator.js at 88c79f6

1/*! Forminator conversion detection (MIT)
2 * Detects: form submission. Pushes dataLayer event: forminator_form_submitted
3 * From the conversion-tracking skill in Marketing Skills */
4(function () {
5 if (window.__ctForminatorForms) return;
6 window.__ctForminatorForms = true;
7 window.dataLayer = window.dataLayer || [];
8 var listeners=[],lastEvent=null;
9 window.__ctForminatorSubscribe=function(listener){if(listener&&typeof listener==='object')listeners.push(listener);};
10 function isForm(form){
11 try{return !!(form&&String(form.tagName||'').toLowerCase()==='form'&&form.classList&&form.classList.contains('forminator-custom-form'));}
12 catch(e){return false;}
13 }
14 function notify(phase,form,candidate,event){
15 var handled=false;
16 for(var i=0;i<listeners.length;i++)try{var fn=listeners[i]&&listeners[i][phase];if(typeof fn==='function'&&fn(form,candidate,event)===true)handled=true;}catch(e){}
17 return handled;
18 }
19 function submit(event){try{var form=event.target;if(isForm(form))notify('beforeAttempt',form,false,event);}catch(e){}}
20 function success(event){
21 try{
22 if(event&&typeof event==='object'&&event===lastEvent)return;
23 lastEvent=event;
24 if(event&&typeof event==='object')setTimeout(function(){if(lastEvent===event)lastEvent=null;},0);
25 var form=event&&event.target;if(!isForm(form))return;
26 if(!notify('onCandidate',form,true,event))window.dataLayer.push({event:'forminator_form_submitted',form_id:form.getAttribute('data-form-id')||''});
27 }catch(e){}
28 }
29 document.addEventListener('submit',submit,true);
30 // Page-reload forms render their verdict in the returned page instead of
31 // emitting the AJAX event. Read only the confirmation class and form ID.
32 var confirmedForms=[];
33 function nativeConfirmations(){
34 try{
35 var forms=document.querySelectorAll('form.forminator-custom-form:not(.forminator_ajax)');
36 for(var i=0;i<forms.length;i++){
37 var form=forms[i],message=form.querySelector('.forminator-response-message.forminator-success');
38 if(!message||!message.getClientRects().length||confirmedForms.indexOf(form)!==-1)continue;
39 confirmedForms.push(form);
40 success({target:form});
41 }
42 }catch(e){}
43 }
44 function watchNative(){
45 nativeConfirmations();
46 if(window.MutationObserver&&document.documentElement){
47 new MutationObserver(nativeConfirmations).observe(document.documentElement,{childList:true,subtree:true,attributes:true,attributeFilter:['class','style']});
48 }
49 }
50 if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',watchNative);
51 else watchNative();
52 window.addEventListener('load',nativeConfirmations);
53 function hook(){
54 try{
55 if(window.__ctForminatorSuccessHooked)return true;
56 var jq=window.jQuery||(typeof jQuery!=='undefined'?jQuery:(typeof $!=='undefined'?$:null));
57 if(!jq)return false;
58 window.__ctForminatorSuccessHooked=true;
59 jq(document).on('forminator:form:submit:success',success);return true;
60 }catch(e){return false;}
61 }
62 if(!hook()){document.addEventListener('DOMContentLoaded',hook);window.addEventListener('load',hook);}
63})();