0

I'm using GTM to track submissions to an embedded Mailchimp form. Relevant post here: Tracking submissions on MailChimp embedded form

Per the original post answer, I am able to use this code to track form submissions.

$('form#mc-embedded-subscribe-form').submit(function(e) {
   dataLayer.push({'event':'formSubmit'});
   return true;
});

But right now, all clicks of the submit button are being tracked as form submissions, even if the form is not submitted. The answer included a tip to add e.preventDefault(); to prevent false form submissions from being tracked. Could someone tell me where I need to add preventDefault(), or if there's another method, how I can prevent false form submissions from being tracked.

I have tried inserting preventDefault() a number of places in the code, and have not gotten the desired result.

<!-- Begin Mailchimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/classic-10_7.css" rel="stylesheet" type="text/css">
<style type="text/css">
    #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
    /* Add your own Mailchimp form style overrides in your site stylesheet or in this style block.
       We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<div id="mc_embed_signup">
<form action="https://..." method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
    <div id="mc_embed_signup_scroll">
    <h2>Subscribe</h2>
<div class="indicates-required"><span class="asterisk">*</span> indicates required</div>
<div class="mc-field-group">
    <label for="mce-EMAIL">Email Address  <span class="asterisk">*</span>
</label>
    <input type="email" value="" name="EMAIL" class="required email" id="mce-EMAIL">
</div>
<div class="mc-field-group">
    <label for="mce-FNAME">First Name </label>
    <input type="text" value="" name="FNAME" class="" id="mce-FNAME">
</div>
<div class="mc-field-group">
    <label for="mce-LNAME">Last Name </label>
    <input type="text" value="" name="LNAME" class="" id="mce-LNAME">
</div>
    <div id="mce-responses" class="clear">
        <div class="response" id="mce-error-response" style="display:none"></div>
        <div class="response" id="mce-success-response" style="display:none"></div>
    </div>    <!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
    <div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_c46d540e26068777472a049e9_3aa4dd9218" tabindex="-1" value=""></div>
    <div class="clear"><input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button"></div>
    </div>
</form>
</div>
<script type='text/javascript' src='//s3.amazonaws.com/downloads.mailchimp.com/js/mc-validate.js'></script><script type='text/javascript'>(function($) {window.fnames = new Array(); window.ftypes = new Array();fnames[0]='EMAIL';ftypes[0]='email';fnames[1]='FNAME';ftypes[1]='text';fnames[2]='LNAME';ftypes[2]='text';...fnames[13]='PAGEURL';ftypes[13]='text';}(jQuery));var $mcj = jQuery.noConflict(true);$('form#mc-embedded-subscribe-form').submit(function(e){dataLayer.push({'event':'formSubmit'});return true;});</script>
<!--End mc_embed_signup-->
jbmn
  • 15
  • 4

2 Answers2

0

The e.preventDefault() function only stops the form from submitting, it does nothing to check for validation and without having anything after it, nothing will happen.

The e.preventDefault() solution mentioned helps you to stop the trigger from being run, and then allows you to validate the form inputs before you actually trigger the event in Google Tag Manager.

The validation of inputs depend on what inputs are required in your form, so this will have to vary based on each form you create. But you could use a generic function that checks all inputs with class 'required', like so:

// Get all required inputs
var requiredFields = document.querySelectorAll('input.required');

// Create function to validate inputs
function validateInputs(callback){

  // Set formstatus to valid
  var formOkay = true;

  // Check each field
  requiredFields.forEach(i => {

    // Check error state
    if ((i.value == "") || ((i.type === 'checkbox') && (i.checked == false))) {
      // Form was invalid
      console.log('Form was invalid');
      formOkay = false;
    }
  })
  
  // Return formStatus;
  callback(formOK ? true : false);
}

Now you can use this function to validate the form, before you send the Google Tag Manager trigger, like so:

document.getElementById('mc-embedded-subscribe-form').addEventListener('submit', e => {
  e.preventDefault();
  validateInputs( res => {
    // check res
    if (res == true){
      dataLayer.push({'event':'formSubmit'});
    }
  })
})

Note: This solution will check that the form inputs are valid, and not if the user was actually subscribed to the list. The best approach would be to subscribe the user, using ajax and then trigger the GTM-tag if the callback returns with status success.

0

I used a mutation observer to listen for changes to the div with the success message, which then could push an event to the dataLayer

// The element with success message
const successElement = document.getElementById('mce-success-response');

if(successElement){                   
    const mutationConfig = { attributes: true };

    const callback = function(mutationsList, observer) {
        for(const mutation of mutationsList) {
            if (mutation.type === 'attributes' 
                && mutation.attributeName == 'style'
                && successElement.style.display === '') {
                    window.dataLayer.push({
                    "event" : "my-super-hot-lead" 
                    })
            }
        }
    };

    const observer = new MutationObserver(callback);
    observer.observe(successElement, mutationConfig);
}