Trazar envíos correctos e incorrectos de formularios con Google Tag Manager (GTM)

¿Qué tal funcionan tus formularios de contacto? ¿Se envían de forma correcta? ¿Cuántas veces fallan tus usuarios antes de enviar los formularios bien? He trabajado en muchos proyectos de implementación de analítica en ‘sites’ orientados a la generación de ‘leads’ (envíos de formularios de contacto). Algunos de estos ‘sites’ tenían una cierta analítica desarrollada ya. Muchos basaban el ‘tracking’ de sus formularios de contacto en clics sobre el botón de enviar.

Esto no basta. Un usuario puede rellenar mal un formulario y hacer clic en ‘Enviar’. Puede hacer clic en este botón y ni siquiera haber rellenado el formulario. Bajo mi punto de vista es fundamental diferenciar entre envíos correctos e incorrectos de formularios.

En este post te voy a enseñar una forma muy sencilla de conseguir esto a través de Google Tag Manager (GTM). La clave está en trabajar con el método checkValidity() que habilita la Constraint Validation API

El método checkValidity() y los formularios de contacto

checkValidity() es un método de validación de elementos del DOM (de formularios). Si el formulario está validado, el método checkValidity() devuelve true, de lo contrario devuelve false. El objetivo es hacer una validación en cliente (en el navegador) antes de enviar los datos del formulario de contacto al servidor. Cuando un formulario está validado, no se puede enviar hasta que esté bien rellenado

¿Cómo puedes saber si un formulario está validado? Lo normal es que a día de hoy todos lo estén. Pero si quieres salir de dudas, puedes hacerlo de varias formas. En mi opinión lo más sencillo es usar la consola de tu navegador para alojar el formulario en una variable, y luego aplicar el método checkValidity(). Si el método método devuelve true o false, enhorabuena, ¡el formulario está validado! También puedes usar este método con cualquiera de los elementos del formulario (siempre y cuando estén validados también).

Fíjate, puedes realizar la prueba tú mismo con el siguiente formulario (validado) que he creado para este post (los datos no se envían a ningún servidor – es un formulario ‘dummy’):







Y aquí el código que tienes que ejecutar en la consola de depuración e tu navegador:

let formulario = document.querySelector('form#formularioPrueba');
formulario.checkValidity()

Aprovechar el método checkValidity() desde Google Tag Manager (GTM) para un tracking fiable y robusto

Cuando un navegador renderiza un documento html, pasa a interpretarlo como un objeto: el DOM (Document Object Model por siglas en inglés) Con Google Tag Manager puedes trabajar con el DOM y explotar todas sus propiedades, métodos… y nodos, como por ejemplo los formularios de contacto. La fórmula que te propongo en este post sigue esta senda y se basa en el desarrollo que el gran Simo Ahava propone en su post: ‘Simple Custom Event Listeners with Google Tag Manager’. Se trata de localizar los nodos del DOM con los que quieres trabajar (los formularios), guardarlos en una variable y usar el método addEventListener() para ‘escuchar’ una determinada interacción. Todo ello condicionado a que el formulario esté validado, o no.

Acometer esto con GTM es sencillo, necesitarás: 

  • Un tag de tipo HTML personalizado (’Custom HTML tag’) para alojar el formulario en una variable y añadir un addEventListener()
  • Una variable ‘Custom JavaScript’ que se encargue de comprobar si el formulario está validado, o no, y empujar al dataLayer (vía un dataLayer.push()) unos parámetros u otros de forma conecuente.

Puesto que lo que estás haciendo es un pequeño desarrollo en JavaScript, es importante que sepas que GTM sólo soporta ECMASCRIPT 5 (ES5) al trabajar con tags de tipo HTML personalizado y variables de tipo ‘Custom JavaScript’. Sin embargo, sí puedes usar ECMASCRIPT 6 (ES6) si estás desarrollando un ‘custom template‘ (un tag, una variable o un cliente en el caso de los contenedores de GTM server-side)

CHTML tag: guarda el formulario en una variable y establece el método addEventListener()

Bien, este el código que debes usar en tu tag de tipo HTML Personalizado: 
<script>
  
(function () {
  
 //The form to be tracked is saved in a locally scoped variable
 var formulario = document.querySelector('form#formularioPrueba');
 //The Custom JavaScript variable to act as the event handler is also saved in a locally scoped variable
 var formSubmitHandler = {{CJS - formSubmitHandler}};
 
 //If the form is present in the DOM, attach an eventListener to it
 if(formulario){

  formulario.addEventListener('click', formSubmitHandler, true);
  
 }
 
})();
  
</script>  

-En la línea 6 se localiza el formulario de contacto que quieres trazar usando el método querySelector()  y se aloja en una variable. Este método permite usar diferentes selectores CSS. Yo he usado un ID (basándome en el formulario de prueba de antes), pero puedes usar el que más te convenga, como por ejemplo un atributo o una clase.

-A continuación añado el método addEventListener() a la variable. Este método requiere dos argumentos obligados: el tipo de evento que quieres ‘escuchar’ (‘click’ ya que queremos escuchar clics en el botón ‘Enviar’) y la función que ejecutará la lógica (alojada en la variable ‘Custom JavaScript’ que se detalla más adelante) Se pueden añadir más argumentos que son opcionales. En este caso he añadido el argumento useCapture. Al estar su valor ‘seteado en true el evento de tipo clic se ejecutará en el capturing phase de dicho evento (te recomiendo que leas la entrada ‘Bubbling and capturing’, de javascript.info)

-Ahora fíjate en el if () statement. Verás que el eventListener sólo se añade si el formulario está presente en la página. Esto es así porque si añades un eventListener a un elemento que no está presente en el DOM empezarás a ver alertas en la consola JavaScript de tu navegador. Si lo prefieres, puedes obviar este enfoque y añadir un trigger a este ‘CHTML Tag’ para que se ejecute sólo en las páginas en las que sabes que hay un formulario de contacto. En mi opinión es más óptimo hacerlo así.

La variable ‘Custom JavaScript’ se encarga de ejecutar la lógica de la función del método addEventListener()

El segundo argumento de un eventListener es siempre la función que se encarga de ejecutar la lógica de dicho listener. Bien, siguiendo la senda de lo que propone Simo en el post al que enlazo antes, a mi siempre me gusta alojar esta función en una variable (de tipo JavaScript personalizado) a la cual llamar desde el anterior script. Yo lo hago por una cuestión de higiene de código, pero si lo prefieres puedes desarrollar esta función en el propio CHTML tag. 

Lo hagas como lo hagas, la función que te propongo es la siguiente (en este caso, la Custom JavaScript Variable devuelve una función):

function(){

  return function(event){
    //The timeout value in mls is stored in a locally scoped variable
    var timeout = 200;
    //The dataLayer aray is stored in a locally scoped variable
    var dataLayer = window.dataLayer || [];
    
    try{
    
      window.setTimeout(function(){
        //If a click event is emited by the submit button
        if(event.target.id === 'submit'){
          //Check if the form is validated and perform a dataLayer.push with this info
          if(event.target.parentElement.checkValidity() === true){
            
            dataLayer.push({
           'event':'successful form submit'
            })
            
          }
          //If the form is not validated perform a dataLayer.push with this other info
          else{
          
            dataLayer.push({
           'event':'unsuccessful form submit'
              
            })
                    
          }
        
        }
          
      }, timeout);
    }
    catch(error){}
  
  }

}

Cosas a resaltar: 

-El eventListener está añadido al formulario, pero a través de event delegation puedes ‘escuchar’ eventos de tipo ‘click’ en cualquiera de los elementos que hay dentro del form. En este caso, a través de la propiedad event.target.id escuchamos sólo clics en en el botón ‘Enviar’.

La clave de esta implementación viene a continuación. Fíjate en el if()  statement. Si el método checkValidity() devuelve true (es decir, si el formulario está rellenado de forma correcta), se ejecuta un dataLayer.push() para empujar unos valores determinados al dataLayer. Si checkValidity() devuelve false (porque el formulario no está bien cumplimentado) se ‘empujan’ al dataLayer otros valores. ¿Lo ves? A través del método checkValidity() puedes lograr un ‘tracking’ de envíos de formulario sólido que te permite diferenciar entre envíos correctos e incorrectos de formularios. Despídete para siempre de sólo trazar clics en el botón de enviar. 

-Toda la función está wrapped (envuelta) dentro del método setTimeOut() (un método del objeto Window). Esto te va a permitir retrasar el envío del formulario de contacto las milésimas de segundo que tu script necesite para comprobar si el formulario está, en efecto, bien relleno o no. Ha habido proyectos en los que no he necesitado hacer uso de este método, pero en otros casos sí (el formulario se enviaba antes de que GTM pudiese comprobar si estaba bien o mal rellenado). Suelo incluirlo siempre por precaución, aunque desde el punto de vista del rendimiento no es la mejor opción. 

El CHTML tag que contiene el formulario y le asigna un addEventListener() se ejecuta en el evento gtm.js
El formulario de contacto está mal cumplimentado. Se hace clic en 'Submit' y el método checkValidity() devuelve false. Se empuja un objeto al dataLayer con esta información.
El formulario está bien cumplimentado y se hace clic en 'Submit'. El método checkValidity() se resuelve a true y se empuja un objeto al dataLayer con esta información.

Reflexiones finales

Como te decía al principio de este post, con Google Tag Manager es muy fácil trabajar con el DOM. Es más, haciendo uso de las propiedades y métodos del DOM puedes exprimir al máximo el potencial de GTM. El desarrollo que te he detallado es uno de estos casos.

No obstante, si cuentas con el soporte de un equipo de Desarrollo, quizá sea más fácil que ellos hagan uso del método checkValidity() del formulario de contacto para empujar un evento u otro al dataLayer (form success y form error, por ejemplo). Así las cosas, sólo tendrías que aprovechar dichos eventos para articular tu ‘tracking’ desde GTM.

¿Qué opción es mejor? ¿Hacer el desarrollo de analítica en Google Tag Manager o solicitar este desarrollo a tu equipo DES? Pregunta difícil, cada opción tiene sus pros y sus contras. 

pornance.net
www.fuck-videos.net
zettaporn.com