{"version":3,"file":"assets/dist/js/Forms.js","mappings":"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","sources":["webpack://wdgdc/gtm-analytics/./assets/js/forms/_form-type.js","webpack://wdgdc/gtm-analytics/./assets/js/Forms.js","webpack://wdgdc/gtm-analytics/./assets/js/forms/_form-starts.js","webpack://wdgdc/gtm-analytics/./assets/js/forms/_form-fails.js"],"sourcesContent":["/**\n * Identifies the type of a form.\n * Checks for specific classes, attributes, or IDs to determine the form type.\n * @param {HTMLFormElement} form - The form element to identify.\n * @returns {string} The type of the form.\n */\nfunction getFormType(form) {\n\tif (form.classList.contains('gform_wrapper')) {\n\t\treturn 'gravity-forms';\n\t} if (form.classList.contains('hs-form')) {\n\t\treturn 'hubspot';\n\t} if (form.id === 'loginform' || form.id === 'wp-login-form') {\n\t\treturn 'log-in';\n\t} if (form.classList.contains('search-form') || form.querySelector('input[type=\"search\"]')) {\n\t\treturn 'search';\n\t}\n\treturn 'other';\n}\n\nexport default getFormType;\n","/**\n * Import custom GTM scripts here.\n *\n * @see {@link ./forms}\n */\nimport formStarts from './forms/_form-starts.js';\nimport formFails from './forms/_form-fails.js';\n\ndocument.addEventListener('DOMContentLoaded', () => {\n\tformStarts();\n\tformFails();\n});\n","import getFormType from './_form-type.js';\n\n/**\n * GTM form interaction handling.\n */\nexport default function formStarts() {\n\tconst interactedForms = new Set(); // To keep track of forms that have been interacted with\n\n\t/**\n\t * Handles interactions with form elements and pushes data to the dataLayer.\n\t * Adds special support for Gravity Forms.\n\t *\n\t * @param {Event} event - The DOM event triggered by interacting with a form element.\n\t */\n\tconst handleInteraction = (event) => {\n\t  const { form } = event.target;\n\t  if (!form) return; // Exit if the event target is not part of a form\n\n\t  const formIdOrName = form.id || form.name; // Use ID or name as the identifier\n\n\t  // Check if this form has already been interacted with\n\t  if (interactedForms.has(formIdOrName)) return;\n\n\t  // Mark this form as interacted\n\t  interactedForms.add(formIdOrName);\n\n\t  const formLocation = window.location.href; // Current URL\n\t  const formElement = event.target.name || 'Unnamed Element'; // Name of the form element, if available\n\t  let formName = form.name || form.id || 'Unnamed Form'; // Use name or id, fallback to 'Unnamed Form'\n\n\t  // Special handling for Gravity Forms\n\t  if (form.classList.contains('gform_wrapper')) {\n\t\t\tconst titleElement = form.querySelector('.gform_title');\n\t\t\tif (titleElement) {\n\t\t  formName = titleElement.textContent || titleElement.innerText;\n\t\t\t}\n\t  }\n\t  window.dataLayer = window.dataLayer || [];\n\t  window.dataLayer.push({\n\t\t\tevent: 'form_start',\n\t\t\tform_location: formLocation,\n\t\t\tform_element: formElement,\n\t\t\tform_name: formName,\n\t\t\tform_type: getFormType(form)\n\t  });\n\t};\n\n\t// Get all forms on the page\n\tconst forms = document.querySelectorAll('form');\n\n\t// Attach a single event listener to each form\n\tforms.forEach((form) => {\n\t  form.addEventListener('input', handleInteraction); // for text inputs, textareas\n\t  form.addEventListener('change', handleInteraction); // for selects, radio buttons, checkboxes\n\t});\n}\n","import getFormType from './_form-type.js';\n\n/**\n * GTM form validation with support for Gravity Forms. Checks forms for validation errors on page load\n * and upon form submission, pushing errors to the dataLayer for GTM tracking.\n * @exports\n */\nexport default function formFails() {\n\t/**\n\t* Retrieves a form's name, falling back to the Gravity Forms title if present, or a default name.\n\t* @param {HTMLFormElement} form - The form to retrieve the name for.\n\t* @returns {string} The name of the form.\n\t*/\n\tconst getFormName = (form) => {\n\t\tif (form.closest('.gform_wrapper')) {\n\t\t\tconst titleElement = form.querySelector('.gform_title');\n\t\t\treturn titleElement ? titleElement.textContent.trim() : form.name || form.id || 'Unnamed Form';\n\t\t}\n\t\treturn form.name || form.id || 'Unnamed Form';\n\t};\n\n\t/**\n\t* Collects all validation error messages from a form and returns them in an array.\n\t* @param {HTMLFormElement} form - The form element to check for validation errors.\n\t* @returns {string[]} An array of validation error messages.\n\t*/\n\tfunction getGformErrors(form) {\n\t\t// Array to hold error messages\n\t\tconst errorMessages = [];\n\n\t\t// Select all elements with validation errors\n\t\t// For Gravity Forms, error messages are often indicated by '.gfield_error' class\n\t\t// Adjust the selector according to your form's error message structure\n\t\tconst errorElements = form.querySelectorAll('.validation_message');\n\n\t\t// Iterate over error elements and extract messages\n\t\terrorElements.forEach((element) => {\n\t\t\t// Assuming the error message is the text content of the error element\n\t\t\t// Adjust this line if the structure of your error messages is different\n\t\t\tconst errorMessage = element.textContent.trim();\n\t\t\tif (errorMessage) {\n\t\t\t\tconst label = element.parentElement.querySelector('label')?.textContent;\n\t\t\t\tconst legend = element.parentElement.querySelector('legend')?.textContent;\n\t\t\t\terrorMessages.push({ field: legend || label, message: errorMessage });\n\t\t\t}\n\t\t});\n\n\t\treturn errorMessages;\n\t}\n\n\t/**\n\t* Collects all HTML5 validation error messages from a form and returns them in an array.\n\t* @param {HTMLFormElement} form - The form element to check for HTML5 validation errors.\n\t* @returns {string[]} An array of HTML5 validation error messages.\n\t*/\n\tfunction getHTML5FormErrors(form) {\n\t\t// Array to hold error messages\n\t\tconst errorMessages = [];\n\n\t\t// Iterate over each form element\n\t\tfor (const element of form.elements) {\n\t\t\t// Check if the element will validate and if it is currently invalid\n\t\t\tif (element.willValidate && !element.validity.valid) {\n\t\t\t\t// Add the validation message to the array\n\t\t\t\terrorMessages.push({ field: element.name, message: element.validationMessage });\n\t\t\t}\n\t\t}\n\n\t\treturn errorMessages;\n\t}\n\n\t/**\n\t* Pushes form errors to the dataLayer based on a form element.\n\t* @param {HTMLFormElement} form - The form element to be checked for errors.\n\t*/\n\tconst pushToDataLayer = (form) => {\n\t\tconsole.log('errors');\n\t\tconst isGform = form.closest('.gform_wrapper');\n\t\tconst formLocation = window.location.href; // Current URL\n\t\tconst formElement = form.name || 'Unnamed Element'; // Name of the form element, if available\n\t\tconst formName = getFormName(form);\n\t\twindow.dataLayer = window.dataLayer || [];\n\t\twindow.dataLayer.push({\n\t\t\tevent: 'form_fails',\n\t\t\tform_name: formName,\n\t\t\tform_location: formLocation,\n\t\t\tform_element: formElement,\n\t\t\tform_errors: isGform ? getGformErrors(form) : getHTML5FormErrors(form),\n\t\t\tform_type: getFormType(form),\n\t\t});\n\t};\n\n\t/**\n\t* Checks for Gravity Forms-specific validation errors and pushes them to the dataLayer if any are found.\n\t* @param {HTMLFormElement} form - The form element to be checked for Gravity Forms-specific validation errors.\n\t*/\n\tconst checkGravityFormsErrors = (form) => {\n\t\t// Check for Gravity Forms specific validation errors\n\t\tconst gravityErrors = form.querySelectorAll('.gfield_error');\n\t\tif (gravityErrors.length > 0) {\n\t\t\tpushToDataLayer(form);\n\t\t}\n\t};\n\n\t/**\n\t* Handles the form submission event. It differentiates between Gravity Forms and non-Gravity Forms,\n\t* applying appropriate validation checking.\n\t* @param {Event} event - The form submission event.\n\t*/\n\tconst handleSubmit = (event) => {\n\t\tconst form = event.target;\n\t\tif (!form.closest('.gform_wrapper')) {\n\t\t\t// For non-Gravity Forms, use HTML5 form validation\n\t\t\tpushToDataLayer(form);\n\t\t}\n\t};\n\n\t/**\n\t* Attaches a listener for the Gravity Forms 'gform_post_render' event to check for validation errors\n\t* on AJAX form submissions.\n\t*/\n\tjQuery(document).on('gform_post_render', (event, formId, currentPage) => {\n\t\tconst form = document.getElementById(`gform_${formId}`);\n\t\tcheckGravityFormsErrors(form);\n\t});\n\n\t/**\n\t* Attaches the submit event listener to each form on the page for handling form submissions.\n\t*/\n\tconst forms = document.querySelectorAll('form');\n\tforms.forEach((form) => {\n\t\tform.addEventListener('submit', handleSubmit);\n\t});\n}\n"],"names":["form","classList","contains","id","querySelector","document","addEventListener","interactedForms","Set","handleInteraction","event","target","formIdOrName","name","has","add","formLocation","window","location","href","formElement","formName","titleElement","textContent","innerText","dataLayer","push","form_location","form_element","form_name","form_type","getFormType","querySelectorAll","forEach","formStarts","getGformErrors","errorMessages","element","errorMessage","trim","label","parentElement","legend","field","message","getHTML5FormErrors","elements","willValidate","validity","valid","validationMessage","pushToDataLayer","console","log","isGform","closest","getFormName","form_errors","handleSubmit","jQuery","on","formId","currentPage","getElementById","length","formFails"],"sourceRoot":""}