ePrivacy and GPDR Cookie Consent by Cookie Consent Skip to main content

How to track contact forms from the website

It may be handy to maintain common structure for contact form events through multiple places (eg. on multiple microsites created by different developer teams, for randomly generated input names without common semantics). Having a consistent structure will help analysts and will quicken the next steps of working with the collected data. 

How to track

 contact form

Prerequisite:Warning: Prerequisite is Meiro Event SDK must be deployed on the website

To track contact form you need to implement following MeiroEvents method call:

if (MeiroEvents && typeof MeiroEvents.track === "function") {
  MeiroEvents.track("contactFormSubmit", {
    form_id: "unique_form_id",
    email: "john@doe.com",
    first_name: "John",
    last_name: "Doe",
    phone_number: "00420604334554",
    national_id: "CZ",
    gender: "male",
    birthdate: "10-10-1934",
    whatsapp: "@strictacular",
    instagram: "spectator",
    facebook: "JohnDoe1943",
    linkedin: "JohnDoe-49456780",
    internal_user_id: "09FDAS0930",
    external_id: "094309F09SD09",
    field00: true,
    ...
    field30: ["car", "bicycle"]
  })
}

You are free to add .then() or .catch() functions (track function returns javascript Promise).

Validation

The event payload must pass strict Meiro Events SDK validation, otherwise, it will be rejected.

The rules are the following:

form_id: ["required", "string", "minLength1"],
email: ["string", "optional"],
first_name: ["string", "optional"],
last_name: ["string", "optional"],
phone_number: ["string", "optional"],
national_id: ["string", "optional"],
gender: ["string", "optional"],
birthdate: ["string", "optional"],
whatsapp: ["string", "optional"],
instagram: ["string", "optional"],
facebook: ["string", "optional"],
linkedin: ["string", "optional"],
internal_user_id: ["string", "optional"],
external_id: ["string", "optional"],
field00: optional scalar value (null, string, number, boolean) or array of scalar values,
...
field30: optional scalar value (null, string, number, boolean) or array of scalar values

 

Warning: The event will be rejected if you send it with payload:

-Without filled string
form_id. form_id should be a unique and understandable name of the form that will help to separate this from the others set on the website.
-With field violating validation rule (eg. gender with number value).
-With additional unknown fields.

If you are not able to send the event successfully, add a  .catch() function to check the validation error. 

MeiroEvents.track("contactFormSubmit", {
  email: "john@doe.com",
  first_name: "John",
  last_name: "Doe",
  phone_number: "00420604334554",
  national_id: "CZ",
  gender: "male",
  birthdate: "10-10-1934,
  whatsapp: "@strictacular",
  instagram: "spectator",
  facebook: "JohnDoe1943",
  linkedin: "JohnDoe-49456780",
  internal_user_id: "09FDAS0930",
  external_id: "094309F09SD09"
}).catch(err => {
  console.log(err.name); // ValidationError
  console.log(err.message); // The field form_id must be present in event payload.
})

FullExample: full Code Vanilla JS example

Consider the following form to submit asynchronously:

<form id="contact-form">
  <div class="form-row">
    <label for="name">Name:</label>
    <input name="name" type="text" required />
  </div>
  <div class="form-row">
    <div><label for="gender">Gender:</label></div>
    <input type="radio" name="gender" value="male" checked /> Male<br />
    <input type="radio" name="gender" value="female" /> Female<br />
    <input type="radio" name="gender" value="other" /> Other
  </div>
  <div class="form-row">
    <div><label>Vehicles:</label></div>
    <input type="checkbox" name="vehicle1" value="Bike" /> I have a bike<br />
    <input type="checkbox" name="vehicle2" value="Car" /> I have a car
  </div>

  <button type="submit">Submit</button>
</form>

Then the javascript code can be following (placed inside the bottom of the <body> element):

<script>
  function contactFormSubmit(evt) {
    // I want to submit form asynchronously
    evt.preventDefault();
    // I don't want to propagate submit event, because I have automatic form tracking enabled
    evt.stopPropagation();

    var form = evt.target || evt.srcElement;
    var elements = form.elements;
    var payload = {
      form_id: "contact_form",
      field00: []
    };
    for (var i = 0; i < elements.length; i++) {
      var elem = elements[i];
      switch (elem.name) {
        case "name": {
          payload["first_name"] = elem.value;
          break;
        }
        case "gender": {
          if (elem.checked) {
            payload["gender"] = elem.value;
          }
          break;
        }
        case "vehicle1": {
          if (elem.checked) {
            payload["field00"].push(elem.value);
          }
          break;
        }
        case "vehicle2": {
          if (elem.checked) {
            payload["field00"].push(elem.value);
          }
          break;
        }
        default:
          break;
      }
    }

    MeiroEvents.track("contactFormSubmit", payload);

    // submit form asynchronously (in case you are changing location after form submission,
    // it's better to place it into .then() and .catch() tracker functions to prevent event loss)
    fetch("https://api.example.com", {
      headers: { "Content-Type": "application/json; charset=utf-8" },
      method: "POST",
      body: JSON.stringify(payload),
      credentials: "include"
    }).then(res => {
      if (!res.ok) {
        throw new Error("API could not process the request.");
      } else {
        alert("Form was sucessfully sent!");
      }
    });
  }
  
  // form submit listenner
  document
    .getElementById("contact-form")
    .addEventListener("submit", contactFormSubmit, false);
</script>

There are multiple ways of obtaining input values (eg. tagging inputs with unique ids and getting them via document.getElementById, using JQuery selectors). Therefore it’s not required to write the exact same code, it depends on the current form code, situation, and used technologies.

Internal_user_id and external_user_id

Both do not have specific treatment fields that can be filled.

They are there to keep a structure in place for data possible to collect through SDK.

Internal_user_ID refers to the user Id one gets once login to an application, anything client owns, runs or develops.

External ID refers to any ID one wish to match with the Meiro events cookie.

For example, an external Google Analytics Id to connect with  ME internal ID that can be connected together through the matching table. 

 

 

HowEvent to prevent Meiro Events contact form submit event being cancelledcancellation

If you’re tracking form which submission is followed by an immediate redirect to another page,page (page transition), you may possibly face a problem with the cancelled event for contact form submit. 

This should not occur for forms sent asynchronously (ajax, single-page applications, …).

To check if this occurs, please go to the Inspect console in your browser, slow your internet connection and check the results:

slow-internet.png

To fix this problem:

  1. Prevent origin form submission event.
  2. Send Meiro Events’ contact form submit an event and wait for its success/error response.
  3. Make form submission right after the previous step.

Warning: Remember you should not set two different tracking methods on the same page as an event likely will be tracked twice. Choose the one that is the most suitable for your use case.

Implementation differs based on website implementation. Please, see an example for commonly used  jQuery:

 <form id="form-survey">
 <div class="form-row">
   <label for="email">Email</label>
   <input
     type="email"
     name="email"
     placeholder="Enter the email address"
     required
   />
 </div>
 <div class="form-row">
   <button type="submit" id="form-survey-submit">Submit</button>
 </div>
</form>
<script>
 (function ($) {
   $("#form-survey").on("submit", function (evt, options) {
     options = options || {};
     if (!options.event_sent && typeof MeiroEvents === "object") {
       evt.preventDefault();
       MeiroEvents.track("contactFormSubmit", { payload })
         .then(function () {
           $(evt.currentTarget).trigger("submit", { event_sent: true });
         })
         .catch(function () {
           // submit also if Meiro Events tracking call fails!
           $(evt.currentTarget).trigger("submit", { event_sent: true });
         })
     }
   });
 })(jQuery);
</script>