1/* form-stepper.js â HubSpot v2åãè¾¼ã¿(hbspt.forms.create)ãã©ã¼ã ç´134ãã¼ã¸ã 2 * 3ã¹ãããUIã¸ä¸æ¬ç½®æããéã«ä½¿ãæ±ç¨stepperã 3 * 4 * ctform-stepper.js(ãåãåããç¨ãã¤ããã, /services/keymanappointer/contact ç)㨠5 * åãã.stepéãï¼Forms Submission API v3ç´POSTãæ¹å¼ããã¼ã¹ã«ãè³æè«æ±ãã¼ã¸å´ã® 6 * ç«¶åãã¡ã¤ã³å¤å®(/screen ã«emailãPOSTâç«¶åãªã data-altããã以å¤ã¯ data-thanks 㸠7 * é·ç§»)ã data-screen 屿§ã®æç¡ã§åãæ¿ããããããæ±ç¨åãããã®ã1ãã¼ã¸ã«è¤æ° 8 * ãã©ã¼ã ããããã¨ã¯æ³å®ãã¦ããªãããboot()ã¯querySelectorAllã§å ¨ä»¶åæåããã 9 * /screen ã® fetch 㯠HubSpotã¸ã®éä¿¡POSTã¨åæã«éå§ãã¦ä¸¦ååãã¦ãã(PR #41ã® 10 * æå³ãç§»æ¤ã»2026-08-04)ãPOSTæåå¾ã¯2500msã¿ã¤ã ã¢ã¦ãã¨ã®raceã§é·ç§»ããã 11 * 12 * ä½¿ãæ¹: 13 * <form class="hsform-stepper" novalidate 14 * data-portal="<portalId>" data-form="<formId>" data-thanks="<ãµã³ã¯ã¹URLãã¹>" 15 * data-ga-form-id="<generate_leadã®form_idããµã³ã¯ã¹å´ã®å¾æ¥å¤ã¨åä¸ã«ãã>" 16 * data-ga-lead-type="<generate_leadã®lead_type>" data-ga-form-ref="<æ§hashIDãåèå¤>" 17 * data-screen="<screenå¤å®APIã®URL>"(è³æè«æ±ãã¼ã¸ã®ã¿) data-alt="<ç«¶åæã®é·ç§»å >"> 18 * <div class="hsform-step is-active" data-step="1"> ... </div> 19 * <div class="hsform-step" data-step="2"> ... </div> 20 * <div class="hsform-step" data-step="3"> ... <button type="submit">...</button></div> 21 * </form> 22 * ãããé²æã¯ .hsform-dot[data-dot] ãåã .hsform-shell å ã«ç½®ã(ä»»æ)ã 23 * data-thanks ãçç¥ããã¨ãéä¿¡æåæã«ãã¼ã¸é·ç§»ãããã©ã¼ã ããã®å ´ã§ 24 * å®äºã¡ãã»ã¼ã¸ã«å·®ãæ¿ãã(åã .hsform-shell å ã® .hsform-done[hidden] ã表示ã 25 * ç¡ããã°æ¢å®ã®æè¨ãçæ)ãã¹ãããã¯1ã¤ã ãã§ããã(/contact/proposal ç¨ã»2026-08-11)ã 26 * 27 * æ¢åã® ctform-stepper.js / seminar-stepper.js ã¯ãã®ãã¡ã¤ã«ã®è¿½å ã«ä¼´ã夿´ããªãã 28 * 29 * åæãã§ãã¯ããã¯ã¹ã¯ name="consent" ã¨ããdata-subscription-id / data-consent-text / 30 * data-checkbox-text ãæãããã¨(seminar-stepper.jsã¨åæ§ã«)legalConsentOptionsã¨ã㦠31 * éä¿¡ããã(2026-09-24追å ãã¢ã¼ã«ã¤ãè¦è´ãã©ã¼ã ã®å ±å¬ä¼æ¥åãåæãã§ãã¯ãã 32 * HubSpotå´ã«åå¨ããªãããããã£åã§ç´POSTãããµã¤ã¬ã³ãã«ç ´æ£ããã¦ããããã®ä¿®æ£)ã 33 */ 34(function () { 35 function qs(sel, root) { 36 return (root || document).querySelector(sel); 37 } 38 function qsa(sel, root) { 39 return Array.prototype.slice.call((root || document).querySelectorAll(sel)); 40 } 41 42 function getCookie(name) { 43 var m = document.cookie.match(new RegExp("(?:^|; )" + name + "=([^;]*)")); 44 return m ? decodeURIComponent(m[1]) : ""; 45 } 46 47 function getUtmParams() { 48 var params = new URLSearchParams(location.search); 49 var out = {}; 50 [ 51 "utm_source", 52 "utm_medium", 53 "utm_campaign", 54 "utm_term", 55 "utm_content", 56 ].forEach(function (k) { 57 var v = params.get(k); 58 if (v) out[k] = v; 59 }); 60 return out; 61 } 62 63 function showStep(form, n) { 64 qsa(".hsform-step", form).forEach(function (el) { 65 el.classList.toggle( 66 "is-active", 67 Number(el.getAttribute("data-step")) === n, 68 ); 69 }); 70 qsa(".hsform-dot", form.closest(".hsform-shell") || document).forEach( 71 function (dot) { 72 var d = Number(dot.getAttribute("data-dot")); 73 dot.classList.toggle("is-active", d === n); 74 dot.classList.toggle("is-done", d < n); 75 }, 76 ); 77 } 78 79 function validateStep(stepEl) { 80 var invalid = qsa("input,select,textarea", stepEl).filter(function (el) { 81 if (!el.required) return false; 82 if (el.type === "checkbox") return !el.checked; 83 return !el.value || !el.value.trim(); 84 }); 85 if (invalid.length) { 86 invalid[0].reportValidity 87 ? invalid[0].reportValidity() 88 : invalid[0].focus(); 89 return false;
90 } 91 return true; 92 } 93 94 function setError(form, msg) { 95 var box = qs(".hsform-error", form); 96 if (!box) { 97 box = document.createElement("p"); 98 box.className = "hsform-error"; 99 box.style.cssText = 100 "color:#e0245e;font-size:13px;margin:0 0 14px;font-weight:700"; 101 form.insertBefore(box, form.firstChild); 102 } 103 box.textContent = msg || ""; 104 box.style.display = msg ? "block" : "none"; 105 } 106 107 // HubSpotå´(blockedEmailDomains)ãããªã¼ã¡ã¼ã«ãæå¦ããå ´åãæ±ç¨ã®é信失æ 108 // ã¡ãã»ã¼ã¸ã ã¨åå ãä¼ãããªããããå°ç¨ã®æ¡å æãè¿ãã 109 function errorMessageFor(err) { 110 var blocked = 111 err && 112 Array.isArray(err.errors) && 113 err.errors.some(function (e) { 114 return e.errorType === "BLOCKED_EMAIL"; 115 }); 116 if (blocked) { 117 return "ããªã¼ã¡ã¼ã«ï¼Gmailã»Yahoo!ã¡ã¼ã«çï¼ã§ã¯ãç³ãè¾¼ã¿ããã ãã¾ãããä¼ç¤¾ã®ã¡ã¼ã«ã¢ãã¬ã¹ããå ¥åãã ããã"; 118 } 119 return "éä¿¡ã«å¤±æãã¾ãããæéãããã¦å度ã試ãããã ãããå 容ãã確èªã®ããåéä¿¡ãã¦ãã ããã"; 120 } 121 122 function collectFields(form) { 123 var fields = []; 124 qsa("input,select,textarea", form).forEach(function (el) { 125 if (!el.name || el.name === "consent") return; 126 if (el.type === "checkbox") { 127 fields.push({ name: el.name, value: el.checked ? "true" : "false" }); 128 } else { 129 if (el.value) fields.push({ name: el.name, value: el.value }); 130 } 131 }); 132 var utm = getUtmParams(); 133 Object.keys(utm).forEach(function (k) { 134 if ( 135 !fields.some(function (f) { 136 return f.name === k; 137 }) 138 ) { 139 fields.push({ name: k, value: utm[k] }); 140 } 141 }); 142 var emailField = fields.filter(function (f) { 143 return f.name === "email"; 144 })[0]; 145 if (emailField && emailField.value) { 146 fields.push({ 147 name: "clarity_recording_url", 148 value: clarityRecordingsUrl(emailField.value), 149 }); 150 } 151 return fields; 152 } 153 154 function consentOptions(form) { 155 var cb = qs('input[name="consent"]', form); 156 if (!cb) return null; 157 return { 158 consent: { 159 consentToProcess: true, 160 text: cb.getAttribute("data-consent-text") || "", 161 communications: [ 162 { 163 value: cb.checked, 164 subscriptionTypeId: Number(cb.getAttribute("data-subscription-id")), 165 text: cb.getAttribute("data-checkbox-text") || "", 166 }, 167 ], 168 }, 169 }; 170 } 171 172 function trackLead(form) { 173 if (typeof gtag !== "function") return; 174 gtag("event", "generate_lead", { 175 form_id: 176 form.getAttribute("data-ga-form-id") || form.getAttribute("data-form"), 177 lead_type: form.getAttribute("data-ga-lead-type") || "", 178 form_ref: 179 form.getAttribute("data-ga-form-ref") || 180 form.getAttribute("data-ga-form-id") || 181 form.getAttribute("data-form"), 182 }); 183 } 184 185 // CV(HubSpotãã©ã¼ã éä¿¡)çºçæã«Clarityã»ãã·ã§ã³ã¸ã¡ã¼ã«ã¢ãã¬ã¹ãç´ä»ããã 186 // identify()ã¯Custom User IDã¨ãã¦å¤ãããã·ã¥åã»ãã¹ã¯ãã¦éä¿¡ãããã峿ã«ã¯ 187 // æ¤ç´¢ã§ããªããã2026-08-09宿¸¬ã§ããã2æ¥å¾ã«ã¯Custom IDæ¤ç´¢ãããããããã¨ã 188 // ç¢ºèªæ¸ã¿(åãªãåæ é å»¶ã§ãããã·ã¥èªä½ãæ¤ç´¢ã妨ãã¦ããããã§ã¯ãªãã£ã)ã 189 // set()ã®ã«ã¹ã¿ã ã¿ã°ã¯å¹³æéä¿¡ã ãURLã§ã®çµãè¾¼ã¿ãã§ããªã(å ¬å¼ããã¥ã¡ã³ãã§ 190 // URLãã©ã¡ã¼ã¿æ¹å¼ãåå¨ããªããã¨ãç¢ºèªæ¸ã¿)ãããidentify()ãã¡ã¤ã³ã®ææ®µã¨ãã 191 // ã«ã¹ã¿ã ã¿ã°ã¯æåæ¤ç´¢ç¨ã®ãã©ã¼ã«ããã¯ã¨ãã¦ä¸¡æ¹éã£ã¦ããã 192 var CLARITY_PROJECT_ID = "xxdpepkv6h"; 193 194 function clarityRecordingsUrl(email) { 195 // Custom User ID(identify()ã®ç¬¬1弿°)ã¯URLã¯ã¨ãªã§ã®çµãè¾¼ã¿ã«å¯¾å¿ãã¦ããã 196 // 2026-08-09宿©ç¢ºèª: Clarityå´ã®ãã£ã«ã¿ã¼UIãçæããURLã¯å¤ãäºéURL 197 // ã¨ã³ã³ã¼ããã¦ãã(+ã@ã2段ã¨ã³ã³ã¼ã)ããã®å½¢å¼ã§ãªãã¨æ£ããçµãè¾¼ã¾ããªãã 198 var doubleEncoded = encodeURIComponent(encodeURIComponent(email)); 199 return ( 200 "https://clarity.microsoft.com/projects/view/" + 201 CLARITY_PROJECT_ID + 202 "/impressions?date=Last%2030%20days&CustomUserId=is%3B" + 203 doubleEncoded 204 ); 205 } 206 207 function tagClarity(form) { 208 if (typeof window.clarity !== "function") return; 209 var emailEl = qs('input[name="email"]', form); 210 var email = emailEl ? emailEl.value.trim() : ""; 211 if (!email) return; 212 window.clarity("identify", email); 213 window.clarity("set", "hubspot_email", email); 214 } 215 216 // è³æè«æ±ãã¼ã¸å°ç¨: éä¿¡ã¡ã¼ã«ã®ãã¡ã¤ã³ã/screenã§å¤å®ããç«¶åãã¡ã¤ã³ãªã 217 // data-alt ã¸ããã以å¤(å¤å®å¤±æã»ã¿ã¤ã ã¢ã¦ãå«ã常ã«ãã§ã¤ã«ãªã¼ãã³)㯠218 // data-thanks ã¸é·ç§»ãããdata-screen ãç¡ããã©ã¼ã ã¯å³ data-thanks ã¸ã 219 // 220 // /screen ã® fetch 㯠startScreenCheck() ã§ HubSpot ã¸ã®éä¿¡POSTã¨ä¸¦åã«(éä¿¡éå§ã¨ 221 // åæã«)éå§ãã¦ãããç«¶åãã¡ã¤ã³ãå¦ãã®booleanã«æ£è¦åããPromiseã¨ãã¦ä¿æãã 222 // (PR #41ãè³æè«æ±ãã©ã¼ã éä¿¡å¾ã®ç©ºç½ã«ã¼ããè§£æ¶ãã®æå³ãform-stepper.jså´ã«ã
223 // ç§»æ¤ã»2026-08-04)ãéä¿¡POSTæåå¾ã«redirectAfterSubmitã§ãã®Promiseãå¾ ã¤ããã 224 // å®è³ªçãªè¿½å å¾ ã¡æéã¯POSTå®äºæç¹ã§ã»ã¼è§£æ±ºæ¸ã¿ã®ã±ã¼ã¹ãå¤ãç縮ãããã 225 // 2500msã®ãã§ã¤ã«ã»ã¼ãã¿ã¤ã ã¢ã¦ãã¯POSTæåå¾(=redirectAfterSubmitå¼ã³åºãæ)ã« 226 // æ¹ãã¦èµ·åãã(screenå¤å®ãç°å¸¸ã«é å»¶ããå ´åã®ä¿éº)ãéä¿¡ä¸ã¯ãã¿ã³ãæ¢ã« 227 // ãéä¿¡ä¸â¦ã表示ã®ã¾ã¾ç¡å¹åããã¦ããããããã®å¾ ã¡æéä¸ã空ç½ç¶æ ã«ã¯ãªããªãã 228 function startScreenCheck(form) { 229 var screenUrl = form.getAttribute("data-screen"); 230 if (!screenUrl) return null; 231 var emailEl = qs('input[name="email"]', form); 232 var email = emailEl ? emailEl.value : ""; 233 if (!email) return Promise.resolve(false); 234 return fetch(screenUrl, { 235 method: "POST", 236 headers: { "Content-Type": "application/json" }, 237 body: JSON.stringify({ email: email }), 238 }) 239 .then(function (r) { 240 return r.ok ? r.json() : Promise.reject(); 241 }) 242 .then(function (d) { 243 return !!(d && d.reason === "competitor"); 244 }) 245 .catch(function () { 246 return false; 247 }); 248 } 249 250 // data-thanks ãç¡ããã©ã¼ã ã®å®äºè¡¨ç¤º: ã¹ãããè¡¨ç¤ºã¨æ¬ä½ãé ãã 251 // åãã·ã§ã«å ã® .hsform-done[hidden] ã表示ãã(ç¡ããã°æ¢å®æè¨ãçæ)ã 252 function showDone(form) { 253 var shell = form.closest(".hsform-shell"); 254 var steps = shell ? qs(".hsform-steps", shell) : null; 255 if (steps) steps.style.display = "none"; 256 form.style.display = "none"; 257 var done = shell ? qs(".hsform-done", shell) : null; 258 if (!done) { 259 done = document.createElement("div"); 260 done.className = "hsform-done"; 261 done.innerHTML = 262 "<p class='hsform-done__t'>éä¿¡ãå®äºãã¾ãã</p>" + 263 "<p class='hsform-done__d'>ãåãåãããããã¨ããããã¾ããã</p>"; 264 (shell || form.parentElement).appendChild(done); 265 } 266 done.hidden = false; 267 (shell || done).scrollIntoView({ block: "start", behavior: "smooth" }); 268 } 269 270 function redirectAfterSubmit(form, screenPromise) { 271 var thanks = form.getAttribute("data-thanks"); 272 if (!thanks) { 273 showDone(form); 274 return; 275 } 276 if (!screenPromise) { 277 location.href = thanks; 278 return; 279 } 280 var alt = form.getAttribute("data-alt") || thanks; 281 var done = false; 282 var t = setTimeout(function () { 283 if (done) return; 284 done = true; 285 location.href = thanks; 286 }, 2500); 287 screenPromise 288 .then(function (isCompetitor) { 289 if (done) return; 290 done = true; 291 clearTimeout(t); 292 location.href = isCompetitor ? alt : thanks; 293 }) 294 .catch(function () { 295 if (done) return; 296 done = true; 297 clearTimeout(t); 298 location.href = thanks; 299 }); 300 } 301 302 // ãã©ã¼ã å¶æ¥botã message æ¬ã«æ°åã®ã¿ãå ¥ãã¦éã£ã¦ããããã 303 // ãã®å ´åã¯HubSpotã«éãããµã¤ã¬ã³ãã«ç ´æ£ãã(botã«å¼¾ãããã¨å¦ç¿ãããªã)ã 304 function isNumericOnlyMessage(form) { 305 var messageEl = qs('textarea[name="message"]', form); 306 if (!messageEl) return false; 307 var stripped = messageEl.value.replace(/[\sã]/g, ""); 308 return stripped.length > 0 && /^[0-9ï¼-ï¼]+$/.test(stripped); 309 } 310 311 function submitForm(form) { 312 var portal = form.getAttribute("data-portal"); 313 var formId = form.getAttribute("data-form"); 314 var submitBtn = qs('button[type="submit"]', form); 315 var submitLabel = submitBtn ? submitBtn.textContent : ""; 316 if (submitBtn) { 317 submitBtn.disabled = true; 318 submitBtn.textContent = "éä¿¡ä¸â¦"; 319 } 320 setError(form, ""); 321 322 if (isNumericOnlyMessage(form)) { 323 redirectAfterSubmit(form, null); 324 return; 325 } 326 327 var payload = { 328 fields: collectFields(form), 329 context: { 330 pageUri: location.href, 331 pageName: document.title, 332 }, 333 }; 334 var legal = consentOptions(form); 335 if (legal) payload.legalConsentOptions = legal; 336 var hutk = getCookie("hubspotutk"); 337 if (hutk) payload.context.hutk = hutk; 338
339 // /screenå¤å®ã¯HubSpotã¸ã®éä¿¡POSTã¨åæã«(ãã®POSTãæããç´åã«)éå§ãã 340 // POSTå®äºãå¾ ãã並åã§èµ°ãããã 341 var screenPromise = startScreenCheck(form); 342 343 fetch( 344 "https://api.hsforms.com/submissions/v3/integration/submit/" + 345 portal + 346 "/" + 347 formId, 348 { 349 method: "POST", 350 headers: { "Content-Type": "application/json" }, 351 body: JSON.stringify(payload), 352 }, 353 ) 354 .then(function (r) { 355 if (!r.ok) 356 return r.json().then(function (j) { 357 throw j; 358 }); 359 return r.json(); 360 }) 361 .then(function () { 362 trackLead(form); 363 tagClarity(form); 364 redirectAfterSubmit(form, screenPromise); 365 }) 366 .catch(function (err) { 367 console.error("hsform-stepper submit failed", err); 368 setError(form, errorMessageFor(err)); 369 if (submitBtn) { 370 submitBtn.disabled = false; 371 submitBtn.textContent = submitLabel || "éä¿¡ãã"; 372 } 373 }); 374 } 375 376 function init(form) { 377 var steps = qsa(".hsform-step", form).map(function (el) { 378 return Number(el.getAttribute("data-step")); 379 }); 380 var max = Math.max.apply(null, steps); 381 showStep(form, 1); 382 383 form.addEventListener("click", function (e) { 384 var nextBtn = e.target.closest("[data-next]"); 385 var backBtn = e.target.closest("[data-back]"); 386 if (!nextBtn && !backBtn) return; 387 e.preventDefault(); 388 var current = qs(".hsform-step.is-active", form); 389 var n = Number(current.getAttribute("data-step")); 390 if (nextBtn) { 391 if (!validateStep(current)) return; 392 showStep(form, Math.min(n + 1, max)); 393 } else { 394 showStep(form, Math.max(n - 1, 1)); 395 } 396 var shell = current.closest(".hsform-shell"); 397 (shell || form).scrollIntoView({ block: "start", behavior: "smooth" }); 398 }); 399 400 form.addEventListener("submit", function (e) { 401 e.preventDefault(); 402 var current = qs(".hsform-step.is-active", form); 403 if (!validateStep(current)) return; 404 submitForm(form); 405 }); 406 } 407 408 function boot() { 409 qsa("form.hsform-stepper[data-form]").forEach(init); 410 } 411 412 if (document.readyState === "loading") { 413 document.addEventListener("DOMContentLoaded", boot); 414 } else { 415 boot(); 416 } 417})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.