@rtstic.dev/pulse 0.0.47 → 0.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/form/index.js +2 -2
- package/package.json +1 -1
package/dist/form/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";(()=>{var M=Object.create;var
|
|
2
|
-
e.g. <script src="https://cdn.jsdelivr.net/npm/intl-tel-input@25/build/js/intlTelInput.min.js"><\/script>`),s)}function v(d,t){try{let e=d.getSelectedCountryData?.();if(!e?.dialCode)return;document.querySelectorAll(t).forEach(r=>{r.value=`+${e.dialCode}`})}catch{}}function F(d){return d.closest("[pulse-form-block]")?.getAttribute("pulse-field-name")??"unknown"}var E=window.location.host==="influur-staging.webflow.io";function o(d,...t){E&&console.log(`%c[MSF:${d}]`,"color:#6cf;font-weight:bold",...t)}function p(d,...t){E&&console.warn(`[MSF:${d}]`,...t)}function h(d,...t){E&&console.error(`[MSF:${d}]`,...t)}function g(d){E&&console.group(`%c[MSF] ${d}`,"color:#6cf;font-weight:bold")}function f(){E&&console.groupEnd()}var C={1:[{selector:'[data-action="back"]',property:"display",value:"none"},{selector:'[pricing-form-element="progress-fill"]',property:"width",value:"50%"}],2:[{selector:'[data-action="back"]',property:"display",value:"flex"},{selector:'[pricing-form-element="progress-fill"]',property:"width",value:"100%"}]},A=[{type:"company_type",name:"Record Label / Music Distributor","calender-name":"valeria","embed-url":"https://meetings.hubspot.com/valeria-angelini/pulse-valeria-and-alessandra?embed=true"},{type:"industry",name:"Financial Services","calender-name":"david","embed-url":"https://meetings.hubspot.com/david-zarate2?embed=true"},{type:"industry",name:"Sports","calender-name":"steven","embed-url":"https://meetings.hubspot.com/steven-campos?embed=true"},{type:"industry",name:"Beauty","calender-name":"albany","embed-url":"https://meetings.hubspot.com/david-zarate2?embed=true"},{type:"industry",name:"Music","calender-name":"steven","embed-url":"https://meetings.hubspot.com/steven-campos?embed=true"},{type:"industry",name:"Customer Packaged Goods","calender-name":"david","embed-url":"https://meetings.hubspot.com/david-zarate2?embed=true"},{type:"industry",name:"Other","calender-name":"david","embed-url":"https://meetings.hubspot.com/david-zarate2?embed=true"}],L={required:"This field is required",email_invalid:"Please enter a valid email address",email_company:"Please use your company email address",phone_invalid:"Please enter a valid phone number",selection_required:"Please select at least one option",legal_required:"You must accept this to continue"},N={"pulse-demo":["pulse-demo-only","common-fields"],"white-glove-services":["white-glove-only","common-fields"]},O={1:{heading:"Your info",subheading:"Pulse is launching March 2025. Spots for onboarding cohort 1 are limited.",counter:"Step 1/2"},2:{heading:"Personalize",subheading:"Help us personalize your demo.",counter:"Step 2/2"}},S=class{constructor(t,e){this.currentStepIndex=0;this.stepHasBeenValidated=!1;this.originalRequired=new WeakMap;this.fieldState=new Map;this.form=t,this.itiInstances=e,g("Constructor"),this.steps=Array.from(t.querySelectorAll('[data-msf="step"]')),o("init",`Found ${this.steps.length} steps`),this.steps.length===0&&h("init","No steps found! Check [data-msf='step'] selectors in HTML."),this.steps.forEach((r,n)=>{let i=r.dataset.step;i?o("init",`Step ${n}: data-step="${i}"`):p("init",`Step element at index ${n} is missing data-step attribute`)}),o("init",`ITI instances count: ${e.size}`),this.bindEvents(),this.cacheOriginalRequiredState(),this.initializeFieldState(),this.showStep(0),this.applyFlowConditions(),this.syncAllFieldState(),o("init","Field state after full init:",this.getFormStateJSON()),f()}bindEvents(){o("bindEvents","Attaching all event listeners"),this.form.addEventListener("click",t=>{let e=t.target;if(!e)return;let r=e.closest("[data-action]");if(!r)return;let n=r.dataset.action;o("click",`Action button clicked: "${n}"`),n==="next"&&(t.preventDefault(),this.next()),n==="back"&&(t.preventDefault(),this.back())}),this.form.addEventListener("submit",t=>{t.preventDefault(),p("submit","Native form submit intercepted and prevented")}),this.form.addEventListener("input",t=>{let e=t.target;e&&(!(e instanceof HTMLInputElement)&&!(e instanceof HTMLTextAreaElement)&&!(e instanceof HTMLSelectElement)||this.handleLiveValidation())}),this.itiInstances.forEach((t,e)=>{e.addEventListener("countrychange",()=>{o("countrychange",`Country changed on field: "${e.name}"`),this.stepHasBeenValidated&&this.handleLiveValidation()})}),this.form.addEventListener("change",t=>{let e=t.target;e&&e instanceof HTMLInputElement&&e.type==="radio"&&e.name==="flow-type"&&(o("flowChange",`Flow type changed to: "${e.value}"`),this.applyFlowConditions())}),this.form.addEventListener("input",t=>{let e=t.target;if(!e)return;let r=e.closest("[data-field-key]");if(!r)return;let n=r.dataset.fieldKey;n&&this.updateFieldState(n)}),this.form.addEventListener("change",t=>{let e=t.target;if(!e)return;let r=e.closest("[data-field-key]");if(!r)return;let n=r.dataset.fieldKey;n&&this.updateFieldState(n)})}handleLiveValidation(){if(!this.stepHasBeenValidated)return;o("liveValidation",`Running on step ${this.currentStepIndex}`);let t=this.validateStep(this.currentStepIndex);this.clearErrors(),Object.keys(t).length>0?(o("liveValidation","Errors still present:",t),this.showErrors(t)):o("liveValidation","All errors cleared")}showStep(t){if(o("showStep",`Transitioning to step ${t}`),t<0||t>=this.steps.length){h("showStep",`Invalid step index: ${t} (total steps: ${this.steps.length})`);return}this.steps.forEach((r,n)=>{r.style.display=n===t?"flex":"none"}),this.currentStepIndex=t,this.stepHasBeenValidated=!1,this.clearErrors();let e=t+1;this.updateStepText(e),this.applyStepStyles(e),o("showStep",`Now on step ${e}, fields in step:`,this.getFieldsForStep(t).map(r=>r.name||"(unnamed)"))}next(){g(`next (from step ${this.currentStepIndex+1})`),this.stepHasBeenValidated=!0;let t=this.validateStep(this.currentStepIndex);if(Object.keys(t).length>0){p("next","Validation failed, cannot proceed:",t),this.clearErrors(),this.showErrors(t),this.focusFirstError(t),f();return}o("next","Validation passed"),this.clearErrors(),this.stepHasBeenValidated=!1;let e=this.currentStepIndex+1;if(e>=this.steps.length){o("next","Last step reached \u2192 submitting form");let n=this.steps[this.currentStepIndex].querySelector('[data-action="next"]');if(n){let s=n.querySelector("[data-action-text]");s?(s.textContent="Submitting...",o("next","Button text set to 'Submitting...'")):p("next","No [data-action-text] element found inside next button")}else p("next","No [data-action='next'] button found in current step");o("next","Final field state before submit:",this.getFormStateJSON()),this.mirrorFieldStateToDOM(),this.loadCalendarEmbed();let i=document.getElementById("webflow-form-submit"),a=document.getElementById("hubspot-form-submit");i||h("submit","Missing #webflow-form-submit button in DOM!"),a||h("submit","Missing #hubspot-form-submit button in DOM!"),i&&a?(o("submit","Clicking both submit buttons (Webflow + HubSpot)"),i.click(),a.click()):h("submit","One or both submit buttons not found \u2014 form NOT submitted"),f();return}o("next",`Moving to step ${e+1}`),this.showStep(e),f()}showErrors(t){o("showErrors",`Displaying ${Object.keys(t).length} errors:`,t),Object.entries(t).forEach(([e,r])=>{let n=this.form.querySelector(`[data-required-group="${e}"]`)||this.form.querySelector(`[data-required-legal="${e}"]`);if(n){n.classList.add("has-error");let s=n.querySelector(".field-error");s||(s=document.createElement("div"),s.className="field-error",n.appendChild(s)),s.textContent=L[r],s.setAttribute("data-error-code",r),o("showErrors",`Group error: "${e}" \u2192 ${r}`);return}let i=this.form.querySelector(`[name="${e}"]`);if(!i){p("showErrors",`Cannot find field or group for error key: "${e}"`);return}i.classList.add("has-error");let a=i.parentElement?.querySelector(".field-error");a||(a=document.createElement("div"),a.className="field-error",i.parentElement?.appendChild(a)),a.textContent=L[r],a.setAttribute("data-error-code",r),o("showErrors",`Field error: "${e}" \u2192 ${r}`)})}clearErrors(){let t=this.form.querySelectorAll(".field-error"),e=this.form.querySelectorAll(".has-error");(t.length>0||e.length>0)&&o("clearErrors",`Removing ${t.length} error messages and ${e.length} error classes`),t.forEach(r=>r.remove()),e.forEach(r=>r.classList.remove("has-error"))}back(){let t=this.currentStepIndex-1;if(t<0){p("back","Already at first step, cannot go back");return}o("back",`Going back from step ${this.currentStepIndex+1} to step ${t+1}`),this.showStep(t)}getFieldsForStep(t){let e=this.steps[t];if(!e)return h("getFieldsForStep",`Step at index ${t} does not exist`),[];let r=Array.from(e.querySelectorAll("input, select, textarea"));return o("getFieldsForStep",`Step ${t}: found ${r.length} fields`,r.map(n=>`${n.name||"(unnamed)"}[${n.type}]${n.disabled?" DISABLED":""}${n.hasAttribute("required")?" REQ":""}`)),r}validateStep(t){g(`validateStep(${t})`);let e={};this.getFieldsForStep(t).forEach(s=>{let c=s.name;if(!c){p("validate",`Skipping unnamed field (type: ${s.type})`);return}if(s.type==="checkbox"||s.type==="radio")return;let l=s.value.trim();if(s.hasAttribute("required")&&!l){e[c]="required",o("validate",`"${c}" \u2192 REQUIRED but empty`);return}if(s.type==="email"&&l){if(!this.isValidEmailFormat(l)){e[c]="email_invalid",o("validate",`"${c}" \u2192 email format invalid: "${l}"`);return}if(!this.isCompanyEmail(l)){e[c]="email_company",o("validate",`"${c}" \u2192 personal email blocked: "${l}"`);return}}if(s.type==="tel"&&l&&this.validatePhoneField(s)){e[c]="phone_invalid",o("validate",`"${c}" \u2192 phone invalid: "${l}"`);return}});let n=this.validateRequiredSelectionGroups(t),i=this.validateLegalGroups(t),a={...e,...n,...i};return Object.keys(a).length===0?o("validateStep","\u2705 All clear \u2014 no errors"):o("validateStep",`\u274C ${Object.keys(a).length} error(s):`,a),f(),a}validateRequiredSelectionGroups(t){let e=this.steps[t],r={},n=e.querySelectorAll("[data-required-group]");return o("validateGroups",`Step ${t}: found ${n.length} selection groups`),n.forEach(i=>{let a=i.dataset.requiredGroup;if(!a)return;let c=Array.from(i.querySelectorAll('input[type="checkbox"], input[type="radio"]')).filter(u=>!u.disabled);if(c.length===0){o("validateGroups",`Group "${a}": no enabled inputs \u2192 skipping`);return}if(!c.some(u=>u.checked))r[a]="selection_required",o("validateGroups",`Group "${a}": nothing selected (${c.length} enabled inputs)`);else{let u=c.filter(m=>m.checked).map(m=>m.value);o("validateGroups",`Group "${a}": selected \u2192 [${u.join(", ")}]`)}}),r}validateLegalGroups(t){let e=this.steps[t],r={},n=e.querySelectorAll("[data-required-legal]");return o("validateLegal",`Step ${t}: found ${n.length} legal groups`),n.forEach(i=>{let a=i.dataset.requiredLegal;if(!a)return;let s=i.querySelector('input[type="checkbox"]');if(!s||s.disabled){o("validateLegal",`Legal "${a}": checkbox missing or disabled \u2192 skipping`);return}s.checked||(r[a]="legal_required",o("validateLegal",`Legal "${a}": not checked`))}),r}isValidEmailFormat(t){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)}isCompanyEmail(t){let e=["gmail.com","yahoo.com","hotmail.com","outlook.com","icloud.com","aol.com"],r=t.split("@")[1]?.toLowerCase();return r?!e.includes(r):!1}validatePhoneField(t){let e=this.itiInstances.get(t);return e?t.value.trim()?e.isValidNumber()?null:"phone_invalid":null:(p("phoneValidation",`No ITI instance found for field "${t.name}" \u2014 skipping phone validation`),null)}focusFirstError(t){let e=Object.keys(t)[0];if(!e)return;o("focus",`Focusing first error field: "${e}"`);let r=this.form.querySelector(`[data-required-group="${e}"]`)||this.form.querySelector(`[data-required-legal="${e}"]`);if(r){let i=r.querySelector("input, select, textarea");i?i.focus():p("focus",`Group "${e}" has no focusable input`);return}let n=this.form.querySelector(`[name="${e}"]`);n?n.focus():p("focus",`Could not find any element to focus for "${e}"`)}getFlowType(){let t=this.form.querySelector('[data-required-group="flow-type"]');if(!t)return p("getFlowType",'No [data-required-group="flow-type"] element found'),null;let r=t.querySelector('input[type="radio"]:checked')?.value??null;return o("getFlowType",`Current flow type: "${r}"`),r}applyFlowConditions(){g("applyFlowConditions");let t=this.getFlowType();if(!t){p("flowConditions","No flow type selected \u2014 skipping"),f();return}let e=N[t]||[];e.length===0?p("flowConditions",`No FLOW_CONDITIONS entry for flow type: "${t}"`):o("flowConditions",`Visible conditional blocks: [${e.join(", ")}]`);let r=this.form.querySelectorAll("[data-conditional]");o("flowConditions",`Total conditional blocks in form: ${r.length}`),r.forEach(n=>{let i=n.dataset.conditional;if(!i)return;let a=e.includes(i),s=n.querySelectorAll("input, select, textarea");if(a)n.style.display="",s.forEach(c=>{c.disabled=!1,this.originalRequired.get(c)&&c.setAttribute("required","true")}),o("flowConditions",`SHOW block "${i}" (${s.length} inputs enabled)`);else{n.style.display="none",s.forEach(l=>{l.disabled=!0,l.removeAttribute("required"),l instanceof HTMLInputElement?l.type==="checkbox"||l.type==="radio"?l.checked=!1:l.value="":l instanceof HTMLSelectElement?l.selectedIndex=0:l instanceof HTMLTextAreaElement&&(l.value="");let u=l.closest("[data-field-key]");if(!u)return;let m=u.dataset.fieldKey;if(!m)return;let y=this.fieldState.get(m);y&&(y.required=!1,y.valid=!0,y.value="",this.fieldState.set(m,y))});let c=n.dataset.fieldKey;if(c){let l=this.fieldState.get(c);l&&(l.required=!1,l.valid=!0,l.value="",this.fieldState.set(c,l))}this.clearErrorsInBlock(n),o("flowConditions",`HIDE block "${i}" (${s.length} inputs disabled & cleared)`)}}),this.updateValidityForStep(this.currentStepIndex+1),f()}cacheOriginalRequiredState(){let t=this.form.querySelectorAll("input, select, textarea"),e=0;t.forEach(r=>{let n=r.hasAttribute("required");this.originalRequired.set(r,n),n&&e++}),o("cacheRequired",`Cached ${t.length} inputs, ${e} originally required`)}clearErrorsInBlock(t){t.querySelectorAll(".field-error").forEach(e=>e.remove()),t.querySelectorAll(".has-error").forEach(e=>e.classList.remove("has-error"))}initializeFieldState(){let t=this.form.querySelectorAll("[data-field-key]");o("initFieldState",`Found ${t.length} trackable [data-field-key] elements`),t.forEach(e=>{let r=e.dataset.fieldKey;if(!r)return;let n=e.closest("[data-msf='step']"),i=n?Number(n.dataset.step):this.currentStepIndex+1;n||p("initFieldState",`Field "${r}" is not inside a [data-msf="step"] element \u2014 defaulting to step ${i}`),this.fieldState.set(r,{"field-name":r,value:"",required:!1,valid:!0,"step-number":i})}),o("initFieldState","Initialized keys:",Array.from(this.fieldState.keys()))}updateFieldState(t){let e=this.form.querySelector(`[data-field-key="${t}"]`);if(!e){p("updateFieldState",`No element found for field key: "${t}"`);return}let r="",n=!1;if(e.hasAttribute("data-group")){let l=Array.from(e.querySelectorAll("input[type='radio'], input[type='checkbox']")).filter(u=>!u.disabled);if(n=e.hasAttribute("data-required-group"),l.some(u=>u.type==="radio")){let u=l.find(m=>m.checked);u?r=u.closest("label")?.querySelector("span")?.textContent?.trim()??u.value??"":r=""}else r=l.filter(m=>m.checked).map(m=>m.closest("label")?.querySelector("span")?.textContent?.trim()??m.value??"").join(",")}else if(e.hasAttribute("data-required-legal")){let l=e.querySelector("input[type='checkbox']");l&&!l.disabled&&(n=!0,r=l.checked?"true":"false")}else(e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(n=e.hasAttribute("required")&&!e.disabled,e instanceof HTMLInputElement&&e.type==="checkbox"?r=e.checked?"true":"false":r=e.value.trim());let i=e.closest("[data-msf='step']"),a=i?Number(i.dataset.step):this.currentStepIndex+1,s=this.fieldState.get(t);if(!s){p("updateFieldState",`No state entry for key "${t}" \u2014 was it initialized?`);return}let c=s.value;s.value=r,s.required=n,s["step-number"]=a,this.fieldState.set(t,s),c!==r&&o("updateFieldState",`"${t}": "${c}" \u2192 "${r}" (required: ${n})`),this.updateValidityForStep(a)}updateValidityForStep(t){let e=this.steps.findIndex(i=>Number(i.dataset.step)===t);if(e===-1){p("updateValidity",`No step element found with data-step="${t}"`);return}let r=this.validateStep(e);Array.from(this.fieldState.values()).filter(i=>i["step-number"]===t).forEach(i=>{let a=i.valid;i.valid=!r[i["field-name"]],a!==i.valid&&o("updateValidity",`"${i["field-name"]}": valid ${a} \u2192 ${i.valid}`)})}getFormStateJSON(){return Array.from(this.fieldState.values())}updateStepText(t){let e=O[t];if(!e){p("updateStepText",`No STEP_TEXT config for step ${t}`);return}if(e.heading){let r=this.form.querySelector('[data-dynamic-text="heading"]');r?r.textContent=e.heading:p("updateStepText",'Missing [data-dynamic-text="heading"] element')}if(e.subheading){let r=this.form.querySelector('[data-dynamic-text="subheading"]');r?r.textContent=e.subheading:p("updateStepText",'Missing [data-dynamic-text="subheading"] element')}if(e.counter){let r=this.form.querySelector('[data-dynamic-text="counter"]');r?r.textContent=e.counter:p("updateStepText",'Missing [data-dynamic-text="counter"] element')}}syncAllFieldState(){o("syncAll","Syncing all field state..."),this.fieldState.forEach((t,e)=>{this.updateFieldState(e)}),o("syncAll","Sync complete. Full state:",this.getFormStateJSON())}mirrorFieldStateToDOM(){g("mirrorFieldStateToDOM");let t=this.getFormStateJSON(),e=document.getElementById("form-hubspot-book-a-demo");if(!e){h("mirror","HubSpot form #form-hubspot-book-a-demo NOT FOUND in DOM!"),f();return}let r=0,n=0;t.forEach(i=>{let a=e?.querySelector(`[data-mirror="${i["field-name"]}"]`);if(!a){p("mirror",`No mirror element for data-mirror="${i["field-name"]}"`),n++;return}if(a instanceof HTMLInputElement&&a.disabled){o("mirror",`Skipping disabled mirror: "${i["field-name"]}"`);return}a instanceof HTMLInputElement?a.type==="checkbox"?a.checked=i.value==="true":a.type==="radio"?a.checked=a.value===i.value:a.value=i.value:a.value=i.value,r++,o("mirror",`"${i["field-name"]}" \u2192 "${i.value}"`)}),o("mirror",`Done: ${r} mirrored, ${n} missing`),f()}resolveCalendarEntry(){let t=this.fieldState.get("company_type")?.value??"";return A.find(e=>e.type==="company_type"&&e.name===t)??null}loadCalendarEmbed(){g("loadCalendarEmbed");let t=document.querySelector("[hs-calender-block]");if(!t){h("calendar","No [hs-calender-block] element found in DOM!"),f();return}let e=this.resolveCalendarEntry();if(!e){t.setAttribute("hs-calender-block-active","false"),t.innerHTML="",p("calendar","No entry \u2192 embed cleared, block set to inactive"),f();return}t.setAttribute("hs-calender-block-active","true"),t.innerHTML="";let r=document.createElement("div");r.className="meetings-iframe-container",r.setAttribute("data-src",e["embed-url"]),t.appendChild(r);let n="https://static.hsappstatic.net/MeetingsEmbed/ex/MeetingsEmbedCode.js",i=document.querySelector(`script[src="${n}"]`);i&&(o("calendar","Removing existing HubSpot meetings script"),i.remove());let a=document.createElement("script");a.type="text/javascript",a.src=n,a.addEventListener("load",()=>{o("calendar","HubSpot meetings script loaded successfully")}),a.addEventListener("error",s=>{h("calendar","HubSpot meetings script FAILED to load:",s)}),t.appendChild(a),o("calendar",`Embed loaded: "${e["calender-name"]}" \u2192 ${e["embed-url"]}`),f()}applyStepStyles(t){let e=C[t];if(!e){p("applyStepStyles",`No STEP_STYLES config for step ${t}`);return}e.forEach(({selector:r,property:n,value:i})=>{let a=document.querySelectorAll(r);a.length===0&&p("applyStepStyles",`Selector "${r}" matched 0 elements`),a.forEach(s=>{s.style.setProperty(n,i)})}),o("applyStepStyles",`Applied ${e.length} style rules for step ${t}`)}};document.addEventListener("DOMContentLoaded",()=>{E&&console.log("%c[MSF] \u{1F527} STAGING MODE ACTIVE \u2014 debug logging enabled","color:#0f0;font-weight:bold;font-size:14px;background:#222;padding:4px 8px;border-radius:4px");let d=document.querySelector('[data-msf="form"]');if(!d){h("boot",'No form element found with [data-msf="form"] \u2014 MultiStepForm NOT initialized');return}o("boot","Form element found, initializing intl-tel-input...");let t;try{t=T({root:d}),o("boot",`intl-tel-input ready, ${t.size} phone fields initialized`)}catch(e){h("boot","intl-tel-input initialization FAILED:",e),t=new Map}try{let e=new S(d,t);window.msf=e,o("boot","MultiStepForm instance created and exposed as window.msf")}catch(e){h("boot","MultiStepForm constructor THREW:",e)}});})();
|
|
1
|
+
"use strict";(()=>{var M=Object.create;var S=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var I=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var q=(c=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(c,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):c)(function(c){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+c+'" is not supported')});var x=(c,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of $(t))!k.call(c,n)&&n!==e&&S(c,n,{get:()=>t[n],enumerable:!(r=H(t,n))||r.enumerable});return c};var w=(c,t,e)=>(e=c!=null?M(I(c)):{},x(t||!c||!c.__esModule?S(e,"default",{value:c,enumerable:!0}):e,c));function T(c={}){let{root:t=document,initialCountry:e="us",separateDialCode:r=!0,countryCodeSelector:n='input[pulse-form-field="country-code"]',onInit:o,onError:a=u=>console.warn(`[initIntlTelInput] ${u}`)}=c,s=new Map,d=window.intlTelInput;return d?(t.querySelectorAll('input[type="tel"]').forEach(u=>{try{let m=d(u,{initialCountry:e,separateDialCode:r,strictMode:!1,loadUtils:()=>import("https://cdn.jsdelivr.net/npm/intl-tel-input@25/build/js/utils.js")});s.set(u,m),v(m,n),u.addEventListener("countrychange",()=>{v(m,n)}),o?.(u,m)}catch(m){a(`Failed to init on input inside "${F(u)}"`,m)}}),s):(a(`intlTelInput not found on window. Include the script before calling this function.
|
|
2
|
+
e.g. <script src="https://cdn.jsdelivr.net/npm/intl-tel-input@25/build/js/intlTelInput.min.js"><\/script>`),s)}function v(c,t){try{let e=c.getSelectedCountryData?.();if(!e?.dialCode)return;document.querySelectorAll(t).forEach(r=>{r.value=`+${e.dialCode}`})}catch{}}function F(c){return c.closest("[pulse-form-block]")?.getAttribute("pulse-field-name")??"unknown"}var E=window.location.host==="influur-staging.webflow.io";function i(c,...t){E&&console.log(`%c[MSF:${c}]`,"color:#6cf;font-weight:bold",...t)}function p(c,...t){E&&console.warn(`[MSF:${c}]`,...t)}function h(c,...t){E&&console.error(`[MSF:${c}]`,...t)}function g(c){E&&console.group(`%c[MSF] ${c}`,"color:#6cf;font-weight:bold")}function f(){E&&console.groupEnd()}var C={1:[{selector:'[data-action="back"]',property:"display",value:"none"},{selector:'[pricing-form-element="progress-fill"]',property:"width",value:"50%"}],2:[{selector:'[data-action="back"]',property:"display",value:"flex"},{selector:'[pricing-form-element="progress-fill"]',property:"width",value:"100%"}]},A=[{type:"company_type",name:"Record Label / Music Distributor","calender-name":"valeria","embed-url":"https://meetings.hubspot.com/valeria-angelini/pulse-valeria-and-alessandra?embed=true"},{type:"industry",name:"Financial Services","calender-name":"david","embed-url":"https://meetings.hubspot.com/david-zarate2?embed=true"},{type:"industry",name:"Sports","calender-name":"steven","embed-url":"https://meetings.hubspot.com/steven-campos?embed=true"},{type:"industry",name:"Beauty","calender-name":"albany","embed-url":"https://meetings.hubspot.com/david-zarate2?embed=true"},{type:"industry",name:"Music","calender-name":"steven","embed-url":"https://meetings.hubspot.com/steven-campos?embed=true"},{type:"industry",name:"Customer Packaged Goods","calender-name":"david","embed-url":"https://meetings.hubspot.com/david-zarate2?embed=true"},{type:"industry",name:"Other","calender-name":"david","embed-url":"https://meetings.hubspot.com/david-zarate2?embed=true"}],L={required:"This field is required",email_invalid:"Please enter a valid email address",email_company:"Please use your company email address",phone_invalid:"Please enter a valid phone number",selection_required:"Please select at least one option",legal_required:"You must accept this to continue"},N={"pulse-demo":["pulse-demo-only","common-fields"],"white-glove-services":["white-glove-only","common-fields"]},O={1:{heading:"Your info",subheading:"Pulse is launching March 2025. Spots for onboarding cohort 1 are limited.",counter:"Step 1/2"},2:{heading:"Personalize",subheading:"Help us personalize your demo.",counter:"Step 2/2"}},b=class{constructor(t,e){this.currentStepIndex=0;this.stepHasBeenValidated=!1;this.originalRequired=new WeakMap;this.fieldState=new Map;this.form=t,this.itiInstances=e,g("Constructor"),this.steps=Array.from(t.querySelectorAll('[data-msf="step"]')),i("init",`Found ${this.steps.length} steps`),this.steps.length===0&&h("init","No steps found! Check [data-msf='step'] selectors in HTML."),this.steps.forEach((r,n)=>{let o=r.dataset.step;o?i("init",`Step ${n}: data-step="${o}"`):p("init",`Step element at index ${n} is missing data-step attribute`)}),i("init",`ITI instances count: ${e.size}`),this.bindEvents(),this.cacheOriginalRequiredState(),this.initializeFieldState(),this.showStep(0),this.applyFlowConditions(),this.syncAllFieldState(),i("init","Field state after full init:",this.getFormStateJSON()),f()}bindEvents(){i("bindEvents","Attaching all event listeners"),this.form.addEventListener("click",t=>{let e=t.target;if(!e)return;let r=e.closest("[data-action]");if(!r)return;let n=r.dataset.action;i("click",`Action button clicked: "${n}"`),n==="next"&&(t.preventDefault(),this.next()),n==="back"&&(t.preventDefault(),this.back())}),this.form.addEventListener("submit",t=>{t.preventDefault(),p("submit","Native form submit intercepted and prevented")}),this.form.addEventListener("input",t=>{let e=t.target;e&&(!(e instanceof HTMLInputElement)&&!(e instanceof HTMLTextAreaElement)&&!(e instanceof HTMLSelectElement)||this.handleLiveValidation())}),this.itiInstances.forEach((t,e)=>{e.addEventListener("countrychange",()=>{i("countrychange",`Country changed on field: "${e.name}"`),this.stepHasBeenValidated&&this.handleLiveValidation()})}),this.form.addEventListener("change",t=>{let e=t.target;e&&e instanceof HTMLInputElement&&e.type==="radio"&&e.name==="flow-type"&&(i("flowChange",`Flow type changed to: "${e.value}"`),this.applyFlowConditions())}),this.form.addEventListener("input",t=>{let e=t.target;if(!e)return;let r=e.closest("[data-field-key]");if(!r)return;let n=r.dataset.fieldKey;n&&this.updateFieldState(n)}),this.form.addEventListener("change",t=>{let e=t.target;if(!e)return;let r=e.closest("[data-field-key]");if(!r)return;let n=r.dataset.fieldKey;n&&this.updateFieldState(n)})}handleLiveValidation(){if(!this.stepHasBeenValidated)return;i("liveValidation",`Running on step ${this.currentStepIndex}`);let t=this.validateStep(this.currentStepIndex);this.clearErrors(),Object.keys(t).length>0?(i("liveValidation","Errors still present:",t),this.showErrors(t)):i("liveValidation","All errors cleared")}showStep(t){if(i("showStep",`Transitioning to step ${t}`),t<0||t>=this.steps.length){h("showStep",`Invalid step index: ${t} (total steps: ${this.steps.length})`);return}this.steps.forEach((r,n)=>{r.style.display=n===t?"flex":"none"}),this.currentStepIndex=t,this.stepHasBeenValidated=!1,this.clearErrors();let e=t+1;this.updateStepText(e),this.applyStepStyles(e),i("showStep",`Now on step ${e}, fields in step:`,this.getFieldsForStep(t).map(r=>r.name||"(unnamed)"))}next(){g(`next (from step ${this.currentStepIndex+1})`),this.stepHasBeenValidated=!0;let t=this.validateStep(this.currentStepIndex);if(Object.keys(t).length>0){p("next","Validation failed, cannot proceed:",t),this.clearErrors(),this.showErrors(t),this.focusFirstError(t),f();return}i("next","Validation passed"),this.clearErrors(),this.stepHasBeenValidated=!1;let e=this.currentStepIndex+1;if(e>=this.steps.length){i("next","Last step reached \u2192 submitting form");let n=this.steps[this.currentStepIndex].querySelector('[data-action="next"]');if(n){let s=n.querySelector("[data-action-text]");s?(s.textContent="Submitting...",i("next","Button text set to 'Submitting...'")):p("next","No [data-action-text] element found inside next button")}else p("next","No [data-action='next'] button found in current step");i("next","Final field state before submit:",this.getFormStateJSON()),this.mirrorFieldStateToDOM(),this.loadCalendarEmbed();let o=document.getElementById("webflow-form-submit"),a=document.getElementById("hubspot-form-submit");o||h("submit","Missing #webflow-form-submit button in DOM!"),a||h("submit","Missing #hubspot-form-submit button in DOM!"),o&&a?(i("submit","Clicking both submit buttons (Webflow + HubSpot)"),o.click(),a.click()):h("submit","One or both submit buttons not found \u2014 form NOT submitted"),f();return}i("next",`Moving to step ${e+1}`),this.showStep(e),f()}showErrors(t){i("showErrors",`Displaying ${Object.keys(t).length} errors:`,t),Object.entries(t).forEach(([e,r])=>{let n=this.form.querySelector(`[data-required-group="${e}"]`)||this.form.querySelector(`[data-required-legal="${e}"]`);if(n){n.classList.add("has-error");let s=n.querySelector(".field-error");s||(s=document.createElement("div"),s.className="field-error",n.appendChild(s)),s.textContent=L[r],s.setAttribute("data-error-code",r),i("showErrors",`Group error: "${e}" \u2192 ${r}`);return}let o=this.form.querySelector(`[name="${e}"]`);if(!o){p("showErrors",`Cannot find field or group for error key: "${e}"`);return}o.classList.add("has-error");let a=o.parentElement?.querySelector(".field-error");a||(a=document.createElement("div"),a.className="field-error",o.parentElement?.appendChild(a)),a.textContent=L[r],a.setAttribute("data-error-code",r),i("showErrors",`Field error: "${e}" \u2192 ${r}`)})}clearErrors(){let t=this.form.querySelectorAll(".field-error"),e=this.form.querySelectorAll(".has-error");(t.length>0||e.length>0)&&i("clearErrors",`Removing ${t.length} error messages and ${e.length} error classes`),t.forEach(r=>r.remove()),e.forEach(r=>r.classList.remove("has-error"))}back(){let t=this.currentStepIndex-1;if(t<0){p("back","Already at first step, cannot go back");return}i("back",`Going back from step ${this.currentStepIndex+1} to step ${t+1}`),this.showStep(t)}getFieldsForStep(t){let e=this.steps[t];if(!e)return h("getFieldsForStep",`Step at index ${t} does not exist`),[];let r=Array.from(e.querySelectorAll("input, select, textarea"));return i("getFieldsForStep",`Step ${t}: found ${r.length} fields`,r.map(n=>`${n.name||"(unnamed)"}[${n.type}]${n.disabled?" DISABLED":""}${n.hasAttribute("required")?" REQ":""}`)),r}validateStep(t){g(`validateStep(${t})`);let e={};this.getFieldsForStep(t).forEach(s=>{let d=s.name;if(!d){p("validate",`Skipping unnamed field (type: ${s.type})`);return}if(s.type==="checkbox"||s.type==="radio")return;let l=s.value.trim();if(s.hasAttribute("required")&&!l){e[d]="required",i("validate",`"${d}" \u2192 REQUIRED but empty`);return}if(s.type==="email"&&l){if(!this.isValidEmailFormat(l)){e[d]="email_invalid",i("validate",`"${d}" \u2192 email format invalid: "${l}"`);return}if(!this.isCompanyEmail(l)){e[d]="email_company",i("validate",`"${d}" \u2192 personal email blocked: "${l}"`);return}}if(s.type==="tel"&&l&&this.validatePhoneField(s)){e[d]="phone_invalid",i("validate",`"${d}" \u2192 phone invalid: "${l}"`);return}});let n=this.validateRequiredSelectionGroups(t),o=this.validateLegalGroups(t),a={...e,...n,...o};return Object.keys(a).length===0?i("validateStep","\u2705 All clear \u2014 no errors"):i("validateStep",`\u274C ${Object.keys(a).length} error(s):`,a),f(),a}validateRequiredSelectionGroups(t){let e=this.steps[t],r={},n=e.querySelectorAll("[data-required-group]");return i("validateGroups",`Step ${t}: found ${n.length} selection groups`),n.forEach(o=>{let a=o.dataset.requiredGroup;if(!a)return;let d=Array.from(o.querySelectorAll('input[type="checkbox"], input[type="radio"]')).filter(u=>!u.disabled);if(d.length===0){i("validateGroups",`Group "${a}": no enabled inputs \u2192 skipping`);return}if(!d.some(u=>u.checked))r[a]="selection_required",i("validateGroups",`Group "${a}": nothing selected (${d.length} enabled inputs)`);else{let u=d.filter(m=>m.checked).map(m=>m.value);i("validateGroups",`Group "${a}": selected \u2192 [${u.join(", ")}]`)}}),r}validateLegalGroups(t){let e=this.steps[t],r={},n=e.querySelectorAll("[data-required-legal]");return i("validateLegal",`Step ${t}: found ${n.length} legal groups`),n.forEach(o=>{let a=o.dataset.requiredLegal;if(!a)return;let s=o.querySelector('input[type="checkbox"]');if(!s||s.disabled){i("validateLegal",`Legal "${a}": checkbox missing or disabled \u2192 skipping`);return}s.checked||(r[a]="legal_required",i("validateLegal",`Legal "${a}": not checked`))}),r}isValidEmailFormat(t){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)}isCompanyEmail(t){let e=["gmail.com","yahoo.com","hotmail.com","outlook.com","icloud.com","aol.com"],r=t.split("@")[1]?.toLowerCase();return r?!e.includes(r):!1}validatePhoneField(t){let e=this.itiInstances.get(t);return e?t.value.trim()?e.isValidNumber()?null:"phone_invalid":null:(p("phoneValidation",`No ITI instance found for field "${t.name}" \u2014 skipping phone validation`),null)}focusFirstError(t){let e=Object.keys(t)[0];if(!e)return;i("focus",`Focusing first error field: "${e}"`);let r=this.form.querySelector(`[data-required-group="${e}"]`)||this.form.querySelector(`[data-required-legal="${e}"]`);if(r){let o=r.querySelector("input, select, textarea");o?o.focus():p("focus",`Group "${e}" has no focusable input`);return}let n=this.form.querySelector(`[name="${e}"]`);n?n.focus():p("focus",`Could not find any element to focus for "${e}"`)}getFlowType(){let t=this.form.querySelector('[data-required-group="flow-type"]');if(!t)return p("getFlowType",'No [data-required-group="flow-type"] element found'),null;let r=t.querySelector('input[type="radio"]:checked')?.value??null;return i("getFlowType",`Current flow type: "${r}"`),r}applyFlowConditions(){g("applyFlowConditions");let t=this.getFlowType();if(!t){p("flowConditions","No flow type selected \u2014 skipping"),f();return}let e=N[t]||[];e.length===0?p("flowConditions",`No FLOW_CONDITIONS entry for flow type: "${t}"`):i("flowConditions",`Visible conditional blocks: [${e.join(", ")}]`);let r=this.form.querySelectorAll("[data-conditional]");i("flowConditions",`Total conditional blocks in form: ${r.length}`),r.forEach(n=>{let o=n.dataset.conditional;if(!o)return;let a=e.includes(o),s=n.querySelectorAll("input, select, textarea");if(a)n.style.display="",s.forEach(d=>{d.disabled=!1,this.originalRequired.get(d)&&d.setAttribute("required","true")}),i("flowConditions",`SHOW block "${o}" (${s.length} inputs enabled)`);else{n.style.display="none",s.forEach(l=>{l.disabled=!0,l.removeAttribute("required"),l instanceof HTMLInputElement?l.type==="checkbox"||l.type==="radio"?l.checked=!1:l.value="":l instanceof HTMLSelectElement?l.selectedIndex=0:l instanceof HTMLTextAreaElement&&(l.value="");let u=l.closest("[data-field-key]");if(!u)return;let m=u.dataset.fieldKey;if(!m)return;let y=this.fieldState.get(m);y&&(y.required=!1,y.valid=!0,y.value="",this.fieldState.set(m,y))});let d=n.dataset.fieldKey;if(d){let l=this.fieldState.get(d);l&&(l.required=!1,l.valid=!0,l.value="",this.fieldState.set(d,l))}this.clearErrorsInBlock(n),i("flowConditions",`HIDE block "${o}" (${s.length} inputs disabled & cleared)`)}}),this.updateValidityForStep(this.currentStepIndex+1),f()}cacheOriginalRequiredState(){let t=this.form.querySelectorAll("input, select, textarea"),e=0;t.forEach(r=>{let n=r.hasAttribute("required");this.originalRequired.set(r,n),n&&e++}),i("cacheRequired",`Cached ${t.length} inputs, ${e} originally required`)}clearErrorsInBlock(t){t.querySelectorAll(".field-error").forEach(e=>e.remove()),t.querySelectorAll(".has-error").forEach(e=>e.classList.remove("has-error"))}initializeFieldState(){let t=this.form.querySelectorAll("[data-field-key]");i("initFieldState",`Found ${t.length} trackable [data-field-key] elements`),t.forEach(e=>{let r=e.dataset.fieldKey;if(!r)return;let n=e.closest("[data-msf='step']"),o=n?Number(n.dataset.step):this.currentStepIndex+1;n||p("initFieldState",`Field "${r}" is not inside a [data-msf="step"] element \u2014 defaulting to step ${o}`),this.fieldState.set(r,{"field-name":r,value:"",required:!1,valid:!0,"step-number":o})}),i("initFieldState","Initialized keys:",Array.from(this.fieldState.keys()))}updateFieldState(t){let e=this.form.querySelector(`[data-field-key="${t}"]`);if(!e){p("updateFieldState",`No element found for field key: "${t}"`);return}let r="",n=!1;if(e.hasAttribute("data-group")){let l=Array.from(e.querySelectorAll("input[type='radio'], input[type='checkbox']")).filter(u=>!u.disabled);if(n=e.hasAttribute("data-required-group"),l.some(u=>u.type==="radio")){let u=l.find(m=>m.checked);u?r=u.closest("label")?.querySelector("span")?.textContent?.trim()??u.value??"":r=""}else r=l.filter(m=>m.checked).map(m=>m.closest("label")?.querySelector("span")?.textContent?.trim()??m.value??"").join(",")}else if(e.hasAttribute("data-required-legal")){let l=e.querySelector("input[type='checkbox']");l&&!l.disabled&&(n=!0,r=l.checked?"true":"false")}else(e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(n=e.hasAttribute("required")&&!e.disabled,e instanceof HTMLInputElement&&e.type==="checkbox"?r=e.checked?"true":"false":r=e.value.trim());let o=e.closest("[data-msf='step']"),a=o?Number(o.dataset.step):this.currentStepIndex+1,s=this.fieldState.get(t);if(!s){p("updateFieldState",`No state entry for key "${t}" \u2014 was it initialized?`);return}let d=s.value;s.value=r,s.required=n,s["step-number"]=a,this.fieldState.set(t,s),d!==r&&i("updateFieldState",`"${t}": "${d}" \u2192 "${r}" (required: ${n})`),this.updateValidityForStep(a)}updateValidityForStep(t){let e=this.steps.findIndex(o=>Number(o.dataset.step)===t);if(e===-1){p("updateValidity",`No step element found with data-step="${t}"`);return}let r=this.validateStep(e);Array.from(this.fieldState.values()).filter(o=>o["step-number"]===t).forEach(o=>{let a=o.valid;o.valid=!r[o["field-name"]],a!==o.valid&&i("updateValidity",`"${o["field-name"]}": valid ${a} \u2192 ${o.valid}`)})}getFormStateJSON(){return Array.from(this.fieldState.values())}updateStepText(t){let e=O[t];if(!e){p("updateStepText",`No STEP_TEXT config for step ${t}`);return}if(e.heading){let r=this.form.querySelector('[data-dynamic-text="heading"]');r?r.textContent=e.heading:p("updateStepText",'Missing [data-dynamic-text="heading"] element')}if(e.subheading){let r=this.form.querySelector('[data-dynamic-text="subheading"]');r?r.textContent=e.subheading:p("updateStepText",'Missing [data-dynamic-text="subheading"] element')}if(e.counter){let r=this.form.querySelector('[data-dynamic-text="counter"]');r?r.textContent=e.counter:p("updateStepText",'Missing [data-dynamic-text="counter"] element')}}syncAllFieldState(){i("syncAll","Syncing all field state..."),this.fieldState.forEach((t,e)=>{this.updateFieldState(e)}),i("syncAll","Sync complete. Full state:",this.getFormStateJSON())}mirrorFieldStateToDOM(){g("mirrorFieldStateToDOM");let t=this.getFormStateJSON(),e=document.getElementById("form-hubspot-book-a-demo");if(!e){h("mirror","HubSpot form #form-hubspot-book-a-demo NOT FOUND in DOM!"),f();return}let r=0,n=0;t.forEach(o=>{let a=e?.querySelector(`[data-mirror="${o["field-name"]}"]`);if(!a){p("mirror",`No mirror element for data-mirror="${o["field-name"]}"`),n++;return}if(a instanceof HTMLInputElement&&a.disabled){i("mirror",`Skipping disabled mirror: "${o["field-name"]}"`);return}a instanceof HTMLInputElement?a.type==="checkbox"?a.checked=o.value==="true":a.type==="radio"?a.checked=a.value===o.value:a.value=o.value:a.value=o.value,r++,i("mirror",`"${o["field-name"]}" \u2192 "${o.value}"`)}),i("mirror",`Done: ${r} mirrored, ${n} missing`),f()}resolveCalendarEntry(){let t=this.fieldState.get("company_type")?.value??"";return A.find(e=>e.type==="company_type"&&e.name===t)??null}loadCalendarEmbed(){g("loadCalendarEmbed");let t=document.querySelector("[hs-calender-block]");if(!t){h("calendar","No [hs-calender-block] element found in DOM!"),f();return}let e=this.resolveCalendarEntry();if(!e){t.setAttribute("hs-calender-block-active","false"),t.innerHTML="";let d=document.querySelectorAll("[hs-thankyou-block-active]");d.forEach(l=>l.setAttribute("hs-thankyou-block-active","true")),i("calendar",`No entry \u2192 embed cleared, ${d.length} thank-you block(s) set to active`),f();return}t.setAttribute("hs-calender-block-active","true"),t.innerHTML="";let r=document.querySelectorAll("[hs-thankyou-block-active]");r.forEach(d=>d.setAttribute("hs-thankyou-block-active","false")),i("calendar",`Calendar active \u2192 ${r.length} thank-you block(s) set to inactive`);let n=document.createElement("div");n.className="meetings-iframe-container",n.setAttribute("data-src",e["embed-url"]),t.appendChild(n);let o="https://static.hsappstatic.net/MeetingsEmbed/ex/MeetingsEmbedCode.js",a=document.querySelector(`script[src="${o}"]`);a&&(i("calendar","Removing existing HubSpot meetings script"),a.remove());let s=document.createElement("script");s.type="text/javascript",s.src=o,s.addEventListener("load",()=>{i("calendar","HubSpot meetings script loaded successfully")}),s.addEventListener("error",d=>{h("calendar","HubSpot meetings script FAILED to load:",d)}),t.appendChild(s),i("calendar",`Embed loaded: "${e["calender-name"]}" \u2192 ${e["embed-url"]}`),f()}applyStepStyles(t){let e=C[t];if(!e){p("applyStepStyles",`No STEP_STYLES config for step ${t}`);return}e.forEach(({selector:r,property:n,value:o})=>{let a=document.querySelectorAll(r);a.length===0&&p("applyStepStyles",`Selector "${r}" matched 0 elements`),a.forEach(s=>{s.style.setProperty(n,o)})}),i("applyStepStyles",`Applied ${e.length} style rules for step ${t}`)}};document.addEventListener("DOMContentLoaded",()=>{E&&console.log("%c[MSF] \u{1F527} STAGING MODE ACTIVE \u2014 debug logging enabled","color:#0f0;font-weight:bold;font-size:14px;background:#222;padding:4px 8px;border-radius:4px");let c=document.querySelector('[data-msf="form"]');if(!c){h("boot",'No form element found with [data-msf="form"] \u2014 MultiStepForm NOT initialized');return}i("boot","Form element found, initializing intl-tel-input...");let t;try{t=T({root:c}),i("boot",`intl-tel-input ready, ${t.size} phone fields initialized`)}catch(e){h("boot","intl-tel-input initialization FAILED:",e),t=new Map}try{let e=new b(c,t);window.msf=e,i("boot","MultiStepForm instance created and exposed as window.msf")}catch(e){h("boot","MultiStepForm constructor THREW:",e)}});})();
|