1<!doctype html> 2<html lang="en"> 3<head > 4 <meta charset="utf-8"/> 5<meta name="title" content="Contact us"/> 6<meta name="robots" content="NOINDEX,NOFOLLOW"/> 7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/> 8<title>Contact us</title> 9 <link rel="stylesheet" type="text/css" media="all" href="https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB/css/styles.min.css" /> 10<link rel="stylesheet" type="text/css" media="all" href="https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB/Amasty_Storelocator/vendor/chosen/chosen.min.css" /> 11<link rel="stylesheet" type="text/css" media="all" href="https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB/Trustpilot_Reviews/css/trustpilot.min.css" /> 12 13<link rel="icon" type="image/x-icon" href="https://www.banham.co.uk/media/favicon/stores/1/Banham_Logo_FA-04.png" /> 14<link rel="shortcut icon" type="image/x-icon" href="https://www.banham.co.uk/media/favicon/stores/1/Banham_Logo_FA-04.png" /> 15<!-- [HEAD Scripts and Style Sheets (store)] --> 16<link rel="preload" as="image" href="https://www.banham.co.uk/media/wysiwyg/Stronger_Together_-_Desktop_Compressed_.gif"/> 17<link rel="preload" as="image" href="https://www.banham.co.uk/media/wysiwyg/Stronger_Together_-_Mobile_4.gif"/> 18 19<meta name="google-site-verification" content="tlRCJ39nLLEuusvkrLQgs0hMLKjni_c_coG3u7dexYs" /> 20 21<meta name="p:domain_verify" content="FXieQwTo44FvqeK7UsLQWQazWnZ4AsMS"/> 22 23<meta name="trustpilot-one-time-domain-verification-id" content="uzIvKWRHCcxSIDidTTo2LpYtOOFSJrSEaWynJNnM"/> 24<link rel="dns-prefetch" href="//consent.cookiebot.com" /> 25 26<style type="text/css"> 27 /* to hide slide out form on these 2 pages */ 28.catalog-category-view.categorypath-safes .enquiries-slide , 29.catalog-category-view.category-gates-grilles-shutters .enquiries-slide { 30 display: none !important; 31 } 32.product-social-links__items a.action.mailto.friend {display:none; } 33 34 35.product-add-form .wishlist { 36 margin-top: 13px; 37 display: block; 38} 39.product-add-form .wishlist svg { 40 width: 20px; 41} 42 43.payment-method input#sagepaysuitepi + label { 44display: inline-block !important; 45} 46 47 48 49 50</style> 51 52<meta name="google-site-verification" content="jaCDjXkWDNHwKHL7TPsqP_5XnPTLp5HMop_7H2Cu5SE" /> 53 54 55<style> 56/*style for task BAN-2451*/ 57.nav-sections .navigation li.level0.mofx-mmn-our-difference { 58 order: -1; 59} 60 @media only screen and (max-width: 991px) { 61 .navigation ul { 62 display: flex; 63 flex-direction: column; 64 } 65} 66/* end style for task BAN-2451*/ 67.enquiries-slide-open .pca .pcaautocomplete { 68 max-width: 260px; 69 } 70.enquiries-slide-open .pca .pcaitem { 71 white-space: normal; 72 } 73.pca .pcaautocomplete { 74 max-width: 80vw; 75 } 76 77 .pca .pcaitem { 78 white-space: normal!important; 79 } 80/* M60 hotfix */ 81.product-item-info.empty-carousel-item { visibility:hidden; } 82.admin__data-grid-loading-mask {display:none;} 83.catalogsearch-result-index #instant-search-results-container .ais-Hits-item>[class^=col-] { 84 width: 100% !important; 85} 86 87 88 89</style> 90 91<!-- [/HEAD Scripts and Style Sheets (store)] --> 92<meta name="p:domain_verify" content="sYFFWHIheNKJDGZA1eZkGvMNvgwmO745"/> 93 94 95<!-- AB experiment code for doors page --> 96 97 98 99<meta name="facebook-domain-verification" content="v18ynkkipzgbfnaq7fxpdsfu3en2s9" /> 100 101 102<!-- Start VWO Async SmartCode --> 103<link rel="preconnect" href="https://dev.visualwebsiteoptimizer.com" /> 104 105<!-- End VWO Async SmartCode --> 106 107 108<meta name="og:title" content="Contact us"> 109<meta name="twitter:title" content="Contact us"> 110<link rel="canonical" href="https://www.banham.co.uk/contact"> 111 </head> 112<body class="store-default logged-out storyblok-contact storyblok-page-view page-layout-1column" id="html-body"> 113 <!-- [BODY Miscellaneous HTML/ Scripts (store)] --> 114 115<!-- [/BODY Miscellaneous HTML/ Scripts (store)] --> 116<style> 117 #webform-slide-out-fh3oTm { 118 background: #ffffff; 119 border-color: #ffffff; 120 width: 100%; 121 } 122 123 @media (min-width: 768px) { 124 #webform-slide-out-fh3oTm { 125 width: 720px; 126 } 127 } 128 129 /* #webform-slide-out-button-fh3oTm { 130 background: #3c4a54; 131 color: #ffffff; 132 width: 25px; 133 height: 160px; 134 } 135 .slide-out-button-icon{ 136 fill:#ffffff; 137 width: 1.25rem; 138 height: 1.25rem; 139 margin-right: .5rem; 140 } */ 141</style> 142 143 <style>.webforms .actions-toolbar{border:none}.webforms .actions-toolbar.submit-center .primary{margin:0 auto}.webforms .actions-toolbar.submit-left{flex-direction:row}.webforms .actions-toolbar.submit-left .primary{float:left}.webforms .actions-toolbar.submit-right{flex-direction:row-reverse}.webforms .actions-toolbar.submit-right .primary{float:right}.webforms .actions-toolbar button.sbtn-l{line-height:2rem;font-size:1.5rem}.webforms .actions-toolbar button.sbtn-xl{line-height:2.3rem;font-size:1.8rem}.webforms .field-error input,.webforms .field-error textarea,.webforms .field-error .drop-zone{border-color:red}.webforms .inline-elements .choice{display:inline-flex}@media screen and (min-width:640px){.webforms .wf-sm-row{clear:left}}@media screen and (min-width:768px){.webforms .wf-md-row{clear:left}.webforms .wf-sm-row{clear:unset}}@media screen and (min-width:1024px){.webforms .wf-lg-row{clear:left !important}.webforms .wf-md-row,.webforms .wf-sm-row{clear:unset}}.webforms figcaption{padding:5px 0;margin:5px}.webforms .image_picker_image{height:auto}.webforms .mm-map{height:400px;width:100%}.webforms .mm-map-search{margin:2px;width:40%}.webforms .mm-logic-hidden{display:none !important}</style> 144<div x-data="{ isOpen: false }" 145 146 x-init="$watch('isOpen', function(val) { if (val && window.resetSlideOutForm) window.resetSlideOutForm('fh3oTm'); })"> 147 <!-- Slide-out form --> 148 <div id="webform-slide-out-fh3oTm" 149 x-cloak 150 class="webform-content fixed top-0 right-0 md:max-w-[80%] md:max-w-auto md:w-1/3 lg:w-1/4 h-full shadow-2xl transform transition-transform duration-300 ease-in-out z-[9999]" 151 :class="{ 'translate-x-full': !isOpen }" 152 @click="isOpen && (document.documentElement.style.overflow = isOpen ? 'hidden' : 'auto')" 153 x-effect="document.documentElement.style.overflow = isOpen ? 'hidden' : 'auto'"> 154 <div class="md:px-36 md:pt-[60px] md:pb-10 px-5 py-10 h-full overflow-y-auto relative max-h-svh flex flex-col"> 155 <!-- Close button --> 156 <button @click="isOpen = false" class="close-btn absolute top-5 right-5 text-black hover:text-gray-700"> 157 <i class="ti ti-x text-xl"></i> 158 </button> 159 160 <div id="webform_fh3oTm_heading"> 161 162 </div> 163 164 <div id="webform_fh3oTm_success_text" class="form-success-message flex flex-col h-full hyva-success-msg" 165 style="display:none"></div> 166 167 168 169 <div id="webform_fh3oTm_form" 170 class="webforms webform-slide-out-form flex-shrink-0 flex-grow"> 171 172 <div id="fh3oTmform_description" class="webforms-description-text text-center"> 173 <p class="absolute top-0 left-0 right-0 bg-primary-darkGray mb
173-6 !text-sm" style="padding: 10px;">Prefer to call? Reach us on <a style="text-decoration:none" class="!text-sm" href="tel:+442078193730">020 7819 3730 </a></p> 174 </div> 175 176 177 178<form method="post" 179 name="webform_fh3oTm" 180 id="webform_fh3oTm" enctype="multipart/form-data" 181 class="form h-full enquiry-form survey-booking-form" 182 style="" 183 x-cloak 184 x-data="bbPCAForm({ loqateFindUrl: window.loqateFindUrl, loqateRetrieveUrl: window.loqateRetrieveUrl })" 185 @alpine:initialized="init()" 186> 187 188 <input name="form_key" type="hidden" value=""/> 189 <input type="hidden" name="submitForm_2" value="1"/> 190 <input type="hidden" name="form_id" value="2"/> 191 192 193 <input name='field[1035]' 194 id="enquiry_topic_product" 195 type='hidden' 196 value='' 197 /><input name='field[762]' 198 id="utm_source" 199 type='hidden' 200 value='' 201 /><input name='field[768]' 202 id="utm_campaign" 203 type='hidden' 204 value='' 205 /><input name='field[765]' 206 id="utm_medium" 207 type='hidden' 208 value='' 209 /> 210 211 <div id="wizardfh3oTm" class="h-full"> 212 213 <div class="step-app h-full flex flex-col pt-6" > 214 <div x-data="stepProgress()" x-init="init()" class=""> 215 <!-- Header: Question X of N --> 216 <div class="text-black text-sm font-normal leading-tight mb-5"> 217 Question <span x-text="currentStep"></span> of <span x-text="totalSteps"></span> 218 </div> 219 220 <!-- Progress bar --> 221 <div class="w-full h-1 bg-[#EDEDED] rounded"> 222 <div class="h-1 bg-primary rounded transition-all duration-300" 223 :style="`width: ${percent()}%`"></div> 224 </div> 225 226 <!-- Keep original steps for wizard logic, but hide them --> 227 <ul class="step-steps hidden" x-ref="stepList"> 228 <li id="title_fieldset_fh3oTm56" 229 class=""> 230 <a href="#stepfh3oTm56"> 231 Which Banham products are you interested in? </a> 232 </li> 233 <li id="title_fieldset_fh3oTm59" 234 class=""> 235 <a href="#stepfh3oTm59"> 236 About Your Enquiry </a> 237 </li> 238 <li id="title_fieldset_fh3oTm62" 239 class=""> 240 <a href="#stepfh3oTm62"> 241 Weâll need a little information about you </a> 242 </li> 243 <li id="title_fieldset_fh3oTm65" 244 class=""> 245 <a href="#stepfh3oTm65"> 246 Search for the property youâd like surveyed </a> 247 </li> 248 <li id="title_fieldset_fh3oTm68" 249 class=""> 250 <a href="#stepfh3oTm68"> 251 Choose your preferred survey date </a> 252 </li> 253 </ul> 254 </div> 255 <div class="step-content"> 256 <div class="step-tab-panel form-step active [&_h3]:my-10" id="stepfh3oTm56"> 257 <fieldset id="fieldset_fh3oTm56" class="fieldset-56 hyva-fieldset lg:w-full md:w-full w-full " style="" role="group" aria-labelledby="legend_fh3oTm56"> <h3 class="hyva-fieldset-label" id="legend_fh3oTm56"><span> Which Banham products are you interested in?</span></h3>
257 <div id="field_fh3oTm626" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-626 webforms-fields-enquiry-topic " > <div class="control" role="group" ><input id='enquiry-topic' 258 name='field[626]' 259 type='text' 260 class='input-text hyva-text' 261 style='' 262 value="" 263 placeholder="" 264 aria-label="Enquiry Topic" 265 /> 266 </div></div> <div id="field_fh3oTm1778" role="group" class="field hyva-field lg:w-full md:w-full w-full type-swatches webforms-fields-1778 webforms-fields-also_interested_in " > <div class="control" role="group" > <style>.webforms .mm-swatches .field{padding-left:0}.webforms .mm-swatches .field label input{position:fixed;opacity:0;z-index:-1}.webforms .mm-swatches .field label span{display:inline-block;border:1px solid #dadada;cursor:pointer;max-width:100%;overflow:hidden;position:relative;text-align:center;text-overflow:ellipsis;background:#f0f0f0;color:#686868;font-weight:600;line-height:30px;height:30px;min-width:20px;padding:0 1rem;box-sizing:content-box;user-select:none;border-radius:.35rem}.webforms .mm-swatches .field label input:disabled+span{box-shadow:unset;cursor:default;pointer-events:none}.webforms .mm-swatches .field label input:not([disabled]):hover+span{background-color:#ffffff;color:black}.webforms .mm-swatches .field label input:checked+span{background-color:#ffffff;border:1px solid #ffffff;color:black;outline:3px solid #0088cc}</style> 267<div class="mm-swatches"> 268 269 <div class='field choice option-0 mr-3 overflow-hidden text-sm leading-5 w-full self-stretch rounded inline-flex flex-col justify-start items-start gap-2' 270 style='' 271 > 272 <label id="fieldfh3oTm17780_label" class="w-full "> 273 <input id='fieldfh3oTm17780' 274 name='field[1778][]' 275 type='checkbox' 276 value="Locks" 277 class=' text-sm leading-5 w-full' 278 data-uid="fh3oTm1778" 279 aria-labelledby="fieldfh3oTm17780_label" 280 /> 281 <span style='' class="text-sm leading-5 w-full ">Locks</span> 282 </label> 283 284 </div> 285 286 287 <div class='field choice option-1 mr-3 overflow-hidden text-sm leading-5 w-full self-stretch rounded inline-flex flex-col justify-start items-start gap-2' 288 style='' 289 > 290 <label id="fieldfh3oTm17781_label" class="w-full "> 291 <input id='fieldfh3oTm17781' 292 name='field[1778][]' 293 type='checkbox' 294 value="Intruder Alarm" 295 class=' text-sm leading-5 w-full' 296 data-uid="fh3oTm1778" 297 aria-labelledby="fieldfh3oTm17781_label" 298 /> 299 <span style='' class="text-sm leading-5 w-full ">Alarms</span> 300 </label> 301 302 </div> 303 304 305 <div class='field choice option-2 mr-3 overflow-hidden text-sm leading-5 w-full self-stretch rounded inline-flex flex-col justify-start items-start gap-2' 306 style='' 307 > 308 <label id="fieldfh3oTm17782_label" class="w-full "> 309 <input id='fieldfh3oTm17782' 310 name='field[1778][]' 311 type='checkbox' 312 value="Doors" 313 class=' text-sm leading-5 w-full' 314 data-uid="fh3oTm1778" 315 aria-labelledby="fieldfh3oTm17782_label" 316 />
317 <span style='' class="text-sm leading-5 w-full ">Doors</span> 318 </label> 319 320 </div> 321 322 323 <div class='field choice option-3 mr-3 overflow-hidden text-sm leading-5 w-full self-stretch rounded inline-flex flex-col justify-start items-start gap-2' 324 style='' 325 > 326 <label id="fieldfh3oTm17783_label" class="w-full "> 327 <input id='fieldfh3oTm17783' 328 name='field[1778][]' 329 type='checkbox' 330 value="Keyholding" 331 class=' text-sm leading-5 w-full' 332 data-uid="fh3oTm1778" 333 aria-labelledby="fieldfh3oTm17783_label" 334 /> 335 <span style='' class="text-sm leading-5 w-full ">Keyholding</span> 336 </label> 337 338 </div> 339 340 341 <div class='field choice option-4 mr-3 overflow-hidden text-sm leading-5 w-full self-stretch rounded inline-flex flex-col justify-start items-start gap-2' 342 style='' 343 > 344 <label id="fieldfh3oTm17784_label" class="w-full "> 345 <input id='fieldfh3oTm17784' 346 name='field[1778][]' 347 type='checkbox' 348 value="Safes" 349 class=' text-sm leading-5 w-full' 350 data-uid="fh3oTm1778" 351 aria-labelledby="fieldfh3oTm17784_label" 352 /> 353 <span style='' class="text-sm leading-5 w-full ">Safes</span> 354 </label> 355 356 </div> 357 358 359 <div class='field choice option-5 mr-3 overflow-hidden text-sm leading-5 w-full self-stretch rounded inline-flex flex-col justify-start items-start gap-2' 360 style='' 361 > 362 <label id="fieldfh3oTm17785_label" class="w-full "> 363 <input id='fieldfh3oTm17785' 364 name='field[1778][]' 365 type='checkbox' 366 value="Metalwork" 367 class=' text-sm leading-5 w-full' 368 data-uid="fh3oTm1778" 369 aria-labelledby="fieldfh3oTm17785_label" 370 /> 371 <span style='' class="text-sm leading-5 w-full ">Gates / Grilles & Shutters</span> 372 </label> 373 374 </div> 375 376 </div> 377 378 379 </div></div></fieldset> 380 <div class="actions-toolbar w-full"> 381 </div> 382 </div> 383 <div class="step-tab-panel form-step [&_h3]:my-10" id="stepfh3oTm59"> 384 <fieldset id="fieldset_fh3oTm59" class="fieldset-59 hyva-fieldset lg:w-full md:w-full w-full " style="" role="group" aria-labelledby="legend_fh3oTm59"> <h3 class="hyva-fieldset-label" id="legend_fh3oTm59"><span>About Your Enquiry</span></h3> <div id="field_fh3oTm8" role="group" class="field hyva-field lg:w-full md:w-full w-full type-textarea webforms-fields-8 webforms-fields-enquiry required" > <div class="control" role="group" > <textarea id='fieldfh3oTm8' 385 name='field[8]' 386 class=' hyva-textarea' 387 rows='5' 388 style='' 389 placeholder="Enter your enquiry here" 390 data-validate="{'required-entry':true}" 391 aria-label="Your Enquiry" 392 aria-required="true" ></textarea> </div></div></fieldset> 393 <div class="actions-toolbar w-full"> 394 </div> 395 </div> 396 <div class="step-tab-panel form-step [&_h3]:my-10" id="stepfh3oTm62"> 397 <fieldset id="fieldset_fh3oTm62" class="fieldset-62 hyva-fieldset lg:w-full md:w-full w-full " style="" role="group" aria-labelledby="legend_fh3oTm62"> <h3 class="hyva-fieldset-label" id="legend_fh3oTm62"><span>Weâll need a little information about you</span></h3>
397 <div id="field_fh3oTm5" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select webforms-fields-5 webforms-fields-enquiry-type required" > <div class="control" role="group" > <select id='fieldfh3oTm5' name='field[5]' class=' hyva-select' style='' data-validate="{'validate-select':true}" aria-label="Enquiry Type" aria-required="true" > <option value="Residential" >Residential</option> <option value="Business" >Business</option></select> </div></div> <div id="field_fh3oTm23" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text mm-logic-hidden webforms-fields-23 webforms-fields-company_name required" > <div class="control" role="group" ><input id='company_name' 398 name='field[23]' 399 type='text' 400 class='input-text hyva-text' 401 style='' 402 value="" 403 placeholder="Company name" 404 data-validate="{'required-entry':true, 'validate-length-max':'60'}" 405 aria-label="Company Name" 406 aria-required="true" /> 407 </div></div> <div id="field_fh3oTm11" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-11 webforms-fields-firstname required" > <div class="control" role="group" ><input id='firstname' 408 name='field[11]' 409 type='text' 410 class='input-text hyva-text' 411 style='' 412 value="" 413 placeholder="Please enter your first name here" 414 data-validate="{'required-entry':true, 'validate-length-max':'30'}" 415 aria-label="First name" 416 aria-required="true" x-data="MageMe.WebForms.customerData()" 417 @private-content-loaded.window="receiveCustomerData($event.detail.data)" 418 x-model="customer.customer_firstname" 419 /> 420 </div></div> <div id="field_fh3oTm14" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-14 webforms-fields-lastname required" > <div class="control" role="group" ><input id='lastname' 421 name='field[14]' 422 type='text' 423 class='input-text hyva-text' 424 style='' 425 value="" 426 placeholder="Please enter your last name here" 427 data-validate="{'required-entry':true, 'validate-length-max':'30'}" 428 aria-label="Last name" 429 aria-required="true" x-data="MageMe.WebForms.customerData()" 430 @private-content-loaded.window="receiveCustomerData($event.detail.data)" 431 x-model="customer.customer_lastname" 432 /> 433 </div></div> <div id="field_fh3oTm2" role="group" class="field hyva-field lg:w-full md:w-full w-full type-email webforms-fields-2 webforms-fields-email required" > <div class="control" role="group" > <input id='fieldfh3oTm2' name='field[2]' type='email' class='input-text hyva-text' style='' value="" placeholder="[email protected]" data-validate="{'required-entry':true, 'validate-email':true}" aria-label="Email" aria-required="true" x-data="mmWebformsEmailDatafieldfh3oTm2" @input="trimSpace" @private-content-loaded.window="setCustomerData" /> </div></div> <div id="field_fh3oTm17" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-17 webforms-fields-contact-number required" > <div class="control" role="group" ><input id='contact-number' 434 name='field[17]' 435 type='text' 436 class='input-text hyva-text' 437 style='' 438 value="" 439 placeholder="Contact number" 440 data-validate="{'required-entry':true, 'mm-pattern':'^((\\d[\\-. ]?)?((\\(\\{d3}\\))|\\d{3}))?[\\-. ]?\\d{3,4}[\\-. ]?\\d{4}$'}" 441 data-msg-required-entry="Please enter a valid phone number."data-msg-mm-pattern="Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890." aria-label="Contact number" 442 aria-required="true" /> 443 <div style="display:none" class="hyva-comment-label" id="advice-required-entry-fieldfh3oTm17">Please enter a valid phone number.</div> </div></div></fieldset> 444 <div class="actions-toolbar w-full"> 445 </div> 446 </div> 447 <div class="step-tab-panel form-step [&_h3]:my-10" id="stepfh3oTm65"> 448 <fieldset id="fieldset_fh3oTm65" class="fieldset-65 hyva-fieldset address-search lg:w-full md:w-full w-full " style="" role="group" aria-labelledby="legend_fh3oTm65"> <h3 class="hyva-fieldset-label" id="legend_fh3oTm65"><span>Search for the property youâd like surveyed</span></h3>
448 <div id="field_fh3oTm1781" role="group" class="field hyva-field search-address lg:w-full md:w-full w-full type-text webforms-fields-1781 " > <div class="control" role="group" ><input id='' 449 name='field[1781]' 450 type='text' 451 class='input-text hyva-text' 452 style='' 453 value="" 454 placeholder="Search Address" 455 aria-label="Search Address" 456 /> 457 </div></div> <div id="field_fh3oTm20" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-20 webforms-fields-street required" > <div class="control" role="group" ><input id='street' 458 name='field[20]' 459 type='text' 460 class='input-text hyva-text' 461 style='' 462 value="" 463 placeholder="Address Line 1" 464 data-validate="{'required-entry':true, 'validate-length-max':'40'}" 465 aria-label="Street & Number" 466 aria-required="true" /> 467 </div></div> <div id="field_fh3oTm629" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-629 webforms-fields-street1 " > <div class="control" role="group" ><input id='street1' 468 name='field[629]' 469 type='text' 470 class='input-text hyva-text' 471 style='' 472 value="" 473 placeholder="Address Line 2" 474 data-validate="{'validate-length-max':'40'}" 475 aria-label="Street 1" 476 /> 477 </div></div> <div id="field_fh3oTm632" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-632 webforms-fields-street2 " > <div class="control" role="group" ><input id='street2' 478 name='field[632]' 479 type='text' 480 class='input-text hyva-text' 481 style='' 482 value="" 483 placeholder="Address Line 3" 484 data-validate="{'validate-length-max':'40'}" 485 aria-label="Street 2" 486 /> 487 </div></div> <div id="field_fh3oTm26" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-26 webforms-fields-city required" > <div class="control" role="group" ><input id='city' 488 name='field[26]' 489 type='text' 490 class='input-text hyva-text' 491 style='' 492 value="" 493 placeholder="Town / City" 494 data-validate="{'required-entry':true, 'validate-length-max':'30'}" 495 aria-label="Town / City" 496 aria-required="true" /> 497 </div></div> <div id="field_fh3oTm29" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-29 webforms-fields-country required" > <div class="control" role="group" ><input id='country' 498 name='field[29]' 499 type='text' 500 class='input-text hyva-text' 501 style='' 502 value="" 503 placeholder="Country" 504 data-validate="{'required-entry':true, 'validate-length-max':'30'}" 505 aria-label="Country" 506 aria-required="true" /> 507 </div></div> <div id="field_fh3oTm32" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-32 webforms-fields-postcode required" > <div class="control" role="group" ><input id='postcode' 508 name='field[32]' 509 type='text' 510 class='input-text hyva-text' 511 style='' 512 value="" 513 placeholder="Postcode" 514 data-validate="{'required-entry':true, 'validate-length-max':'10'}" 515 aria-label="Postcode" 516 aria-required="true" /> 517 </div></div></fieldset> 518 <div class="actions-toolbar w-full"> 519 </div> 520 </div> 521 <div class="step-tab-panel form-step [&_h3]:my-10" id="stepfh3oTm68"> 522 <fieldset id="fieldset_fh3oTm68" class="fieldset-68 hyva-fieldset lg:w-full md:w-full w-full " style="" role="group" aria-labelledby="legend_fh3oTm68"> <h3 class="hyva-fieldset-label" id="legend_fh3oTm68"><span>Choose your preferred survey date</span></h3>
522 <div id="field_fh3oTm1032" role="group" class="field hyva-field lg:w-full md:w-full w-full type-date webforms-fields-1032 webforms-fields-survey-date required" > <div class="control" role="group" ><div class='webforms-datepicker ddd'> 523 <div id='fieldfh3oTm1032_calendar' class='webforms-calendar'> 524 <div class="relative"> 525 <input id='fieldfh3oTm1032' 526 name='field[1032]' 527 type='text' 528 class='input-text _has-datepicker hyva-text pr-10' 529 style='' 530 value='' 531 placeholder="" 532 data-validate="{'required-entry':true}" 533 aria-label="Preferred Survey Date" 534 aria-required="true" /> 535 536 <svg class="text-gray-400 pointer-events-none" style="position: absolute; top:20px; right:20px; width:20px;"viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> 537 <path d="M3.33337 5.83329C3.33337 5.39127 3.50897 4.96734 3.82153 4.65478C4.13409 4.34222 4.55801 4.16663 5.00004 4.16663H15C15.4421 4.16663 15.866 4.34222 16.1786 4.65478C16.4911 4.96734 16.6667 5.39127 16.6667 5.83329V15.8333C16.6667 16.2753 16.4911 16.6992 16.1786 17.0118C15.866 17.3244 15.4421 17.5 15 17.5H5.00004C4.55801 17.5 4.13409 17.3244 3.82153 17.0118C3.50897 16.6992 3.33337 16.2753 3.33337 15.8333V5.83329Z" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 538 <path d="M13.3334 2.5V5.83333" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 539 <path d="M6.66663 2.5V5.83333" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 540 <path d="M3.33337 9.16663H16.6667" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 541 <path d="M5.83337 11.6666H5.84421" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 542 <path d="M8.34167 11.6666H8.34667" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 543 <path d="M10.8417 11.6666H10.8467" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 544 <path d="M13.3458 11.6666H13.3508" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 545 <path d="M10.8458 14.1666H10.8508" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 546 <path d="M5.84167 14.1666H5.84667" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 547 <path d="M8.34167 14.1666H8.34667" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 548 </svg> 549 </div> 550 </div> 551</div> 552 </div></div> <div id="field_fh3oTm38" role="group" class="field hyva-field lg:w-full md:w-full w-full type-subscribe choice webforms-fields-38 webforms-fields-subscribe " aria-describedby="comment_fieldfh3oTm38"> <div class="control" role="group" > <div class="field choice option-0"><input id='fieldfh3oTm380' name='field[38]' type='checkbox' class='hyva-checkbox' style='float:left' value='1' /><label for='fieldfh3oTm380' class=' hyva-checkbox-label' style='' >Subscribe</label></div> <p class="hyva-comment-label" id="comment_fieldfh3oTm38" tabindex="0">I consent to Banham sending me email updates on special offers, products, and services. If you would like further information on how we use your personal data, please check our <a href="/privacy-promise" target="_blank">Privacy Policy</a>.</p></div></div></fieldset> 553 <div class="actions-toolbar w-full"> 554 <div id="captcha-container-fh3oTm"></div> 555 </div> 556 </div> 557 </div> 558 559 <div class="step-footer mt-auto" 560 x-data="{ 561 handleKey(e) { 562 const btnNext = this.$root.querySelector('button[data-direction=\'next\']'); 563 const btnPrev = this.$root.querySelector('button[data-direction=\'prev\']'); 564 const btnFinish = this.$root.querySelector('button[data-direction=\'finish\']'); 565 if (e.key === 'ArrowRight') { 566 if (btnNext && btnNext.offsetParent !== null) btnNext.focus(); 567 else if (btnFinish && btnFinish.offsetParent !== null) btnFinish.focus(); 568 } 569 if (e.key === 'ArrowLeft') { 570 if (btnPrev && btnPrev.offsetParent !== null) btnPrev.focus(); 571 } 572 } 573 }" 574 @keydown.window="handleKey($event)" 575 > 576 577 <div class="please-wait text-center" id="webform_fh3oTm_sending_data" 578 style="display:none;"> 579 <div class="loading-indicator"></div>
580 <span id="webform_fh3oTm_progress_text">Sending...</span> 581 </div> 582 <button type="button" tabindex="0" 583 data-direction="next" 584 @click="handleNextStep" 585 class="btn btn-primary step-btn action primary w-full">Next</button> 586 <button type="submit" tabindex="0" 587 data-direction="finish" 588 id="webform_fh3oTm_submit_button" 589 style="display:none" 590 class="btn btn-primary step-btn action submit primary w-full ">Next</button> 591 <button type="button" tabindex="0" 592 data-direction="prev" 593 style="display:none" 594 class=" leading-5 text-sm m-auto mt-5 border-b border-primary-darker">Back</button> 595 <div class="w-full text-center grecaptcha-legal mt-5"> 596 <p class="my-4 text-sm"> 597 <em>This site is protected by reCAPTCHA.</em> 598</p> </div> 599 600 </div> 601 </div> 602 </div> <!--wizard--> 603 </form> 604 605 606 607 </div> 608 609 <style> .recaptcha-position-inline{ clear: both; box-sizing: border-box; padding: 0 2rem 2rem 0; width: 100%; float: left; }</style> 610 </div> 611 </div> 612 613 614 <div id="webform-slide-out-button-fh3oTm" 615 x-data="{ isScrolled: false }" 616 @scroll.window="isScrolled = window.scrollY > 0" 617 @click=" 618 isOpen = true; 619 window.surveyOpening = window.surveyOpeningSource === 'Opened from CTA' 620 ? 'Opened from CTA' 621 : 'Opened from sidebar'; 622 if (!window.surveyStartedPushed) { 623 var openingSource = window.surveyOpening; 624 var enquiryTopicEl = document.getElementById('enquiry-topic'); 625 window.surveyTypeVal = ''; 626 window.logged_in_status = false; 627 window.dataLayer = window.dataLayer || []; 628 window.dataLayer.push({ 629 event: 'survey_started', 630 site_type: window.site_type, 631 logged_in_status: false, 632 journey_type: 'product', 633 survey_opening: openingSource, 634 }); 635 window.surveyStartedPushed = true; 636 } 637 window.surveyOpeningSource = null; 638 " 639 class="open-slide-form-button fixed z-30 py-4 pl-6 pr-4 right-5 md:right-10 bottom-5 md:bottom-16 lg:bottom-10 group flex items-center bg-primary text-white rounded-full overflow-hidden transition-all duration-300 ease-in-out hover:!w-[350px] justify-end cursor-pointer text-base shadow-md" 640 :class="isScrolled ? 'w-14' : 'w-[350px]'" 641 > 642 <span 643 class="whitespace-nowrap mr-auto transition-all duration-300 group-hover:!opacity-100 font-heading" 644 :class="isScrolled ? 'opacity-0' : 'opacity-100'" 645 > 646 Book a Free Survey </span> 647 <i class="ti ti-calendar-check text-2xl flex items-center justify-center"> 648 </i> 649 </div> 650 651 <div id="webform-slide-out-overlayfh3oTm" 652 x-cloak 653 class="fixed inset-0 bg-black opacity-50 z-[999]" 654 x-show="isOpen" 655 @click="isOpen = false"></div> 656 </div> 657 658 659<input name="form_key" type="hidden" value="qqHJt21KnCGuKef4" /> 660 <noscript> 661 <section 662 class="message global noscript border-b-2 border-blue-500 bg-blue-50 shadow-none m-0 px-0 rounded-none font-normal" 663 aria-labelledby="messageGlobalNoScriptMessage" 664 > 665 <div class="container text-center"> 666 <p id="messageGlobalNoScriptMessage"> 667 <strong>JavaScript seems to be disabled in your browser.</strong>
668 <span> 669 For the best experience on our site, be sure to turn on Javascript in your browser. </span> 670 </p> 671 </div> 672 </section> 673 </noscript> 674 675 676 677 <div class="page-wrapper"><header class="page-header"><a class="action skip sr-only focus:not-sr-only focus:absolute focus:z-40 focus:bg-white 678 contentarea" 679 href="#contentarea"> 680 <span> 681 Skip to Content </span> 682</a><!-- Action Name: /contact/ --> 683<div id="header" role="banner" 684 x-data="{ 685 ...initHeader(), 686 isSticky: false 687 }" 688 689 x-init=" 690 const updateHeaderHeight = () => { 691 const headerEl = document.querySelector('#header'); 692 const bannerEl = document.querySelector('.announcement-banner'); 693 const headerHeight = headerEl ? headerEl.offsetHeight : 0; 694 const bannerHeight = bannerEl ? bannerEl.offsetHeight : 0; 695 document.documentElement.style.setProperty('--header-height', (headerHeight + bannerHeight) + 'px'); 696 }; 697 window.addEventListener('scroll', () => { 698 isSticky = window.scrollY > 50 699 }); 700 window.addEventListener('resize', updateHeaderHeight); 701 updateHeaderHeight(); 702 " 703 :class="isSticky 704 ? 'fixed top-0 left-0 z-100 w-full bg-white' 705 : 'relative z-30 w-full bg-white '" 706 @private-content-loaded.window="getData(event.detail.data)" 707> 708 <div class="relative container flex flex-wrap lg:flex-nowrap items-center justify-between w-full min-h-[60px] px-5 py-5 mx-auto mt-0 md:px-10 lg:min-h-[84px]"> 709 710 <!--Main Navigation--> 711 <div class="flex items-center gap-4 lg:gap-7"> 712 <nav 713 x-data="initMenuMobile_6ab56541136c6()" 714 @keydown.window.escape="closeMenu()" 715 @private-content-loaded.window="setCustomerState($event.detail.data)" 716 class="z-20 navigation leading-none" 717 aria-label="Site navigation" 718 role="navigation" 719> 720 <button 721 x-ref="mobileMenuTrigger" 722 @click="openMenu()" 723 type="button" 724 aria-label="Open menu" 725 aria-haspopup="menu" 726 :aria-expanded="open" 727 class="h-5 focus:border-primary-lighter focus:outline-none focus:ring-0 leading-none" 728 title="Navigation" 729 > 730 <i class="ti ti-menu text-xl"></i> 731 </button> 732 <div 733 x-ref="mobileMenuNavLinks" 734 class=" 735 fixed top-0 left-0 w-full h-full flex 736 flex-col 737 -translate-x-full 738 z-40 739 transition-transform duration-300 ease-in-out 740 overflow-y-auto overflow-x-hidden max-w-[350px] md:max-w-[384px] lg:max-w-[100%] focus:border-primary-lighter focus:outline-none focus:ring-0" 741 :class="{ 742 'translate-x-0': open, 743 '-translate-x-full': !open, 744 }" 745 :aria-hidden="open ? 'false' : 'true'" 746 role="dialog" 747 aria-modal="true" 748 > 749 <div 750 class="fixed inset-0 z-[-1]" 751 @click="closeMenu()" 752 ></div> 753 <div 754 class="lg:max-w-[480px] h-full bg-white shadow " 755 :class="{ 756 'max-lg:-translate-x-full': mobilePanelActiveId, 757 }" 758 > 759 <div class="w-full h-full pb-[60px] overflow-y-auto overflow-x-hidden" 760 :class="{ 'submenu-open': mobilePanelActiveId !== null && mobilePanelActiveId !== 0 }" 761 > 762 <button 763 @click="closeMenu()" 764 class="flex justify-start w-full self-start py-5 px-5 md:px-10 focus:border-primary-lighter focus:outline-none focus:ring-0" 765 aria-label="Close menu" 766 type="button" 767 > 768 <i class="ti ti-x text-xl"></i> 769 </button> 770 <ul 771 772 class="flex flex-col" 773 aria-label="Site navigation links" 774 > 775 776 <li x-show="open" 777 x-transition:enter="transition ease-out duration-400" 778 x-transition:enter-start="opacity-0 -translate-y-2" 779 x-transition:enter-end="opacity-100 translate-y-0" 780 style="transition-delay: 90ms;" 781 class="md:hidden level-0 px-5 py-[6px] md:px-10"> 782 <a class="relative flex items-center cursor-pointer level-0 focus:border-primary-lighter focus:outline-none focus:ring-0 hover:text-primary-darker" href="/book-a-survey/" title="Book a Survey"><span>Book a Survey</span></a> 783 </li> 784 <li 785 x-show="open" 786 data-child-id="category-node-469-main" 787 x-transition:enter="transition ease-out duration-700" 788 x-transition:enter-start="opacity-0 -translate-y-2" 789 x-transition:enter-end="opacity-100 translate-y-0" 790 style="transition-delay: 0ms;" 791 class="level-0 px-5 py-[6px] md:px-10" 792 :class="{ 'active': mobilePanelActiveId === 'category-node-469' }" 793 > 794 <div class="flex items-center transition-transform duration-150 ease-in-out transform"> 795 <a 796 class="relative flex items-center justify-between cursor-pointer level-0 w-full focus:border-primary-lighter focus:outline-none focus:ring-0 hover:text-primary-darker" 797 title="Locks" 798 @click="openSubcategory('category-node-469')" 799 aria-label="Open Locks subcategories" 800 aria-haspopup="true" 801 :aria-expanded="mobilePanelActiveId === 'category-node-469'" 802 > 803 Locks <i class="ti ti-chevron-right text-base"></i> 804 </a> 805 </div> 806 <div 807 data-child-id="category-node-469" 808 class="absolute top-[0] left-[0] flex flex-col w-full h-full bg-white border-l border-primary pt-16 pb-[60px] overflow-y-auto overflow-x-hidden lg:left-[480px] lg:max-w-[480px] lg:translate-x-0 max-lg:translate-x-full transition-transform duration-150 ease-in-out z-[-1] invisible pointer-events-none" 809 :class="{ 810 '!-translate-x-full invisible pointer-events-none': mobilePanelActiveId !== 'category-node-469', 811 'translate-x-0 visible pointer-events-auto': mobilePanelActiveId === 'category-node-469', 812 813 }" 814 > 815 <button 816 type="button" 817 class="absolute top-5 left-5 flex justify-start w-auto self-start cursor-pointer w-full md:left-10 lg:hidden focu
817s:border-primary-lighter focus:outline-none focus:ring-0" 818 @click="backToMainCategories('category-node-469-main')" 819 aria-label="Back to main categories" 820 > 821 <i class="ti ti-arrow-left text-xl"></i> 822 </button> 823 <ul aria-label="Subcategories"> 824 <li x-show="mobilePanelActiveId === 'category-node-469'" 825 x-transition:enter="transition ease-out duration-700" 826 x-transition:enter-start="opacity-0 -translate-y-2" 827 x-transition:enter-end="opacity-100 translate-y-0" 828 style="transition-delay: 0ms;" class="px-5 pb-2 md:px-10"> 829 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]"> 830 Locks </span> 831 </li> 832 <li x-show="mobilePanelActiveId === 'category-node-469'" 833 x-transition:enter="transition ease-out duration-700" 834 x-transition:enter-start="opacity-0 -translate-y-2" 835 x-transition:enter-end="opacity-100 translate-y-0" 836 style="transition-delay: 40ms;" class="px-5 pb-2 md:px-10"> 837 <a 838 href="https://www.banham.co.uk/locks/" 839 title="Locks" 840 > 841 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 842 All Locks </span> 843 </a> 844 </li> 845 <li 846 x-show="mobilePanelActiveId === 'category-node-469'" 847 x-transition:enter="transition ease-out duration-700" 848 x-transition:enter-start="opacity-0 -translate-y-2" 849 x-transition:enter-end="opacity-100 translate-y-0" 850 style="transition-delay: 80ms;" 851 class="px-5 pb-2 md:px-10"> 852 <a 853 href="https://www.banham.co.uk/locks/door-locks/" 854 title="Door Locks" 855 > 856 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 857 Door Locks </span> 858 </a> 859 </li> 860 <li 861 x-show="mobilePanelActiveId === 'category-node-469'" 862 x-transition:enter="transition ease-out duration-700" 863 x-transition:enter-start="opacity-0 -translate-y-2" 864 x-transition:enter-end="opacity-100 translate-y-0" 865 style="transition-delay: 120ms;" 866 class="px-5 pb-2 md:px-10"> 867 <a 868 href="https://www.banham.co.uk/locks/locks-additional-security/" 869 title="Window Locks & Door Bolts" 870 >
871 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 872 Window Locks & Door Bolts </span> 873 </a> 874 </li> 875 <li 876 x-show="mobilePanelActiveId === 'category-node-469'" 877 x-transition:enter="transition ease-out duration-700" 878 x-transition:enter-start="opacity-0 -translate-y-2" 879 x-transition:enter-end="opacity-100 translate-y-0" 880 style="transition-delay: 160ms;" 881 class="px-5 pb-2 md:px-10"> 882 <a 883 href="https://www.banham.co.uk/locks/keys-and-accessories/" 884 title="Keys, Fobs & Accessories" 885 > 886 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 887 Keys, Fobs & Accessories </span> 888 </a> 889 </li> 890 </ul> 891 <ul class="submenu-custom-link"> 892 <li x-show="mobilePanelActiveId === 'category-node-469'" 893 x-transition:enter="transition ease-out duration-700" 894 x-transition:enter-start="opacity-0 -translate-y-2" 895 x-transition:enter-end="opacity-100 translate-y-0" 896 style="transition-delay: 200ms;" 897 class="px-5 pt-10 pb-2 md:px-10"> 898 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]">SERVICES</span> 899 </li> 900 <li x-show="mobilePanelActiveId === 'category-node-469'" 901 x-transition:enter="transition ease-out duration-700" 902 x-transition:enter-start="opacity-0 -translate-y-2" 903 x-transition:enter-end="opacity-100 translate-y-0" 904 style="transition-delay: 240ms;" 905 class="px-5 pb-2 md:px-10"> 906 <a href="/locks/key-cutting-key-registration/" title="Keycutting and Key Registration"> 907 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Keycutting and Key Registration</span> 908 </a> 909 </li> 910 <li x-show="mobilePanelActiveId === 'category-node-469'" 911 x-transition:enter="transition ease-out duration-700" 912 x-transition:enter-start="opacity-0 -translate-y-2" 913 x-transition:enter-end="opacity-100 translate-y-0" 914 style="transition-delay: 280ms;" 915 class="px-5 pb-2 md:px-10"> 916 <a href="/locksmith-service/" title="Emergency Locksmiths">
917 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Emergency Locksmiths</span> 918 </a> 919 </li> 920 </ul> 921 <div x-show="mobilePanelActiveId === 'category-node-469'" 922 x-transition:enter="transition ease-out duration-700" 923 x-transition:enter-start="opacity-0 -translate-y-2" 924 x-transition:enter-end="opacity-100 translate-y-0" 925 style="transition-delay: 320ms;" 926 class="menu-cutom-block px-5 mt-[60px] md:px-10"> 927 <img src="https://a.storyblok.com/f/286600090739628/400x400/b01178a975/banham-locks-menu.png" alt="Banham door lock with a reflective surface, mounted on a dark blue door next to a white frame." class="w-full"/> 928 <div class="inner-detials flex flex-col gap-4 bg-primary px-7 pt-7 pb-[60px]"> 929 <h4 class="text-white mb-0">Trusted Since 1926</h4> 930 <p class="text-white mb-0"> Elegant, strong and secure: our locks come in 931a range of quality finishes.</p> 932 <a href="/locks" class="underline-link"><span class="text-white">Learn More</span></a> 933 </div> 934 </div> 935 </div> 936 </li> 937 <li 938 x-show="open" 939 data-child-id="category-node-472-main" 940 x-transition:enter="transition ease-out duration-700" 941 x-transition:enter-start="opacity-0 -translate-y-2" 942 x-transition:enter-end="opacity-100 translate-y-0" 943 style="transition-delay: 40ms;" 944 class="level-0 px-5 py-[6px] md:px-10" 945 :class="{ 'active': mobilePanelActiveId === 'category-node-472' }" 946 > 947 <div class="flex items-center transition-transform duration-150 ease-in-out transform"> 948 <a 949 class="relative flex items-center justify-between cursor-pointer level-0 w-full focus:border-primary-lighter focus:outline-none focus:ring-0 hover:text-primary-darker" 950 title="Doors" 951 @click="openSubcategory('category-node-472')" 952 aria-label="Open Doors subcategories" 953 aria-haspopup="true" 954 :aria-expanded="mobilePanelActiveId === 'category-node-472'" 955 > 956 Doors <i class="ti ti-chevron-right text-base"></i> 957 </a> 958 </div> 959 <div 960 data-child-id="category-node-472" 961 class="absolute top-[0] left-[0] flex flex-col w-full h-full bg-white border-l border-primary pt-16 pb-[60px] overflow-y-auto overflow-x-hidden lg:left-[480px] lg:max-w-[480px] lg:translate-x-0 max-lg:translate-x-full transition-transform duration-150 ease-in-out z-[-1] invisible pointer-events-none" 962 :class="{ 963 '!-translate-x-full invisible pointer-events-none': mobilePanelActiveId !== 'category-node-472', 964 'translate-x-0 visible pointer-events-auto': mobilePanelActiveId === 'category-node-472', 965 966 }" 967 > 968 <button 969 type="button" 970 class="absolute top-5 left-5 flex justify-start w-auto self-start cursor-pointer w-full md:left-10 lg:hidden focu
970s:border-primary-lighter focus:outline-none focus:ring-0" 971 @click="backToMainCategories('category-node-472-main')" 972 aria-label="Back to main categories" 973 > 974 <i class="ti ti-arrow-left text-xl"></i> 975 </button> 976 <ul aria-label="Subcategories"> 977 <li x-show="mobilePanelActiveId === 'category-node-472'" 978 x-transition:enter="transition ease-out duration-700" 979 x-transition:enter-start="opacity-0 -translate-y-2" 980 x-transition:enter-end="opacity-100 translate-y-0" 981 style="transition-delay: 0ms;" class="px-5 pb-2 md:px-10"> 982 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]"> 983 Doors </span> 984 </li> 985 <li x-show="mobilePanelActiveId === 'category-node-472'" 986 x-transition:enter="transition ease-out duration-700" 987 x-transition:enter-start="opacity-0 -translate-y-2" 988 x-transition:enter-end="opacity-100 translate-y-0" 989 style="transition-delay: 40ms;" class="px-5 pb-2 md:px-10"> 990 <a 991 href="https://www.banham.co.uk/doors/" 992 title="Doors" 993 > 994 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 995 All Doors </span> 996 </a> 997 </li> 998 <li 999 x-show="mobilePanelActiveId === 'category-node-472'" 1000 x-transition:enter="transition ease-out duration-700" 1001 x-transition:enter-start="opacity-0 -translate-y-2" 1002 x-transition:enter-end="opacity-100 translate-y-0" 1003 style="transition-delay: 80ms;" 1004 class="px-5 pb-2 md:px-10"> 1005 <a 1006 href="https://www.banham.co.uk/doors/security-doors/" 1007 title="Front Doors" 1008 > 1009 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1010 Front Doors </span> 1011 </a> 1012 </li> 1013 <li 1014 x-show="mobilePanelActiveId === 'category-node-472'" 1015 x-transition:enter="transition ease-out duration-700" 1016 x-transition:enter-start="opacity-0 -translate-y-2" 1017 x-transition:enter-end="opacity-100 translate-y-0" 1018 style="transition-delay: 120ms;" 1019 class="px-5 pb-2 md:px-10"> 1020 <a 1021 href="https://www.banham.co.uk/doors/fire-doors/" 1022 title="Fire Doors" 1023 >
1024 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1025 Fire Doors </span> 1026 </a> 1027 </li> 1028 <li 1029 x-show="mobilePanelActiveId === 'category-node-472'" 1030 x-transition:enter="transition ease-out duration-700" 1031 x-transition:enter-start="opacity-0 -translate-y-2" 1032 x-transition:enter-end="opacity-100 translate-y-0" 1033 style="transition-delay: 160ms;" 1034 class="px-5 pb-2 md:px-10"> 1035 <a 1036 href="https://www.banham.co.uk/doors/door-furniture/" 1037 title="Door Furniture" 1038 > 1039 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1040 Door Furniture </span> 1041 </a> 1042 </li> 1043 </ul> 1044 <ul class="submenu-custom-link"> 1045 <li x-show="mobilePanelActiveId === 'category-node-472'" 1046 x-transition:enter="transition ease-out duration-700" 1047 x-transition:enter-start="opacity-0 -translate-y-2" 1048 x-transition:enter-end="opacity-100 translate-y-0" 1049 style="transition-delay: 200ms;" 1050 class="px-5 pt-10 pb-2 md:px-10"> 1051 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]">Services</span> 1052 </li> 1053 <li x-show="mobilePanelActiveId === 'category-node-472'" 1054 x-transition:enter="transition ease-out duration-700" 1055 x-transition:enter-start="opacity-0 -translate-y-2" 1056 x-transition:enter-end="opacity-100 translate-y-0" 1057 style="transition-delay: 240ms;" 1058 class="px-5 pb-2 md:px-10"> 1059 <a href="/locks/key-cutting-key-registration/" title="Keycutting & Key Registration"> 1060 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Keycutting & Key Registration</span> 1061 </a> 1062 </li> 1063 <li x-show="mobilePanelActiveId === 'category-node-472'" 1064 x-transition:enter="transition ease-out duration-700" 1065 x-transition:enter-start="opacity-0 -translate-y-2" 1066 x-transition:enter-end="opacity-100 translate-y-0" 1067 style="transition-delay: 280ms;" 1068 class="px-5 pb-2 md:px-10"> 1069 <a href="/locksmith-service/" title="Emergency Locksmiths">
1070 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Emergency Locksmiths</span> 1071 </a> 1072 </li> 1073 </ul> 1074 <div x-show="mobilePanelActiveId === 'category-node-472'" 1075 x-transition:enter="transition ease-out duration-700" 1076 x-transition:enter-start="opacity-0 -translate-y-2" 1077 x-transition:enter-end="opacity-100 translate-y-0" 1078 style="transition-delay: 320ms;" 1079 class="menu-cutom-block px-5 mt-[60px] md:px-10"> 1080 <img src="https://a.storyblok.com/f/286600090739628/400x400/4dcd04b053/banham-doors-menu.png" alt="Bespoke Banham Blue door with stained glass panels featuring geometric patterns. Gold hardware and mail slot. Greenery visible on the side." class="w-full"/> 1081 <div class="inner-detials flex flex-col gap-4 bg-primary px-7 pt-7 pb-[60px]"> 1082 <h4 class="text-white mb-0">Doors</h4> 1083 <p class="text-white mb-0"> Security doors with bespoke design.</p> 1084 <a href="/doors" class="underline-link"><span class="text-white">Learn More</span></a> 1085 </div> 1086 </div> 1087 </div> 1088 </li> 1089 <li 1090 x-show="open" 1091 data-child-id="category-node-15-main" 1092 x-transition:enter="transition ease-out duration-700" 1093 x-transition:enter-start="opacity-0 -translate-y-2" 1094 x-transition:enter-end="opacity-100 translate-y-0" 1095 style="transition-delay: 80ms;" 1096 class="level-0 px-5 py-[6px] md:px-10" 1097 :class="{ 'active': mobilePanelActiveId === 'category-node-15' }" 1098 > 1099 <div class="flex items-center transition-transform duration-150 ease-in-out transform"> 1100 <a 1101 class="relative flex items-center justify-between cursor-pointer level-0 w-full focus:border-primary-lighter focus:outline-none focus:ring-0 hover:text-primary-darker" 1102 title="Burglar Alarms" 1103 @click="openSubcategory('category-node-15')" 1104 aria-label="Open Burglar Alarms subcategories" 1105 aria-haspopup="true" 1106 :aria-expanded="mobilePanelActiveId === 'category-node-15'" 1107 > 1108 Burglar Alarms <i class="ti ti-chevron-right text-base"></i> 1109 </a> 1110 </div> 1111 <div 1112 data-child-id="category-node-15" 1113 class="absolute top-[0] left-[0] flex flex-col w-full h-full bg-white border-l border-primary pt-16 pb-[60px] overflow-y-auto overflow-x-hidden lg:left-[480px] lg:max-w-[480px] lg:translate-x-0 max-lg:translate-x-full transition-transform duration-150 ease-in-out z-[-1] invisible pointer-events-none" 1114 :class="{ 1115 '!-translate-x-full invisible pointer-events-none': mobilePanelActiveId !== 'category-node-15', 1116 'translate-x-0 visible pointer-events-auto': mobilePanelActiveId === 'category-node-15', 1117 1118 }" 1119 > 1120 <button 1121 type="button" 1122 class="absolute top-5 left-5 flex justify-start w-auto self-start cursor-pointer w-full md:left-10 lg:hidden focu
1122s:border-primary-lighter focus:outline-none focus:ring-0" 1123 @click="backToMainCategories('category-node-15-main')" 1124 aria-label="Back to main categories" 1125 > 1126 <i class="ti ti-arrow-left text-xl"></i> 1127 </button> 1128 <ul aria-label="Subcategories"> 1129 <li x-show="mobilePanelActiveId === 'category-node-15'" 1130 x-transition:enter="transition ease-out duration-700" 1131 x-transition:enter-start="opacity-0 -translate-y-2" 1132 x-transition:enter-end="opacity-100 translate-y-0" 1133 style="transition-delay: 0ms;" class="px-5 pb-2 md:px-10"> 1134 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]"> 1135 Burglar Alarms </span> 1136 </li> 1137 <li x-show="mobilePanelActiveId === 'category-node-15'" 1138 x-transition:enter="transition ease-out duration-700" 1139 x-transition:enter-start="opacity-0 -translate-y-2" 1140 x-transition:enter-end="opacity-100 translate-y-0" 1141 style="transition-delay: 40ms;" class="px-5 pb-2 md:px-10"> 1142 <a 1143 href="https://www.banham.co.uk/burglar-alarms/" 1144 title="Burglar Alarms" 1145 > 1146 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1147 All Burglar Alarms </span> 1148 </a> 1149 </li> 1150 <li 1151 x-show="mobilePanelActiveId === 'category-node-15'" 1152 x-transition:enter="transition ease-out duration-700" 1153 x-transition:enter-start="opacity-0 -translate-y-2" 1154 x-transition:enter-end="opacity-100 translate-y-0" 1155 style="transition-delay: 80ms;" 1156 class="px-5 pb-2 md:px-10"> 1157 <a 1158 href="https://www.banham.co.uk/burglar-alarms/alarm-consultation/" 1159 title="Alarm Consultation" 1160 > 1161 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1162 Alarm Consultation </span> 1163 </a> 1164 </li> 1165 <li 1166 x-show="mobilePanelActiveId === 'category-node-15'" 1167 x-transition:enter="transition ease-out duration-700" 1168 x-transition:enter-start="opacity-0 -translate-y-2" 1169 x-transition:enter-end="opacity-100 translate-y-0" 1170 style="transition-delay: 120ms;" 1171 class="px-5 pb-2 md:px-10"> 1172 <a 1173 href="https://www.banham.co.uk/burglar-alarms/alarm-installation/" 1174 title="Alarm Installation" 1175 >
1176 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1177 Alarm Installation </span> 1178 </a> 1179 </li> 1180 <li 1181 x-show="mobilePanelActiveId === 'category-node-15'" 1182 x-transition:enter="transition ease-out duration-700" 1183 x-transition:enter-start="opacity-0 -translate-y-2" 1184 x-transition:enter-end="opacity-100 translate-y-0" 1185 style="transition-delay: 160ms;" 1186 class="px-5 pb-2 md:px-10"> 1187 <a 1188 href="https://www.banham.co.uk/burglar-alarms/car-shield/" 1189 title="Car Shield" 1190 > 1191 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1192 Car Shield </span> 1193 </a> 1194 </li> 1195 <li 1196 x-show="mobilePanelActiveId === 'category-node-15'" 1197 x-transition:enter="transition ease-out duration-700" 1198 x-transition:enter-start="opacity-0 -translate-y-2" 1199 x-transition:enter-end="opacity-100 translate-y-0" 1200 style="transition-delay: 200ms;" 1201 class="px-5 pb-2 md:px-10"> 1202 <a 1203 href="https://www.banham.co.uk/burglar-alarms/alarm-system-upgrade/" 1204 title="Upgrade Your Alarm System" 1205 > 1206 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1207 Upgrade Your Alarm System </span> 1208 </a> 1209 </li> 1210 </ul> 1211 <ul class="submenu-custom-link"> 1212 <li x-show="mobilePanelActiveId === 'category-node-15'" 1213 x-transition:enter="transition ease-out duration-700" 1214 x-transition:enter-start="opacity-0 -translate-y-2" 1215 x-transition:enter-end="opacity-100 translate-y-0" 1216 style="transition-delay: 240ms;" 1217 class="px-5 pt-10 pb-2 md:px-10"> 1218 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]">Services</span> 1219 </li> 1220 <li x-show="mobilePanelActiveId === 'category-node-15'" 1221 x-transition:enter="transition ease-out duration-700" 1222 x-transition:enter-start="opacity-0 -translate-y-2" 1223 x-transition:enter-end="opacity-100 translate-y-0" 1224 style="transition-delay: 280ms;" 1225 class="px-5 pb-2 md:px-10"> 1226 <a href="/burglar-alarms/alarm-monitoring/" title="Alarm Monitoring">
1227 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Alarm Monitoring</span> 1228 </a> 1229 </li> 1230 <li x-show="mobilePanelActiveId === 'category-node-15'" 1231 x-transition:enter="transition ease-out duration-700" 1232 x-transition:enter-start="opacity-0 -translate-y-2" 1233 x-transition:enter-end="opacity-100 translate-y-0" 1234 style="transition-delay: 320ms;" 1235 class="px-5 pb-2 md:px-10"> 1236 <a href="/burglar-alarms/banham-smart-security-app/" title="Smart Security App"> 1237 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Smart Security App</span> 1238 </a> 1239 </li> 1240 <li x-show="mobilePanelActiveId === 'category-node-15'" 1241 x-transition:enter="transition ease-out duration-700" 1242 x-transition:enter-start="opacity-0 -translate-y-2" 1243 x-transition:enter-end="opacity-100 translate-y-0" 1244 style="transition-delay: 360ms;" 1245 class="px-5 pb-2 md:px-10"> 1246 <a href="/keyholding/" title="Keyholding and Alarm Response"> 1247 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Keyholding and Alarm Response</span> 1248 </a> 1249 </li> 1250 <li x-show="mobilePanelActiveId === 'category-node-15'" 1251 x-transition:enter="transition ease-out duration-700" 1252 x-transition:enter-start="opacity-0 -translate-y-2" 1253 x-transition:enter-end="opacity-100 translate-y-0" 1254 style="transition-delay: 400ms;" 1255 class="px-5 pb-2 md:px-10"> 1256 <a href="/commercial" title="Banham Commercial"> 1257 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Banham Commercial</span> 1258 </a> 1259 </li> 1260 <li x-show="mobilePanelActiveId === 'category-node-15'" 1261 x-transition:enter="transition ease-out duration-700" 1262 x-transition:enter-start="opacity-0 -translate-y-2" 1263 x-transition:enter-end="opacity-100 translate-y-0" 1264 style="transition-delay: 440ms;" 1265 class="px-5 pb-2 md:px-10"> 1266 <a href="/pstn/" title="Digital Phone Switchover">
1267 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Digital Phone Switchover</span> 1268 </a> 1269 </li> 1270 </ul> 1271 <div x-show="mobilePanelActiveId === 'category-node-15'" 1272 x-transition:enter="transition ease-out duration-700" 1273 x-transition:enter-start="opacity-0 -translate-y-2" 1274 x-transition:enter-end="opacity-100 translate-y-0" 1275 style="transition-delay: 480ms;" 1276 class="menu-cutom-block px-5 mt-[60px] md:px-10"> 1277 <img src="https://a.storyblok.com/f/286600090739628/359x261/e65714dc7f/alarms-q3-megamenu.jpg" alt="" class="w-full"/> 1278 <div class="inner-detials flex flex-col gap-4 bg-primary px-7 pt-7 pb-[60px]"> 1279 <h4 class="text-white mb-0">Alarms</h4> 1280 <p class="text-white mb-0"> Bespoke-designed alarm systems installed and maintained by experts.</p> 1281 <a href="/burglar-alarms" class="underline-link"><span class="text-white">Learn More</span></a> 1282 </div> 1283 </div> 1284 </div> 1285 </li> 1286 <li 1287 x-show="open" 1288 data-child-id="category-node-4-main" 1289 x-transition:enter="transition ease-out duration-700" 1290 x-transition:enter-start="opacity-0 -translate-y-2" 1291 x-transition:enter-end="opacity-100 translate-y-0" 1292 style="transition-delay: 120ms;" 1293 class="level-0 px-5 py-[6px] md:px-10" 1294 :class="{ 'active': mobilePanelActiveId === 'category-node-4' }" 1295 > 1296 <div class="flex items-center transition-transform duration-150 ease-in-out transform"> 1297 <a 1298 class="relative flex items-center justify-between cursor-pointer level-0 w-full focus:border-primary-lighter focus:outline-none focus:ring-0 hover:text-primary-darker" 1299 title="CCTV" 1300 @click="openSubcategory('category-node-4')" 1301 aria-label="Open CCTV subcategories" 1302 aria-haspopup="true" 1303 :aria-expanded="mobilePanelActiveId === 'category-node-4'" 1304 > 1305 CCTV <i class="ti ti-chevron-right text-base"></i> 1306 </a> 1307 </div> 1308 <div 1309 data-child-id="category-node-4" 1310 class="absolute top-[0] left-[0] flex flex-col w-full h-full bg-white border-l border-primary pt-16 pb-[60px] overflow-y-auto overflow-x-hidden lg:left-[480px] lg:max-w-[480px] lg:translate-x-0 max-lg:translate-x-full transition-transform duration-150 ease-in-out z-[-1] invisible pointer-events-none" 1311 :class="{ 1312 '!-translate-x-full invisible pointer-events-none': mobilePanelActiveId !== 'category-node-4', 1313 'translate-x-0 visible pointer-events-auto': mobilePanelActiveId === 'category-node-4', 1314 1315 }" 1316 > 1317 <button 1318 type="button" 1319 class="absolute top-5 left-5 flex justify-start w-auto self-start cursor-pointer w-full md:left-10 lg:hidden focu
1319s:border-primary-lighter focus:outline-none focus:ring-0" 1320 @click="backToMainCategories('category-node-4-main')" 1321 aria-label="Back to main categories" 1322 > 1323 <i class="ti ti-arrow-left text-xl"></i> 1324 </button> 1325 <ul aria-label="Subcategories"> 1326 <li x-show="mobilePanelActiveId === 'category-node-4'" 1327 x-transition:enter="transition ease-out duration-700" 1328 x-transition:enter-start="opacity-0 -translate-y-2" 1329 x-transition:enter-end="opacity-100 translate-y-0" 1330 style="transition-delay: 0ms;" class="px-5 pb-2 md:px-10"> 1331 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]"> 1332 CCTV </span> 1333 </li> 1334 <li x-show="mobilePanelActiveId === 'category-node-4'" 1335 x-transition:enter="transition ease-out duration-700" 1336 x-transition:enter-start="opacity-0 -translate-y-2" 1337 x-transition:enter-end="opacity-100 translate-y-0" 1338 style="transition-delay: 40ms;" class="px-5 pb-2 md:px-10"> 1339 <a 1340 href="https://www.banham.co.uk/cctv-entry/" 1341 title="CCTV" 1342 > 1343 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1344 All CCTV </span> 1345 </a> 1346 </li> 1347 <li 1348 x-show="mobilePanelActiveId === 'category-node-4'" 1349 x-transition:enter="transition ease-out duration-700" 1350 x-transition:enter-start="opacity-0 -translate-y-2" 1351 x-transition:enter-end="opacity-100 translate-y-0" 1352 style="transition-delay: 80ms;" 1353 class="px-5 pb-2 md:px-10"> 1354 <a 1355 href="https://www.banham.co.uk/cctv-entry/cctv/" 1356 title="CCTV Systems" 1357 > 1358 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1359 CCTV Systems </span> 1360 </a> 1361 </li> 1362 <li 1363 x-show="mobilePanelActiveId === 'category-node-4'" 1364 x-transition:enter="transition ease-out duration-700" 1365 x-transition:enter-start="opacity-0 -translate-y-2" 1366 x-transition:enter-end="opacity-100 translate-y-0" 1367 style="transition-delay: 120ms;" 1368 class="px-5 pb-2 md:px-10"> 1369 <a 1370 href="https://www.banham.co.uk/cctv-entry/entry-access-control-systems/" 1371 title="Entry & Access Control Systems" 1372 >
1373 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1374 Entry & Access Control Systems </span> 1375 </a> 1376 </li> 1377 </ul> 1378 <ul class="submenu-custom-link"> 1379 <li x-show="mobilePanelActiveId === 'category-node-4'" 1380 x-transition:enter="transition ease-out duration-700" 1381 x-transition:enter-start="opacity-0 -translate-y-2" 1382 x-transition:enter-end="opacity-100 translate-y-0" 1383 style="transition-delay: 160ms;" 1384 class="px-5 pt-10 pb-2 md:px-10"> 1385 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]">Services</span> 1386 </li> 1387 <li x-show="mobilePanelActiveId === 'category-node-4'" 1388 x-transition:enter="transition ease-out duration-700" 1389 x-transition:enter-start="opacity-0 -translate-y-2" 1390 x-transition:enter-end="opacity-100 translate-y-0" 1391 style="transition-delay: 200ms;" 1392 class="px-5 pb-2 md:px-10"> 1393 <a href="/cctv-entry/cctv/cctv-monitoring-services/" title="CCTV Monitoring"> 1394 <span class="relative text-sm text-primary-darker hover:text-primary-darker">CCTV Monitoring</span> 1395 </a> 1396 </li> 1397 <li x-show="mobilePanelActiveId === 'category-node-4'" 1398 x-transition:enter="transition ease-out duration-700" 1399 x-transition:enter-start="opacity-0 -translate-y-2" 1400 x-transition:enter-end="opacity-100 translate-y-0" 1401 style="transition-delay: 240ms;" 1402 class="px-5 pb-2 md:px-10"> 1403 <a href="/keyholding/" title="Keyholding and Alarm Response"> 1404 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Keyholding and Alarm Response</span> 1405 </a> 1406 </li> 1407 <li x-show="mobilePanelActiveId === 'category-node-4'" 1408 x-transition:enter="transition ease-out duration-700" 1409 x-transition:enter-start="opacity-0 -translate-y-2" 1410 x-transition:enter-end="opacity-100 translate-y-0" 1411 style="transition-delay: 280ms;" 1412 class="px-5 pb-2 md:px-10"> 1413 <a href="/cctv-entry/cctv/routine-cctv-maintenance-24-hour-service/" title="Routine CCTV Maintenance and 24-Hour Service">
1414 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Routine CCTV Maintenance and 24-Hour Service</span> 1415 </a> 1416 </li> 1417 <li x-show="mobilePanelActiveId === 'category-node-4'" 1418 x-transition:enter="transition ease-out duration-700" 1419 x-transition:enter-start="opacity-0 -translate-y-2" 1420 x-transition:enter-end="opacity-100 translate-y-0" 1421 style="transition-delay: 320ms;" 1422 class="px-5 pb-2 md:px-10"> 1423 <a href="/commercial" title="Banham Commercial"> 1424 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Banham Commercial</span> 1425 </a> 1426 </li> 1427 <li x-show="mobilePanelActiveId === 'category-node-4'" 1428 x-transition:enter="transition ease-out duration-700" 1429 x-transition:enter-start="opacity-0 -translate-y-2" 1430 x-transition:enter-end="opacity-100 translate-y-0" 1431 style="transition-delay: 360ms;" 1432 class="px-5 pb-2 md:px-10"> 1433 <a href="/pstn/" title="Digital Phone Switchover"> 1434 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Digital Phone Switchover</span> 1435 </a> 1436 </li> 1437 <li x-show="mobilePanelActiveId === 'category-node-4'" 1438 x-transition:enter="transition ease-out duration-700" 1439 x-transition:enter-start="opacity-0 -translate-y-2" 1440 x-transition:enter-end="opacity-100 translate-y-0" 1441 style="transition-delay: 400ms;" 1442 class="px-5 pb-2 md:px-10"> 1443 <a href="/direct-debits/" title="Direct Debit Options"> 1444 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Direct Debit Options</span> 1445 </a> 1446 </li> 1447 </ul> 1448 <div x-show="mobilePanelActiveId === 'category-node-4'" 1449 x-transition:enter="transition ease-out duration-700" 1450 x-transition:enter-start="opacity-0 -translate-y-2" 1451 x-transition:enter-end="opacity-100 translate-y-0" 1452 style="transition-delay: 440ms;" 1453 class="menu-cutom-block px-5 mt-[60px] md:px-10"> 1454 <img src="https://a.storyblok.com/f/286600090739628/359x261/5e9a2dae8f/meganav_cctv_entry2.jpg" alt="" class="w-full"/> 1455 <div class="inner-detials flex flex-col gap-4 bg-primary px-7 pt-7 pb-[60px]"> 1456 <h4 class="text-white mb-0">CCTV & Entry</h4> 1457 <p class="text-white mb-0"> Intelligent CCTV and entry systems tailored to your property.</p> 1458 <a href="/cctv-entry" class="underline-link"><span class="text-white">Learn More</span></a> 1459 </div> 1460 </div> 1461 </div> 1462 </li> 1463 <li 1464 x-show="open" 1465 data-child-id="category-node-30-main" 1466 x-transition:enter="transition ease-out duration-700" 1467 x-transition:enter-start="opacity-0 -translate-y-2" 1468 x-transition:enter-end="opacity-100 translate-y-0" 1469 style="transition-delay: 160ms;" 1470 class="level-0 px-5 py-[6px] md:px-10" 1471 :class="{ 'active': mobilePanelActiveId === 'category-node-30' }" 1472 > 1473 <div class="flex items-center transition-transform duration-150 ease-in-out transform"> 1474 <a 1475 class="relative flex items-center justify-between cursor-pointer level-0 w-full focus:border-primary-lighter focus:outline-none focus:ring-0 hover:text-primary-darker" 1476 title="Fire Alarms" 1477 @click="openSubcategory('category-node-30')" 1478 aria-label="Open Fire Alarms subcategories" 1479 aria-haspopup="true" 1480 :aria-expanded="mobilePanelActiveId === 'category-node-30'" 1481 > 1482 Fire Alarms <i class="ti ti-chevron-right text-base"></i> 1483 </a> 1484 </div> 1485 <div 1486 data-child-id="category-node-30" 1487 class="absolute top-[0] left-[0] flex flex-col w-full h-full bg-white border-l border-primary pt-16 pb-[60px] overflow-y-auto overflow-x-hidden lg:left-[480px] lg:max-w-[480px] lg:translate-x-0 max-lg:translate-x-full transition-transform duration-150 ease-in-out z-[-1] invisible pointer-events-none" 1488 :class="{ 1489 '!-translate-x-full invisible pointer-events-none': mobilePanelActiveId !== 'category-node-30', 1490 'translate-x-0 visible pointer-events-auto': mobilePanelActiveId === 'category-node-30', 1491 1492 }" 1493 > 1494 <button 1495 type="button" 1496 class="absolute top-5 left-5 flex justify-start w-auto self-start cursor-pointer w-full md:left-10 lg:hidden focu
1496s:border-primary-lighter focus:outline-none focus:ring-0" 1497 @click="backToMainCategories('category-node-30-main')" 1498 aria-label="Back to main categories" 1499 > 1500 <i class="ti ti-arrow-left text-xl"></i> 1501 </button> 1502 <ul aria-label="Category content"> 1503 <li x-show="mobilePanelActiveId === 'category-node-30'" 1504 x-transition:enter="transition ease-out duration-700" 1505 x-transition:enter-start="opacity-0 -translate-y-2" 1506 x-transition:enter-end="opacity-100 translate-y-0" 1507 style="transition-delay: 0ms;" class="px-5 pb-2 md:px-10"> 1508 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]"> 1509 Fire Alarms </span> 1510 </li> 1511 <li x-show="mobilePanelActiveId === 'category-node-30'" 1512 x-transition:enter="transition ease-out duration-700" 1513 x-transition:enter-start="opacity-0 -translate-y-2" 1514 x-transition:enter-end="opacity-100 translate-y-0" 1515 style="transition-delay: 40ms;" class="px-5 pb-2 md:px-10"> 1516 <a 1517 href="https://www.banham.co.uk/fire-alarms/" 1518 title="Fire Alarms" 1519 > 1520 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1521 All Fire Alarms </span> 1522 </a> 1523 </li> 1524 </ul> 1525 <ul class="submenu-custom-link"> 1526 <li x-show="mobilePanelActiveId === 'category-node-30'" 1527 x-transition:enter="transition ease-out duration-700" 1528 x-transition:enter-start="opacity-0 -translate-y-2" 1529 x-transition:enter-end="opacity-100 translate-y-0" 1530 style="transition-delay: 80ms;" 1531 class="px-5 pt-10 pb-2 md:px-10"> 1532 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]">Related products and services</span> 1533 </li> 1534 <li x-show="mobilePanelActiveId === 'category-node-30'" 1535 x-transition:enter="transition ease-out duration-700" 1536 x-transition:enter-start="opacity-0 -translate-y-2" 1537 x-transition:enter-end="opacity-100 translate-y-0" 1538 style="transition-delay: 120ms;" 1539 class="px-5 pb-2 md:px-10"> 1540 <a href="/fire-extinguishers/" title="Fire Extinguishers">
1541 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Fire Extinguishers</span> 1542 </a> 1543 </li> 1544 <li x-show="mobilePanelActiveId === 'category-node-30'" 1545 x-transition:enter="transition ease-out duration-700" 1546 x-transition:enter-start="opacity-0 -translate-y-2" 1547 x-transition:enter-end="opacity-100 translate-y-0" 1548 style="transition-delay: 160ms;" 1549 class="px-5 pb-2 md:px-10"> 1550 <a href="/doors/fire-doors/" title="Fire Doors"> 1551 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Fire Doors</span> 1552 </a> 1553 </li> 1554 <li x-show="mobilePanelActiveId === 'category-node-30'" 1555 x-transition:enter="transition ease-out duration-700" 1556 x-transition:enter-start="opacity-0 -translate-y-2" 1557 x-transition:enter-end="opacity-100 translate-y-0" 1558 style="transition-delay: 200ms;" 1559 class="px-5 pb-2 md:px-10"> 1560 <a href="/burglar-alarms/alarm-monitoring/" title="Alarm Monitoring"> 1561 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Alarm Monitoring</span> 1562 </a> 1563 </li> 1564 <li x-show="mobilePanelActiveId === 'category-node-30'" 1565 x-transition:enter="transition ease-out duration-700" 1566 x-transition:enter-start="opacity-0 -translate-y-2" 1567 x-transition:enter-end="opacity-100 translate-y-0" 1568 style="transition-delay: 240ms;" 1569 class="px-5 pb-2 md:px-10"> 1570 <a href="/keyholding/" title="Keyholding and Alarm Response"> 1571 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Keyholding and Alarm Response</span> 1572 </a> 1573 </li> 1574 <li x-show="mobilePanelActiveId === 'category-node-30'" 1575 x-transition:enter="transition ease-out duration-700" 1576 x-transition:enter-start="opacity-0 -translate-y-2" 1577 x-transition:enter-end="opacity-100 translate-y-0" 1578 style="transition-delay: 280ms;" 1579 class="px-5 pb-2 md:px-10"> 1580 <a href="/burglar-alarms/routine-alarm-maintenance-24-hour-service/" title="Alarm Maintenance 24/7">
1581 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Alarm Maintenance 24/7</span> 1582 </a> 1583 </li> 1584 <li x-show="mobilePanelActiveId === 'category-node-30'" 1585 x-transition:enter="transition ease-out duration-700" 1586 x-transition:enter-start="opacity-0 -translate-y-2" 1587 x-transition:enter-end="opacity-100 translate-y-0" 1588 style="transition-delay: 320ms;" 1589 class="px-5 pb-2 md:px-10"> 1590 <a href="/commercial" title="Banham Commercial"> 1591 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Banham Commercial</span> 1592 </a> 1593 </li> 1594 </ul> 1595 <div x-show="mobilePanelActiveId === 'category-node-30'" 1596 x-transition:enter="transition ease-out duration-700" 1597 x-transition:enter-start="opacity-0 -translate-y-2" 1598 x-transition:enter-end="opacity-100 translate-y-0" 1599 style="transition-delay: 360ms;" 1600 class="menu-cutom-block px-5 mt-[60px] md:px-10"> 1601 <img src="https://a.storyblok.com/f/286600090739628/359x261/acdca88f26/burglar_alarms_and_fire.jpg" alt="" class="w-full"/> 1602 <div class="inner-detials flex flex-col gap-4 bg-primary px-7 pt-7 pb-[60px]"> 1603 <h4 class="text-white mb-0">Alarms & CCTV</h4> 1604 <p class="text-white mb-0"> Bespoke-designed alarm systems installed and maintained by experts.</p> 1605 <a href="/fire-alarms" class="underline-link"><span class="text-white">Learn More</span></a> 1606 </div> 1607 </div> 1608 </div> 1609 </li> 1610 <li 1611 x-show="open" 1612 data-child-id="category-node-6-main" 1613 x-transition:enter="transition ease-out duration-700" 1614 x-transition:enter-start="opacity-0 -translate-y-2" 1615 x-transition:enter-end="opacity-100 translate-y-0" 1616 style="transition-delay: 200ms;" 1617 class="level-0 px-5 py-[6px] md:px-10" 1618 :class="{ 'active': mobilePanelActiveId === 'category-node-6' }" 1619 > 1620 <div class="flex items-center transition-transform duration-150 ease-in-out transform"> 1621 <a 1622 class="relative flex items-center justify-between cursor-pointer level-0 w-full focus:border-primary-lighter focus:outline-none focus:ring-0 hover:text-primary-darker" 1623 title="Safes" 1624 @click="openSubcategory('category-node-6')" 1625 aria-label="Open Safes subcategories" 1626 aria-haspopup="true" 1627 :aria-expanded="mobilePanelActiveId === 'category-node-6'" 1628 > 1629 Safes <i class="ti ti-chevron-right text-base"></i> 1630 </a> 1631 </div> 1632 <div 1633 data-child-id="category-node-6" 1634 class="absolute top-[0] left-[0] flex flex-col w-full h-full bg-white border-l border-primary pt-16 pb-[60px] overflow-y-auto overflow-x-hidden lg:left-[480px] lg:max-w-[480px] lg:translate-x-0 max-lg:translate-x-full transition-transform duration-150 ease-in-out z-[-1] invisible pointer-events-none" 1635 :class="{ 1636 '!-translate-x-full invisible pointer-events-none': mobilePanelActiveId !== 'category-node-6', 1637 'translate-x-0 visible pointer-events-auto': mobilePanelActiveId === 'category-node-6', 1638 1639 }" 1640 > 1641 <button 1642 type="button" 1643 class="absolute top-5 left-5 flex justify-start w-auto self-start cursor-pointer w-full md:left-10 lg:hidden focu
1643s:border-primary-lighter focus:outline-none focus:ring-0" 1644 @click="backToMainCategories('category-node-6-main')" 1645 aria-label="Back to main categories" 1646 > 1647 <i class="ti ti-arrow-left text-xl"></i> 1648 </button> 1649 <ul aria-label="Subcategories"> 1650 <li x-show="mobilePanelActiveId === 'category-node-6'" 1651 x-transition:enter="transition ease-out duration-700" 1652 x-transition:enter-start="opacity-0 -translate-y-2" 1653 x-transition:enter-end="opacity-100 translate-y-0" 1654 style="transition-delay: 0ms;" class="px-5 pb-2 md:px-10"> 1655 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]"> 1656 Safes </span> 1657 </li> 1658 <li x-show="mobilePanelActiveId === 'category-node-6'" 1659 x-transition:enter="transition ease-out duration-700" 1660 x-transition:enter-start="opacity-0 -translate-y-2" 1661 x-transition:enter-end="opacity-100 translate-y-0" 1662 style="transition-delay: 40ms;" class="px-5 pb-2 md:px-10"> 1663 <a 1664 href="https://www.banham.co.uk/safes/" 1665 title="Safes" 1666 > 1667 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1668 All Safes </span> 1669 </a> 1670 </li> 1671 <li 1672 x-show="mobilePanelActiveId === 'category-node-6'" 1673 x-transition:enter="transition ease-out duration-700" 1674 x-transition:enter-start="opacity-0 -translate-y-2" 1675 x-transition:enter-end="opacity-100 translate-y-0" 1676 style="transition-delay: 80ms;" 1677 class="px-5 pb-2 md:px-10"> 1678 <a 1679 href="https://www.banham.co.uk/bespoke-safes/" 1680 title="Bespoke Safes" 1681 > 1682 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1683 Bespoke Safes </span> 1684 </a> 1685 </li> 1686 <li 1687 x-show="mobilePanelActiveId === 'category-node-6'" 1688 x-transition:enter="transition ease-out duration-700" 1689 x-transition:enter-start="opacity-0 -translate-y-2" 1690 x-transition:enter-end="opacity-100 translate-y-0" 1691 style="transition-delay: 120ms;" 1692 class="px-5 pb-2 md:px-10"> 1693 <a 1694 href="https://www.banham.co.uk/safes/freestanding-safes/" 1695 title="Freestanding Safes" 1696 >
1697 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1698 Freestanding Safes </span> 1699 </a> 1700 </li> 1701 </ul> 1702 <ul class="submenu-custom-link"> 1703 <li x-show="mobilePanelActiveId === 'category-node-6'" 1704 x-transition:enter="transition ease-out duration-700" 1705 x-transition:enter-start="opacity-0 -translate-y-2" 1706 x-transition:enter-end="opacity-100 translate-y-0" 1707 style="transition-delay: 160ms;" 1708 class="px-5 pt-10 pb-2 md:px-10"> 1709 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]">Services</span> 1710 </li> 1711 <li x-show="mobilePanelActiveId === 'category-node-6'" 1712 x-transition:enter="transition ease-out duration-700" 1713 x-transition:enter-start="opacity-0 -translate-y-2" 1714 x-transition:enter-end="opacity-100 translate-y-0" 1715 style="transition-delay: 200ms;" 1716 class="px-5 pb-2 md:px-10"> 1717 <a href="/safes/safe-services/" title="Safe Services"> 1718 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Safe Services</span> 1719 </a> 1720 </li> 1721 <li x-show="mobilePanelActiveId === 'category-node-6'" 1722 x-transition:enter="transition ease-out duration-700" 1723 x-transition:enter-start="opacity-0 -translate-y-2" 1724 x-transition:enter-end="opacity-100 translate-y-0" 1725 style="transition-delay: 240ms;" 1726 class="px-5 pb-2 md:px-10"> 1727 <a href="/locksmith-service/" title="Emergency Locksmiths"> 1728 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Emergency Locksmiths</span> 1729 </a> 1730 </li> 1731 </ul> 1732 <div x-show="mobilePanelActiveId === 'category-node-6'" 1733 x-transition:enter="transition ease-out duration-700" 1734 x-transition:enter-start="opacity-0 -translate-y-2" 1735 x-transition:enter-end="opacity-100 translate-y-0" 1736 style="transition-delay: 280ms;" 1737 class="menu-cutom-block px-5 mt-[60px] md:px-10"> 1738 <img src="https://a.storyblok.com/f/286600090739628/359x261/2f56f4ebea/meganav_safes.png" alt="" class="w-full"/> 1739 <div class="inner-detials flex flex-col gap-4 bg-primary px-7 pt-7 pb-[60px]"> 1740 <h4 class="text-white mb-0">Safes</h4> 1741 <p class="text-white mb-0"> Beautifully-designed, insurance-approved safes to keep your valuables secure.</p> 1742 <a href="/safes" class="underline-link"><span class="text-white">Learn More</span></a> 1743 </div> 1744 </div> 1745 </div> 1746 </li> 1747 <li 1748 x-show="open" 1749 data-child-id="category-node-7-main" 1750 x-transition:enter="transition ease-out duration-700" 1751 x-transition:enter-start="opacity-0 -translate-y-2" 1752 x-transition:enter-end="opacity-100 translate-y-0" 1753 style="transition-delay: 240ms;" 1754 class="level-0 px-5 py-[6px] md:px-10" 1755 :class="{ 'active': mobilePanelActiveId === 'category-node-7' }" 1756 > 1757 <div class="flex items-center transition-transform duration-150 ease-in-out transform"> 1758 <a 1759 class="relative flex items-center justify-between cursor-pointer level-0 w-full focus:border-primary-lighter focus:outline-none focus:ring-0 hover:text-primary-darker" 1760 title="Gates & Grilles" 1761 @click="openSubcategory('category-node-7')" 1762 aria-label="Open Gates & Grilles subcategories" 1763 aria-haspopup="true" 1764 :aria-expanded="mobilePanelActiveId === 'category-node-7'" 1765 > 1766 Gates & Grilles <i class="ti ti-chevron-right text-base"></i> 1767 </a> 1768 </div> 1769 <div 1770 data-child-id="category-node-7" 1771 class="absolute top-[0] left-[0] flex flex-col w-full h-full bg-white border-l border-primary pt-16 pb-[60px] overflow-y-auto overflow-x-hidden lg:left-[480px] lg:max-w-[480px] lg:translate-x-0 max-lg:translate-x-full transition-transform duration-150 ease-in-out z-[-1] invisible pointer-events-none" 1772 :class="{ 1773 '!-translate-x-full invisible pointer-events-none': mobilePanelActiveId !== 'category-node-7', 1774 'translate-x-0 visible pointer-events-auto': mobilePanelActiveId === 'category-node-7', 1775 1776 }" 1777 > 1778 <button 1779 type="button" 1780 class="absolute top-5 left-5 flex justify-start w-auto self-start cursor-pointer w-full md:left-10 lg:hidden focu
1780s:border-primary-lighter focus:outline-none focus:ring-0" 1781 @click="backToMainCategories('category-node-7-main')" 1782 aria-label="Back to main categories" 1783 > 1784 <i class="ti ti-arrow-left text-xl"></i> 1785 </button> 1786 <ul aria-label="Subcategories"> 1787 <li x-show="mobilePanelActiveId === 'category-node-7'" 1788 x-transition:enter="transition ease-out duration-700" 1789 x-transition:enter-start="opacity-0 -translate-y-2" 1790 x-transition:enter-end="opacity-100 translate-y-0" 1791 style="transition-delay: 0ms;" class="px-5 pb-2 md:px-10"> 1792 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]"> 1793 Gates & Grilles </span> 1794 </li> 1795 <li x-show="mobilePanelActiveId === 'category-node-7'" 1796 x-transition:enter="transition ease-out duration-700" 1797 x-transition:enter-start="opacity-0 -translate-y-2" 1798 x-transition:enter-end="opacity-100 translate-y-0" 1799 style="transition-delay: 40ms;" class="px-5 pb-2 md:px-10"> 1800 <a 1801 href="https://www.banham.co.uk/gates-grilles-shutters/" 1802 title="Gates & Grilles" 1803 > 1804 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1805 All Gates & Grilles </span> 1806 </a> 1807 </li> 1808 <li 1809 x-show="mobilePanelActiveId === 'category-node-7'" 1810 x-transition:enter="transition ease-out duration-700" 1811 x-transition:enter-start="opacity-0 -translate-y-2" 1812 x-transition:enter-end="opacity-100 translate-y-0" 1813 style="transition-delay: 80ms;" 1814 class="px-5 pb-2 md:px-10"> 1815 <a 1816 href="https://www.banham.co.uk/gates-grilles-shutters/gates/" 1817 title="Security Gates" 1818 > 1819 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1820 Security Gates </span> 1821 </a> 1822 </li> 1823 <li 1824 x-show="mobilePanelActiveId === 'category-node-7'" 1825 x-transition:enter="transition ease-out duration-700" 1826 x-transition:enter-start="opacity-0 -translate-y-2" 1827 x-transition:enter-end="opacity-100 translate-y-0" 1828 style="transition-delay: 120ms;" 1829 class="px-5 pb-2 md:px-10"> 1830 <a 1831 href="https://www.banham.co.uk/gates-grilles-shutters/gr
1831illes/" 1832 title="Security Grilles" 1833 > 1834 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1835 Security Grilles </span> 1836 </a> 1837 </li> 1838 <li 1839 x-show="mobilePanelActiveId === 'category-node-7'" 1840 x-transition:enter="transition ease-out duration-700" 1841 x-transition:enter-start="opacity-0 -translate-y-2" 1842 x-transition:enter-end="opacity-100 translate-y-0" 1843 style="transition-delay: 160ms;" 1844 class="px-5 pb-2 md:px-10"> 1845 <a 1846 href="https://www.banham.co.uk/gates-grilles-shutters/railings/" 1847 title="Railings" 1848 > 1849 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1850 Railings </span> 1851 </a> 1852 </li> 1853 <li 1854 x-show="mobilePanelActiveId === 'category-node-7'" 1855 x-transition:enter="transition ease-out duration-700" 1856 x-transition:enter-start="opacity-0 -translate-y-2" 1857 x-transition:enter-end="opacity-100 translate-y-0" 1858 style="transition-delay: 200ms;" 1859 class="px-5 pb-2 md:px-10"> 1860 <a 1861 href="https://www.banham.co.uk/gates-grilles-shutters/roller-shutters/" 1862 title="Roller Shutters" 1863 > 1864 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1865 Roller Shutters </span> 1866 </a> 1867 </li> 1868 </ul> 1869 <ul class="submenu-custom-link"> 1870 <li x-show="mobilePanelActiveId === 'category-node-7'" 1871 x-transition:enter="transition ease-out duration-700" 1872 x-transition:enter-start="opacity-0 -translate-y-2" 1873 x-transition:enter-end="opacity-100 translate-y-0" 1874 style="transition-delay: 240ms;" 1875 class="px-5 pt-10 pb-2 md:px-10"> 1876 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]">Related Products </span> 1877 </li> 1878 <li x-show="mobilePanelActiveId === 'category-node-7'" 1879 x-transition:enter="transition ease-out duration-700" 1880 x-transition:enter-start="opacity-0 -translate-y-2" 1881 x-transition:enter-end="opacity-100 translate-y-0" 1882 style="transition-delay: 280ms;" 1883 class="px-5 pb-2 md:px-10"> 1884 <a href="/locks/key-cutting-key-registration/" title="Keycutting and Key Registration">
1885 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Keycutting and Key Registration</span> 1886 </a> 1887 </li> 1888 <li x-show="mobilePanelActiveId === 'category-node-7'" 1889 x-transition:enter="transition ease-out duration-700" 1890 x-transition:enter-start="opacity-0 -translate-y-2" 1891 x-transition:enter-end="opacity-100 translate-y-0" 1892 style="transition-delay: 320ms;" 1893 class="px-5 pb-2 md:px-10"> 1894 <a href="/locksmith-service/" title="Emergency Locksmiths"> 1895 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Emergency Locksmiths</span> 1896 </a> 1897 </li> 1898 <li x-show="mobilePanelActiveId === 'category-node-7'" 1899 x-transition:enter="transition ease-out duration-700" 1900 x-transition:enter-start="opacity-0 -translate-y-2" 1901 x-transition:enter-end="opacity-100 translate-y-0" 1902 style="transition-delay: 360ms;" 1903 class="px-5 pb-2 md:px-10"> 1904 <a href="/commercial" title="Banham Commercial"> 1905 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Banham Commercial</span> 1906 </a> 1907 </li> 1908 </ul> 1909 <div x-show="mobilePanelActiveId === 'category-node-7'" 1910 x-transition:enter="transition ease-out duration-700" 1911 x-transition:enter-start="opacity-0 -translate-y-2" 1912 x-transition:enter-end="opacity-100 translate-y-0" 1913 style="transition-delay: 400ms;" 1914 class="menu-cutom-block px-5 mt-[60px] md:px-10"> 1915 <img src="https://a.storyblok.com/f/286600090739628/359x261/4001e6e188/meganav_gates_grilles_shutters.png" alt="" class="w-full"/> 1916 <div class="inner-detials flex flex-col gap-4 bg-primary px-7 pt-7 pb-[60px]"> 1917 <h4 class="text-white mb-0">Gates, Grilles & Shutters</h4> 1918 <p class="text-white mb-0"> Sturdy gates, grilles and shutters we can customise to match your property.</p> 1919 <a href="/gates-grilles-shutters/" class="underline-link"><span class="text-white">Learn More</span></a> 1920 </div> 1921 </div> 1922 </div> 1923 </li> 1924 <li 1925 x-show="open" 1926 data-child-id="category-node-54-main" 1927 x-transition:enter="transition ease-out duration-700" 1928 x-transition:enter-start="opacity-0 -translate-y-2" 1929 x-transition:enter-end="opacity-100 translate-y-0" 1930 style="transition-delay: 280ms;" 1931 class="level-0 px-5 py-[6px] md:px-10" 1932 :class="{ 'active': mobilePanelActiveId === 'category-node-54' }" 1933 > 1934 <div class="flex items-center transition-transform duration-150 ease-in-out transform"> 1935 <a 1936 class="relative flex items-center justify-between cursor-pointer level-0 w-full focus:border-primary-lighter focus:outline-none focus:ring-0 hover:text-primary-darker" 1937 title="Keyholding" 1938 @click="openSubcategory('category-node-54')" 1939 aria-label="Open Keyholding subcategories" 1940 aria-haspopup="true" 1941 :aria-expanded="mobilePanelActiveId === 'category-node-54'" 1942 > 1943 Keyholding <i class="ti ti-chevron-right text-base"></i> 1944 </a> 1945 </div> 1946 <div 1947 data-child-id="category-node-54" 1948 class="absolute top-[0] left-[0] flex flex-col w-full h-full bg-white border-l border-primary pt-16 pb-[60px] overflow-y-auto overflow-x-hidden lg:left-[480px] lg:max-w-[480px] lg:translate-x-0 max-lg:translate-x-full transition-transform duration-150 ease-in-out z-[-1] invisible pointer-events-none" 1949 :class="{ 1950 '!-translate-x-full invisible pointer-events-none': mobilePanelActiveId !== 'category-node-54', 1951 'translate-x-0 visible pointer-events-auto': mobilePanelActiveId === 'category-node-54', 1952 1953 }" 1954 > 1955 <button 1956 type="button" 1957 class="absolute top-5 left-5 flex justify-start w-auto self-start cursor-pointer w-full md:left-10 lg:hidden focu
1957s:border-primary-lighter focus:outline-none focus:ring-0" 1958 @click="backToMainCategories('category-node-54-main')" 1959 aria-label="Back to main categories" 1960 > 1961 <i class="ti ti-arrow-left text-xl"></i> 1962 </button> 1963 <ul aria-label="Subcategories"> 1964 <li x-show="mobilePanelActiveId === 'category-node-54'" 1965 x-transition:enter="transition ease-out duration-700" 1966 x-transition:enter-start="opacity-0 -translate-y-2" 1967 x-transition:enter-end="opacity-100 translate-y-0" 1968 style="transition-delay: 0ms;" class="px-5 pb-2 md:px-10"> 1969 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]"> 1970 Keyholding </span> 1971 </li> 1972 <li x-show="mobilePanelActiveId === 'category-node-54'" 1973 x-transition:enter="transition ease-out duration-700" 1974 x-transition:enter-start="opacity-0 -translate-y-2" 1975 x-transition:enter-end="opacity-100 translate-y-0" 1976 style="transition-delay: 40ms;" class="px-5 pb-2 md:px-10"> 1977 <a 1978 href="https://www.banham.co.uk/keyholding/" 1979 title="Keyholding" 1980 > 1981 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1982 All Keyholding </span> 1983 </a> 1984 </li> 1985 <li 1986 x-show="mobilePanelActiveId === 'category-node-54'" 1987 x-transition:enter="transition ease-out duration-700" 1988 x-transition:enter-start="opacity-0 -translate-y-2" 1989 x-transition:enter-end="opacity-100 translate-y-0" 1990 style="transition-delay: 80ms;" 1991 class="px-5 pb-2 md:px-10"> 1992 <a 1993 href="https://www.banham.co.uk/keyholding/residential/" 1994 title="For Homes" 1995 > 1996 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 1997 For Homes </span> 1998 </a> 1999 </li> 2000 <li 2001 x-show="mobilePanelActiveId === 'category-node-54'" 2002 x-transition:enter="transition ease-out duration-700" 2003 x-transition:enter-start="opacity-0 -translate-y-2" 2004 x-transition:enter-end="opacity-100 translate-y-0" 2005 style="transition-delay: 120ms;" 2006 class="px-5 pb-2 md:px-10"> 2007 <a 2008 href="https://www.banham.co.uk/keyholding/pricing/" 2009 title="Pricing" 2010 >
2011 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 2012 Pricing </span> 2013 </a> 2014 </li> 2015 </ul> 2016 <ul class="submenu-custom-link"> 2017 <li x-show="mobilePanelActiveId === 'category-node-54'" 2018 x-transition:enter="transition ease-out duration-700" 2019 x-transition:enter-start="opacity-0 -translate-y-2" 2020 x-transition:enter-end="opacity-100 translate-y-0" 2021 style="transition-delay: 160ms;" 2022 class="px-5 pt-10 pb-2 md:px-10"> 2023 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]">Related Services</span> 2024 </li> 2025 <li x-show="mobilePanelActiveId === 'category-node-54'" 2026 x-transition:enter="transition ease-out duration-700" 2027 x-transition:enter-start="opacity-0 -translate-y-2" 2028 x-transition:enter-end="opacity-100 translate-y-0" 2029 style="transition-delay: 200ms;" 2030 class="px-5 pb-2 md:px-10"> 2031 <a href="/commercial" title="Banham Commercial"> 2032 <span class="relative text-sm text-primary-darker hover:text-primary-darker">Banham Commercial</span> 2033 </a> 2034 </li> 2035 </ul> 2036 <div x-show="mobilePanelActiveId === 'category-node-54'" 2037 x-transition:enter="transition ease-out duration-700" 2038 x-transition:enter-start="opacity-0 -translate-y-2" 2039 x-transition:enter-end="opacity-100 translate-y-0" 2040 style="transition-delay: 240ms;" 2041 class="menu-cutom-block px-5 mt-[60px] md:px-10"> 2042 <img src="https://a.storyblok.com/f/286600090739628/359x261/64109011f1/meganav-trade-more-from-banham.jpg" alt="" class="w-full"/> 2043 <div class="inner-detials flex flex-col gap-4 bg-primary px-7 pt-7 pb-[60px]"> 2044 <h4 class="text-white mb-0">Keyholding & Alarm Response</h4> 2045 <p class="text-white mb-0"> Peace of mind knowing we'll be there when you need us.</p> 2046 <a href="/keyholding" class="underline-link"><span class="text-white">Learn More</span></a> 2047 </div> 2048 </div> 2049 </div> 2050 </li> 2051 <li 2052 x-show="open" 2053 data-child-id="category-node-47-main" 2054 x-transition:enter="transition ease-out duration-700" 2055 x-transition:enter-start="opacity-0 -translate-y-2" 2056 x-transition:enter-end="opacity-100 translate-y-0" 2057 style="transition-delay: 320ms;" 2058 class="level-0 px-5 py-[6px] md:px-10" 2059 :class="{ 'active': mobilePanelActiveId === 'category-node-47' }" 2060 > 2061 <div class="flex items-center transition-transform duration-150 ease-in-out transform"> 2062 <a 2063 class="relative flex items-center justify-between cursor-pointer level-0 w-full focus:border-primary-lighter focus:outline-none focus:ring-0 hover:text-primary-darker" 2064 title="Locksmith" 2065 @click="openSubcategory('category-node-47')" 2066 aria-label="Open Locksmith subcategories" 2067 aria-haspopup="true" 2068 :aria-expanded="mobilePanelActiveId === 'category-node-47'" 2069 > 2070 Locksmith <i class="ti ti-chevron-right text-base"></i> 2071 </a> 2072 </div> 2073 <div 2074 data-child-id="category-node-47" 2075 class="absolute top-[0] left-[0] flex flex-col w-full h-full bg-white border-l border-primary pt-16 pb-[60px] overflow-y-auto overflow-x-hidden lg:left-[480px] lg:max-w-[480px] lg:translate-x-0 max-lg:translate-x-full transition-transform duration-150 ease-in-out z-[-1] invisible pointer-events-none" 2076 :class="{ 2077 '!-translate-x-full invisible pointer-events-none': mobilePanelActiveId !== 'category-node-47', 2078 'translate-x-0 visible pointer-events-auto': mobilePanelActiveId === 'category-node-47', 2079 2080 }" 2081 > 2082 <button 2083 type="button" 2084 class="absolute top-5 left-5 flex justify-start w-auto self-start cursor-pointer w-full md:left-10 lg:hidden focu
2084s:border-primary-lighter focus:outline-none focus:ring-0" 2085 @click="backToMainCategories('category-node-47-main')" 2086 aria-label="Back to main categories" 2087 > 2088 <i class="ti ti-arrow-left text-xl"></i> 2089 </button> 2090 <ul aria-label="Subcategories"> 2091 <li x-show="mobilePanelActiveId === 'category-node-47'" 2092 x-transition:enter="transition ease-out duration-700" 2093 x-transition:enter-start="opacity-0 -translate-y-2" 2094 x-transition:enter-end="opacity-100 translate-y-0" 2095 style="transition-delay: 0ms;" class="px-5 pb-2 md:px-10"> 2096 <span class="relative text-[10px] text-primary font-grotesk uppercase tracking-[0.8px]"> 2097 Locksmith </span> 2098 </li> 2099 <li x-show="mobilePanelActiveId === 'category-node-47'" 2100 x-transition:enter="transition ease-out duration-700" 2101 x-transition:enter-start="opacity-0 -translate-y-2" 2102 x-transition:enter-end="opacity-100 translate-y-0" 2103 style="transition-delay: 40ms;" class="px-5 pb-2 md:px-10"> 2104 <a 2105 href="https://www.banham.co.uk/locksmith-service/" 2106 title="Locksmith" 2107 > 2108 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 2109 All Locksmith </span> 2110 </a> 2111 </li> 2112 <li 2113 x-show="mobilePanelActiveId === 'category-node-47'" 2114 x-transition:enter="transition ease-out duration-700" 2115 x-transition:enter-start="opacity-0 -translate-y-2" 2116 x-transition:enter-end="opacity-100 translate-y-0" 2117 style="transition-delay: 80ms;" 2118 class="px-5 pb-2 md:px-10"> 2119 <a 2120 href="https://www.banham.co.uk/locksmith-service/emergency-locksmith/" 2121 title="Emergency Locksmith" 2122 > 2123 <span class="relative text-sm text-primary-darker hover:text-primary-darker"> 2124 Emergency Locksmith </span> 2125 </a> 2126 </li> 2127 </ul> 2128 <div x-show="mobilePanelActiveId === 'category-node-47'" 2129 x-transition:enter="transition ease-out duration-700" 2130 x-transition:enter-start="opacity-0 -translate-y-2" 2131 x-transition:enter-end="opacity-100 translate-y-0" 2132 style="transition-delay: 120ms;" 2133 class="menu-cutom-block px-5 mt-[60px] md:px-10"> 2134 <img src="https://a.storyblok.com/f/286600090739628/359x261/eb8d21273f/locksmith-menu.jpg" alt="" class="w-full"/> 2135 <div class="inner-detials flex flex-col gap-4 bg-primary px-7 pt-7 pb-[60px]"> 2136 <h4 class="text-white mb-0">Locksmith Services</h4> 2137 <p class="text-white mb-0"> Expert locksmiths providing lock changes, cylinder changes, emergency lock outs and more.</p> 2138 <a href="/locksmith-service/emergency-locksmith" class="underline-link"><span class="text-white">Learn More</span></a> 2139 </div> 2140 </div> 2141 </div> 2142 </li> 2143 </ul> 2144 <div class="menu-custom-links"> 2145 <ul> 2146 <li x-show="open" 2147 x-transition:enter="transition ease-out duration-700" 2148 x-transition:enter-start="opacity-0 -translate-y-2" 2149 x-transition:enter-end="opacity-100 translate-y-0" 2150 style="transition-delay: 360ms;"> 2151 <a 2152 href="/customer/account/login/" 2153 :href="isLoggedIn ? accountUrl : '\u002Fcustomer\u002Faccount\u002Flogin\u002F'" 2154 :title="isLoggedIn ? accountText : signInText" 2155 >
2156 <span x-text="isLoggedIn ? accountText : signInText">Sign In</span> 2157 </a> 2158 </li> 2159 <li x-show="open" 2160 x-transition:enter="transition ease-out duration-700" 2161 x-transition:enter-start="opacity-0 -translate-y-2" 2162 x-transition:enter-end="opacity-100 translate-y-0" 2163 style="transition-delay: 400ms;"> 2164 <a href="/customer/account/login/"><span>Make a Payment</span></a> 2165 </li> 2166 <li x-show="open" 2167 x-transition:enter="transition ease-out duration-700" 2168 x-transition:enter-start="opacity-0 -translate-y-2" 2169 x-transition:enter-end="opacity-100 translate-y-0" 2170 style="transition-delay: 440ms;"> 2171 <a href="/customer-help-centre"><span>Help and Support</span></a> 2172 </li> 2173 <li x-show="open" 2174 x-transition:enter="transition ease-out duration-700" 2175 x-transition:enter-start="opacity-0 -translate-y-2" 2176 x-transition:enter-end="opacity-100 translate-y-0" 2177 style="transition-delay: 480ms;"> 2178 <a href="/contact/""><span>Contact Us</span></a> 2179 </li> 2180 <li x-show="open" 2181 x-transition:enter="transition ease-out duration-700" 2182 x-transition:enter-start="opacity-0 -translate-y-2" 2183 x-transition:enter-end="opacity-100 translate-y-0" 2184 style="transition-delay: 520ms;"> 2185 <a href="/trade/trade-area"><span>Trade Site</span></a> 2186 </li> 2187 <li x-show="open" 2188 x-transition:enter="transition ease-out duration-700" 2189 x-transition:enter-start="opacity-0 -translate-y-2" 2190 x-transition:enter-end="opacity-100 translate-y-0" 2191 style="transition-delay: 560ms;"> 2192 <a href="/about-us"><span>About Us</span></a> 2193 </li> 2194 <li x-show="open" 2195 x-transition:enter="transition ease-out duration-700" 2196 x-transition:enter-start="opacity-0 -translate-y-2" 2197 x-transition:enter-end="opacity-100 translate-y-0" 2198 style="transition-delay: 600ms;"> 2199 <a href="/journal"><span>Journal</span></a> 2200 </li> 2201 <li x-show="open" 2202 x-transition:enter="transition ease-out duration-700" 2203 x-transition:enter-start="opacity-0 -translate-y-2" 2204 x-transition:enter-end="opacity-100 translate-y-0" 2205 style="transition-delay: 640ms;"> 2206 <a href="/showrooms"><span>Showrooms</span></a> 2207 </li> 2208 <li x-show="open" 2209 x-transition:enter="transition ease-out duration-700" 2210 x-transition:enter-start="opacity-0 -translate-y-2" 2211 x-transition:enter-end="opacity-100 translate-y-0" 2212 style="transition-delay: 680ms;"> 2213 <a href="/book-a-survey"><span>Arrange a Consultation</span></a> 2214 </li> 2215 <li x-show="open" 2216 x-transition:enter="transition ease-out duration-700" 2217 x-transition:enter-start="opacity-0 -translate-y-2" 2218 x-transition:enter-end="opacity-100 translate-y-0" 2219 style="transition-delay: 720ms;"> 2220 <a href="tel:+442076225151""><span>020 7622 5151</span></a> 2221 </li> 2222 </ul> 2223 </div> 2224 </div> 2225 </div> 2226 </div> 2227 <div 2228 class="menu-overlay bg-black fixed inset-0 z-[-1] transition-opacity duration-300 opacity-0" 2229 :class="{ 'opacity-50': open, 'opacity-0 pointer-events-none': !open }" 2230 ></div> 2231</nav> 2232 <div class="header-custom-links gap-4 flex"> 2233 <a href="#open_enquiry_form"><i class="ti ti-phone lg:hidden text-xl"></i><span class="text-[0] lg:text-sm">Book a Survey </span></a> 2234 <a href="tel:+442076225151"><i class="ti ti-phone lg:hidden text-xl"></i><span class="text-[0] lg:text-sm">Call Us</span></a> 2235 </div> 2236 </div> 2237 2238 <!--Logo--> 2239 <div class="absolute left-1/2 transform -translate-x-1/2"> 2240 <a 2241 class="flex items-center justify-center text-xl font-medium tracking-wide text-gray-800 2242 no-underline hover:no-underline font-title" 2243 href="https://www.banham.co.uk/" 2244 aria-label="Go to Home page" 2245 > 2246 <svg class="w-[135px] lg:w-auto" width="190" height="28" viewBox="0 0 190 28" fill="none" xmlns="http://www.w3.org/2000/svg"> 2247 <g clip-path="url(#clip0_645_11687)"> 2248 <mask id="mask0_645_11687" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="190" height="28"> 2249 <path d="M189.5 0H0.5V28H189.5V0Z" fill="white"/> 2250 </mask> 2251 <g mask="url(#mask0_645_11687)"> 2252 <path d="M22.7401 19.7514C22.7401 24.5436 18.5183 27.5017 11.8285 27.5017H0.626192L0.5 25.9176L2.29703 25.3762C3.13245 25.1263 3.42637 24.7092 3.42637 23.6679V3.83374C3.42637 2.79252 3.13405 2.37539 2.29703 2.12543L0.5 1.58412L0.626192 0H11.747C17.5566 0 21.0261 2.45818 21.0261 6.54188C21.0261 9.49997 19.0198 11.834 15.8427 12.8752C20.1492 13.6251 22.7401 16.1676 22.7401 19.7498M10.5746 2.37539H8.1913V12.1253H10.3653C13.9194 12.1253 16.2612 10.0429 16.2612 6.91761C16.2612 4.12668 14.0872 2.37539 10.5
2252762 2.37539M10.9515 25.1263C15.258 25.1263 17.8074 23.168 17.8074 20.0014C17.8074 16.6261 15.0488 14.5007 10.7423 14.5007H8.1929V25.1263H10.9515Z" fill="black"/> 2253 <path d="M54.4701 27.5017H43.8093L43.6831 25.9176L45.2725 25.5418C46.3172 25.2919 46.6942 24.792 46.3172 23.7077L44.6447 18.9156H34.821L33.0239 23.6648C32.6469 24.6646 32.8977 25.2903 33.944 25.5402L35.5334 25.916L35.4072 27.5001H26.8373L26.7127 25.916L27.8405 25.6246C28.9698 25.3333 29.5129 24.9161 29.8899 23.9577L37.5397 4.24769C38.0412 2.95651 37.832 2.24803 36.7873 1.95668L35.4503 1.58095L35.5749 -0.00158691H42.8493C43.4339 1.91528 44.5217 5.04055 46.0265 9.16564L51.3776 23.8319C51.7115 24.749 52.2562 25.2489 53.1331 25.4988L54.5963 25.916L54.4701 27.5001V27.5017ZM41.3015 9.29141C40.5491 7.12459 40.2137 5.49907 39.9629 3.29085C39.629 5.49907 39.2105 7.12459 38.4166 9.25002L35.6995 16.5418H43.8509L41.3015 9.29141Z" fill="black"/> 2254 <path d="M77.504 16.209C78.9256 18.2501 79.9703 20.2083 81.0166 22.7923C80.6396 20.3341 80.5565 18.1673 80.5565 15.1678V3.83374C80.5565 2.79252 80.2642 2.334 79.4272 2.12543L77.2947 1.58412L77.4209 0H86.2L86.3262 1.58412L84.5292 2.12543C83.6937 2.37539 83.3998 2.79252 83.3998 3.83374V13.7508C83.3998 20.5841 83.4414 23.3766 83.6091 27.1259L80.0134 28.0016L68.6833 11.834C66.8432 9.20862 65.6739 6.91761 64.7953 4.41804C65.0877 6.54347 65.1723 8.79309 65.1723 11.834V23.6679C65.1723 24.7092 65.4646 25.1677 66.3017 25.3762L68.4341 25.9176L68.3079 27.5017H59.5288L59.4042 25.9176L61.2013 25.3762C62.0367 25.1263 62.3306 24.7092 62.3306 23.6679V3.83374C62.3306 2.79252 62.0383 2.37539 61.2013 2.12543L59.4042 1.58412L59.5272 0H66.1755L77.504 16.209Z" fill="black"/> 2255 <path d="M116.885 23.6679C116.885 24.7092 117.178 25.1263 118.015 25.3762L119.812 25.9175L119.687 27.5017H108.985L108.859 25.9175L110.991 25.3762C111.827 25.1677 112.121 24.7092 112.121 23.6679V14.3335H99.8704V23.6679C99.8704 24.7092 100.163 25.1677 101 25.3762L103.132 25.9175L103.006 27.5017H92.3036L92.1774 25.9175L93.9745 25.3762C94.8115 25.1263 95.1038 24.7092 95.1038 23.6679V3.83374C95.1038 2.79251 94.8115 2.37539 93.9745 2.12543L92.1774 1.58412L92.3036 0.00158691H103.006L103.132 1.58412L101 2.12543C100.164 2.33399 99.8704 2.79251 99.8704 3.83374V11.9581H112.121V3.83374C112.121 2.79251 111.828 2.33399 110.991 2.12543L108.859 1.58412L108.985 0.00158691H119.687L119.812 1.58412L118.015 2.12543C117.179 2.37539 116.885 2.79251 116.885 3.83374V23.6679Z" fill="black"/> 2256 <path d="M152.377 27.5017H141.716L141.59 25.9176L143.18 25.5418C144.224 25.2919 144.601 24.792 144.224 23.7077L142.552 18.9156H132.728L130.931 23.6648C130.554 24.6646 130.805 25.2903 131.851 25.5402L133.439 25.916L133.314 27.5001H124.744L124.62 25.916L125.748 25.6246C126.877 25.3333 127.42 24.9161 127.797 23.9577L135.447 4.24769C135.948 2.95651 135.739 2.24803 134.694 1.95668L133.357 1.58095L133.482 -0.00158691H140.756C141.341 1.91528 142.429 5.04055 143.933 9.16564L149.285 23.8319C149.619 24.749 150.163 25.2489 151.04 25.4988L152.503 25.916L152.377 27.5001V27.5017ZM139.208 9.29141C138.456 7.12459 138.121 5.49907 137.87 3.29085C137.536 5.49907 137.118 7.12459 136.324 9.25002L133.607 16.5418H141.758L139.208 9.29141Z" fill="black"/> 2257 <path d="M186.573 23.6679C186.573 24.7092 186.866 25.1263 187.703 25.3762L189.5 25.9176L189.375 27.5017H178.673L178.547 25.9176L180.679 25.3762C181.515 25.1677 181.807 24.7092 181.807 23.6679V13.1267C181.807 9.41878 182.016 6.75203 182.35 4.29385C181.513 6.75203 180.636 8.75328 179.297 11.4614L174.029 22.087H170.728L165.293 11.5872C164.039 9.17041 163.161 6.79502 162.533 4.33684C162.91 7.04498 163.076 9.75311 163.076 13.1283V23.6695C163.076 24.7108 163.369 25.1693 164.206 25.3778L166.338 25.9191L166.212 27.5033H157.433L157.308 25.9191L159.105 25.3778C159.942 25.1279 160.235 24.7108 160.235 23.6695V3.83374C160.235 2.79252 159.942 2.37539 159.105 2.12543L157.308 1.58412L157.433 0.00159209H164.498L170.769 12.0855C171.772 14.0438 172.525 15.7107 173.362 17.8361C174.156 15.8365 174.908 14.1696 175.911 12.0855L181.807 0H189.374L189.498 1.58253L187.701 2.12384C186.866 2.3738 186.572 2.79093 186.572 3.83215V23.6663L186.573 23.6679Z" fill="black"/> 2258 </g> 2259 </g> 2260 <defs> 2261 <clipPath id="clip0_645_11687"> 2262 <rect width="189" height="28" fill="white" transform="translate(0.5)"/> 2263 </clipPath> 2264 </defs> 2265 </svg> 2266 2267 </a> 2268</div> 2269 <div class="flex items-center gap-4 md:gap-4 order-3"> 2270 <!--Search Icon--> 2271 <button 2272 id="menu-search-icon" 2273 class="leading-none" 2274 @click.prevent=" 2275 searchOpen = !searchOpen;
2276 $dispatch('search-open'); 2277 " 2278 aria-label="Toggle search form" 2279 aria-haspopup="true" 2280 :aria-expanded="searchOpen" 2281 x-ref="searchButton" 2282 title="Search" 2283 > 2284 <i class="ti ti-search text-xl"></i> 2285 </button> 2286 2287 <!-- Additional Header Elements --> 2288 2289 <!--Customer Icon & Dropdown--> 2290 <!-- BLOCK header.customer --> 2291<div 2292 class="relative hidden lg:inline-block" 2293 x-data="{ open: false }" 2294 @keyup.escape="open = false" 2295 @click.outside="open = false" 2296> 2297 <button 2298 type="button" 2299 id="customer-menu" 2300 class="block leading-none" 2301 @click="open = !open" 2302 :aria-expanded="open ? 'true' : 'false'" 2303 aria-label="My Account" 2304 aria-haspopup="true" 2305 title="My Account" 2306 > 2307 <i class="ti ti-user text-xl"></i> 2308 </button> 2309 <nav 2310 class=" 2311 absolute right-0 z-20 w-40 py-2 mt-2 -mr-4 px-1 overflow-auto origin-top-right rounded-sm 2312 shadow-lg sm:w-48 lg:mt-3 bg-container-lighter 2313 " 2314 x-cloak 2315 x-show="open" 2316 aria-labelledby="customer-menu" 2317 > 2318 2319<a id="customer.header.sign.in.link" 2320 class="block px-4 py-2 lg:px-5 lg:py-2 hover:bg-gray-100" 2321 onclick="hyva.setCookie && hyva.setCookie( 2322 'login_redirect', 2323 window.location.href, 2324 1 2325 )" 2326 href="https://www.banham.co.uk/customer/account/index/" 2327 title="Sign In" 2328> 2329 Sign In</a> 2330 <a id="customer.header.register.link" 2331 class="block px-4 py-2 lg:px-5 lg:py-2 hover:bg-gray-100" 2332 href="https://www.banham.co.uk/customer/account/create/" 2333 title="Create an Account" 2334 > 2335 Create an Account </a> 2336 <a id="customer.header.online.payment.link.guest" class="block px-4 py-2 lg:px-5 lg:py-2 hover:bg-gray-100" href="https://www.banham.co.uk/banham-payment/customer/view/" title="Online Payment" >Online Payment</a> </nav> 2337</div><!-- /BLOCK header.customer --> 2338 <!--Cart Icon--> 2339 <button 2340 id="menu-cart-icon" 2341 class="relative inline-block leading-none" 2342 x-ref="cartButton" 2343 :aria-disabled="isCartEmpty()" 2344 :aria-label="` 2345 Toggle minicart, 2346 ${isCartEmpty() 2347 ? 'Cart is empty' 2348 : cart.summary_count > 1 2349 ? hyva.str('%1 items', cart.summary_count) 2350 : hyva.str('%1 item', cart.summary_count) 2351 }`" 2352 title="View cart" 2353 @click.prevent="() => { 2354 $dispatch('toggle-cart', { isOpen: true }) 2355 }" 2356 @toggle-cart.window="toggleCart($event)" 2357 :aria-expanded="isCartOpen" 2358 aria-haspopup="dialog" 2359 > 2360 <i class="ti ti-shopping-bag text-xl"></i> 2361 <span 2362 x-text="cart.summary_count" 2363 x-show="!isCartEmpty()" 2364 x-cloak 2365 class="mini-count absolute bottom-[1px] right-[1px] w-[7px] h-[7px] border-0 rounded-full bg-primary text-white text-[0]" 2366 aria-hidden="true" 2367 ></span> 2368 </button> 2369 </div> 2370 </div> 2371 <!--Search--> 2372 <div class="header-search absolute z-10 w-full border-t bg-white border-container-lighter" 2373 id="search-content" 2374 x-cloak x-show="searchOpen" 2375 @click.outside="searchOpen = false" 2376 @keydown.escape=" 2377 searchOpen = false; 2378 $refs.searchButton.focus(); 2379 " 2380 > 2381 2382<div class="container py-10 mx-auto text-black" x-data="initMiniSearch()"> 2383 <search title="Store" role="search"> 2384 <form 2385 id="search_mini_form" 2386 class="form minisearch flex justify-center" 2387 action="https://www.banham.co.uk/catalogsearch/result/" 2388 method="get" 2389 @submit.prevent="search()" 2390 x-ref="form" 2391 > 2392 <div class="relative flex w-full lg:max-w-[660px]"> 2393 <i class="ti ti-search absolute left-5 top-1/2 transform -translate-y-1/2 text-xl"></i> 2394 <input 2395 id="search" 2396 x-ref="searchInput" 2397 type="search" 2398 autocomplete="off" 2399 name="q" 2400 value="" 2401 placeholder="Search" 2402 maxlength="64" 2403 aria-label="Search" 2404 class="form-input min-h-[53px] py-4 pl-12 placeholder:text-black" 2405 @search-open.window.debounce.10="$el.focus(); $el.select()" 2406 > 2407 </div> 2408 <button 2409 type="submit" 2410 class="hidden action search btn btn-primary rounded-l-none rounded-r shrink-0 p-3 shadow-none" 2411 title="Search" 2412 aria-label="Search" 2413 > 2414 <i class="ti ti-search text-xl"></i> 2415 </button> 2416 </form> 2417 </search> 2418 </div> </div> 2419
2420 <!--Cart Drawer--> 2421 2422<section x-cloak 2423 x-show="cart" 2424 id="cart-drawer" 2425 x-data="initCartDrawer()" 2426 @private-content-loaded.window="getData($event.detail.data)" 2427 @toggle-cart.window="toggleCartDrawer($event)" 2428 @keydown.escape="closeCartDrawer" 2429> 2430 <div role="dialog" 2431 aria-labelledby="cart-drawer-title" 2432 aria-modal="true" 2433 :aria-hidden="!open" 2434 class="fixed inset-y-0 right-0 z-50 flex max-w-full"> 2435 <div class="backdrop" 2436 x-show="open" 2437 x-transition:enter="ease-in-out duration-500" 2438 x-transition:enter-start="opacity-0" 2439 x-transition:enter-end="opacity-100" 2440 x-transition:leave="ease-in-out duration-500" 2441 x-transition:leave-start="opacity-100" 2442 x-transition:leave-end="opacity-0" 2443 role="button" 2444 @click="closeCartDrawer" 2445 aria-label="Close minicart"></div> 2446 <div class="relative w-screen max-w-[430px] shadow-2xl" 2447 x-show="open" 2448 x-transition:enter="transform transition ease-in-out duration-500 sm:duration-700" 2449 x-transition:enter-start="translate-x-full" 2450 x-transition:enter-end="translate-x-0" 2451 x-transition:leave="transform transition ease-in-out duration-500 sm:duration-700" 2452 x-transition:leave-start="translate-x-0" 2453 x-transition:leave-end="translate-x-full" 2454 x-ref="cartDialogContent" 2455 role="region" 2456 :tabindex="open ? 0 : -1" 2457 aria-label="Bag" 2458 2459 > 2460 <div class="flex flex-col h-full max-h-screen bg-white text-black shadow-xl"> 2461 2462 <header class="relative flex justify-between items-center px-5 sm:px-6 md:px-10 bg-white text-primary "> 2463 <div class="relative flex justify-between items-center w-full py-5 border-b border-container"> 2464 <h4 id="cart-drawer-title" class="flex items-center m-0"> 2465 Bag <span class="ml-2"> 2466 (<span x-text="itemsCount"></span>) 2467 </span> 2468 <!-- <span class="items-total text-xs" 2469 x-show="maxItemsToDisplay && maxItemsToDisplay < itemsCount" 2470 x-text="getItemCountTitle()"> 2471 </span> --> 2472 </h4> 2473 <button 2474 type="button" 2475 @click="closeCartDrawer" 2476 aria-label="Close minicart" 2477 class="transition-colors hover:text-primary leading-none" 2478 title="Close minicart" 2479 > 2480 <i class="ti ti-x text-xl"></i> 2481 </button> 2482 </div> 2483 </header> 2484 2485 2486 <template x-if="!itemsCount"> 2487 <div class="relative flex items-center justify-center px-10 py-6 bg-white border-bs sm:px-6 border-container"> 2488 You have no items in your bag. </div> 2489 </template> 2490 2491 <template x-if="itemsCount"> 2492 <div class="relative grid bg-white overflow-y-auto overscroll-y-contain px-5 sm:px-6 md:px-10"> 2493 <template x-for="item in cartItems"> 2494 <div class="item-wrapper flex items-start space-x-4 py-5 border-b border-container last:border-0"> 2495 <div class="flex items-start"> 2496 <template x-if="item.product_has_url && item.is_visible_in_site_visibility"> 2497 <a :href="item.product_url" 2498 class="w-1/4 !ml-0" 2499 :aria-label="hyva.strf('Product\u0020\u0022\u00250\u0022', item.product_name)" 2500 > 2501 <img class="w-full object-cover" 2502 :src="item.product_image.src" 2503 :width="item.product_image.width" 2504 :height="item.product_image.height" 2505 loading="lazy" 2506 :alt="item.product_name" 2507 /> 2508 </a> 2509 </template> 2510 <template x-if="!item.product_has_url || !item.is_visible_in_site_visibility"> 2511 <div class="w-1/4 !ml-0"> 2512 <img class="w-full object-cover" 2513 :src="item.product_image.src" 2514 :width="item.product_image.width" 2515 :height="item.product_image.height" 2516 loading="lazy" 2517 :alt="item.product_name" 2518 /> 2519 </div> 2520 </template> 2521 <div class="w-3/4"> 2522 <div> 2523 <p class="mb-0"><span x-html="item.product_sku"></span></p> 2524 <p>
2525 <span x-html="item.product_name"></span> 2526 </p> 2527 </div> 2528 <template x-for="option in item.options"> 2529 <div class="flex gap-1 mb-3"> 2530 <p class="mb-0" x-text="option.label + ':'"></p> 2531 <p class="mb-0" x-html="option.value"></p> 2532 </div> 2533 </template> 2534 <div class="flex items-center justify-between m-0 p-0"> 2535 <div class="flex items-center gap-2"> 2536 <div class="flex border border-primary rounded"> 2537 <button @click="decrementQty(item)" 2538 class="flex items-center justify-center w-[32px] h-[32px]" 2539 aria-label="Decrease Quantity"> 2540 <i class="ti ti-minus"></i> 2541 </button> 2542 <input x-model="item.qty" 2543 x-on:change="updateItemQty(item)" 2544 type="number" 2545 size="4" 2546 step="any" 2547 class="flex items-center justify-center border-primary border-t-0 border-b-0 w-[60px] h-[32px] text-center [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none [-moz-appearance:textfield]" 2548 min="1" 2549 data-role="cart-item-qty"> 2550 <button @click="incrementQty(item)" 2551 class="flex items-center justify-center w-[32px] h-[32px]" 2552 aria-label="Increase Quantity"> 2553 <i class="ti ti-plus"></i> 2554 </button> 2555 </div> 2556 <button type="button" 2557 class="flex p-[6px] h-[33px] btn btn-lighter" 2558 @click="deleteItemFromCart(item.item_id)" 2559 :aria-label="hyva.strf('Remove\u0020product\u0020\u0022\u00250\u0022\u0020from\u0020cart', item.product_name)" 2560 title="Remove product" 2561 > 2562 <i class="ti ti-trash text-lg"></i> 2563 </button> 2564 </div> 2565 <span x-html="hyva.formatPrice(item.product_price_value * item.qty)" class="text-sm"></span> 2566 </div> 2567 </div> 2568 </div> 2569 </div> 2570 </template> 2571 </div> 2572 </template> 2573 2574 <template x-if="itemsCount"> 2575 <div class="mt-auto pb-10 px-5 sm:px-6 md:px-10"> 2576 <div x-show="extraProducts.length > 0" class="flex flex-col gap-3 pt-5 border-t border-primary"> 2577 <h4 class="mb-0" x-text="extraProducts[0]?.title"></h4> 2578 <p class="mb-0 text-xs" x-text="extraProducts[0]?.description"></p> 2579 </div> 2580 <!-- Extra Products Section --> 2581 <template x-if="extraProducts.length > 0"> 2582 <div class="extra-products-section py-5"> 2583 <div 2584 x-ref="extraProductsSplide" 2585 class="extra-products-splide" 2586 :class="{ 'splide': extraProducts.length > 1 }" 2587 > 2588 <div class="splide__track"> 2589 <ul class="splide__list"> 2590 <template x-for="(product, index) in extraProducts" :key="product.id"> 2591 <li class="splide__slide"> 2592 <div class="extra-product-item flex gap-3"> 2593 <div class="flex-shrink-0 w-16"> 2594 <img class="w-full h-auto object-cover rounded" 2595 :src="product.image" 2596 :alt="product.name" 2597 loading="lazy" /> 2598 </div> 2599 <div class="flex-1 min-w-0"> 2600 <p class="mb-0" x-text="product.name"></p> 2601 <div class="flex justify-between"> 2602 <p class="mb-0" x-text="product.sku"></p> 2603 <sp
2603an class="text-sm" x-html="product.price"></span> 2604 </div> 2605 2606 <div class="flex gap-2 mt-2"> 2607 <div class="flex items-center justify-between"> 2608 <div class="flex items-center border rounded"> 2609 <button type="button" 2610 @click="decrementExtraQty(index)" 2611 class="flex items-center justify-center w-[32px] [34px]"> 2612 <span class="text-sm">â</span> 2613 </button> 2614 <input type="number" 2615 x-model.number="extraProductQtys[index]" min="1" max="10000" 2616 class="flex items-center justify-center border-primary border-t-0 border-b-0 w-[60px] h-[34px] text-center [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none [-moz-appearance:textfield]" /> 2617 <button type="button" 2618 @click="incrementExtraQty(index)" 2619 class="flex items-center justify-center w-[32px] h-[34px]"> 2620 <span class="">+</span> 2621 </button> 2622 </div> 2623 </div> 2624 <button type="button" 2625 @click="addExtraProduct(product, index)" 2626 class="btn btn-primary btn-size-xs w-full"> 2627 Add to Bag </button> 2628 </div> 2629 </div> 2630 </div> 2631 </li> 2632 </template> 2633 </ul> 2634 </div> 2635 </div> 2636 </div> 2637 </template> 2638 2639 <div class="relative grid bg-white"> 2640 <div class="relative flex justify-between items-center w-full py-5 bg-white text-primary border-t border-container"> 2641 <p class="flex items-center justify-between w-full mb-0">Subtotal: <span x-html="cart.subtotal"></span></p> 2642 </div> 2643 <div class="flex gap-3 w-full"> 2644 <a @click.prevent.stop="closeCartDrawer; $dispatch('toggle-authentication', 2645 {url: 'https://www.banham.co.uk/checkout/'});" 2646 href="https://www.banham.co.uk/checkout/" 2647 class="w-full btn btn-primary" 2648 > 2649 Checkout </a> 2650 <a href="https://www.banham.co.uk/checkout/cart/" 2651 class="w-full btn btn-light-gray" 2652 > 2653 View Bag </a> 2654 </div>
2655 <div x-html="getSectionDataExtraActions()"></div> 2656 </div> 2657 </div> 2658 </template> 2659 2660 </div> 2661 </div> 2662 <div 2663 class="z-50 fixed inset-0 flex justify-center items-center bg-white/70 select-none" 2664 x-show="isLoading" 2665 x-cloak 2666 x-transition.opacity.duration.200ms 2667> 2668 <div class="flex items-center"> 2669 <svg xmlns="http://www.w3.org/2000/svg" width="54" height="54" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" class="animate-spin" aria-hidden="true"> 2670 <circle style="opacity: .3;" cx="12" cy="12" r="10"/> 2671 <path fill="none" stroke-width="2" d="M12,2 a10,10 0 0,1 10,10"/> 2672</svg> 2673 <div class="ml-10 text-xl"> 2674 Loading... </div> 2675 </div> 2676</div> </div> 2677 2678</section> 2679 <!--Authentication Pop-Up--> 2680 <!-- BLOCK authentication-popup --> 2681 2682<dialog 2683 id="authentication-popup" 2684 aria-labelledby="cart-drawer-title" 2685 class="open:flex flex-col transition ease-out duration-300 motion-reduce:duration-0 p-0" 2686 x-data="initAuthentication" 2687 x-bind="eventListeners" 2688 x-show="open" 2689 x-htmldialog="close" 2690 closeby="any" 2691 x-transition 2692> 2693 <div class="pt-8 px-8"> 2694 <div class="flex gap-2 justify-between items-center"> 2695 <p class="text-xl"> 2696 <strong>Customer Login</strong> 2697 </p> 2698 <button 2699 type="button" 2700 class="btn bg-transparent border-transparent p-2" 2701 @click="close" 2702 aria-label="Close panel" 2703 > 2704 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" viewBox="0 0 24 24" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg> 2705 </button> 2706 </div> 2707 2708 <div class="message error" x-show="errors" x-cloak> 2709 <template x-for="(message, index) in errorMessages" :key="index"> 2710 <div> 2711 <template x-if="message"> 2712 <span x-html="message"></span> 2713 </template> 2714 </div> 2715 </template> 2716 </div> 2717 </div> 2718 2719 <div class="block-customer-login p-8"> 2720 <p id="authenticate-customer-login" class="text-lg mb-2"> 2721 <strong>Checkout using your account</strong> 2722 </p> 2723 2724 <form 2725 id="login-form" 2726 class="form form-login" 2727 method="post" 2728 @submit.prevent="submitForm" 2729 > 2730 <div class="control"> 2731 <input type="hidden" 2732 value="" 2733 name="g-recaptcha-response" 2734 > 2735</div> <input name="context" type="hidden" value="checkout"> 2736 2737 <div class="flex flex-col gap-4"> 2738 <div class="field email required"> 2739 <label for="form-login-username"> 2740 <span>Email Address</span> 2741 </label> 2742 <div class="control"> 2743 <input 2744 id="form-login-username" 2745 name="username" 2746 type="email" 2747 class="form-input w-full" 2748 required 2749 autocomplete="off" 2750 x-ref="customer-email" 2751 @change="resetErrors" 2752 > 2753 </div> 2754 </div> 2755 <div class="field password required"> 2756 <label for="form-login-password"> 2757 <span>Password</span> 2758 </label> 2759 <div class="control"> 2760 <input 2761 id="form-login-password" 2762 name="password" 2763 type="password" 2764 class="form-input w-full" 2765 required 2766 autocomplete="off" 2767 x-ref="customer-password" 2768 @change="resetErrors" 2769 > 2770 </div> 2771 </div> 2772 </div> 2773 2774 <div class="actions-toolbar"> 2775 <button 2776 type="submit" 2777 class="btn btn-primary" 2778 > 2779 Sign In </button> 2780 <a 2781 href="https://www.banham.co.uk/customer/account/forgotpassword/" 2782 class="underline hover:no-underline" 2783 > 2784 Forgot Your Password? </a> 2785 </div> 2786 </form> 2787 <p class="my-4 text-sm"> 2788 <em>This site is protected by reCAPTCHA.</em> 2789</p> </div> 2790 <div class="block-new-customer p-8 border-t border-gray-300">
2791 <p id="authenticate-new-customer" class="text-lg mb-2"> 2792 <strong>Checkout as a new customer</strong> 2793 </p> 2794 2795 <div class="block-content"> 2796 <p class="mb-1"> 2797 Creating an account has many benefits: </p> 2798 <ul class="list-disc pl-5"> 2799 <li> See order and shipping status</li> 2800 <li> Track order history</li> 2801 <li> Check out faster</li> 2802 </ul> 2803 <div class="actions-toolbar mt-6 mb-2"> 2804 <a href="https://www.banham.co.uk/customer/account/create/" 2805 class="inline-flex btn btn-primary"> 2806 Create an Account </a> 2807 </div> 2808 </div> 2809 </div> 2810</dialog><!-- /BLOCK authentication-popup --></div></header><div class="top-container"><!-- Action Name: /contact/ --> 2811<nav class="breadcrumbs text-black border-b " aria-label="Breadcrumb"> 2812 <div class="container"> 2813 <ol class="items list-reset py-5 flex flex-wrap text-black leading-tight"> 2814 <li class="item flex home"> 2815 <a 2816 href="https://www.banham.co.uk/" 2817 class="hover:underline text-sm leading-tight" 2818 aria-label="Home" 2819 >Home</a> 2820 </li> 2821 <li class="item flex contact"> 2822 <span><i class="ti ti-chevron-right px-2 text-sm leading-tight"></i></span> 2823 <span class="text-sm leading-tight" aria-current="page"> 2824 Contact </span> 2825 </li> 2826 </ol> 2827 </div> 2828</nav> 2829 2830 2831</div><main id="maincontent" class="page-main"><div id="contentarea" tabindex="-1"></div><div class="page messages"><!-- Action Name: /contact/ --> 2832<section id="messages" x-data="initMessages" :class="sectionClass" x-bind="eventListeners" role="alert"> 2833 <template x-if="hasMessages"> 2834 <div class="w-full"> 2835 <div class="messages"> 2836 <template x-for="(message, index) in messages" :key="index"> 2837 <div class="flex item-center gap-2"> 2838 <template x-if="hasMessage"> 2839 <div class="message" 2840 :class="message.type" 2841 :ui-id="getMessageUiId" 2842 > 2843 <div class="container flex justify-between"> 2844 <span class="mx-auto text-white" x-html="message.text"></span> 2845 <button 2846 type="button" 2847 class="text-white hover:text-primary-lighter" 2848 aria-label="Close message" 2849 @click.prevent="removeMessage" 2850 > 2851 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="stroke-current" width="18" height="18" aria-hidden="true"> 2852 <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/> 2853</svg> 2854 </button> 2855 </div> 2856 </div> 2857 </template> 2858 </div> 2859 </template> 2860 </div> 2861 </div> 2862 </template> 2863</section></div><!-- action name: /contact/ --><div class="columns"><div class="column main"> <div id="monkey_campaign" style="display:none;" data-mage-init='{"campaigncatcher":{"checkCampaignUrl": "https://www.banham.co.uk/mailchimp/campaign/check/"}}'></div> <div><style> 2864 .hero-text-cd8b099b-0e0e-46fc-b292-c4374cad1baf { 2865 background-color: #ffffff; } 2866</style> 2867 2868<div class="hero-text-cd8b099b-0e0e-46fc-b292-c4374cad1baf flex w-full top-padding-md bottom-padding-md"> 2869 <div class="hero-text container flex flex-col gap-[60px]"> 2870 <div class="wrapper relative [&_.video-controller]:!flex " style="background-color: #333E48; min-height: 490px; "> 2871 <div class="content inset-0 z-5 flex flex-col gap-5 justify-center items-center text-center px-5 md:px-10 lg:px-20" style="position: absolute;"> 2872 <h1 class="text-4xl lg:text-5xl font-normal font-heading leading-10 lg:leading-[52.80px] tracking-[0.36px] lg:tracking-[0.48px] mb-0 max-w-[310px] md:max-w-[400px] lg:max-w-[426px]" style="color:#fff;">Contact Us</h1> 2873 <p class="text-base max-w-[290px] md:max-w-[466px] lg:max-w-[426px] mb-2" style="color:#fff;">Welcome to our Contact Us page. Please select a box below and we will direct your query to the best team that can help supp
2873ort you.</p> 2874 </div> 2875 </div> 2876 </div> 2877</div> 2878<div class="container contact-top flex flex-col lg:flex-row gap-10"> 2879 <div class="lg:w-1/2 bg-primary-Keyline p-10 flex flex-col justify-start [&_a]:underline [&_a]:text-[length:inherit]"> 2880 <h3><strong>Existing Customers</strong></h3><h3>Tel:Â <a href="tel:02076225151">020 7622 5151</a></h3><p>To expedite your enquiry, if you are an existing customer, please call <a href="tel:02076225151"><u>020 7622 5151</u></a> or complete the form below.</p> </div> 2881 <div class="lg:w-1/2 bg-primary-Keyline p-10 flex flex-col justify-start [&_a]:underline [&_a]:text-[length:inherit]"> 2882 <h3><strong>For New Security Solutions Enquiries</strong></h3><h3>Tel:Â <a href="tel:02078193730">020 7819 3730</a></h3><p>To speak with one of our security consultants about a new enquiry or to schedule a security review of your property please call <a href="tel:02078193730"><u>020 7819 3730</u></a> or complete the form below and we'll be in touch. You can also find out more about our <a href="/book-a-survey" target="_self"><u>free consultation service here</u></a>.</p> </div> 2883</div> 2884 2885<div 2886 x-data="contactFormTabs()" 2887 class="container my-10" 2888> 2889 <!-- Tab Titles --> 2890 <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-6"> 2891 2892 2893 <button 2894 type="button" 2895 class="form-block-title flex-1 flex flex-col gap-5 justify-center items-center text-center min-h-48 p-10 border border-primary-darker transition-colors duration-300 cursor-pointer 2896 hover:bg-primary hover:text-white 2897 " 2898 :class="{ 'bg-primary text-white': activeTab === '10f8a50a-8bba-4ef8-8fe5-88312b39d219' }" 2899 @click="setActiveTab('10f8a50a-8bba-4ef8-8fe5-88312b39d219', 'banham-lock-queries')" 2900 > 2901 <h3 class="m-0 text-inherit">Banham Lock Queries</h3> 2902 </button> 2903 2904 2905 <button 2906 type="button" 2907 class="form-block-title flex-1 flex flex-col gap-5 justify-center items-center text-center min-h-48 p-10 border border-primary-darker transition-colors duration-300 cursor-pointer 2908 hover:bg-primary hover:text-white 2909 " 2910 :class="{ 'bg-primary text-white': activeTab === 'a682ed85-29c5-437c-b4e3-1113aaa32c62' }" 2911 @click="setActiveTab('a682ed85-29c5-437c-b4e3-1113aaa32c62', 'locksmiths-emergency-locksmith')" 2912 > 2913 <h3 class="m-0 text-inherit">Locksmiths & Emergency Locksmith</h3> 2914 <div class="[&_p]:mb-2 [&_*]:text-inherit [&_a]:text-lg [&_.ti]:flex [&_.ti]:justify-center [&_.ti]:items-center [&_.ti:before]:mr-2 [&_.ti:before]:text-md"> 2915 <p>Rapid Response, 24/7, 365</p><p><a href="tel:+442076225151" target="_self"><span class="ti ti-phone">020 7622 5151</span></a></p> </div> 2916 </button> 2917 2918 2919 <button 2920 type="button" 2921 class="form-block-title flex-1 flex flex-col gap-5 justify-center items-center text-center min-h-48 p-10 border border-primary-darker transition-colors duration-300 cursor-pointer 2922 hover:bg-primary hover:text-white 2923 " 2924 :class="{ 'bg-primary text-white': activeTab === '93718e28-037a-4c05-9e0d-9299d3ddcf8a' }" 2925 @click="setActiveTab('93718e28-037a-4c05-9e0d-9299d3ddcf8a', 'banham-alarm-queries')" 2926 > 2927 <h3 class="m-0 text-inherit">Banham Alarm Queries</h3> 2928 </button> 2929 2930 2931 <button 2932 type="button" 2933 class="form-block-title flex-1 flex flex-col gap-5 justify-center items-center text-center min-h-48 p-10 border border-primary-darker transition-colors duration-300 cursor-pointer 2934 hover:bg-primary hover:text-white 2935 " 2936 :class="{ 'bg-primary text-white': activeTab === 'dea59f1d-3c21-48e7-b117-66062eda44f6' }" 2937 @click="setActiveTab('dea59f1d-3c21-48e7-b117-66062eda44f6', 'keyholding-alarm-response')" 2938 > 2939 <h3 class="m-0 text-inherit">Keyholding & Alarm Response</h3> 2940 </button> 2941 2942 2943 <button 2944 type="button" 2945 class="form-block-title flex-1 flex flex-col gap-5 justify-center items-center text-center min-h-48 p-10 border border-primary-darker transition-colors duration-300 cursor-pointer 2946 hover:bg-primary hover:text-white 2947 " 2948 :class="{ 'bg-primary text-white': activeTab === '1022ce70-8dbd-4ce4-8ab7-aedfefa4ca79' }" 2949 @click="setActiveTab('1022ce70-8dbd-4ce4-8ab7-aedfefa4ca79', 'online-order-queries')" 2950 > 2951 <h3 class="m-0 text-inherit">Online Order Queries</h3> 2952 </button> 2953 2954 2955 <button 2956 type="button" 2957 class="form-block-title flex-1 flex flex-col gap-5 justify-center items-center text-center min-h-48 p-10 border border-primary-darker transition-colors duration-300 cursor-pointer 2958 hover:bg-primary hover:text-white 2959 " 2960 :class="{ 'bg-primary text-white': activeTab === '6370bf61-81cf-4eb3-b045-510dfff450b5' }" 2961 @click="setActiveTab('6370bf61-81cf-4eb3-b045-510dfff450b5', 'banham-account-queries')" 2962 > 2963 <h3 class="m-0 text-inherit">Banham Account Queries</h3> 2964 </button> 2965 2966 2967 <button 2968 type="button" 2969 class="form-block-title flex-1 flex flex-col gap-5 justify-center items-center text-center min-h-48 p-10 border border-primary-darker transition-colors duration-300 cursor-pointer 2970 hover:bg-primary hover:text-white 2971 " 2972 :class="{ 'bg-primary text-white': activeTab === 'e1794b6d-d916-407c-846e-5c918f0f724d' }" 2973 @click="setActiveTab('e1794b6d-d916-407c-846e-5c918f0f724d', 'banham-product-queries')" 2974 > 2975 <h3 class="m-0 text-inherit">Banham Product Queries</h3> 2976 </button> 2977 2978 2979 <button 2980 type="button" 2981 class="form-block-title flex-1 flex flex-col gap-5 justify-center items-center text-center min-h-48 p-10 border border-primary-darker transition-colors duration-300 cursor-pointer 2982 hover:bg-primary hover:text-white 2983 " 2984 :class="{ 'bg-primary text-white': activeTab === '257df155-bcb9-4b83-9e64-7c2c0a251ebd' }" 2985 @click="setActiveTab('257df155-bcb9-4b83-9e64-7c2c0a251ebd', 'banham-contract-queries')" 2986 > 2987 <h3 class="m-0 text-inherit">Banham Contract Queries</h3> 2988 </button> 2989 2990 2991 <button 2992 type="button" 2993 class="form-block-title flex-1 flex flex-col gap-5 justify-center items-center text-center min-h-48 p-10 border border-primary-darker transition-colors duration-300 cursor-pointer 2994 hover:bg-primary hover:text-white 2995 " 2996 :class="{ 'bg-primary text-white': activeTab === 'eb2d7d4b-9ff0-44db-aa9d-d3ddc041aed3' }" 2997 @click="setActiveTab('eb2d7d4b-9ff0-44db-aa9d-d3ddc041aed3', 'update-your-details')" 2998 > 2999 <h3 class="m-0 text-inherit">Update your details</h3> 3000 </button> 3001 </div> 3002 3003 <!-- Tab Contents --> 3004 <div class="form-block-wrap scroll-mt-20"> 3005 <div 3006 x-show="activeTab === '10f8a50a-8bba-4ef8-8fe5-88312b39d219'" 3007 x-transition 3008 class="form-block flex flex-col justify-center items-center p-5 md:p-10 duration-300"
3009 id="form-block-content-10f8a50a-8bba-4ef8-8fe5-88312b39d219" 3010 > 3011 3012 3013<div class="flex flex-col max-w-[660px] w-full mx-auto"> 3014 3015 <div id="webform_PpTRdM_success_text" class="hyva-success-msg" 3016 style="display:none"></div> 3017 3018 3019 <div id="webform_PpTRdM_form" class="webforms"> 3020 3021 3022 <form method="post" name="webform_PpTRdM" id="webform_PpTRdM" enctype="multipart/form-data" class="form hyva-form contactForm" style="" aria-label="Contact Form" role="none"><input name="form_key" type="hidden"/><input type="hidden" name="submitForm_4" value="1"/><input type="hidden" name="form_id" value="4"/> <input name='field[864]' 3023 id="utm_source" 3024 type='hidden' 3025 value='' 3026 /><input name='field[867]' 3027 id="utm_medium" 3028 type='hidden' 3029 value='' 3030 /><input name='field[870]' 3031 id="utm_campaign" 3032 type='hidden' 3033 value='' 3034 /> <fieldset id="fieldset_PpTRdM0" class="fieldset-0 hyva-fieldset w-full" style="" role="group" > <div id="field_PpTRdM80" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select_contact webforms-fields-80 webforms-fields-subject required" aria-labelledby="label_fieldPpTRdM80" > <label class="hyva-field-lable" id="label_fieldPpTRdM80" for="fieldPpTRdM80">What is your query related to? </label> <div class="control" role="group" aria-labelledby="label_fieldPpTRdM80"> <select id='fieldPpTRdM80' name='field[80]' class='enquiry-options hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldPpTRdM80" aria-required="true" > <option value="Please Select" selected>Please Select</option> <option value="1" >Banham Lock Queries</option> <option value="2" >Emergency Locksmith & Locksmith</option> <option value="3" >Banham Alarms</option> <option value="4" >Keyholding & Alarm Response</option> <option value="5" >Online Order Queries</option> <option value="6" >Banham Account Queries</option> <option value="7" >Banham Survey Queries</option> <option value="8" >Banham Product Queries</option> <option value="9" >Update your details</option></select> </div></div> <div id="field_PpTRdM86" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select mm-logic-hidden webforms-fields-86 webforms-fields-alarm_query_type required" aria-labelledby="label_fieldPpTRdM86" > <label class="hyva-field-lable" id="label_fieldPpTRdM86" for="fieldPpTRdM86">Your Alarm Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldPpTRdM86"> <select id='fieldPpTRdM86' name='field[86]' class=' hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldPpTRdM86" aria-required="true" > <option value="Please Select" selected disabled>Please Select</option> <option value="I am interested in Banham alarms" >I am interested in Banham alarms</option> <option value="I have a query about my Banham alarm" >I have a query about my Banham alarm</option></select> </div></div> <div id="field_PpTRdM89" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select mm-logic-hidden webforms-fields-89 webforms-fields-lock_query_type required" aria-labelledby="label_fieldPpTRdM89" > <label class="hyva-field-lable" id="label_fieldPpTRdM89" for="fieldPpTRdM89">Your Lock Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldPpTRdM89"> <select id='fieldPpTRdM89' name='field[89]' class=' hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldPpTRdM89" aria-required="true" > <option value="Please Select" selected disabled>Please Select</option> <option value="I am interested in Banham locks" >I am interested in Banham locks</option> <option value="I have a query about my Banham locks" >I have a query about my Banham locks</option> <option value="Key cutting or registration query" >Key cutting or registration query</option></select> </div></div> <div id="field_PpTRdM98" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-98 webforms-fields-name required" aria-labelledby="label_fieldPpTRdM98" > <label class="hyva-field-lable" id="label_fieldPpTRdM98" for="fieldPpTRdM98">Name </label> <div class="control" role="group" aria-labelledby="label_fieldPpTRdM98"><input id='name' 3035 name='field[98]' 3036 type='text' 3037 class='input-text hyva-text' 3038 style='' 3039 value="" 3040 placeholder="Please enter your name here" 3041 data-validate="{'required-entry':true}" 3042 aria-labelledby="label_fieldPpTRdM98" aria-required="true" x-data="MageMe.WebForms.customerData()" 3043 @private-content-loaded.window="receiveCustomerData($event.detail.data)"
3044 x-model="customer.customer_name" 3045 /> 3046 </div></div> <div id="field_PpTRdM41" role="group" class="field hyva-field lg:w-full md:w-full w-full type-email webforms-fields-41 webforms-fields-email required" aria-labelledby="label_fieldPpTRdM41" > <label class="hyva-field-lable" id="label_fieldPpTRdM41" for="fieldPpTRdM41">Email </label> <div class="control" role="group" aria-labelledby="label_fieldPpTRdM41"> <input id='fieldPpTRdM41' name='field[41]' type='email' class='input-text hyva-text' style='' value="" placeholder="[email protected]" data-validate="{'required-entry':true, 'validate-email':true}" aria-labelledby="label_fieldPpTRdM41" aria-required="true" x-data="mmWebformsEmailDatafieldPpTRdM41" @input="trimSpace" @private-content-loaded.window="setCustomerData" /> </div></div> <div id="field_PpTRdM47" role="group" class="field hyva-field lg:w-full md:w-full w-full type-textarea webforms-fields-47 webforms-fields-your_enquiry required" aria-labelledby="label_fieldPpTRdM47" > <label class="hyva-field-lable" id="label_fieldPpTRdM47" for="fieldPpTRdM47">Your Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldPpTRdM47"> <textarea id='fieldPpTRdM47' 3047 name='field[47]' 3048 class=' hyva-textarea' 3049 rows='5' 3050 style='' 3051 placeholder="Enter your enquiry here" 3052 data-validate="{'required-entry':true}" 3053 aria-labelledby="label_fieldPpTRdM47" aria-required="true" ></textarea> </div></div> <div id="field_PpTRdM56" role="group" class="field hyva-field lg:w-full md:w-full w-full type-number webforms-fields-56 webforms-fields-contact_number required" aria-labelledby="label_fieldPpTRdM56" > <label class="hyva-field-lable" id="label_fieldPpTRdM56" for="fieldPpTRdM56">Contact number </label> <div class="control" role="group" aria-labelledby="label_fieldPpTRdM56"> <input id='fieldPpTRdM56' name='field[56]' type='number' step="any" class='input-text hyva-text' style='' value="" placeholder="Contact number" data-validate="{'required-entry':true, 'validate-number':true}" aria-labelledby="label_fieldPpTRdM56" aria-required="true" /> </div></div> <div id="field_PpTRdM59" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-59 webforms-fields-street required" aria-labelledby="label_fieldPpTRdM59" > <label class="hyva-field-lable" id="label_fieldPpTRdM59" for="fieldPpTRdM59">Street & Number </label> <div class="control" role="group" aria-labelledby="label_fieldPpTRdM59"><input id='street' 3054 name='field[59]' 3055 type='text' 3056 class='input-text hyva-text' 3057 style='' 3058 value="" 3059 placeholder="" 3060 data-validate="{'required-entry':true}" 3061 aria-labelledby="label_fieldPpTRdM59" aria-required="true" /> 3062 </div></div> <div id="field_PpTRdM65" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-65 webforms-fields-city required" aria-labelledby="label_fieldPpTRdM65" > <label class="hyva-field-lable" id="label_fieldPpTRdM65" for="fieldPpTRdM65">Town / City </label> <div class="control" role="group" aria-labelledby="label_fieldPpTRdM65"><input id='city' 3063 name='field[65]' 3064 type='text' 3065 class='input-text hyva-text' 3066 style='' 3067 value="" 3068 placeholder="Town / City" 3069 data-validate="{'required-entry':true}" 3070 aria-labelledby="label_fieldPpTRdM65" aria-required="true" /> 3071 </div></div> <div id="field_PpTRdM68" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-68 webforms-fields-county " aria-labelledby="label_fieldPpTRdM68" > <label class="hyva-field-lable" id="label_fieldPpTRdM68" for="fieldPpTRdM68">County </label> <div class="control" role="group" aria-labelledby="label_fieldPpTRdM68"><input id='county' 3072 name='field[68]' 3073 type='text' 3074 class='input-text hyva-text' 3075 style='' 3076 value="" 3077 placeholder="County" 3078 aria-labelledby="label_fieldPpTRdM68" /> 3079 </div></div> <div id="field_PpTRdM71" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-71 webforms-fields-postcode required" aria-labelledby="label_fieldPpTRdM71" > <label class="hyva-field-lable" id="label_fieldPpTRdM71" for="fieldPpTRdM71">Postcode </label> <div class="control" role="group" aria-labelledby="label_fieldPpTRdM71"><input id='postcode' 3080 name='field[71]' 3081 type='text' 3082 class='input-text hyva-text' 3083 style='' 3084 value="" 3085 placeholder="Postcode" 3086 data-validate="{'required-entry':true}" 3087 aria-labelledby="label_fieldPpTRdM71" aria-required="true" /> 3088 </div></div> <div id="field_PpTRdM92" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-92 webforms-fields-account-number " aria-labelledby="label_fieldPpTRdM92" > <label class="hyva-field-lable" id="label_fieldPpTRdM92" for="fieldPpTRdM92">Account Number </label> <div class="control" role="group" aria-labelledby="label_fieldPpTRdM92"><input id='account-number' 3089 name='field[92]' 3090 type='text' 3091 class='input-text hyva-text' 3092 style='' 3093 value="" 3094 placeholder="Your account number" 3095 aria-labelledby="label_fieldPpTRdM92" /> 3096 </div></div></fieldset> <div id="captcha-container-PpTRdM" class="captcha-container px-4 clear-both float-left w-full"></div> <div id="submitPpTRdM" class="flex !flex-col gap-2 actions-toolbar submit-right w-full clear-both !m-0"> 3097 <div class="primary w-full mx-auto text-center"> 3098 <button type="submit" class="action submit primary w-auto " 3099 id="webform_PpTRdM_submit_button" 3100 title="Submit" 3101 name="submit_button_PpTRdM">
3102 <span>Submit</span> 3103 </button> 3104 <div class="w-full grecaptcha-legal mt-5"> 3105 <p class="my-4 text-sm"> 3106 <em>This site is protected by reCAPTCHA.</em> 3107</p> </div> 3108 </div> 3109 <div class="secondary"> 3110 <div class="please-wait" id="webform_PpTRdM_sending_data" 3111 style="display:none;"> 3112 <div class="loading-indicator"></div> 3113 <span id="webform_PpTRdM_progress_text">Sending...</span> 3114 </div> 3115 </div> 3116</div></form> 3117 3118 </div> 3119 3120 <style> .recaptcha-position-inline{ clear: both; box-sizing: border-box; padding: 0 2rem 2rem 0; width: 100%; float: left; }</style> 3121 </div> </div> 3122 <div 3123 x-show="activeTab === 'a682ed85-29c5-437c-b4e3-1113aaa32c62'" 3124 x-transition 3125 class="form-block flex flex-col justify-center items-center p-5 md:p-10 duration-300" 3126 id="form-block-content-a682ed85-29c5-437c-b4e3-1113aaa32c62" 3127 > 3128 3129 3130<div class="flex flex-col max-w-[660px] w-full mx-auto"> 3131 <div class="flex flex-col flex-wrap"> 3132 <h2 class="text-center text-4xl tracking-[0.24px] mb-[60px]"> 3133 <span class="base" 3134 data-ui-id="page-title-wrapper">BOOK A LOCKSMITH</span> 3135 </h2> 3136 </div> 3137 3138 <div id="webform_de7Gm7_success_text" class="hyva-success-msg" 3139 style="display:none"></div> 3140 3141 3142 <div id="webform_de7Gm7_form" class="webforms"> 3143 3144 <div id="de7Gm7form_description" class="webforms-description-text text-center [&_a]:text-[length:inherit]"> 3145 Emergencies: if you require urgent help please contact our emergency locksmith team, available 24/7 - call <br><a href="tel:02076225151">020 7622 5151</a>.</p> </div> 3146 3147 <form method="post" name="webform_de7Gm7" id="webform_de7Gm7" enctype="multipart/form-data" class="form hyva-form " style="" aria-label="Locksmith Enquiry" role="none"><input name="form_key" type="hidden"/><input type="hidden" name="submitForm_27" value="1"/><input type="hidden" name="form_id" value="27"/> <input name='field[855]' 3148 id="utm_source" 3149 type='hidden' 3150 value='' 3151 /><input name='field[858]' 3152 id="utm_medium" 3153 type='hidden' 3154 value='' 3155 /><input name='field[861]' 3156 id="utm_campaign" 3157 type='hidden' 3158 value='' 3159 /> <fieldset id="fieldset_de7Gm70" class="fieldset-0 hyva-fieldset w-full" style="" role="group" > <div id="field_de7Gm7329" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select_radio webforms-fields-329 webforms-fields-enquiry-type required" aria-labelledby="label_fieldde7Gm7329" > <label class="hyva-field-lable" id="label_fieldde7Gm7329" >Enquiry Type </label> <div class="control" role="group" aria-labelledby="label_fieldde7Gm7329"> <div aria-labelledby="label_fieldde7Gm7329" > <div class='field choice option-0' style='' ><input id='fieldde7Gm73290' name='field[329]' type='radio' value="Business" class='hyva-radio' data-validate="{'validate-one-required-by-name':true}" aria-labelledby="fieldde7Gm73290_label label_fieldde7Gm7329" /><label id="fieldde7Gm73290_label" for='fieldde7Gm73290' class=' hyva-radio-label'>Business</label> </div> <div class='field choice option-1' style='' ><input id='fieldde7Gm73291' name='field[329]' type='radio' value="Residential" class='hyva-radio' data-validate="{'validate-one-required-by-name':true}" aria-labelledby="fieldde7Gm73291_label label_fieldde7Gm7329" checked /><label id="fieldde7Gm73291_label" for='fieldde7Gm73291' class=' hyva-radio-label'>Residential</label> </div></div> </div></div> <div id="field_de7Gm7623" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-623 webforms-fields-enquiry-topic " aria-labelledby="label_fieldde7Gm7623" > <label class="hyva-field-lable" id="label_fieldde7Gm7623" for="fieldde7Gm7623">Enquiry topic </label> <div class="control" role="group" aria-labelledby="label_fieldde7Gm7623"><input id='enquiry-topic' 3160 name='field[623]' 3161 type='text' 3162 class='input-text hyva-text' 3163 style='' 3164 value="" 3165 placeholder="" 3166 aria-labelledby="label_fieldde7Gm7623" /> 3167 </div></div> <div id="field_de7Gm7335" role="group" class="field hyva-field lg:w-full md:w-full w-full type-textarea webforms-fields-335 webforms-fields-enquiry required" aria-labelledby="label_fieldde7Gm7335" > <label class="hyva-field-lable" id="label_fieldde7Gm7335" for="fieldde7Gm7335">Your Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldde7Gm7335"> <textarea id='fieldde7Gm7335' 3168 name='field[335]' 3169 class=' hyva-textarea' 3170 rows='5' 3171 style='' 3172 placeholder="Enter your enquiry here" 3173 data-validate="{'required-entry':true}" 3174 aria-labelledby="label_fieldde7Gm7335" aria-required="true" ></textarea> </div></div> <div id="field_de7Gm7338" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-338 webforms-fields-firstname required" aria-labelledby="label_fieldde7Gm7338" > <label class="hyva-field-lable" id="label_fieldde7Gm7338" for="fieldde7Gm7338">First Name </label> <div class="control" role="group" aria-labelledby="label_fieldde7Gm7338"><input id='firstname' 3175 name='field[338]' 3176 type='text' 3177 class='input-text hyva-text' 3178 style='' 3179 value="" 3180 placeholder="Please enter your first name here" 3181 data-validate="{'required-entry':true, 'validate-length-max':'30'}" 3182 aria-labelledby="label_fieldde7Gm7338" aria-required="true" x-data="MageMe.WebForms.customerData()" 3183 @private-content-loaded.window="receiveCustomerData($event.detail.data)"
3184 x-model="customer.customer_firstname" 3185 /> 3186 </div></div> <div id="field_de7Gm7341" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-341 webforms-fields-lastname required" aria-labelledby="label_fieldde7Gm7341" > <label class="hyva-field-lable" id="label_fieldde7Gm7341" for="fieldde7Gm7341">Last name </label> <div class="control" role="group" aria-labelledby="label_fieldde7Gm7341"><input id='lastname' 3187 name='field[341]' 3188 type='text' 3189 class='input-text hyva-text' 3190 style='' 3191 value="" 3192 placeholder="Please enter your last name here" 3193 data-validate="{'required-entry':true, 'validate-length-max':'30'}" 3194 aria-labelledby="label_fieldde7Gm7341" aria-required="true" x-data="MageMe.WebForms.customerData()" 3195 @private-content-loaded.window="receiveCustomerData($event.detail.data)" 3196 x-model="customer.customer_lastname" 3197 /> 3198 </div></div> <div id="field_de7Gm7332" role="group" class="field hyva-field lg:w-full md:w-full w-full type-email webforms-fields-332 webforms-fields-email required" aria-labelledby="label_fieldde7Gm7332" > <label class="hyva-field-lable" id="label_fieldde7Gm7332" for="fieldde7Gm7332">Email </label> <div class="control" role="group" aria-labelledby="label_fieldde7Gm7332"> <input id='fieldde7Gm7332' name='field[332]' type='email' class='input-text hyva-text' style='' value="" placeholder="[email protected]" data-validate="{'required-entry':true, 'validate-email':true}" aria-labelledby="label_fieldde7Gm7332" aria-required="true" x-data="mmWebformsEmailDatafieldde7Gm7332" @input="trimSpace" @private-content-loaded.window="setCustomerData" /> </div></div> <div id="field_de7Gm7344" role="group" class="field hyva-field lg:w-full md:w-full w-full type-number webforms-fields-344 webforms-fields-contact-number required" aria-labelledby="label_fieldde7Gm7344" > <label class="hyva-field-lable" id="label_fieldde7Gm7344" for="fieldde7Gm7344">Contact number </label> <div class="control" role="group" aria-labelledby="label_fieldde7Gm7344"> <input id='fieldde7Gm7344' name='field[344]' type='number' step="any" class='input-text hyva-text' style='' value="" placeholder="" data-validate="{'required-entry':true, 'validate-number':true}" aria-labelledby="label_fieldde7Gm7344" aria-required="true" /> </div></div> <div id="field_de7Gm7347" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-347 webforms-fields-street required" aria-labelledby="label_fieldde7Gm7347" > <label class="hyva-field-lable" id="label_fieldde7Gm7347" for="fieldde7Gm7347">Street & Number </label> <div class="control" role="group" aria-labelledby="label_fieldde7Gm7347"><input id='street' 3199 name='field[347]' 3200 type='text' 3201 class='input-text hyva-text' 3202 style='' 3203 value="" 3204 placeholder="" 3205 data-validate="{'required-entry':true, 'validate-length-max':'40'}" 3206 aria-labelledby="label_fieldde7Gm7347" aria-required="true" /> 3207 </div></div> <div id="field_de7Gm7635" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-635 webforms-fields-street1 " > <div class="control" role="group" ><input id='street1' 3208 name='field[635]' 3209 type='text' 3210 class='input-text hyva-text' 3211 style='' 3212 value="" 3213 placeholder="" 3214 data-validate="{'validate-length-max':'40'}" 3215 aria-label="Street 1" 3216 /> 3217 </div></div> <div id="field_de7Gm7638" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-638 webforms-fields-street2 " > <div class="control" role="group" ><input id='street2' 3218 name='field[638]' 3219 type='text' 3220 class='input-text hyva-text' 3221 style='' 3222 value="" 3223 placeholder="" 3224 data-validate="{'validate-length-max':'40'}" 3225 aria-label="Street 2" 3226 /> 3227 </div></div> <div id="field_de7Gm7350" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-350 webforms-fields-company_name " aria-labelledby="label_fieldde7Gm7350" > <label class="hyva-field-lable" id="label_fieldde7Gm7350" for="fieldde7Gm7350">Company Name </label> <div class="control" role="group" aria-labelledby="label_fieldde7Gm7350"><input id='company_name' 3228 name='field[350]' 3229 type='text' 3230 class='input-text hyva-text' 3231 style='' 3232 value="" 3233 placeholder="Company name" 3234 data-validate="{'validate-length-max':'60'}" 3235 aria-labelledby="label_fieldde7Gm7350" /> 3236 </div></div> <div id="field_de7Gm7353" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-353 webforms-fields-city required" aria-labelledby="label_fieldde7Gm7353" > <label class="hyva-field-lable" id="label_fieldde7Gm7353" for="fieldde7Gm7353">Town / City </label> <div class="control" role="group" aria-labelledby="label_fieldde7Gm7353"><input id='city' 3237 name='field[353]' 3238 type='text' 3239 class='input-text hyva-text' 3240 style='' 3241 value="" 3242 placeholder="Town / City" 3243 data-validate="{'required-entry':true, 'validate-length-max':'30'}" 3244 aria-labelledby="label_fieldde7Gm7353" aria-required="true" /> 3245 </div></div> <div id="field_de7Gm7356" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-356 webforms-fields-country " aria-labelledby="label_fieldde7Gm7356" > <label class="hyva-field-lable" id="label_fieldde7Gm7356" for="fieldde7Gm7356">Country </label> <div class="control" role="group" aria-labelledby="label_fieldde7Gm7356"><input id='country' 3246 name='field[356]' 3247 type='text' 3248 class='input-text hyva-text' 3249 style='' 3250 value="" 3251 placeholder="Country" 3252 data-validate="{'validate-length-max':'30'}" 3253 aria-labelledby="label_fieldde7Gm7356" /> 3254 </div></div> <div id="field_de7Gm7359" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-359 webforms-fields-postcode required" aria-labelledby="label_fieldde7Gm7359" > <label class="hyva-field-lable" id="label_fieldde7Gm7359" for="fieldde7Gm7359">Postcode </label> <div class="control" role="group" aria-labelledby="label_fieldde7Gm7359"><input id='postcode' 3255 name='field[359]' 3256 type='text' 3257 class='input-text hyva-text' 3258 style='' 3259 value="" 3260 placeholder="Postcode" 3261 data-validate="{'required-entry':true, 'validate-length-max':'10'}" 3262 aria-labelledby="label_fieldde7Gm7359" aria-required="true" /> 3263 </div></div> <div id="field_de7Gm7362" role="group" class="field hyva-field lg:w-full md:w-full w-full type-date webforms-fields-362 webforms-fields-survey-date required" aria-labelledby="label_fieldde7Gm7362" > <label class="hyva-field-lable" id="label_fieldde7Gm7362" for="fieldde7Gm7362">Preferred Locksmith Date </label> <div class="control" role="group" aria-labelledby="label_fieldde7Gm7362"><div class='webforms-datepicker ddd'> 3264 <div id='fieldde7Gm7362_calendar' class='webforms-calendar'> 3265 <div class="relative"> 3266 <input id='fieldde7Gm7362' 3267 name='field[362]' 3268 type='text' 3269 class='input-text _has-datepicker hyva-text pr-10' 3270 style='' 3271 value='' 3272 placeholder="" 3273 data-validate="{'required-entry':true}" 3274 aria-labelledby="label_fieldde7Gm7362" aria-required="true" /> 3275 3276 <svg class="text-gray-400 pointer-events-none" style="position: absolute; top:20px; right:20px; width:20px;"viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> 3277 <path d="M3.33337 5.83329C3.33337 5.39127 3.50897 4.96734 3.82153 4.65478C4.13409 4.34222 4.55801 4.16663 5.00004 4.16663H15C15.4421 4.16663 15.866 4.34222 16.1786 4.65478C16.4911 4.96734 16.6667 5.39127 16.6667 5.83329V15.8333C16.6667 16.2753 16.4911 16.6992 16.1786 17.0118C15.866 17.3244 15.4421 17.5 15 17.5H5.00004C4.55801 17.5 4.13409 17.3244 3.82153 17.0118C3.50897 16.6992 3.33337 16.2753 3.33337 15.8333V5.83329Z" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 3278 <path d="M13.3334 2.5V5.83333" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 3279 <path d="M6.66663 2.5V5.83333" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 3280 <path d="M3.33337 9.16663H16.6667" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 3281 <path d="M5.83337 11.6666H5.84421" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 3282 <path d="M8.34167 11.6666H8.34667" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 3283 <path d="M10.8417 11.6666H10.8467" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 3284 <path d="M13.3458 11.6666H13.3508" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 3285 <path d="M10.8458 14.1666H10.8508" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 3286 <path d="M5.84167 14.1666H5.84667" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 3287 <path d="M8.34167 14.1666H8.34667" stroke="black" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/> 3288 </svg> 3289 </div> 3290 </div> 3291</div> 3292 </div></div> <div id="field_de7Gm7365" role="group" class="field hyva-field lg:w-full md:w-full w-full type-sub
3292scribe choice webforms-fields-365 webforms-fields-subscribe " aria-describedby="comment_fieldde7Gm7365"> <div class="control" role="group" > <div class="field choice option-0"><input id='fieldde7Gm73650' name='field[365]' type='checkbox' class='hyva-checkbox' style='float:left' value='1' /><label for='fieldde7Gm73650' class=' hyva-checkbox-label' style='' >Subscribe</label></div> <p class="hyva-comment-label" id="comment_fieldde7Gm7365" tabindex="0">I consent to Banham sending me email updates on special offers, products, and services. If you would like further information on how we use your personal data, please check our <a href="/privacy-promise" target="_blank">Privacy Policy</a>.</p></div></div></fieldset> <div id="captcha-container-de7Gm7" class="captcha-container px-4 clear-both float-left w-full"></div> <div id="submitde7Gm7" class="flex !flex-col gap-2 actions-toolbar submit-center w-full clear-both !m-0"> 3293 <div class="primary w-full mx-auto text-center"> 3294 <button type="submit" class="action submit primary w-auto " 3295 id="webform_de7Gm7_submit_button" 3296 title="Submit" 3297 name="submit_button_de7Gm7"> 3298 <span>Submit</span> 3299 </button> 3300 <div class="w-full grecaptcha-legal mt-5"> 3301 <p class="my-4 text-sm"> 3302 <em>This site is protected by reCAPTCHA.</em> 3303</p> </div> 3304 </div> 3305 <div class="secondary"> 3306 <div class="please-wait" id="webform_de7Gm7_sending_data" 3307 style="display:none;"> 3308 <div class="loading-indicator"></div> 3309 <span id="webform_de7Gm7_progress_text">Sending...</span> 3310 </div> 3311 </div> 3312</div></form> 3313 3314 </div> 3315 3316 <style> .recaptcha-position-inline{ clear: both; box-sizing: border-box; padding: 0 2rem 2rem 0; width: 100%; float: left; }</style> 3317 </div> </div> 3318 <div 3319 x-show="activeTab === '93718e28-037a-4c05-9e0d-9299d3ddcf8a'" 3320 x-transition 3321 class="form-block flex flex-col justify-center items-center p-5 md:p-10 duration-300" 3322 id="form-block-content-93718e28-037a-4c05-9e0d-9299d3ddcf8a" 3323 > 3324 3325 3326<div class="flex flex-col max-w-[660px] w-full mx-auto"> 3327 3328 <div id="webform_XpSqJw_success_text" class="hyva-success-msg" 3329 style="display:none"></div> 3330 3331 3332 <div id="webform_XpSqJw_form" class="webforms"> 3333 3334 3335 <form method="post" name="webform_XpSqJw" id="webform_XpSqJw" enctype="multipart/form-data" class="form hyva-form contactForm" style="" aria-label="Contact Form" role="none"><input name="form_key" type="hidden"/><input type="hidden" name="submitForm_4" value="1"/><input type="hidden" name="form_id" value="4"/> <input name='field[864]' 3336 id="utm_source" 3337 type='hidden' 3338 value='' 3339 /><input name='field[867]' 3340 id="utm_medium" 3341 type='hidden' 3342 value='' 3343 /><input name='field[870]' 3344 id="utm_campaign" 3345 type='hidden' 3346 value='' 3347 /> <fieldset id="fieldset_XpSqJw0" class="fieldset-0 hyva-fieldset w-full" style="" role="group" > <div id="field_XpSqJw80" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select_contact webforms-fields-80 webforms-fields-subject required" aria-labelledby="label_fieldXpSqJw80" > <label class="hyva-field-lable" id="label_fieldXpSqJw80" for="fieldXpSqJw80">What is your query related to? </label> <div class="control" role="group" aria-labelledby="label_fieldXpSqJw80"> <select id='fieldXpSqJw80' name='field[80]' class='enquiry-options hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldXpSqJw80" aria-required="true" > <option value="Please Select" selected>Please Select</option> <option value="1" >Banham Lock Queries</option> <option value="2" >Emergency Locksmith & Locksmith</option> <option value="3" >Banham Alarms</option> <option value="4" >Keyholding & Alarm Response</option> <option value="5" >Online Order Queries</option> <option value="6" >Banham Account Queries</option> <option value="7" >Banham Survey Queries</option> <option value="8" >
3347Banham Product Queries</option> <option value="9" >Update your details</option></select> </div></div> <div id="field_XpSqJw86" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select mm-logic-hidden webforms-fields-86 webforms-fields-alarm_query_type required" aria-labelledby="label_fieldXpSqJw86" > <label class="hyva-field-lable" id="label_fieldXpSqJw86" for="fieldXpSqJw86">Your Alarm Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldXpSqJw86"> <select id='fieldXpSqJw86' name='field[86]' class=' hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldXpSqJw86" aria-required="true" > <option value="Please Select" selected disabled>Please Select</option> <option value="I am interested in Banham alarms" >I am interested in Banham alarms</option> <option value="I have a query about my Banham alarm" >I have a query about my Banham alarm</option></select> </div></div> <div id="field_XpSqJw89" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select mm-logic-hidden webforms-fields-89 webforms-fields-lock_query_type required" aria-labelledby="label_fieldXpSqJw89" > <label class="hyva-field-lable" id="label_fieldXpSqJw89" for="fieldXpSqJw89">Your Lock Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldXpSqJw89"> <select id='fieldXpSqJw89' name='field[89]' class=' hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldXpSqJw89" aria-required="true" > <option value="Please Select" selected disabled>Please Select</option> <option value="I am interested in Banham locks" >I am interested in Banham locks</option> <option value="I have a query about my Banham locks" >I have a query about my Banham locks</option> <option value="Key cutting or registration query" >Key cutting or registration query</option></select> </div></div> <div id="field_XpSqJw98" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-98 webforms-fields-name required" aria-labelledby="label_fieldXpSqJw98" > <label class="hyva-field-lable" id="label_fieldXpSqJw98" for="fieldXpSqJw98">Name </label> <div class="control" role="group" aria-labelledby="label_fieldXpSqJw98"><input id='name' 3348 name='field[98]' 3349 type='text' 3350 class='input-text hyva-text' 3351 style='' 3352 value="" 3353 placeholder="Please enter your name here" 3354 data-validate="{'required-entry':true}" 3355 aria-labelledby="label_fieldXpSqJw98" aria-required="true" x-data="MageMe.WebForms.customerData()" 3356 @private-content-loaded.window="receiveCustomerData($event.detail.data)" 3357 x-model="customer.customer_name" 3358 /> 3359 </div></div> <div id="field_XpSqJw41" role="group" class="field hyva-field lg:w-full md:w-full w-full type-email webforms-fields-41 webforms-fields-email required" aria-labelledby="label_fieldXpSqJw41" > <label class="hyva-field-lable" id="label_fieldXpSqJw41" for="fieldXpSqJw41">Email </label> <div class="control" role="group" aria-labelledby="label_fieldXpSqJw41"> <input id='fieldXpSqJw41' name='field[41]' type='email' class='input-text hyva-text' style='' value="" placeholder="[email protected]" data-validate="{'required-entry':true, 'validate-email':true}" aria-labelledby="label_fieldXpSqJw41" aria-required="true" x-data="mmWebformsEmailDatafieldXpSqJw41" @input="trimSpace" @private-content-loaded.window="setCustomerData" /> </div></div> <div id="field_XpSqJw47" role="group" class="field hyva-field lg:w-full md:w-full w-full type-textarea webforms-fields-47 webforms-fields-your_enquiry required" aria-labelledby="label_fieldXpSqJw47" > <label class="hyva-field-lable" id="label_fieldXpSqJw47" for="fieldXpSqJw47">Your Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldXpSqJw47"> <textarea id='fieldXpSqJw47' 3360 name='field[47]' 3361 class=' hyva-textarea' 3362 rows='5' 3363 style='' 3364 placeholder="Enter your enquiry here" 3365 data-validate="{'required-entry':true}" 3366 aria-labelledby="label_fieldXpSqJw47" aria-required="true" ></textarea> </div></div> <div id="field_XpSqJw56" role="group" class="field hyva-field lg:w-full md:w-full w-full type-number webforms-fields-56 webforms-fields-contact_number required" aria-labelledby="label_fieldXpSqJw56" > <label class="hyva-field-lable" id="label_fieldXpSqJw56" for="fieldXpSqJw56">Contact number </label> <div class="control" role="group" aria-labelledby="label_fieldXpSqJw56"> <input id='fieldXpSqJw56' name='field[56]' type='number' step="any" class='input-text hyva-text' style='' value="" placeholder="Contact number" data-validate="{'required-entry':true, 'validate-number':true}" aria-labelledby="label_fieldXpSqJw56" aria-required="true" />
3366 </div></div> <div id="field_XpSqJw59" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-59 webforms-fields-street required" aria-labelledby="label_fieldXpSqJw59" > <label class="hyva-field-lable" id="label_fieldXpSqJw59" for="fieldXpSqJw59">Street & Number </label> <div class="control" role="group" aria-labelledby="label_fieldXpSqJw59"><input id='street' 3367 name='field[59]' 3368 type='text' 3369 class='input-text hyva-text' 3370 style='' 3371 value="" 3372 placeholder="" 3373 data-validate="{'required-entry':true}" 3374 aria-labelledby="label_fieldXpSqJw59" aria-required="true" /> 3375 </div></div> <div id="field_XpSqJw65" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-65 webforms-fields-city required" aria-labelledby="label_fieldXpSqJw65" > <label class="hyva-field-lable" id="label_fieldXpSqJw65" for="fieldXpSqJw65">Town / City </label> <div class="control" role="group" aria-labelledby="label_fieldXpSqJw65"><input id='city' 3376 name='field[65]' 3377 type='text' 3378 class='input-text hyva-text' 3379 style='' 3380 value="" 3381 placeholder="Town / City" 3382 data-validate="{'required-entry':true}" 3383 aria-labelledby="label_fieldXpSqJw65" aria-required="true" /> 3384 </div></div> <div id="field_XpSqJw68" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-68 webforms-fields-county " aria-labelledby="label_fieldXpSqJw68" > <label class="hyva-field-lable" id="label_fieldXpSqJw68" for="fieldXpSqJw68">County </label> <div class="control" role="group" aria-labelledby="label_fieldXpSqJw68"><input id='county' 3385 name='field[68]' 3386 type='text' 3387 class='input-text hyva-text' 3388 style='' 3389 value="" 3390 placeholder="County" 3391 aria-labelledby="label_fieldXpSqJw68" /> 3392 </div></div> <div id="field_XpSqJw71" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-71 webforms-fields-postcode required" aria-labelledby="label_fieldXpSqJw71" > <label class="hyva-field-lable" id="label_fieldXpSqJw71" for="fieldXpSqJw71">Postcode </label> <div class="control" role="group" aria-labelledby="label_fieldXpSqJw71"><input id='postcode' 3393 name='field[71]' 3394 type='text' 3395 class='input-text hyva-text' 3396 style='' 3397 value="" 3398 placeholder="Postcode" 3399 data-validate="{'required-entry':true}" 3400 aria-labelledby="label_fieldXpSqJw71" aria-required="true" /> 3401 </div></div> <div id="field_XpSqJw92" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-92 webforms-fields-account-number " aria-labelledby="label_fieldXpSqJw92" > <label class="hyva-field-lable" id="label_fieldXpSqJw92" for="fieldXpSqJw92">Account Number </label> <div class="control" role="group" aria-labelledby="label_fieldXpSqJw92"><input id='account-number' 3402 name='field[92]' 3403 type='text' 3404 class='input-text hyva-text' 3405 style='' 3406 value="" 3407 placeholder="Your account number" 3408 aria-labelledby="label_fieldXpSqJw92" /> 3409 </div></div></fieldset> <div id="captcha-container-XpSqJw" class="captcha-container px-4 clear-both float-left w-full"></div> <div id="submitXpSqJw" class="flex !flex-col gap-2 actions-toolbar submit-right w-full clear-both !m-0"> 3410 <div class="primary w-full mx-auto text-center"> 3411 <button type="submit" class="action submit primary w-auto " 3412 id="webform_XpSqJw_submit_button" 3413 title="Submit" 3414 name="submit_button_XpSqJw"> 3415 <span>Submit</span> 3416 </button> 3417 <div class="w-full grecaptcha-legal mt-5"> 3418 <p class="my-4 text-sm"> 3419 <em>This site is protected by reCAPTCHA.</em> 3420</p> </div> 3421 </div> 3422 <div class="secondary"> 3423 <div class="please-wait" id="webform_XpSqJw_sending_data" 3424 style="display:none;"> 3425 <div class="loading-indicator"></div>
3426 <span id="webform_XpSqJw_progress_text">Sending...</span> 3427 </div> 3428 </div> 3429</div></form> 3430 3431 </div> 3432 3433 <style> .recaptcha-position-inline{ clear: both; box-sizing: border-box; padding: 0 2rem 2rem 0; width: 100%; float: left; }</style> 3434 </div> </div> 3435 <div 3436 x-show="activeTab === 'dea59f1d-3c21-48e7-b117-66062eda44f6'" 3437 x-transition 3438 class="form-block flex flex-col justify-center items-center p-5 md:p-10 duration-300" 3439 id="form-block-content-dea59f1d-3c21-48e7-b117-66062eda44f6" 3440 > 3441 3442<div class="flex flex-col max-w-[660px] w-full mx-auto"> 3443 <div class="flex flex-col flex-wrap"> 3444 <h2 class="text-center text-4xl tracking-[0.24px]"> 3445 <span class="base" 3446 data-ui-id="page-title-wrapper">DISCUSS YOUR KEYHOLDING REQUIREMENTS</span> 3447 </h2> 3448 </div> 3449 3450 <div id="webform_cvQP2X_success_text" class="hyva-success-msg" 3451 style="display:none"></div> 3452 3453 3454 <div id="webform_cvQP2X_form" class="webforms"> 3455 3456 <div id="cvQP2Xform_description" class="webforms-description-text text-center [&_a]:text-[length:inherit]"> 3457 <h2> Or call <a href="tel:02076270344">020 7627 0344</a></h2> 3458 </div> 3459 3460 <form method="post" name="webform_cvQP2X" id="webform_cvQP2X" enctype="multipart/form-data" class="form hyva-form " style="" aria-label="Keyholding Form" role="none"><input name="form_key" type="hidden"/><input type="hidden" name="submitForm_32" value="1"/><input type="hidden" name="form_id" value="32"/> <input name='field[900]' 3461 id="utm_source" 3462 type='hidden' 3463 value='' 3464 /><input name='field[903]' 3465 id="utm_medium" 3466 type='hidden' 3467 value='' 3468 /><input name='field[906]' 3469 id="utm_campaign" 3470 type='hidden' 3471 value='' 3472 /> <fieldset id="fieldset_cvQP2X0" class="fieldset-0 hyva-fieldset w-full" style="" role="group" > <div id="field_cvQP2X368" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select_radio webforms-fields-368 webforms-fields-enquiry-type required" aria-labelledby="label_fieldcvQP2X368" > <label class="hyva-field-lable" id="label_fieldcvQP2X368" >Enquiry Type </label> <div class="control" role="group" aria-labelledby="label_fieldcvQP2X368"> <div aria-labelledby="label_fieldcvQP2X368" > <div class='field choice option-0' style='' ><input id='fieldcvQP2X3680' name='field[368]' type='radio' value="Business" class='hyva-radio' data-validate="{'validate-one-required-by-name':true}" aria-labelledby="fieldcvQP2X3680_label label_fieldcvQP2X368" /><label id="fieldcvQP2X3680_label" for='fieldcvQP2X3680' class=' hyva-radio-label'>Business</label> </div> <div class='field choice option-1' style='' ><input id='fieldcvQP2X3681' name='field[368]' type='radio' value="Residential" class='hyva-radio' data-validate="{'validate-one-required-by-name':true}" aria-labelledby="fieldcvQP2X3681_label label_fieldcvQP2X368" checked /><label id="fieldcvQP2X3681_label" for='fieldcvQP2X3681' class=' hyva-radio-label'>Residential</label> </div></div> </div></div> <div id="field_cvQP2X377" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-377 webforms-fields-firstname required" aria-labelledby="label_fieldcvQP2X377" > <label class="hyva-field-lable" id="label_fieldcvQP2X377" for="fieldcvQP2X377">First Name </label> <div class="control" role="group" aria-labelledby="label_fieldcvQP2X377"><input id='firstname' 3473 name='field[377]' 3474 type='text' 3475 class='input-text hyva-text' 3476 style='' 3477 value="" 3478 placeholder="Please enter your first name here" 3479 data-validate="{'required-entry':true}" 3480 aria-labelledby="label_fieldcvQP2X377" aria-required="true" x-data="MageMe.WebForms.customerData()" 3481 @private-content-loaded.window="receiveCustomerData($event.detail.data)"
3482 x-model="customer.customer_firstname" 3483 /> 3484 </div></div> <div id="field_cvQP2X380" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-380 webforms-fields-lastname required" aria-labelledby="label_fieldcvQP2X380" > <label class="hyva-field-lable" id="label_fieldcvQP2X380" for="fieldcvQP2X380">Last name </label> <div class="control" role="group" aria-labelledby="label_fieldcvQP2X380"><input id='lastname' 3485 name='field[380]' 3486 type='text' 3487 class='input-text hyva-text' 3488 style='' 3489 value="" 3490 placeholder="Please enter your last name here" 3491 data-validate="{'required-entry':true}" 3492 aria-labelledby="label_fieldcvQP2X380" aria-required="true" x-data="MageMe.WebForms.customerData()" 3493 @private-content-loaded.window="receiveCustomerData($event.detail.data)" 3494 x-model="customer.customer_lastname" 3495 /> 3496 </div></div> <div id="field_cvQP2X371" role="group" class="field hyva-field lg:w-full md:w-full w-full type-email webforms-fields-371 webforms-fields-email required" aria-labelledby="label_fieldcvQP2X371" > <label class="hyva-field-lable" id="label_fieldcvQP2X371" for="fieldcvQP2X371">Email </label> <div class="control" role="group" aria-labelledby="label_fieldcvQP2X371"> <input id='fieldcvQP2X371' name='field[371]' type='email' class='input-text hyva-text' style='' value="" placeholder="[email protected]" data-validate="{'required-entry':true, 'validate-email':true}" aria-labelledby="label_fieldcvQP2X371" aria-required="true" x-data="mmWebformsEmailDatafieldcvQP2X371" @input="trimSpace" @private-content-loaded.window="setCustomerData" /> </div></div> <div id="field_cvQP2X383" role="group" class="field hyva-field lg:w-full md:w-full w-full type-number webforms-fields-383 webforms-fields-contact-number required" aria-labelledby="label_fieldcvQP2X383" > <label class="hyva-field-lable" id="label_fieldcvQP2X383" for="fieldcvQP2X383">Contact number </label> <div class="control" role="group" aria-labelledby="label_fieldcvQP2X383"> <input id='fieldcvQP2X383' name='field[383]' type='number' step="any" class='input-text hyva-text' style='' value="" placeholder="Contact number" data-validate="{'required-entry':true, 'validate-number':true}" aria-labelledby="label_fieldcvQP2X383" aria-required="true" /> </div></div> <div id="field_cvQP2X398" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-398 webforms-fields-postcode required" aria-labelledby="label_fieldcvQP2X398" > <label class="hyva-field-lable" id="label_fieldcvQP2X398" for="fieldcvQP2X398">Postcode </label> <div class="control" role="group" aria-labelledby="label_fieldcvQP2X398"><input id='postcode' 3497 name='field[398]' 3498 type='text' 3499 class='input-text hyva-text' 3500 style='' 3501 value="" 3502 placeholder="Postcode" 3503 data-validate="{'required-entry':true}" 3504 aria-labelledby="label_fieldcvQP2X398" aria-required="true" /> 3505 </div></div> <div id="field_cvQP2X386" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-386 webforms-fields-street " aria-labelledby="label_fieldcvQP2X386" > <label class="hyva-field-lable" id="label_fieldcvQP2X386" for="fieldcvQP2X386">Street & Number </label> <div class="control" role="group" aria-labelledby="label_fieldcvQP2X386"><input id='street' 3506 name='field[386]' 3507 type='text' 3508 class='input-text hyva-text' 3509 style='' 3510 value="" 3511 placeholder="" 3512 aria-labelledby="label_fieldcvQP2X386" /> 3513 </div></div> <div id="field_cvQP2X704" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-704 webforms-fields-street1 " > <div class="control" role="group" ><input id='street1' 3514 name='field[704]' 3515 type='text' 3516 class='input-text hyva-text' 3517 style='' 3518 value="" 3519 placeholder="" 3520 aria-label="Street 1" 3521 /> 3522 </div></div> <div id="field_cvQP2X707" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-707 webforms-fields-street2 " > <div class="control" role="group" ><input id='street2' 3523 name='field[707]' 3524 type='text' 3525 class='input-text hyva-text' 3526 style='' 3527 value="" 3528 placeholder="" 3529 aria-label="Street 2" 3530 /> 3531 </div></div> <div id="field_cvQP2X392" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-392 webforms-fields-city " aria-labelledby="label_fieldcvQP2X392" > <label class="hyva-field-lable" id="label_fieldcvQP2X392" for="fieldcvQP2X392">Town / City </label> <div class="control" role="group" aria-labelledby="label_fieldcvQP2X392"><input id='city' 3532 name='field[392]' 3533 type='text' 3534 class='input-text hyva-text' 3535 style='' 3536 value="" 3537 placeholder="Town / City" 3538 aria-labelledby="label_fieldcvQP2X392" /> 3539 </div></div> <div id="field_cvQP2X395" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-395 webforms-fields-country " aria-labelledby="label_fieldcvQP2X395" > <label class="hyva-field-lable" id="label_fieldcvQP2X395" for="fieldcvQP2X395">Country </label> <div class="control" role="group" aria-labelledby="label_fieldcvQP2X395"><input id='country' 3540 name='field[395]' 3541 type='text' 3542 class='input-text hyva-text' 3543 style='' 3544 value="" 3545 placeholder="Country" 3546 aria-labelledby="label_fieldcvQP2X395" /> 3547 </div></div> <div id="field_cvQP2X407" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select_radio webforms-fields-407 webforms-fields-type_of_service required" aria-labelledby="label_fieldcvQP2X407" > <label class="hyva-field-lable" id="label_fieldcvQP2X407" >Which package are you interested in? </label> <div class="control" role="group" aria-labelledby="label_fieldcvQP2X407"> <div aria-labelledby="label_fieldcvQP2X407" > <div class='field choice option-0' style='' ><input id='fieldcvQP2X4070' name='field[407]' type='radio' value="Keyholding & Alarm Response Standard" class='hyva-radio' data-validate="{'validate-one-required-by-name':true}" aria-labelledby="fieldcvQP2X4070_label label_fieldcvQP2X407" checked /><label id="fieldcvQP2X4070_label" for='fieldcvQP2X4070' class=' hyva-radio-label'>Keyholding & Alarm Response Standard</label> </div> <div class='field choice option-1' style='' ><input id='fieldcvQP2X4071' name='field[407]' type='radio' value="Keyholding & Alarm Response Gold" class='hyva-radio' data-validate="{'validate-one-required-by-name':true}" aria-labelledby="fieldcvQP2X4071_label label_fieldcvQP2X407" /><label id="fieldcvQP2X4071_label" for='fieldcvQP2X4071' class=' hyva-radio-label'>Keyholding & Alarm Response Gold</label> </div> <div class='field choice option-2' style='' ><input id='fieldcvQP2X4072' name='field[407]' type='radio' value="Holiday Package" class='hyva-radio' data-validate="{'validate-one-required-by-name':true}" aria-labelledby="fieldcvQP2X4072_label label_fieldcvQP2X407" /><label id="fieldcvQP2X4072_label" for='fieldcvQP2X4072' class=' hyva-radio-label'>Holiday Package</label> </div> <div class='field choice option-3' style='' ><input id='fieldcvQP2X4073' name='field[407]' type='radio' value="Keyholding only" class='hyva-radio' data-validate="{'validate-one-required-by-name':true}" aria-labelledby="fieldcvQP2X4073_label label_fieldcvQP2X407" /><label id="fieldcvQP2X4073_label" for='fieldcvQP2X4073' class=' hyva-radio-label'>Keyholding only</label> </div> <div class='field choice option-4' style='' ><input id='fieldcvQP2X4074' name='field[407]' type='radio' value="Unsure" class='hyva-radio' data-validate="{'validate-one-required-by-name':true}" aria-labelledby="fieldcvQP2X4074_label label_fieldcvQP2X407" /><label id="fieldcvQP2X4074_label" for='fieldcvQP2X4074' class=' hyva-radio-label'>Unsure</label> </div></div> </div></div> <div id="field_cvQP2X410" role="group" class="field hyva-field lg:w-full md:w-full w-full type-textarea webforms-fields-410 webforms-fields-additional_comments " aria-labelledby="label_fieldcvQP2X410" > <label class="hyva-field-lable" id="label_fieldcvQP2X410" for="fieldcvQP2X410">Additional comments/requirements </label> <div class="control" role="group" aria-labelledby="label_fieldcvQP2X410"> <textarea id='fieldcvQP2X410' 3548 name='field[410]' 3549 class=' hyva-textarea' 3550 rows='5' 3551 style='' 3552 placeholder="Enter your comments here" 3553 aria-labelledby="label_fieldcvQP2X410" ></textarea> </div></div> <div id="field_cvQP2X413" role="group" class="field hyva-field lg:w-full md:w-full w-full type-number webforms-fields-413 webforms-fields-existing_account_number " aria-labelledby="label_fieldcvQP2X413" > <label class="hyva-field-lable" id="label_fieldcvQP2X413" for="fieldcvQP2X413">Existing account number if applicable </label> <div class="control" role="group" aria-labelledby="label_fieldcvQP2X413"> <input id='fieldcvQP2X413' name='field[413]' type='number' step="any" class='input-text hyva-text' style='' value="" placeholder="" data-validate="{'validate-number':true}" aria-labelledby="label_fieldcvQP2X413" />
3553 </div></div> <div id="field_cvQP2X404" role="group" class="field hyva-field lg:w-full md:w-full w-full type-subscribe choice webforms-fields-404 webforms-fields-subscribe " aria-describedby="comment_fieldcvQP2X404"> <div class="control" role="group" > <div class="field choice option-0"><input id='fieldcvQP2X4040' name='field[404]' type='checkbox' class='hyva-checkbox' style='float:left' value='1' /><label for='fieldcvQP2X4040' class=' hyva-checkbox-label' style='' >Subscribe</label></div> <p class="hyva-comment-label" id="comment_fieldcvQP2X404" tabindex="0">I consent to Banham sending me email updates on special offers, products, and services. If you would like further information on how we use your personal data, please check our <a href="/privacy-promise" target="_blank">Privacy Policy</a>.</p></div></div></fieldset> <div id="captcha-container-cvQP2X" class="captcha-container px-4 clear-both float-left w-full"></div> <div id="submitcvQP2X" class="flex !flex-col gap-2 actions-toolbar submit-center w-full clear-both !m-0"> 3554 <div class="primary w-full mx-auto text-center"> 3555 <button type="submit" class="action submit primary w-auto " 3556 id="webform_cvQP2X_submit_button" 3557 title="Submit" 3558 name="submit_button_cvQP2X"> 3559 <span>Submit</span> 3560 </button> 3561 <div class="w-full grecaptcha-legal mt-5"> 3562 <p class="my-4 text-sm"> 3563 <em>This site is protected by reCAPTCHA.</em> 3564</p> </div> 3565 </div> 3566 <div class="secondary"> 3567 <div class="please-wait" id="webform_cvQP2X_sending_data" 3568 style="display:none;"> 3569 <div class="loading-indicator"></div> 3570 <span id="webform_cvQP2X_progress_text">Sending...</span> 3571 </div> 3572 </div> 3573</div></form> 3574 3575 </div> 3576 3577 <style> .recaptcha-position-inline{ clear: both; box-sizing: border-box; padding: 0 2rem 2rem 0; width: 100%; float: left; }</style> 3578 </div> </div> 3579 <div 3580 x-show="activeTab === '1022ce70-8dbd-4ce4-8ab7-aedfefa4ca79'" 3581 x-transition 3582 class="form-block flex flex-col justify-center items-center p-5 md:p-10 duration-300" 3583 id="form-block-content-1022ce70-8dbd-4ce4-8ab7-aedfefa4ca79" 3584 > 3585 3586 3587<div class="flex flex-col max-w-[660px] w-full mx-auto"> 3588 3589 <div id="webform_FAq7sZ_success_text" class="hyva-success-msg" 3590 style="display:none"></div> 3591 3592 3593 <div id="webform_FAq7sZ_form" class="webforms"> 3594 3595 3596 <form method="post" name="webform_FAq7sZ" id="webform_FAq7sZ" enctype="multipart/form-data" class="form hyva-form contactForm" style="" aria-label="Contact Form" role="none"><input name="form_key" type="hidden"/><input type="hidden" name="submitForm_4" value="1"/><input type="hidden" name="form_id" value="4"/> <input name='field[864]' 3597 id="utm_source" 3598 type='hidden' 3599 value='' 3600 /><input name='field[867]' 3601 id="utm_medium" 3602 type='hidden' 3603 value='' 3604 /><input name='field[870]' 3605 id="utm_campaign" 3606 type='hidden' 3607 value='' 3608 /> <fieldset id="fieldset_FAq7sZ0" class="fieldset-0 hyva-fieldset w-full" style="" role="group" > <div id="field_FAq7sZ80" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select_contact webforms-fields-80 webforms-fields-subject required" aria-labelledby="label_fieldFAq7sZ80" > <label class="hyva-field-lable" id="label_fieldFAq7sZ80" for="fieldFAq7sZ80">What is your query related to? </label> <div class="control" role="group" aria-labelledby="label_fieldFAq7sZ80"> <select id='fieldFAq7sZ80' name='field[80]' class='enquiry-options hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldFAq7sZ80" aria-required="true" > <option value="Please Select" selected>Please Select</option> <option value="1" >Banham Lock Queries</option> <option value="2" >Emergency Locksmith & Locksmith</option> <option value="3" >
3608Banham Alarms</option> <option value="4" >Keyholding & Alarm Response</option> <option value="5" >Online Order Queries</option> <option value="6" >Banham Account Queries</option> <option value="7" >Banham Survey Queries</option> <option value="8" >Banham Product Queries</option> <option value="9" >Update your details</option></select> </div></div> <div id="field_FAq7sZ86" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select mm-logic-hidden webforms-fields-86 webforms-fields-alarm_query_type required" aria-labelledby="label_fieldFAq7sZ86" > <label class="hyva-field-lable" id="label_fieldFAq7sZ86" for="fieldFAq7sZ86">Your Alarm Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldFAq7sZ86"> <select id='fieldFAq7sZ86' name='field[86]' class=' hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldFAq7sZ86" aria-required="true" > <option value="Please Select" selected disabled>Please Select</option> <option value="I am interested in Banham alarms" >I am interested in Banham alarms</option> <option value="I have a query about my Banham alarm" >I have a query about my Banham alarm</option></select> </div></div> <div id="field_FAq7sZ89" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select mm-logic-hidden webforms-fields-89 webforms-fields-lock_query_type required" aria-labelledby="label_fieldFAq7sZ89" > <label class="hyva-field-lable" id="label_fieldFAq7sZ89" for="fieldFAq7sZ89">Your Lock Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldFAq7sZ89"> <select id='fieldFAq7sZ89' name='field[89]' class=' hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldFAq7sZ89" aria-required="true" > <option value="Please Select" selected disabled>Please Select</option> <option value="I am interested in Banham locks" >I am interested in Banham locks</option> <option value="I have a query about my Banham locks" >I have a query about my Banham locks</option> <option value="Key cutting or registration query" >Key cutting or registration query</option></select> </div></div> <div id="field_FAq7sZ98" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-98 webforms-fields-name required" aria-labelledby="label_fieldFAq7sZ98" > <label class="hyva-field-lable" id="label_fieldFAq7sZ98" for="fieldFAq7sZ98">Name </label> <div class="control" role="group" aria-labelledby="label_fieldFAq7sZ98"><input id='name' 3609 name='field[98]' 3610 type='text' 3611 class='input-text hyva-text' 3612 style='' 3613 value="" 3614 placeholder="Please enter your name here" 3615 data-validate="{'required-entry':true}" 3616 aria-labelledby="label_fieldFAq7sZ98" aria-required="true" x-data="MageMe.WebForms.customerData()" 3617 @private-content-loaded.window="receiveCustomerData($event.detail.data)" 3618 x-model="customer.customer_name" 3619 /> 3620 </div></div> <div id="field_FAq7sZ41" role="group" class="field hyva-field lg:w-full md:w-full w-full type-email webforms-fields-41 webforms-fields-email required" aria-labelledby="label_fieldFAq7sZ41" > <label class="hyva-field-lable" id="label_fieldFAq7sZ41" for="fieldFAq7sZ41">Email </label> <div class="control" role="group" aria-labelledby="label_fieldFAq7sZ41"> <input id='fieldFAq7sZ41' name='field[41]' type='email' class='input-text hyva-text' style='' value="" placeholder="[email protected]" data-validate="{'required-entry':true, 'validate-email':true}" aria-labelledby="label_fieldFAq7sZ41" aria-required="true" x-data="mmWebformsEmailDatafieldFAq7sZ41" @input="trimSpace" @private-content-loaded.window="setCustomerData" /> </div></div> <div id="field_FAq7sZ47" role="group" class="field hyva-field lg:w-full md:w-full w-full type-textarea webforms-fields-47 webforms-fields-your_enquiry required" aria-labelledby="label_fieldFAq7sZ47" >
3620 <label class="hyva-field-lable" id="label_fieldFAq7sZ47" for="fieldFAq7sZ47">Your Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldFAq7sZ47"> <textarea id='fieldFAq7sZ47' 3621 name='field[47]' 3622 class=' hyva-textarea' 3623 rows='5' 3624 style='' 3625 placeholder="Enter your enquiry here" 3626 data-validate="{'required-entry':true}" 3627 aria-labelledby="label_fieldFAq7sZ47" aria-required="true" ></textarea> </div></div> <div id="field_FAq7sZ56" role="group" class="field hyva-field lg:w-full md:w-full w-full type-number webforms-fields-56 webforms-fields-contact_number required" aria-labelledby="label_fieldFAq7sZ56" > <label class="hyva-field-lable" id="label_fieldFAq7sZ56" for="fieldFAq7sZ56">Contact number </label> <div class="control" role="group" aria-labelledby="label_fieldFAq7sZ56"> <input id='fieldFAq7sZ56' name='field[56]' type='number' step="any" class='input-text hyva-text' style='' value="" placeholder="Contact number" data-validate="{'required-entry':true, 'validate-number':true}" aria-labelledby="label_fieldFAq7sZ56" aria-required="true" /> </div></div> <div id="field_FAq7sZ59" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-59 webforms-fields-street required" aria-labelledby="label_fieldFAq7sZ59" > <label class="hyva-field-lable" id="label_fieldFAq7sZ59" for="fieldFAq7sZ59">Street & Number </label> <div class="control" role="group" aria-labelledby="label_fieldFAq7sZ59"><input id='street' 3628 name='field[59]' 3629 type='text' 3630 class='input-text hyva-text' 3631 style='' 3632 value="" 3633 placeholder="" 3634 data-validate="{'required-entry':true}" 3635 aria-labelledby="label_fieldFAq7sZ59" aria-required="true" /> 3636 </div></div> <div id="field_FAq7sZ65" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-65 webforms-fields-city required" aria-labelledby="label_fieldFAq7sZ65" > <label class="hyva-field-lable" id="label_fieldFAq7sZ65" for="fieldFAq7sZ65">Town / City </label> <div class="control" role="group" aria-labelledby="label_fieldFAq7sZ65"><input id='city' 3637 name='field[65]' 3638 type='text' 3639 class='input-text hyva-text' 3640 style='' 3641 value="" 3642 placeholder="Town / City" 3643 data-validate="{'required-entry':true}" 3644 aria-labelledby="label_fieldFAq7sZ65" aria-required="true" /> 3645 </div></div> <div id="field_FAq7sZ68" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-68 webforms-fields-county " aria-labelledby="label_fieldFAq7sZ68" > <label class="hyva-field-lable" id="label_fieldFAq7sZ68" for="fieldFAq7sZ68">County </label> <div class="control" role="group" aria-labelledby="label_fieldFAq7sZ68"><input id='county' 3646 name='field[68]' 3647 type='text' 3648 class='input-text hyva-text' 3649 style='' 3650 value="" 3651 placeholder="County" 3652 aria-labelledby="label_fieldFAq7sZ68" /> 3653 </div></div> <div id="field_FAq7sZ71" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-71 webforms-fields-postcode required" aria-labelledby="label_fieldFAq7sZ71" > <label class="hyva-field-lable" id="label_fieldFAq7sZ71" for="fieldFAq7sZ71">Postcode </label> <div class="control" role="group" aria-labelledby="label_fieldFAq7sZ71"><input id='postcode' 3654 name='field[71]' 3655 type='text' 3656 class='input-text hyva-text' 3657 style='' 3658 value="" 3659 placeholder="Postcode" 3660 data-validate="{'required-entry':true}" 3661 aria-labelledby="label_fieldFAq7sZ71" aria-required="true" /> 3662 </div></div> <div id="field_FAq7sZ92" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-92 webforms-fields-account-number " aria-labelledby="label_fieldFAq7s
3662Z92" > <label class="hyva-field-lable" id="label_fieldFAq7sZ92" for="fieldFAq7sZ92">Account Number </label> <div class="control" role="group" aria-labelledby="label_fieldFAq7sZ92"><input id='account-number' 3663 name='field[92]' 3664 type='text' 3665 class='input-text hyva-text' 3666 style='' 3667 value="" 3668 placeholder="Your account number" 3669 aria-labelledby="label_fieldFAq7sZ92" /> 3670 </div></div></fieldset> <div id="captcha-container-FAq7sZ" class="captcha-container px-4 clear-both float-left w-full"></div> <div id="submitFAq7sZ" class="flex !flex-col gap-2 actions-toolbar submit-right w-full clear-both !m-0"> 3671 <div class="primary w-full mx-auto text-center"> 3672 <button type="submit" class="action submit primary w-auto " 3673 id="webform_FAq7sZ_submit_button" 3674 title="Submit" 3675 name="submit_button_FAq7sZ"> 3676 <span>Submit</span> 3677 </button> 3678 <div class="w-full grecaptcha-legal mt-5"> 3679 <p class="my-4 text-sm"> 3680 <em>This site is protected by reCAPTCHA.</em> 3681</p> </div> 3682 </div> 3683 <div class="secondary"> 3684 <div class="please-wait" id="webform_FAq7sZ_sending_data" 3685 style="display:none;"> 3686 <div class="loading-indicator"></div> 3687 <span id="webform_FAq7sZ_progress_text">Sending...</span> 3688 </div> 3689 </div> 3690</div></form> 3691 3692 </div> 3693 3694 <style> .recaptcha-position-inline{ clear: both; box-sizing: border-box; padding: 0 2rem 2rem 0; width: 100%; float: left; }</style> 3695 </div> </div> 3696 <div 3697 x-show="activeTab === '6370bf61-81cf-4eb3-b045-510dfff450b5'" 3698 x-transition 3699 class="form-block flex flex-col justify-center items-center p-5 md:p-10 duration-300" 3700 id="form-block-content-6370bf61-81cf-4eb3-b045-510dfff450b5" 3701 > 3702 3703 3704<div class="flex flex-col max-w-[660px] w-full mx-auto"> 3705 3706 <div id="webform_SSA2ZV_success_text" class="hyva-success-msg" 3707 style="display:none"></div> 3708 3709 3710 <div id="webform_SSA2ZV_form" class="webforms"> 3711 3712 3713 <form method="post" name="webform_SSA2ZV" id="webform_SSA2ZV" enctype="multipart/form-data" class="form hyva-form contactForm" style="" aria-label="Contact Form" role="none"><input name="form_key" type="hidden"/><input type="hidden" name="submitForm_4" value="1"/><input type="hidden" name="form_id" value="4"/> <input name='field[864]' 3714 id="utm_source" 3715 type='hidden' 3716 value='' 3717 /><input name='field[867]' 3718 id="utm_medium" 3719 type='hidden' 3720 value='' 3721 /><input name='field[870]' 3722 id="utm_campaign" 3723 type='hidden' 3724 value='' 3725 /> <fieldset id="fieldset_SSA2ZV0" class="fieldset-0 hyva-fieldset w-full" style="" role="group" > <div id="field_SSA2ZV80" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select_contact webforms-fields-80 webforms-fields-subject required" aria-labelledby="label_fieldSSA2ZV80" > <label class="hyva-field-lable" id="label_fieldSSA2ZV80" for="fieldSSA2ZV80">What is your query related to? </label> <div class="control" role="group" aria-labelledby="label_fieldSSA2ZV80"> <select id='fieldSSA2ZV80' name='field[80]' class='enquiry-options hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldSSA2ZV80" aria-required="true" > <option value="Please Select" selected>Please Select</option> <option value="1" >Banham Lock Queries</option> <option value="2" >Emergency Locksmith & Locksmith</option> <option value="3" >Banham Alarms</option> <option value="4" >Keyholding & Alarm Response</option> <option value="5" >Online Order Queries</option> <option value="6" >Banham Account Queries</option> <option value="7" >Banham Survey Queries</option> <option value="8" >Banham Product Queries</option> <option value="9" >Update your details</option></select> </div></div> <div id="field_SSA2ZV86" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select mm-logic-hidden webforms-fields-86 webforms-fields-alarm_query_type required" aria-labelledby="label_fieldSSA2ZV86" > <label class="hyva-field-lable" id="label_fieldSSA2ZV86" for="fieldSSA2ZV86">Your Alarm Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldSSA2ZV86"> <select id='fieldSSA2ZV86' name='field[86]' class=' hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldSSA2ZV86" aria-required="true" > <option value="Please Select" selected disabled>Please Select</option> <option value="I am interested in Banham alarms" >I am interested in Banham alarms</option> <option value="I have a query about my Banham alarm" >I have a query about my Banham alarm</option></select> </div></div> <div id="field_SSA2ZV89" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select mm-logic-hidden webforms-fields-89 webforms-fields-lock_query_type required" aria-labelledby="label_fieldSSA2ZV89" > <label class="hyva-field-lable" id="label_fieldSSA2ZV89" for="fieldSSA2ZV89">Your Lock Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldSSA2ZV89"> <select id='fieldSSA2ZV89' name='field[89]' class=' hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldSSA2ZV89" aria-required="true" > <option value="Please Select" selected disabled>Please Select</option> <option value="I am interested in Banham locks" >I am interested in Banham locks</option> <option value="I have a query about my Banham locks" >I have a query about my Banham locks</option> <option value="Key cutting or registration query" >Key cutting or registration query</option></select> </div></div> <div id="field_SSA2ZV98" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-98 webforms-fields-name required" aria-labelledby="label_fieldSSA2ZV98" > <label class="hyva-field-lable" id="label_fieldSSA2ZV98" for="fieldSSA2ZV98">Name </label> <div class="control" role="group" aria-labelledby="label_fieldSSA2ZV98"><input id='name' 3726 name='field[98]' 3727 type='text' 3728 class='input-text hyva-text' 3729 style='' 3730 value="" 3731 placeholder="Please enter your name here" 3732 data-validate="{'required-entry':true}" 3733 aria-labelledby="label_fieldSSA2ZV98" aria-required="true" x-data="MageMe.WebForms.customerData()" 3734 @private-content-loaded.window="receiveCustomerData($event.detail.data)"
3735 x-model="customer.customer_name" 3736 /> 3737 </div></div> <div id="field_SSA2ZV41" role="group" class="field hyva-field lg:w-full md:w-full w-full type-email webforms-fields-41 webforms-fields-email required" aria-labelledby="label_fieldSSA2ZV41" > <label class="hyva-field-lable" id="label_fieldSSA2ZV41" for="fieldSSA2ZV41">Email </label> <div class="control" role="group" aria-labelledby="label_fieldSSA2ZV41"> <input id='fieldSSA2ZV41' name='field[41]' type='email' class='input-text hyva-text' style='' value="" placeholder="[email protected]" data-validate="{'required-entry':true, 'validate-email':true}" aria-labelledby="label_fieldSSA2ZV41" aria-required="true" x-data="mmWebformsEmailDatafieldSSA2ZV41" @input="trimSpace" @private-content-loaded.window="setCustomerData" /> </div></div> <div id="field_SSA2ZV47" role="group" class="field hyva-field lg:w-full md:w-full w-full type-textarea webforms-fields-47 webforms-fields-your_enquiry required" aria-labelledby="label_fieldSSA2ZV47" > <label class="hyva-field-lable" id="label_fieldSSA2ZV47" for="fieldSSA2ZV47">Your Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldSSA2ZV47"> <textarea id='fieldSSA2ZV47' 3738 name='field[47]' 3739 class=' hyva-textarea' 3740 rows='5' 3741 style='' 3742 placeholder="Enter your enquiry here" 3743 data-validate="{'required-entry':true}" 3744 aria-labelledby="label_fieldSSA2ZV47" aria-required="true" ></textarea> </div></div> <div id="field_SSA2ZV56" role="group" class="field hyva-field lg:w-full md:w-full w-full type-number webforms-fields-56 webforms-fields-contact_number required" aria-labelledby="label_fieldSSA2ZV56" > <label class="hyva-field-lable" id="label_fieldSSA2ZV56" for="fieldSSA2ZV56">Contact number </label> <div class="control" role="group" aria-labelledby="label_fieldSSA2ZV56"> <input id='fieldSSA2ZV56' name='field[56]' type='number' step="any" class='input-text hyva-text' style='' value="" placeholder="Contact number" data-validate="{'required-entry':true, 'validate-number':true}" aria-labelledby="label_fieldSSA2ZV56" aria-required="true" /> </div></div> <div id="field_SSA2ZV59" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-59 webforms-fields-street required" aria-labelledby="label_fieldSSA2ZV59" > <label class="hyva-field-lable" id="label_fieldSSA2ZV59" for="fieldSSA2ZV59">Street & Number </label> <div class="control" role="group" aria-labelledby="label_fieldSSA2ZV59"><input id='street' 3745 name='field[59]' 3746 type='text' 3747 class='input-text hyva-text' 3748 style='' 3749 value="" 3750 placeholder="" 3751 data-validate="{'required-entry':true}" 3752 aria-labelledby="label_fieldSSA2ZV59" aria-required="true" /> 3753 </div></div> <div id="field_SSA2ZV65" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-65 webforms-fields-city required" aria-labelledby="label_fieldSSA2ZV65" > <label class="hyva-field-lable" id="label_fieldSSA2ZV65" for="fieldSSA2ZV65">Town / City </label> <div class="control" role="group" aria-labelledby="label_fieldSSA2ZV65"><input id='city' 3754 name='field[65]' 3755 type='text' 3756 class='input-text hyva-text' 3757 style='' 3758 value="" 3759 placeholder="Town / City" 3760 data-validate="{'required-entry':true}" 3761 aria-labelledby="label_fieldSSA2ZV65" aria-required="true" /> 3762 </div></div> <div id="field_SSA2ZV68" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-68 webforms-fields-county " aria-labelledby="label_fieldSSA2ZV68" > <label class="hyva-field-lable" id="label_fieldSSA2ZV68" for="fieldSSA2ZV68">County </label> <div class="control" role="group" aria-labelledby="label_fieldSSA2ZV68"><input id='county' 3763 name='field[68]' 3764 type='text' 3765 class='input-text hyva-text' 3766 style='' 3767 value="" 3768 placeholder="County" 3769 aria-labelledby="label_fieldSSA2ZV68" /> 3770 </div></div> <div id="field_SSA2ZV71" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-71 webforms-fields-postcode required" aria-labelledby="label_fieldSSA2ZV71" > <label class="hyva-field-lable" id="label_fieldSSA2ZV71" for="fieldSSA2ZV71">Postcode </label> <div class="control" role="group" aria-labelledby="label_fieldSSA2ZV71"><input id='postcode' 3771 name='field[71]' 3772 type='text' 3773 class='input-text hyva-text' 3774 style='' 3775 value="" 3776 placeholder="Postcode" 3777 data-validate="{'required-entry':true}" 3778 aria-labelledby="label_fieldSSA2ZV71" aria-required="true" /> 3779 </div></div> <div id="field_SSA2ZV92" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-92 webforms-fields-account-number " aria-labelledby="label_fieldSSA2ZV92" > <label class="hyva-field-lable" id="label_fieldSSA2ZV92" for="fieldSSA2ZV92">Account Number </label> <div class="control" role="group" aria-labelledby="label_fieldSSA2ZV92"><input id='account-number' 3780 name='field[92]' 3781 type='text' 3782 class='input-text hyva-text' 3783 style='' 3784 value="" 3785 placeholder="Your account number" 3786 aria-labelledby="label_fieldSSA2ZV92" /> 3787 </div></div></fieldset> <div id="captcha-container-SSA2ZV" class="captcha-container px-4 clear-both float-left w-full"></div> <div id="submitSSA2ZV" class="flex !flex-col gap-2 actions-toolbar submit-right w-full clear-both !m-0"> 3788 <div class="primary w-full mx-auto text-center"> 3789 <button type="submit" class="action submit primary w-auto " 3790 id="webform_SSA2ZV_submit_button" 3791 title="Submit" 3792 name="submit_button_SSA2ZV">
3793 <span>Submit</span> 3794 </button> 3795 <div class="w-full grecaptcha-legal mt-5"> 3796 <p class="my-4 text-sm"> 3797 <em>This site is protected by reCAPTCHA.</em> 3798</p> </div> 3799 </div> 3800 <div class="secondary"> 3801 <div class="please-wait" id="webform_SSA2ZV_sending_data" 3802 style="display:none;"> 3803 <div class="loading-indicator"></div> 3804 <span id="webform_SSA2ZV_progress_text">Sending...</span> 3805 </div> 3806 </div> 3807</div></form> 3808 3809 </div> 3810 3811 <style> .recaptcha-position-inline{ clear: both; box-sizing: border-box; padding: 0 2rem 2rem 0; width: 100%; float: left; }</style> 3812 </div> </div> 3813 <div 3814 x-show="activeTab === 'e1794b6d-d916-407c-846e-5c918f0f724d'" 3815 x-transition 3816 class="form-block flex flex-col justify-center items-center p-5 md:p-10 duration-300" 3817 id="form-block-content-e1794b6d-d916-407c-846e-5c918f0f724d" 3818 > 3819 3820 3821<div class="flex flex-col max-w-[660px] w-full mx-auto"> 3822 3823 <div id="webform_XFDzRA_success_text" class="hyva-success-msg" 3824 style="display:none"></div> 3825 3826 3827 <div id="webform_XFDzRA_form" class="webforms"> 3828 3829 3830 <form method="post" name="webform_XFDzRA" id="webform_XFDzRA" enctype="multipart/form-data" class="form hyva-form contactForm" style="" aria-label="Contact Form" role="none"><input name="form_key" type="hidden"/><input type="hidden" name="submitForm_4" value="1"/><input type="hidden" name="form_id" value="4"/> <input name='field[864]' 3831 id="utm_source" 3832 type='hidden' 3833 value='' 3834 /><input name='field[867]' 3835 id="utm_medium" 3836 type='hidden' 3837 value='' 3838 /><input name='field[870]' 3839 id="utm_campaign" 3840 type='hidden' 3841 value='' 3842 /> <fieldset id="fieldset_XFDzRA0" class="fieldset-0 hyva-fieldset w-full" style="" role="group" > <div id="field_XFDzRA80" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select_contact webforms-fields-80 webforms-fields-subject required" aria-labelledby="label_fieldXFDzRA80" > <label class="hyva-field-lable" id="label_fieldXFDzRA80" for="fieldXFDzRA80">What is your query related to? </label> <div class="control" role="group" aria-labelledby="label_fieldXFDzRA80"> <select id='fieldXFDzRA80' name='field[80]' class='enquiry-options hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldXFDzRA80" aria-required="true" > <option value="Please Select" selected>Please Select</option> <option value="1" >Banham Lock Queries</option> <option value="2" >Emergency Locksmith & Locksmith</option> <option value="3" >Banham Alarms</option> <option value="4" >Keyholding & Alarm Response</option> <option value="5" >Online Order Queries</option> <option value="6" >Banham Account Queries</option> <option value="7" >Banham Survey Queries</option> <option value="8" >Banham Product Queries</option> <option value="9" >Update your details</option></select> </div></div> <div id="field_XFDzRA86" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select mm-logic-hidden webforms-fields-86 webforms-fields-alarm_query_type required" aria-labelledby="label_fieldXFDzRA86" > <label class="hyva-field-lable" id="label_fieldXFDzRA86" for="fieldXFDzRA86">Your Alarm Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldXFDzRA86"> <select id='fieldXFDzRA86' name='field[86]' class=' hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldXFDzRA86" aria-required="true" > <option value="Please Select" selected disabled>Please Select</option> <option value="I am interested in Banham alarms" >I am interested in Banham alarms</option> <option value="I have a query about my Banham alarm" >I have a query about my Banham alarm</option></select> </div></div> <div id="field_XFDzRA89" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select mm-logic-hidden webforms-fields-89 webforms-fields-lock_query_type required" aria-labelledby="label_fieldXFDzRA89" > <label class="hyva-field-lable" id="label_fieldXFDzRA89" for="fieldXFDzRA89">Your Lock Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldXFDzRA89"> <select id='fieldXFDzRA89' name='field[89]' class=' hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldXFDzRA89" aria-required="true" > <option value="Please Select" selected disabled>Please Select</option> <option value="I am interested in Banham locks" >I am interested in Banham locks</option> <option value="I have a query about my Banham locks" >I have a query about my Banham locks</option> <option value="Key cutting or registration query" >Key cutting or registration query</option></select> </div></div> <div id="field_XFDzRA98" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-98 webforms-fields-name required" aria-labelledby="label_fieldXFDzRA98" > <label class="hyva-field-lable" id="label_fieldXFDzRA98" for="fieldXFDzRA98">Name </label> <div class="control" role="group" aria-labelledby="label_fieldXFDzRA98"><input id='name' 3843 name='field[98]' 3844 type='text' 3845 class='input-text hyva-text' 3846 style='' 3847 value="" 3848 placeholder="Please enter your name here" 3849 data-validate="{'required-entry':true}" 3850 aria-labelledby="label_fieldXFDzRA98" aria-required="true" x-data="MageMe.WebForms.customerData()" 3851 @private-content-loaded.window="receiveCustomerData($event.detail.data)"
3852 x-model="customer.customer_name" 3853 /> 3854 </div></div> <div id="field_XFDzRA41" role="group" class="field hyva-field lg:w-full md:w-full w-full type-email webforms-fields-41 webforms-fields-email required" aria-labelledby="label_fieldXFDzRA41" > <label class="hyva-field-lable" id="label_fieldXFDzRA41" for="fieldXFDzRA41">Email </label> <div class="control" role="group" aria-labelledby="label_fieldXFDzRA41"> <input id='fieldXFDzRA41' name='field[41]' type='email' class='input-text hyva-text' style='' value="" placeholder="[email protected]" data-validate="{'required-entry':true, 'validate-email':true}" aria-labelledby="label_fieldXFDzRA41" aria-required="true" x-data="mmWebformsEmailDatafieldXFDzRA41" @input="trimSpace" @private-content-loaded.window="setCustomerData" /> </div></div> <div id="field_XFDzRA47" role="group" class="field hyva-field lg:w-full md:w-full w-full type-textarea webforms-fields-47 webforms-fields-your_enquiry required" aria-labelledby="label_fieldXFDzRA47" > <label class="hyva-field-lable" id="label_fieldXFDzRA47" for="fieldXFDzRA47">Your Enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldXFDzRA47"> <textarea id='fieldXFDzRA47' 3855 name='field[47]' 3856 class=' hyva-textarea' 3857 rows='5' 3858 style='' 3859 placeholder="Enter your enquiry here" 3860 data-validate="{'required-entry':true}" 3861 aria-labelledby="label_fieldXFDzRA47" aria-required="true" ></textarea> </div></div> <div id="field_XFDzRA56" role="group" class="field hyva-field lg:w-full md:w-full w-full type-number webforms-fields-56 webforms-fields-contact_number required" aria-labelledby="label_fieldXFDzRA56" > <label class="hyva-field-lable" id="label_fieldXFDzRA56" for="fieldXFDzRA56">Contact number </label> <div class="control" role="group" aria-labelledby="label_fieldXFDzRA56"> <input id='fieldXFDzRA56' name='field[56]' type='number' step="any" class='input-text hyva-text' style='' value="" placeholder="Contact number" data-validate="{'required-entry':true, 'validate-number':true}" aria-labelledby="label_fieldXFDzRA56" aria-required="true" /> </div></div> <div id="field_XFDzRA59" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-59 webforms-fields-street required" aria-labelledby="label_fieldXFDzRA59" > <label class="hyva-field-lable" id="label_fieldXFDzRA59" for="fieldXFDzRA59">Street & Number </label> <div class="control" role="group" aria-labelledby="label_fieldXFDzRA59"><input id='street' 3862 name='field[59]' 3863 type='text' 3864 class='input-text hyva-text' 3865 style='' 3866 value="" 3867 placeholder="" 3868 data-validate="{'required-entry':true}" 3869 aria-labelledby="label_fieldXFDzRA59" aria-required="true" /> 3870 </div></div> <div id="field_XFDzRA65" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-65 webforms-fields-city required" aria-labelledby="label_fieldXFDzRA65" > <label class="hyva-field-lable" id="label_fieldXFDzRA65" for="fieldXFDzRA65">Town / City </label> <div class="control" role="group" aria-labelledby="label_fieldXFDzRA65"><input id='city' 3871 name='field[65]' 3872 type='text' 3873 class='input-text hyva-text' 3874 style='' 3875 value="" 3876 placeholder="Town / City" 3877 data-validate="{'required-entry':true}" 3878 aria-labelledby="label_fieldXFDzRA65" aria-required="true" /> 3879 </div></div> <div id="field_XFDzRA68" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-68 webforms-fields-county " aria-labelledby="label_fieldXFDzRA68" > <label class="hyva-field-lable" id="label_fieldXFDzRA68" for="fieldXFDzRA68">County </label> <div class="control" role="group" aria-labelledby="label_fieldXFDzRA68"><input id='county' 3880 name='field[68]' 3881 type='text' 3882 class='input-text hyva-text' 3883 style='' 3884 value="" 3885 placeholder="County" 3886 aria-labelledby="label_fieldXFDzRA68" /> 3887 </div></div> <div id="field_XFDzRA71" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-71 webforms-fields-postcode required" aria-labelledby="label_fieldXFDzRA71" > <label class="hyva-field-lable" id="label_fieldXFDzRA71" for="fieldXFDzRA71">Postcode </label> <div class="control" role="group" aria-labelledby="label_fieldXFDzRA71"><input id='postcode' 3888 name='field[71]' 3889 type='text' 3890 class='input-text hyva-text' 3891 style='' 3892 value="" 3893 placeholder="Postcode" 3894 data-validate="{'required-entry':true}" 3895 aria-labelledby="label_fieldXFDzRA71" aria-required="true" /> 3896 </div></div> <div id="field_XFDzRA92" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-92 webforms-fields-account-number " aria-labelledby="label_fieldXFDzRA92" > <label class="hyva-field-lable" id="label_fieldXFDzRA92" for="fieldXFDzRA92">Account Number </label> <div class="control" role="group" aria-labelledby="label_fieldXFDzRA92"><input id='account-number' 3897 name='field[92]' 3898 type='text' 3899 class='input-text hyva-text' 3900 style='' 3901 value="" 3902 placeholder="Your account number" 3903 aria-labelledby="label_fieldXFDzRA92" /> 3904 </div></div></fieldset> <div id="captcha-container-XFDzRA" class="captcha-container px-4 clear-both float-left w-full"></div> <div id="submitXFDzRA" class="flex !flex-col gap-2 actions-toolbar submit-right w-full clear-both !m-0"> 3905 <div class="primary w-full mx-auto text-center"> 3906 <button type="submit" class="action submit primary w-auto " 3907 id="webform_XFDzRA_submit_button" 3908 title="Submit" 3909 name="submit_button_XFDzRA">
3910 <span>Submit</span> 3911 </button> 3912 <div class="w-full grecaptcha-legal mt-5"> 3913 <p class="my-4 text-sm"> 3914 <em>This site is protected by reCAPTCHA.</em> 3915</p> </div> 3916 </div> 3917 <div class="secondary"> 3918 <div class="please-wait" id="webform_XFDzRA_sending_data" 3919 style="display:none;"> 3920 <div class="loading-indicator"></div> 3921 <span id="webform_XFDzRA_progress_text">Sending...</span> 3922 </div> 3923 </div> 3924</div></form> 3925 3926 </div> 3927 3928 <style> .recaptcha-position-inline{ clear: both; box-sizing: border-box; padding: 0 2rem 2rem 0; width: 100%; float: left; }</style> 3929 </div> </div> 3930 <div 3931 x-show="activeTab === '257df155-bcb9-4b83-9e64-7c2c0a251ebd'" 3932 x-transition 3933 class="form-block flex flex-col justify-center items-center p-5 md:p-10 duration-300" 3934 id="form-block-content-257df155-bcb9-4b83-9e64-7c2c0a251ebd" 3935 > 3936 3937 3938<div class="flex flex-col max-w-[660px] w-full mx-auto"> 3939 <div class="flex flex-col flex-wrap"> 3940 <h2 class="text-center text-4xl tracking-[0.24px] mb-[60px]"> 3941 <span class="base" 3942 data-ui-id="page-title-wrapper">Existing Alarm and Contract Enquiries</span> 3943 </h2> 3944 </div> 3945 3946 <div id="webform_zxVI0s_success_text" class="hyva-success-msg" 3947 style="display:none"></div> 3948 3949 3950 <div id="webform_zxVI0s_form" class="webforms"> 3951 3952 <div id="zxVI0sform_description" class="webforms-description-text text-center [&_a]:text-[length:inherit]"> 3953 Contact us for any contract enquiries, if you're an existing Banham customer moving into a new home or a new customer whoâs inherited Banham products. </div> 3954 3955 <form method="post" name="webform_zxVI0s" id="webform_zxVI0s" enctype="multipart/form-data" class="form hyva-form " style="" aria-label="Contract retention form" role="none"><input name="form_key" type="hidden"/><input type="hidden" name="submitForm_95" value="1"/><input type="hidden" name="form_id" value="95"/> <input name='field[1826]' 3956 id="utm_source" 3957 type='hidden' 3958 value='' 3959 /><input name='field[1829]' 3960 id="utm_medium" 3961 type='hidden' 3962 value='' 3963 /><input name='field[1832]' 3964 id="utm_gclid" 3965 type='hidden' 3966 value='' 3967 /><input name='field[1835]' 3968 id="utm_campaign" 3969 type='hidden' 3970 value='' 3971 /> <fieldset id="fieldset_zxVI0s0" class="fieldset-0 hyva-fieldset w-full" style="" role="group" > <div id="field_zxVI0s1784" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1784 webforms-fields-title required" aria-labelledby="label_fieldzxVI0s1784" > <label class="hyva-field-lable" id="label_fieldzxVI0s1784" for="fieldzxVI0s1784">Title </label> <div class="control" role="group" aria-labelledby="label_fieldzxVI0s1784"><input id='title' 3972 name='field[1784]' 3973 type='text' 3974 class='input-text hyva-text' 3975 style='' 3976 value="" 3977 placeholder="Please enter your title here" 3978 data-validate="{'required-entry':true}" 3979 aria-labelledby="label_fieldzxVI0s1784" aria-required="true" /> 3980 </div></div> <div id="field_zxVI0s1787" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1787 webforms-fields-firstname required" aria-labelledby="label_fieldzxVI0s1787" > <label class="hyva-field-lable" id="label_fieldzxVI0s1787" for="fieldzxVI0s1787">First name </label> <div class="control" role="group" aria-labelledby="label_fieldzxVI0s1787"><input id='firstname' 3981 name='field[1787]' 3982 type='text' 3983 class='input-text hyva-text' 3984 style='' 3985 value="" 3986 placeholder="Please enter your first name here" 3987 data-validate="{'required-entry':true}" 3988 aria-labelledby="label_fieldzxVI0s1787" aria-required="true" x-data="MageMe.WebForms.customerData()" 3989 @private-content-loaded.window="receiveCustomerData($event.detail.data)"
3990 x-model="customer.customer_firstname" 3991 /> 3992 </div></div> <div id="field_zxVI0s1790" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1790 webforms-fields-surname required" aria-labelledby="label_fieldzxVI0s1790" > <label class="hyva-field-lable" id="label_fieldzxVI0s1790" for="fieldzxVI0s1790">Surname </label> <div class="control" role="group" aria-labelledby="label_fieldzxVI0s1790"><input id='surname' 3993 name='field[1790]' 3994 type='text' 3995 class='input-text hyva-text' 3996 style='' 3997 value="" 3998 placeholder="Please enter your surname here" 3999 data-validate="{'required-entry':true}" 4000 aria-labelledby="label_fieldzxVI0s1790" aria-required="true" x-data="MageMe.WebForms.customerData()" 4001 @private-content-loaded.window="receiveCustomerData($event.detail.data)" 4002 x-model="customer.customer_lastname" 4003 /> 4004 </div></div> <div id="field_zxVI0s1793" role="group" class="field hyva-field lg:w-full md:w-full w-full type-email webforms-fields-1793 webforms-fields-email required" aria-labelledby="label_fieldzxVI0s1793" > <label class="hyva-field-lable" id="label_fieldzxVI0s1793" for="fieldzxVI0s1793">Email </label> <div class="control" role="group" aria-labelledby="label_fieldzxVI0s1793"> <input id='fieldzxVI0s1793' name='field[1793]' type='email' class='input-text hyva-text' style='' value="" placeholder="[email protected]" data-validate="{'required-entry':true, 'validate-email':true}" aria-labelledby="label_fieldzxVI0s1793" aria-required="true" x-data="mmWebformsEmailDatafieldzxVI0s1793" @input="trimSpace" @private-content-loaded.window="setCustomerData" /> </div></div> <div id="field_zxVI0s1796" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1796 webforms-fields-contact-number required" aria-labelledby="label_fieldzxVI0s1796" > <label class="hyva-field-lable" id="label_fieldzxVI0s1796" for="fieldzxVI0s1796">Contact number </label> <div class="control" role="group" aria-labelledby="label_fieldzxVI0s1796"><input id='contact-number' 4005 name='field[1796]' 4006 type='text' 4007 class='input-text hyva-text' 4008 style='' 4009 value="" 4010 placeholder="Contact number" 4011 data-validate="{'required-entry':true}" 4012 data-msg-required-entry="Please enter a valid phone number." aria-labelledby="label_fieldzxVI0s1796" aria-required="true" /> 4013 <div style="display:none" class="hyva-comment-label" id="advice-required-entry-fieldzxVI0s1796">Please enter a valid phone number.</div> </div></div> <div id="field_zxVI0s1799" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select_contact webforms-fields-1799 webforms-fields-what_is_your_query_related_to required" aria-labelledby="label_fieldzxVI0s1799" > <label class="hyva-field-lable" id="label_fieldzxVI0s1799" for="fieldzxVI0s1799">What is your query related to? </label> <div class="control" role="group" aria-labelledby="label_fieldzxVI0s1799"> <select id='fieldzxVI0s1799' name='field[1799]' class=' hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldzxVI0s1799" aria-required="true" > <option value="Please Select" selected>Please Select</option> <option value="I want to change my current contract" >I want to change my current contract</option> <option value="Iâve moved into a property with a Banham alarm" >Iâve moved into a property with a Banham alarm</option> <option value="Iâm moving out of a property with a Banham alarm" >Iâm moving out of a property with a Banham alarm</option></select> </div></div> <div id="field_zxVI0s1802" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1802 webforms-fields-street required" aria-labelledby="label_fieldzxVI0s1802" > <label class="hyva-field-lable" id="label_fieldzxVI0s1802" for="fieldzxVI0s1802">Street & Number </label> <div class="control" role="group" aria-labelledby="label_fieldzxVI0s1802"><input id='street' 4014 name='field[1802]' 4015 type='text' 4016 class='input-text hyva-text' 4017 style='' 4018 value="" 4019 placeholder="" 4020 data-validate="{'required-entry':true}" 4021 aria-labelledby="label_fieldzxVI0s1802" aria-required="true" /> 4022 </div></div> <div id="field_zxVI0s1805" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1805 webforms-fields-street1 " > <div class="control" role="group" ><input id='street1' 4023 name='field[1805]' 4024 type='text' 4025 class='input-text hyva-text' 4026 style='' 4027 value="" 4028 placeholder="" 4029 aria-label="Street 1" 4030 /> 4031 </div></div> <div id="field_zxVI0s1808" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1808 webforms-fields-street2 " > <div class="control" role="group" ><input id='street2' 4032 name='field[1808]' 4033 type='text' 4034 class='input-text hyva-text' 4035 style='' 4036 value="" 4037 placeholder="" 4038 aria-label="Street 2" 4039 /> 4040 </div></div> <div id="field_zxVI0s1811" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1811 webforms-fields-city required" aria-labelledby="label_fieldzxVI0s1811" > <label class="hyva-field-lable" id="label_fieldzxVI0s1811" for="fieldzxVI0s1811">Town / City </label> <div class="control" role="group" aria-labelledby="label_fieldzxVI0s1811"><input id='city' 4041 name='field[1811]' 4042 type='text' 4043 class='input-text hyva-text' 4044 style='' 4045 value="" 4046 placeholder="Town / City" 4047 data-validate="{'required-entry':true}" 4048 aria-labelledby="label_fieldzxVI0s1811" aria-required="true" /> 4049 </div></div> <div id="field_zxVI0s1814" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1814 webforms-fields-country required" aria-labelledby="label_fieldzxVI0s1814" > <label class="hyva-field-lable" id="label_fieldzxVI0s1814" for="fieldzxVI0s1814">Country </label> <div class="control" role="group" aria-labelledby="label_fieldzxVI0s1814"><input id='country' 4050 name='field[1814]' 4051 type='text' 4052 class='input-text hyva-text' 4053 style='' 4054 value="" 4055 placeholder="Country" 4056 data-validate="{'required-entry':true}" 4057 aria-labelledby="label_fieldzxVI0s1814" aria-required="true" /> 4058 </div></div> <div id="field_zxVI0s1817" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1817 webforms-fields-postcode required" aria-labelledby="label_fieldzxVI0s1817" > <label class="hyva-field-lable" id="label_fieldzxVI0s1817" for="fieldzxVI0s1817">Postcode </label> <div class="control" role="group" aria-labelledby="label_fieldzxVI0s1817"><input id='postcode' 4059 name='field[1817]' 4060 type='text' 4061 class='input-text hyva-text' 4062 style='' 4063 value="" 4064 placeholder="Postcode" 4065 data-validate="{'required-entry':true}" 4066 aria-labelledby="label_fieldzxVI0s1817" aria-required="true" /> 4067 </div></div> <div id="field_zxVI0s1820" role="group" class="field hyva-field lg:w-full md:w-full w-full type-textarea webforms-fields-1820 webforms-fields-enquiry " aria-labelledby="label_fieldzxVI0s1820" > <label class="hyva-field-lable" id="label_fieldzxVI0s1820" for="fieldzxVI0s1820">About your enquiry </label> <div class="control" role="group" aria-labelledby="label_fieldzxVI0s1820"> <textarea id='fieldzxVI0s1820' 4068 name='field[1820]' 4069 class=' hyva-textarea' 4070 rows='5' 4071 style='' 4072 placeholder="Enter your enquiry here" 4073 aria-labelledby="label_fieldzxVI0s1820" ></textarea> </div></div> <div id="field_zxVI0s1823" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1823 webforms-fields-accountnum " aria-labelledby="label_fieldzxVI0s1823" aria-describedby="comment_fieldzxVI0s1823"> <label class="hyva-field-lable" id="label_fieldzxVI0s1823" for="fieldzxVI0s1823">Banham Account Number </label> <div class="control" role="group" aria-labelledby="label_fieldzxVI0s1823"><input id='accountnum' 4074 name='field[1823]' 4075 type='text' 4076 class='input-text hyva-text' 4077 style='' 4078 value="" 4079 placeholder="Your account number" 4080 aria-labelledby="label_fieldzxVI0s1823" /> 4081 <p class="hyva-comment-label" id="comment_fieldzxVI0s1823" tabindex="0">This is a 9-digit number starting with M. You can find this on any invoice, letter or email</p></div></div></fieldset> <div id="captcha-container-zxVI0s" class="captcha-container px-4 clear-both float-left w-full"></div> <div id="submitzxVI0s" class="flex !flex-col gap-2 actions-toolbar submit-center w-full clear-both !m-0"> 4082 <div class="primary w-full mx-auto text-center"> 4083 <button type="submit" class="action submit primary w-auto " 4084 id="webform_zxVI0s_submit_button" 4085 title="Submit" 4086 name="submit_button_zxVI0s">
4087 <span>Submit</span> 4088 </button> 4089 <div class="w-full grecaptcha-legal mt-5"> 4090 <p class="my-4 text-sm"> 4091 <em>This site is protected by reCAPTCHA.</em> 4092</p> </div> 4093 </div> 4094 <div class="secondary"> 4095 <div class="please-wait" id="webform_zxVI0s_sending_data" 4096 style="display:none;"> 4097 <div class="loading-indicator"></div> 4098 <span id="webform_zxVI0s_progress_text">Sending...</span> 4099 </div> 4100 </div> 4101</div></form> 4102 4103 </div> 4104 4105 <style> .recaptcha-position-inline{ clear: both; box-sizing: border-box; padding: 0 2rem 2rem 0; width: 100%; float: left; }</style> 4106 </div> </div> 4107 <div 4108 x-show="activeTab === 'eb2d7d4b-9ff0-44db-aa9d-d3ddc041aed3'" 4109 x-transition 4110 class="form-block flex flex-col justify-center items-center p-5 md:p-10 duration-300" 4111 id="form-block-content-eb2d7d4b-9ff0-44db-aa9d-d3ddc041aed3" 4112 > 4113 4114 4115<div class="flex flex-col max-w-[660px] w-full mx-auto"> 4116 <div class="flex flex-col flex-wrap"> 4117 <h2 class="text-center text-4xl tracking-[0.24px] mb-[60px]"> 4118 <span class="base" 4119 data-ui-id="page-title-wrapper">UPDATE YOUR DETAILS</span> 4120 </h2> 4121 </div> 4122 4123 <div id="webform_hVWOVe_success_text" class="hyva-success-msg" 4124 style="display:none"></div> 4125 4126 4127 <div id="webform_hVWOVe_form" class="webforms"> 4128 4129 4130 <form method="post" name="webform_hVWOVe" id="webform_hVWOVe" enctype="multipart/form-data" class="form hyva-form customForm" style="" aria-label="Update details request" role="none"><input name="form_key" type="hidden"/><input type="hidden" name="submitForm_62" value="1"/><input type="hidden" name="form_id" value="62"/> <fieldset id="fieldset_hVWOVe0" class="fieldset-0 hyva-fieldset w-full" style="" role="group" > <div id="field_hVWOVe1193" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1193 required" aria-labelledby="label_fieldhVWOVe1193" > <label class="hyva-field-lable" id="label_fieldhVWOVe1193" for="fieldhVWOVe1193">Title </label> <div class="control" role="group" aria-labelledby="label_fieldhVWOVe1193"><input id='' 4131 name='field[1193]' 4132 type='text' 4133 class='input-text hyva-text' 4134 style='' 4135 value="" 4136 placeholder="Please enter your title here" 4137 data-validate="{'required-entry':true}" 4138 aria-labelledby="label_fieldhVWOVe1193" aria-required="true" /> 4139 </div></div> <div id="field_hVWOVe1196" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1196 required" aria-labelledby="label_fieldhVWOVe1196" > <label class="hyva-field-lable" id="label_fieldhVWOVe1196" for="fieldhVWOVe1196">First name </label> <div class="control" role="group" aria-labelledby="label_fieldhVWOVe1196"><input id='' 4140 name='field[1196]' 4141 type='text' 4142 class='input-text hyva-text' 4143 style='' 4144 value="" 4145 placeholder="Please enter your first name here" 4146 data-validate="{'required-entry':true}" 4147 aria-labelledby="label_fieldhVWOVe1196" aria-required="true" /> 4148 </div></div> <div id="field_hVWOVe1199" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1199 required" aria-labelledby="label_fieldhVWOVe1199" > <label class="hyva-field-lable" id="label_fieldhVWOVe1199" for="fieldhVWOVe1199">Surname </label> <div class="control" role="group" aria-labelledby="label_fieldhVWOVe1199"><input id='' 4149 name='field[1199]' 4150 type='text' 4151 class='input-text hyva-text' 4152 style='' 4153 value="" 4154 placeholder="Please enter your surname here" 4155 data-validate="{'required-entry':true}" 4156 aria-labelledby="label_fieldhVWOVe1199" aria-required="true" /> 4157 </div></div> <div id="field_hVWOVe1145" role="group" class="field hyva-field lg:w-full md:w-full w-full type-select_contact webforms-fields-1145 webforms-fields-subject required" aria-labelledby="label_fieldhVWOVe1145" > <label class="hyva-field-lable" id="label_fieldhVWOVe1145" for="fieldhVWOVe1145">What would you like to update? </label> <div class="control" role="group" aria-labelledby="label_fieldhVWOVe1145"> <select id='fieldhVWOVe1145' name='field[1145]' class=' hyva-select' style='' data-validate="{'validate-select':true}" aria-labelledby="label_fieldhVWOVe1145" aria-required="true" > <option value="Please Select" selected>Please Select</option> <option value="1" >Email address</option> <option value="2" >Phone number</option> <option value="3" >
4157Email and phone number</option></select> </div></div> <div id="field_hVWOVe1202" role="group" class="field hyva-field lg:w-full md:w-full w-full type-email mm-logic-hidden webforms-fields-1202 " aria-labelledby="label_fieldhVWOVe1202" > <label class="hyva-field-lable" id="label_fieldhVWOVe1202" for="fieldhVWOVe1202">Previous email address </label> <div class="control" role="group" aria-labelledby="label_fieldhVWOVe1202"> <input id='fieldhVWOVe1202' name='field[1202]' type='email' class='input-text hyva-text' style='' value="" placeholder="[email protected]" data-validate="{'validate-email':true}" aria-labelledby="label_fieldhVWOVe1202" x-data="mmWebformsEmailDatafieldhVWOVe1202" @input="trimSpace" /> </div></div> <div id="field_hVWOVe1205" role="group" class="field hyva-field lg:w-full md:w-full w-full type-email mm-logic-hidden webforms-fields-1205 required" aria-labelledby="label_fieldhVWOVe1205" > <label class="hyva-field-lable" id="label_fieldhVWOVe1205" for="fieldhVWOVe1205">New Email Address: </label> <div class="control" role="group" aria-labelledby="label_fieldhVWOVe1205"> <input id='fieldhVWOVe1205' name='field[1205]' type='email' class='input-text hyva-text' style='' value="" placeholder="[email protected]" data-validate="{'required-entry':true, 'validate-email':true}" aria-labelledby="label_fieldhVWOVe1205" aria-required="true" x-data="mmWebformsEmailDatafieldhVWOVe1205" @input="trimSpace" /> </div></div> <div id="field_hVWOVe1208" role="group" class="field hyva-field lg:w-full md:w-full w-full type-phone_number mm-logic-hidden webforms-fields-1208 " aria-labelledby="label_fieldhVWOVe1208" > <label class="hyva-field-lable" id="label_fieldhVWOVe1208" for="fieldhVWOVe1208">Previous contact number </label> <div class="control" role="group" aria-labelledby="label_fieldhVWOVe1208"> <input id='phonefieldhVWOVe1208' name='phonefield[1208]' type='text' class='webforms-phone input-text hyva-text' style='' placeholder="" data-validate="{'validate-intl-phone-number':true}" aria-labelledby="label_fieldhVWOVe1208" /><input id='fieldhVWOVe1208' name='field[1208]' type="hidden" /> </div></div> <div id="field_hVWOVe1211" role="group" class="field hyva-field lg:w-full md:w-full w-full type-phone_number mm-logic-hidden webforms-fields-1211 required" aria-labelledby="label_fieldhVWOVe1211" > <label class="hyva-field-lable" id="label_fieldhVWOVe1211" for="fieldhVWOVe1211">New contact number </label> <div class="control" role="group" aria-labelledby="label_fieldhVWOVe1211"> <input id='phonefieldhVWOVe1211' name='phonefield[1211]' type='text' class='webforms-phone input-text hyva-text' style='' placeholder="" data-validate="{'required-entry':true, 'validate-intl-phone-number':true}" aria-labelledby="label_fieldhVWOVe1211" aria-required="true" /><input id='fieldhVWOVe1211' name='field[1211]' type="hidden" /> </div></div> <div id="field_hVWOVe1169" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text mm-logic-hidden webforms-fields-1169 webforms-fields-street required" aria-labelledby="label_fieldhVWOVe1169" > <label class="hyva-field-lable" id="label_fieldhVWOVe1169" for="fieldhVWOVe1169">Street & Number </label> <div class="control" role="group" aria-labelledby="label_fieldhVWOVe1169"><input id='street' 4158 name='field[1169]' 4159 type='text' 4160 class='input-text hyva-text' 4161 style='' 4162 value="" 4163 placeholder="" 4164 data-validate="{'required-entry':true}" 4165 aria-labelledby="label_fieldhVWOVe1169" aria-required="true" /> 4166 </div></div> <div id="field_hVWOVe1172" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text mm-logic-hidden webforms-fields-1172 webforms-fields-city required" aria-labelledby="label_fieldhVWOVe1172" > <label class="hyva-field-lable" id="label_fieldhVWOVe1172" for="fieldhVWOVe1172">Town / City </label> <div class="control" role="group" aria-labelledby="label_fieldhVWOVe1172"><input id='city' 4167 name='field[1172]' 4168 type='text' 4169 class='input-text hyva-text' 4170 style='' 4171 value="" 4172 placeholder="Town / City" 4173 data-validate="{'required-entry':true}" 4174 aria-labelledby="label_fieldhVWOVe1172" aria-required="true" /> 4175 </div></div> <div id="field_hVWOVe1175" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text mm-logic-hidden webforms-fields-1175 webforms-fields-county " aria-labelledby="label_fieldhVWOVe1175" > <label class="hyva-field-lable" id="label_fieldhVWOVe1175" for="fieldhVWOVe1175">County </label> <div class="control" role="group" aria-labelledby="label_fieldhVWOVe1175"><input id='county' 4176 name='field[1175]' 4177 type='text' 4178 class='input-text hyva-text' 4179 style='' 4180 value="" 4181 placeholder="County" 4182 aria-labelledby="label_fieldhVWOVe1175" /> 4183 </div></div> <div id="field_hVWOVe1178" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text mm-logic-hidden webforms-fields-1178 webforms-fields-postcode required" aria-labelledby="label_fieldhVWOVe1178" > <label class="hyva-field-lable" id="label_fieldhVWOVe1178" for="fieldhVWOVe1178">Postcode </label> <div class="control" role="group" aria-labelledby="label_fieldhVWOVe1178"><input id='postcode' 4184 name='field[1178]' 4185 type='text' 4186 class='input-text hyva-text' 4187 style='' 4188 value="" 4189 placeholder="Postcode" 4190 data-validate="{'required-entry':true}" 4191 aria-labelledby="label_fieldhVWOVe1178" aria-required="true" /> 4192 </div></div> <div id="field_hVWOVe1181" role="group" class="field hyva-field lg:w-full md:w-full w-full type-text webforms-fields-1181 webforms-fields-account-number required" aria-labelledby="label_fieldhVWOVe1181" > <label class="hyva-field-lable" id="label_fieldhVWOVe1181" for="fieldhVWOVe1181">Account Number </label> <div class="control" role="group" aria-labelledby="label_fieldhVWOVe1181"><input id='account-number' 4193 name='field[1181]' 4194 type='text' 4195 class='input-text hyva-text' 4196 style='' 4197 value="" 4198 placeholder="This is a 9-digit number starting with M. You can find this on any email, letter or invoice." 4199 data-validate="{'required-entry':true}" 4200 aria-labelledby="label_fieldhVWOVe1181" aria-required="true" /> 4201 </div></div></fieldset> <div id="captcha-container-hVWOVe" class="captcha-container px-4 clear-both float-left w-full"></div> <div id="submithVWOVe" class="flex !flex-col gap-2 actions-toolbar submit-right w-full clear-both !m-0"> 4202 <div class="primary w-full mx-auto text-center"> 4203 <button type="submit" class="action submit primary w-auto " 4204 id="webform_hVWOVe_submit_button" 4205 title="Submit" 4206 name="submit_button_hVWOVe">
4207 <span>Submit</span> 4208 </button> 4209 <div class="w-full grecaptcha-legal mt-5"> 4210 <p class="my-4 text-sm"> 4211 <em>This site is protected by reCAPTCHA.</em> 4212</p> </div> 4213 </div> 4214 <div class="secondary"> 4215 <div class="please-wait" id="webform_hVWOVe_sending_data" 4216 style="display:none;"> 4217 <div class="loading-indicator"></div> 4218 <span id="webform_hVWOVe_progress_text">Sending...</span> 4219 </div> 4220 </div> 4221</div></form> 4222 4223 </div> 4224 4225 <style> .recaptcha-position-inline{ clear: both; box-sizing: border-box; padding: 0 2rem 2rem 0; width: 100%; float: left; }</style> 4226 </div> </div> 4227 </div> 4228</div> 4229 4230</div> </div></div></main><footer class="footer-container"><style> 4231 .pre-footer { 4232 background-color: #ffffff; } 4233</style> 4234<div class="footer-wrapper" role="contentinfo"> 4235 <div class="pre-footer text-white text-center splide top-padding-lg bottom-padding-lg"> 4236 <div class="container mx-auto splide__track"> 4237 <div class="splide__list md:!flex md:justify-around"> 4238 <a href="/locksmith-service/" class="splide__slide lg:w-1/3 no-underline text-sm max-md:block max-md:mb-1"> 4239 <h4 class="mb-4">Emergency Locksmiths</h4> 4240 <p class="mb-4">24/7 locksmith support when you need it most.</p> 4241 <span class="relative inline-block pb-[3px] after:content-[''] after:absolute after:left-0 after:bottom-0 after:h-[1px] after:w-full after:bg-current after:transition-all after:duration-300 after:ease-out hover:after:w-0"><span>Learn More</span></span> 4242 </a> 4243 4244 <a href="/locks" class="splide__slide lg:w-1/3 no-underline text-sm max-md:block max-md:mb-1"> 4245 <h4 class="mb-4">Insurance Approved</h4> 4246 <p class="mb-4">Our locks are certified to meet the highest security standards.</p> 4247 <span class="relative inline-block pb-[3px] after:content-[''] after:absolute after:left-0 after:bottom-0 after:h-[1px] after:w-full after:bg-current after:transition-all after:duration-300 after:ease-out hover:after:w-0"><span>Learn More</span></span> 4248 </a> 4249 4250 <a href="/about-us" class="splide__slide lg:w-1/3 no-underline text-sm max-md:block max-md:mb-1"> 4251 <h4 class="mb-4">Trusted Since 1926</h4> 4252 <p class="mb-4">100 years of British security expertise.</p> 4253 <span class="relative inline-block pb-[3px] after:content-[''] after:absolute after:left-0 after:bottom-0 after:h-[1px] after:w-full after:bg-current after:transition-all after:duration-300 after:ease-out hover:after:w-0"><span>Learn More</span></span> 4254 </a> 4255 4256 </div> 4257 </div> 4258 </div> 4259 <div class="page-footer bg-[#333E48] bg-gradient-to-b from-black/0 to-black/20 text-white [&_*]:text-white"> 4260 <div class="footer content container max-md:max-w-[490px] mx-auto grid grid-cols-1 md:grid-cols-[2fr_1fr_1fr] py-[60px] justify-between" aria-label="Footer navigation"> 4261 <div class="flex flex-col md:max-w-[427px]"> 4262 <div class="footer-newsletter"> 4263 <p class="heading-2 max-md:text-center">Get Exclusive Updates,<br/>News, and Advice</p> <div class="footer-newsletter"> 4264 <form 4265 class="form subscribe" 4266 action="https://www.banham.co.uk/newsletter/subscriber/new/" 4267 method="post" 4268 x-data="initNewsletterForm" 4269 @submit.prevent="submitForm" 4270 id="newsletter-validate-detail" 4271 aria-label="Subscribe to Newsletter" 4272 > 4273 <div class="flex border-b mb-10"> 4274 <input 4275 name="email" 4276 type="email" 4277 required 4278 id="newsletter-subscribe" 4279 class="form-input inline-flex w-full text-white bg-transparent border-0 placeholder:text-white/50 p-0" 4280 placeholder="Email Address" 4281 autocomplete="email" 4282 aria-describedby="footer-newsletter-heading" 4283 > 4284 <input name="form_key" type="hidden" value="qqHJt21KnCGuKef4" /> <button class="inline-flex items-center text-sm leading-5 hover:text-white/75 focus:outline-none focus:text-white transition ease-in-out duration-150 font-medium" title="Subscribe"> 4285 Subscribe </button> 4286 </div> 4287 <div> 4288 <template x-if="displayErrorMessage"> 4289 <p class="flex items-center text-red">
4290 <span class="inline-block w-8 h-8 mr-3"> 4291 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" aria-hidden="true"> 4292 <path stroke-linecap="round" stroke-linejoin="round" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/> 4293</svg> 4294 </span> 4295 <template x-for="errorMessage in errorMessages"> 4296 <span x-html="errorMessage"></span> 4297 </template> 4298 </p> 4299 </template> 4300 </div> 4301 </form> 4302 <div class="w-full"> 4303 </div> 4304 4305 </div> <p class="text-sm [&_a]:underline mb-[60px] max-md:text-center max-md:max-w-96 max-md:mx-auto">If you would like further information on how we use your personal data, please check our <a href="/privacy-promise">Privacy Policy</a>.</p> </div> 4306 <ul class="flex gap-5 max-md:justify-center max-md:mb-[60px]"> 4307 <li> 4308 <a href="https://www.facebook.com/Banham.Group/" 4309 class="flex items-center justify-center w-9 h-9 rounded-full bg-white/20 hover:bg-white [&:hover>i]:text-primary-darker transition-all duration-300" 4310 target="_blank" 4311 aria-label="brand-facebook" 4312 rel="noopener noreferrer" 4313 > 4314 <i class="ti ti-brand-facebook text-xl"></i> 4315 </a> 4316 </li> 4317 <li> 4318 <a href="https://www.instagram.com/banhamgroup/" 4319 class="flex items-center justify-center w-9 h-9 rounded-full bg-white/20 hover:bg-white [&:hover>i]:text-primary-darker transition-all duration-300" 4320 target="_blank" 4321 aria-label="brand-instagram" 4322 rel="noopener noreferrer" 4323 > 4324 <i class="ti ti-brand-instagram text-xl"></i> 4325 </a> 4326 </li> 4327 <li> 4328 <a href="https://x.com/banhamsecurity" 4329 class="flex items-center justify-center w-9 h-9 rounded-full bg-white/20 hover:bg-white [&:hover>i]:text-primary-darker transition-all duration-300" 4330 target="_blank" 4331 aria-label="brand-x" 4332 rel="noopener noreferrer" 4333 > 4334 <i class="ti ti-brand-x text-xl"></i> 4335 </a> 4336 </li> 4337 <li> 4338 <a href="https://uk.pinterest.com/banhamgroup/" 4339 class="flex items-center justify-center w-9 h-9 rounded-full bg-white/20 hover:bg-white [&:hover>i]:text-primary-darker transition-all duration-300" 4340 target="_blank" 4341 aria-label="brand-pinterest" 4342 rel="noopener noreferrer" 4343 > 4344 <i class="ti ti-brand-pinterest text-xl"></i> 4345 </a> 4346 </li> 4347 </ul>
4348 <span class="text-5xl mt-auto max-md:hidden">Trusted,<br/>Since 1926</span> </div> 4349 4350 <div class="footer-middle-col flex flex-col justify-between md:gap-14 gap-5 max-md:mb-5" x-data="{}"> 4351 <div x-data="{ index: 0 }"> 4352 <h3 class="text-[10px] uppercase leading-4 max-md:mb-0 max-md:flex items-center justify-between font-grotesk tracking-wide" 4353 @click="$store.footerResponsive.isMobile && $store.footerResponsive.toggle(index)"> 4354 Banham <i class="ti ti-chevron-down inline-block ml-auto text-sm md:hidden transition-transform duration-300" 4355 :class="$store.footerResponsive.isOpen(index) ? 'rotate-180' : 'rotate-0'"></i> 4356 </h3> 4357 4358 <ul class="flex flex-col gap-2 max-md:[&>li:first-child]:mt-3 mb-5 md:mb-0" 4359 x-show="!$store.footerResponsive.isMobile || $store.footerResponsive.isOpen(index)" 4360 x-collapse> 4361 <li> 4362 <a href="/about-us/" aria-label="About Us" 4363 class="inline-block text-sm font-normal leading-tight hover:underline"> 4364 About Us </a> 4365 </li> 4366 <li> 4367 <a href="/showrooms/" aria-label="Showrooms" 4368 class="inline-block text-sm font-normal leading-tight hover:underline"> 4369 Showrooms </a> 4370 </li> 4371 <li> 4372 <a href="/key-cutting-key-registration/" aria-label="Key Registration" 4373 class="inline-block text-sm font-normal leading-tight hover:underline"> 4374 Key Registration </a> 4375 </li> 4376 <li> 4377 <a href="https://www.banham.co.uk/trade/trade-area/" aria-label="Trade Buy Online" 4378 class="inline-block text-sm font-normal leading-tight hover:underline"> 4379 Trade Buy Online </a> 4380 </li> 4381 <li> 4382 <a href="/banham-payment/customer/view/" aria-label="Online Payment" 4383 class="inline-block text-sm font-normal leading-tight hover:underline"> 4384 Online Payment </a> 4385 </li> 4386 <li> 4387 <a href="/moving-home/" aria-label="Moving Home" 4388 class="inline-block text-sm font-normal leading-tight hover:underline"> 4389 Moving Home </a> 4390 </li> 4391 <li> 4392 <a href="/patents/" aria-label="Patents" 4393 class="inline-block text-sm font-normal leading-tight hover:underline"> 4394 Patents </a> 4395 </li> 4396 <li> 4397 <a href="/deliveries-returns/" aria-label="Deliveries and Returns" 4398 class="inline-block text-sm font-normal leading-tight hover:underline"> 4399 Deliveries and Returns </a> 4400 </li> 4401 <li> 4402 <a href="/commercial" aria-label="Banham Commercial" 4403 class="inline-block text-sm font-normal leading-tight hover:underline"> 4404 Banham Commercial </a> 4405 </li> 4406 <li> 4407 <a href="/book-a-survey/" aria-label="Book a Free Survey" 4408 class="inline-block text-sm font-normal leading-tight hover:underline"> 4409 Book a Free Survey </a> 4410 </li> 4411 </ul> 4412 </div> 4413 <div x-data="{ index: 1 }"> 4414 <h3 class="text-[10px] uppercase leading-4 max-md:mb-0 max-md:flex items-center justify-between font-grotesk tracking-wide" 4415 @click="$store.footerResponsive.isMobile && $store.footerResponsive.toggle(index)"> 4416 Customer Support <i class="ti ti-chevron-down inline-block ml-auto text-sm md:hidden transition-transform duration-300" 4417 :class="$store.footerResponsive.isOpen(index) ? 'rotate-180' : 'rotate-0'"></i> 4418 </h3> 4419 4420 <ul class="flex flex-col gap-2 max-md:[&>li:first-child]:mt-3 mb-5 md:mb-0" 4421 x-show="!$store.footerResponsive.isMobile || $store.footerResponsive.isOpen(index)" 4422 x-collapse> 4423 <li> 4424 <a href="/customer-help-centre/" aria-label="Support Centre" 4425 class="inline-block text-sm font-normal leading-tight hover:underline"> 4426 Support Centre </a> 4427 </li> 4428 <li> 4429 <a href="/contact/" aria-label="Contact Us" 4430 class="inline-block text-sm font-normal leading-tight hover:underline"> 4431 Contact Us </a> 4432 </li> 4433 <li> 4434 <a href="/update-your-details/" aria-label="Update Your Details" 4435 class="inline-block text-sm font-normal leading-tight hover:underline"> 4436 Update Your Details </a> 4437 </li> 4438 <li> 4439 <a href="/pstn/" aria-label="Digital Phone Switchover" 4440 class="inline-block text-sm font-normal leading-tight hover:underline"> 4441 Digital Phone Switchover </a> 4442 </li> 4443 <li> 4444 <a href="/complaints/" aria-label="Complaints Procedure" 4445 class="inline-block text-sm font-normal leading-tight hover:underline"> 4446 Complaints Procedure </a> 4447 </li> 4448 <li> 4449 <a href="/annual-contract-details/" aria-label="Annual Contracts Details" 4450 class="inline-block text-sm font-normal leading-tight hover:underline"> 4451 Annual Contracts Details </a> 4452 </li> 4453 <li> 4454 <a href="/direct-debits/" aria-label="Direct Debit Details" 4455 class="inline-block text-sm font-normal leading-tight hover:underline"> 4456 Direct Debit Details </a> 4457 </li> 4458 </ul> 4459 </div> 4460 <div x-data="{ index: 2 }"> 4461 <h3 class="text-[10px] uppercase leading-4 max-md:mb-0 max-md:flex items-center justify-between font-grotesk tracking-wide" 4462 @click="$store.footerResponsive.isMobile && $store.footerResponsive.toggle(index)"> 4463 Whatâs New <i class="ti ti-chevron-down inline-block ml-auto text-sm md:hidden transition-transform duration-300" 4464 :class="$store.footerResponsive.isOpen(index) ? 'rotate-180' : 'rotate-0'"></i> 4465 </h3> 4466 4467 <ul class="flex flex-col gap-2 max-md:[&>li:first-child]:mt-3 mb-5 md:mb-0" 4468 x-show="!$store.footerResponsive.isMobile || $store.footerResponsive.isOpen(index)" 4469 x-collapse> 4470 <li> 4471 <a href="/pstn/" aria-label="Digital Phone Switchover" 4472 class="inline-block text-sm font-normal leading-tight hover:underline"> 4473 Digital Phone Switchover </a> 4474 </li> 4475 <li> 4476 <a href="/journal" aria-label="Journal" 4477 class="inline-block text-sm font-normal leading-tight hover:underline">
4478 Journal </a> 4479 </li> 4480 <li> 4481 <a href="/media/wysiwyg/pdf/online-brochure-banham.pdf" aria-label="Banham Brochure" 4482 class="inline-block text-sm font-normal leading-tight hover:underline"> 4483 Banham Brochure </a> 4484 </li> 4485 </ul> 4486 </div> 4487 4488 </div> 4489 4490 <div class="footer-right-col flex flex-col md:gap-14 gap-5" x-data="{}"> 4491 <div x-data="{ index: 3 }"> 4492 <h3 class="text-[10px] uppercase leading-none max-md:mb-0 max-md:flex items-center justify-between font-grotesk tracking-wide" 4493 @click="$store.footerResponsive.isMobile && $store.footerResponsive.toggle(index)"> 4494 Join Us <i class="ti ti-chevron-down inline-block ml-auto text-sm md:hidden transition-transform duration-300" 4495 :class="$store.footerResponsive.isOpen(index) ? 'rotate-180' : 'rotate-0'"></i> 4496 </h3> 4497 4498 <ul class="flex flex-col gap-2 max-md:[&>li:first-child]:mt-3" 4499 x-show="!$store.footerResponsive.isMobile || $store.footerResponsive.isOpen(index)" 4500 x-collapse> 4501 <li> 4502 <a href="https://careers.banham.com/" aria-label="Banham Careers" 4503 class="inline-block text-sm font-normal leading-tight hover:underline"> 4504 Banham Careers </a> 4505 </li> 4506 <li> 4507 <a href="https://www.banhamacademy.co.uk/" aria-label="Banham Academy" 4508 class="inline-block text-sm font-normal leading-tight hover:underline"> 4509 Banham Academy </a> 4510 </li> 4511 <li> 4512 <a href="/media-enquiries" aria-label="Media Enquiries" 4513 class="inline-block text-sm font-normal leading-tight hover:underline"> 4514 Media Enquiries </a> 4515 </li> 4516 </ul> 4517 </div> 4518 <div x-data="{ index: 4 }"> 4519 <h3 class="text-[10px] uppercase leading-none max-md:mb-0 max-md:flex items-center justify-between font-grotesk tracking-wide" 4520 @click="$store.footerResponsive.isMobile && $store.footerResponsive.toggle(index)"> 4521 Policies <i class="ti ti-chevron-down inline-block ml-auto text-sm md:hidden transition-transform duration-300" 4522 :class="$store.footerResponsive.isOpen(index) ? 'rotate-180' : 'rotate-0'"></i> 4523 </h3> 4524 4525 <ul class="flex flex-col gap-2 max-md:[&>li:first-child]:mt-3" 4526 x-show="!$store.footerResponsive.isMobile || $store.footerResponsive.isOpen(index)" 4527 x-collapse> 4528 <li> 4529 <a href="/terms-conditions/" aria-label="Terms and Conditions" 4530 class="inline-block text-sm font-normal leading-tight hover:underline"> 4531 Terms and Conditions </a> 4532 </li> 4533 <li> 4534 <a href="/website-terms-conditions/" aria-label="Website Terms and Conditions" 4535 class="inline-block text-sm font-normal leading-tight hover:underline"> 4536 Website Terms and Conditions </a> 4537 </li> 4538 <li> 4539 <a href="/privacy-promise/" aria-label="Privacy Promise" 4540 class="inline-block text-sm font-normal leading-tight hover:underline"> 4541 Privacy Promise </a> 4542 </li> 4543 <li> 4544 <a href="/eula/" aria-label="Banham App EULA" 4545 class="inline-block text-sm font-normal leading-tight hover:underline"> 4546 Banham App EULA </a> 4547 </li> 4548 <li> 4549 <a href="/cookie-notice/" aria-label="Cookie Notice" 4550 class="inline-block text-sm font-normal leading-tight hover:underline"> 4551 Cookie Notice </a> 4552 </li> 4553 <li> 4554 <a href="/media/wysiwyg/pdf/banham-patent-locks-ltd-section-172-statement-companies-act-2006.pdf" aria-label="Section 172 Policy" 4555 class="inline-block text-sm font-normal leading-tight hover:underline"> 4556 Section 172 Policy </a> 4557 </li> 4558 <li> 4559 <a href="/media/wysiwyg/pdf/sexual-harassment-statement.pdf" aria-label="Zero Tolerance policy" 4560 class="inline-block text-sm font-normal leading-tight hover:underline"> 4561 Zero Tolerance policy </a> 4562 </li> 4563 <li> 4564 <a href="https://a.storyblok.com/f/286600090739628/x/3672f2235d/modern_slavery_statement_dec-2025.pdf" aria-label="Modern Slavery Policy Statement" 4565 class="inline-block text-sm font-normal leading-tight hover:underline"> 4566 Modern Slavery Policy Statement </a> 4567 </li> 4568 </ul> 4569 </div> 4570 </div>
4571 <span class="text-4xl leading-[43.2px] text-center mt-[60px] md:hidden">Trusted,<br/>Since 1926</span> </div> 4572 <div class="footer-bottom container max-md:max-w-[406px] text-xs leading-[18px] pb-[60px] [&_*]:text-xs [&_p]:mb-0 [&_a]:underline text-center max-md:[&_p]:inline"> 4573 <p>Registered in England and Wales under the Registration Number 00457812. Company address: 20 Thornsett Road, Earlsfield, London, SW18 4EF</p> 4574<p>This site is protected by reCAPTCHA and our <a href="https://www.banham.co.uk/privacy-promise/">Privacy Policy</a> and <a href="https://www.banham.co.uk/website-terms-conditions/">Website T&Cs</a> apply.</p> </div> 4575 </div> 4576 </div> 4577 4578 <div x-data="initNewsletterFormModal"> 4579 <template x-if="shouldShowModal"> 4580 <dialog 4581 id="newsletter-modal" 4582 x-show="open" 4583 x-transition 4584 x-htmldialog="closeModal" 4585 class="open:flex flex-col justify-end md:justify-center md:h-fit h-full max-md:mt-auto my-0 md:m-auto bg-transparent lg:flex-row max-w-full md:max-w-fit after:content-[''] after:flex after:fixed after:inset-0 after:bg-black after:w-full after:h-full after:bg-opacity-50 after:z-[-1]"> 4586 4587 <div class="hidden lg:flex lg:w-[343px] h-auto"> 4588 <img 4589 class="w-full h-full object-cover" 4590 alt="Unlock the latest with the Banham newsletter." 4591 loading="eager" 4592 src="https://a.storyblok.com/f/286600090739628/343x515/516aee5d3b/banham-locks-newsletter.png"> 4593 </div> 4594 4595 <div class="relative flex flex-col items-center justify-center w-full md:w-[426px] lg:w-[506px] gap-10 px-5 md:px-10 pt-10 pb-[60px] text-center bg-white"> 4596 4597 <button 4598 class="absolute right-5 top-5 text-black hover:text-primary-darker focus:outline-none focus:ring-0" 4599 aria-label="Close panel" 4600 @click="closeModal"> 4601 <i class="ti ti-x text-xl"></i> 4602 </button> 4603 4604 <h3 class="m-0 md:max-w-[320px]">Unlock the latest with the Banham newsletter.</h3> 4605 4606 <form 4607 id="newsletter-validate-modal" 4608 action="https://www.banham.co.uk/newsletter/subscriber/new/" 4609 method="post" 4610 @submit.prevent="submitForm" 4611 class="flex flex-col w-full gap-5" 4612 > 4613 <div class="flex flex-col items-start gap-3" :class="{'field-error': errors.firstname}"> 4614 <input 4615 type="text" 4616 name="firstname" 4617 id="newsletter-firstname-modal" 4618 x-model="firstname" 4619 @blur="validateField('firstname')" 4620 :class="{'error': errors.firstname}" 4621 class="form-input" 4622 placeholder="First Name *" 4623 > 4624 <span class="text-error text-xs" x-show="errors.firstname" class="mage-error" x-text="errors.firstname"></span> 4625 </div> 4626 <div class="flex flex-col items-start gap-3" :class="{'field-error': errors.lastname}"> 4627 <input 4628 type="text" 4629 name="lastname" 4630 id="newsletter-lastname-modal" 4631 x-model="lastname" 4632 @blur="validateField('lastname')" 4633 :class="{'error': errors.lastname}" 4634 class="form-input" 4635 placeholder="Last Name *" 4636 >
4637 <span class="text-error text-xs" x-show="errors.lastname" class="mage-error" x-text="errors.lastname"></span> 4638 </div> 4639 <div class="relative email-box flex flex-col items-start gap-3" :class="{'field-error': errors.email}"> 4640 <input 4641 type="email" 4642 name="email" 4643 id="newsletter-subscribe-modal" 4644 x-model="email" 4645 @blur="validateField('email')" 4646 :class="{'error': errors.email}" 4647 class="form-input" 4648 placeholder="Email Address *" 4649 > 4650 <span class="text-error text-xs" x-show="errors.email" class="mage-error" x-text="errors.email"></span> 4651 </div> 4652 4653 <input name="form_key" type="hidden" value="qqHJt21KnCGuKef4" /> 4654 <button type="submit" class="btn btn-primary"> 4655 Subscribe </button> 4656 </form> 4657 4658 4659 <div class="bottom-note m-0 text-primary-lighter [&_p]:m-0 [&_p]:text-primary-lighter"><p>If you would like further information on how we use yourâ¨personal data, please check our<a href="/privacy-promise" target="_self"> Privacy Policy</a>.</p></div> 4660 </div> 4661 </dialog> 4662 </template> 4663 </div> 4664 4665 4666 4667</footer> 4668 4669 4670 4671 4672 4673 4674 4675<style> 4676 @keyframes splide-loading{0%{transform:rotate(0)}to{transform:rotate(1turn)}}.splide__track--draggable{-webkit-touch-callout:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.splide__track--fade>.splide__list>.splide__slide{margin:0!important;opacity:0;z-index:0}.splide__track--fade>.splide__list>.splide__slide.is-active{opacity:1;z-index:1}.splide--rtl{direction:rtl}.splide__track--ttb>.splide__list{display:block}.splide__container{box-sizing:border-box;position:relative}.splide__list{backface-visibility:hidden;display:-ms-flexbox;display:flex;height:100%;margin:0!important;padding:0!important}.splide.is-initialized:not(.is-active) .splide__list{display:grid}.splide__pagination{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:center;justify-content:center;margin:0;pointer-events:none}.splide__pagination li{display:inline-block;line-height:1;list-style-type:none;margin:0;pointer-events:auto}.splide:not(.is-overflow) .splide__pagination{display:none}.splide__progress__bar{width:0}.splide{position:relative;visibility:hidden}.splide.is-initialized,.splide.is-rendered{visibility:visible}.splide__slide{backface-visibility:hidden;box-sizing:border-box;-ms-flex-negative:0;flex-shrink:0;list-style-type:none!important;margin:0;position:relative}.splide__slide img{vertical-align:bottom}.splide__spinner{animation:splide-loading 1s linear infinite;border:2px solid #999;border-left-color:transparent;border-radius:50%;bottom:0;contain:strict;display:inline-block;height:20px;left:0;margin:auto;position:absolute;right:0;top:0;width:20px}.splide__sr{clip:rect(0 0 0 0);border:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.splide__toggle.is-active .splide__toggle__play,.splide__toggle__pause{display:none}.splide__toggle.is-active .splide__toggle__pause{display:inline}.splide__track{overflow:hidden;position:relative;z-index:0} 4677 4678 /* Custom additions from the splide.min.css but without the custom style */ 4679 .splide__pagination--ttb { 4680 position: absolute; 4681 display: inline-flex; 4682 flex-direction: column; 4683 top: 0; 4684 bottom: 0; 4685 right: 100%; 4686 } 4687 4688 /* Hide the pagination dots when the input device is a touch based input */ 4689 @media (pointer: coarse) or (max-width: 639px) { 4690 .splide__pagination { display: none } 4691 } 4692</style> 4693 4694 4695 4696 4697 4698 4699 4700 4701 <!-- [FOOTER Miscellaneous HTML (store)] --> 4702 4703<!-- [/FOOTER Miscellaneous HTML (store)] --> 4704 4705 4706 4707<!-- Google Tag Manager --> 4708 4709<!-- End Google Tag Manager --> 4710 4711<!-- Google Tag Manager (noscript) -->
vendor: 73 bytes, lines 4711-4713
4711 4712<noscript> 4713 <iframe src="https://www.googletagmanager.com/ns.html?id=
4713GTM-5VC2G8L
vendor: 92 bytes, lines 4713-4715
4713" height="0" 4714 width="0" style="display:none;visibility:hidden"></iframe> 4715</noscript>
4716<!-- Google Tag Manager --> 4717 4718<!-- End Google Tag Manager --> 4719 4720<!-- Google Tag Manager (noscript) -->
vendor: 73 bytes, lines 4720-4722
4720 4721<noscript> 4722 <iframe src="https://www.googletagmanager.com/ns.html?id=
4722GTM-5VC2G8L
vendor: 95 bytes, lines 4722-4724
4722" height="0" 4723 width="0" style="display:none;visibility:hidden"></iframe> 4724</noscript>
4724</div> <div style="display: none"><div class="block popup-newsletter"><div class="content"><style>#html-body [data-pb-style=GAY0OEC]{justify-content:flex-start;display:flex;flex-direction:column;background-position:center center;background-size:cover;background-repeat:no-repeat;background-attachment:scroll;min-height:188px}</style><div data-content-type="row" data-appearance="full-bleed" data-enable-parallax="0" data-parallax-speed="0.5" data-background-images='{\"desktop_image\":\"https://www.banham.co.uk/media/wysiwyg/locks-q3-hero-newsletter.jpg\",\"mobile_image\":\"https://www.banham.co.uk/media/wysiwyg/locks-q3-hero-page_1.png\"}' data-background-type="image" data-video-loop="true" data-video-play-only-visible="true" data-video-lazy-load="true" data-video-fallback-src="" data-element="main" data-pb-style="GAY0OEC" data-src="https://www.banham.co.uk/media/wysiwyg/locks-q3-hero-newsletter.jpg" data-mobile-source="https://www.banham.co.uk/media/wysiwyg/locks-q3-hero-page_1.png" class=" lazy background-image-6ab566d99da85"></div><style type="text/css">.background-image-6ab566d99da85 {background-image: url(https://www.banham.co.uk/media/wysiwyg/locks-q3-hero-newsletter.jpg);}@media only screen and (max-width: 767px) and (min-width: 640px) {.background-image-6ab566d99da85 {background-image: url(https://www.banham.co.uk/media/wysiwyg/locks-q3-hero-page_1.png);}}@media only screen and (max-width: 640px) {.background-image-6ab566d99da85 {background-image: url(https://www.banham.co.uk/media/wysiwyg/locks-q3-hero-page_1.png);}}</style> <div class="right"><h3>STAY UP TO DATE WITH <br> THE BANHAM NEWSLETTER</h3><h4>For product updates, company news <br> and the latest stylish products</h4><div class="relative container"> 4725 <div class="flex flex-col items-center justify-center w-full md:w-[426px] lg:w-[506px] gap-10 mx-auto pt-10 lg:pt-20 text-center"> 4726 <div class="flex flex-col gap-4 text-center w-full md:max-w-[320px]"> 4727 <h3 class="m-0">Unlock the latest with the Banham newsletter.</h3> 4728 <p class="mb-0">Weâd love to stay in touch. Sign up to our newsletter and be the first to hear our latest news, launches, and innovations.</p> 4729 </div> 4730 <form 4731 id="newsletter-validate-detail" 4732 action="https://www.banham.co.uk/newsletter/subscriber/new/" 4733 method="post" 4734 x-data="newsletterForm()" 4735 @submit.prevent="submitForm" 4736 class="flex flex-col w-full gap-5" 4737 > 4738 <div class="flex flex-col items-start gap-3" :class="{'field-error': errors.firstname}"> 4739 <input 4740 type="text" 4741 name="firstname" 4742 id="firstname" 4743 x-model="firstname" 4744 @blur="validateField('firstname')" 4745 :class="{'error': errors.firstname}" 4746 class="form-input" 4747 placeholder="First Name *" 4748 > 4749 <span class="text-error text-xs mage-error" x-show="errors.firstname" x-text="errors.firstname"></span> 4750 </div> 4751 4752 <div class="flex flex-col items-start gap-3" :class="{'field-error': errors.lastname}"> 4753 <input 4754 type="text" 4755 name="lastname" 4756 id="lastname" 4757 x-model="lastname" 4758 @blur="validateField('lastname')" 4759 :class="{'error': errors.lastname}" 4760 class="form-input" 4761 placeholder="Last Name *" 4762 > 4763 <span class="text-error text-xs mage-error" x-show="errors.lastname" x-text="errors.lastname"></span> 4764 </div> 4765 4766 <div class="relative flex flex-col items-start gap-3" :class="{'field-error': errors.email}"> 4767 <input 4768 type="email" 4769 name="email" 4770 id="email" 4771 x-model="email" 4772 @blur="validateField('email')" 4773 :class="{'error': errors.email}" 4774 class="form-input" 4775 placeholder="Email Address *" 4776 >
4777 <span class="text-error text-xs mage-error" x-show="errors.email" x-text="errors.email"></span> 4778 </div> 4779 4780 <input name="form_key" type="hidden" value="qqHJt21KnCGuKef4" /> 4781 <button type="submit" class="btn-primary btn btn-primary btn-size-md w-full mb-4"> 4782 Subscribe </button> 4783 4784 </form> 4785 4786 <p class="bottom-note m-0 text-primary-lighter"><p>If you would like further information on how we use yourâ¨personal data, please check our<a href="/privacy-promise" target="_self"> Privacy Policy</a>.</p></p> 4787 </div> 4788</div> 4789 4790 <a class="not-now" href="#">Not Now</a> <style>#html-body [data-pb-style=I98KDDQ]{justify-content:flex-start;display:flex;flex-direction:column;background-position:left top;background-size:cover;background-repeat:no-repeat;background-attachment:scroll}</style><div data-content-type="row" data-appearance="full-bleed" data-enable-parallax="0" data-parallax-speed="0.5" data-background-images="{}" data-background-type="image" data-video-loop="true" data-video-play-only-visible="true" data-video-lazy-load="true" data-video-fallback-src="" data-element="main" data-pb-style="I98KDDQ"><div data-content-type="text" data-appearance="default" data-element="main"><p>If you would like further information on how we use your personal data, please check our <a style="text-decoration: none;" tabindex="0" href="/privacy-promise/">Privacy Policy</a>.</p></div></div></div></div></div></div>
4791<script type="text/javascript">window.amasty_checkout_disabled=true;</script>
vendor: 1 bytes, line 4791
4791
4792<script type="text/javascript" src="https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB/BestResponseMedia_MagemeModification/js/source.js"></script>
vendor: 1 bytes, line 4792
4792
4793<script src="https://eu1-config.doofinder.com/2.x/37bb0b70-b046-4147-8e74-bf61c063a23b.js" async></script>
vendor: 1 bytes, line 4793
4793
4794<script src="https://www.googleoptimize.com/optimize.js?id=OPT-PNJW7FQ"></script>
vendor: 1 bytes, line 4794
4794
4795<script>(function(n,t,i,r){var u,f;n[i]=n[i]||{},n[i].initial={accountCode:"BANHA11114",host:"BANHA11114.pcapredict.com"},n[i].on=n[i].on||function(){(n[i].onq=n[i].onq||[]).push(arguments)},u=t.createElement("script"),u.async=!0,u.src=r,f=t.getElementsByTagName("script")[0],f.parentNode.insertBefore(u,f)})(window,document,"pca","//BANHA11114.pcapredict.com/js/sensor.js")</script>
vendor: 1 bytes, line 4795
4795
4796<script type='text/javascript' id='vwoCode'> 4797window._vwo_code || (function() { 4798var account_id=996012, 4799version=2.1, 4800settings_tolerance=2000, 4801hide_element='body', 4802hide_element_style = 'opacity:0 !important;filter:alpha(opacity=0) !important;background:none !important;transition:none !important;', 4803/* DO NOT EDIT BELOW THIS LINE */ 4804f=false,w=window,d=document,v=d.querySelector('#vwoCode'),cK='_vwo_'+account_id+'_settings',cc={};try{var c=JSON.parse(localStorage.getItem('_vwo_'+account_id+'_config'));cc=c&&typeof c==='object'?c:{}}catch(e){}var stT=cc.stT==='session'?w.sessionStorage:w.localStorage;code={nonce:v&&v.nonce,use_existing_jquery:function(){return typeof use_existing_jquery!=='undefined'?use_existing_jquery:undefined},library_tolerance:function(){return typeof library_tolerance!=='undefined'?library_tolerance:undefined},settings_tolerance:function(){return cc.sT||settings_tolerance},hide_element_style:function(){return'{'+(cc.hES||hide_element_style)+'}'},hide_element:function(){if(performance.getEntriesByName('first-contentful-paint')[0]){return''}return typeof cc.hE==='string'?cc.hE:hide_element},getVersion:function(){return version},finish:function(e){if(!f){f=true;var t=d.getElementById('_vis_opt_path_hides');if(t)t.parentNode.removeChild(t);if(e)(new Image).src='https://dev.visualwebsiteoptimizer.com/ee.gif?a='+account_id+e}},finished:function(){return f},addScript:function(e){var t=d.createElement('script');t.type='text/javascript';if(e.src){t.src=e.src}else{t.text=e.text}v&&t.setAttribute('nonce',v.nonce);d.getElementsByTagName('head')[0].appendChild(t)},load:function(e,t){var n=this.getSettings(),i=d.createElement('script'),r=this;t=t||{};if(n){i.textContent=n;d.getElementsByTagName('head')[0].appendChild(i);if(!w.VWO||VWO.caE){stT.removeItem(cK);r.load(e)}}else{var o=new XMLHttpRequest;o.open('GET',e,true);o.withCredentials=!t.dSC;o.responseType=t.responseType||'text';o.onload=function(){if(t.onloadCb){return t.onloadCb(o,e)}if(o.status===200||o.status===304){_vwo_code.addScript({text:o.responseText})}else{_vwo_code.finish('&e=loading_failure:'+e)}};o.onerror=function(){if(t.onerrorCb){return t.onerrorCb(e)}_vwo_code.finish('&e=loading_failure:'+e)};o.send()}},getSettings:function(){try{var e=stT.getItem(cK);if(!e){return}e=JSON.parse(e);if(Date.now()>e.e){stT.removeItem(cK);return}return e.s}catch(e){return}},init:function(){if(d.URL.indexOf('__vwo_disable__')>-1)return;var e=this.settings_tolerance();w._vwo_settings_timer=setTimeout(function(){_vwo_code.finish();stT.removeItem(cK)},e);var t;if(this.hide_element()!=='body'){t=d.createElement('style');var n=this.hide_element(),i=n?n+this.hide_element_style():'',r=d.getElementsByTagName('head')[0];t.setAttribute('id','_vis_opt_path_hides');v&&t.setAttribute('nonce',v.nonce);t.setAttribute('type','text/css');if(t.styleSheet)t.styleSheet.cssText=i;else t.appendChild(d.createTextNode(i));r.appendChild(t)}else{t=d.getElementsByTagName('head')[0];var i=d.createElement('div');i.style.cssText='z-index: 2147483647 !important;position: fixed !important;left: 0 !important;top: 0 !important;width: 100% !important;height: 100% !important;background: white !important;display: block !important;';i.setAttribute('id','_vis_opt_path_hides');i.classList.add('_vis_hide_layer');t.parentNode.insertBefore(i,t.nextSibling)}var o=window._vis_opt_url||d.URL,s='https://dev.visualwebsiteoptimizer.com/j.php?a='+account_id+'&u='+encodeURIComponent(o)+'&vn='+version;if(w.location.search.indexOf('_vwo_xhr')!==-1){this.addScript({src:s})}else{this.load(s+'&x=true')}}};w._vwo_code=code;code.init();})(); 4805</script>
vendor: 1 bytes, line 4805
4805
4806<script> 4807(function () { 4808 function shouldOpen() { 4809 return window.location.hash === '#open_enquiry_form' || 4810 window.location.search.includes('open=enquiry'); 4811 } 4812 4813 function triggerEnquiryForm() { 4814 if (!shouldOpen()) return; 4815 4816 let tries = 0; 4817 const maxTries = 40; 4818 4819 const timer = setInterval(function () { 4820 const btn = document.querySelector('.open-slide-form-button'); 4821 4822 if (btn) { 4823 window.surveyOpeningSource = 'Opened from CTA'; 4824 btn.click(); 4825 clearInterval(timer); 4826 return; 4827 } 4828 4829 tries++; 4830 if (tries >= maxTries) { 4831 clearInterval(timer); 4832 } 4833 }, 250); 4834 } 4835 4836 if (document.readyState === 'loading') { 4837 document.addEventListener('DOMContentLoaded', triggerEnquiryForm); 4838 } else { 4839 triggerEnquiryForm(); 4840 } 4841 4842 window.addEventListener('hashchange', triggerEnquiryForm); 4843})(); 4844</script>
vendor: 1 bytes, line 4844
4844
4845<script type="text/javascript" data-routing="commerce=rum" defer="defer" src="https://rum.hlx.page/.rum/@adobe/helix-rum-js@^2/dist/rum-standalone.js"></script>
vendor: 1 bytes, line 4845
4845
4846<script type="text/javascript" src="" defer="defer"> 4847</script>
vendor: 1 bytes, line 4847
4847
4848<script> 4849 var BASE_URL = 'https://www.banham.co.uk/'; 4850 var THEME_PATH = 'https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB'; 4851 var COOKIE_CONFIG = { 4852 "expires": null, 4853 "path": "\u002F", 4854 "domain": ".www.banham.co.uk", 4855 "secure": true, 4856 "lifetime": "24800", 4857 "cookie_restriction_enabled": false }; 4858 var CURRENT_STORE_CODE = 'default'; 4859 var CURRENT_WEBSITE_ID = '1'; 4860 4861 window.hyva = window.hyva || {} 4862 4863 window.cookie_consent_groups = window.cookie_consent_groups || {} 4864 window.cookie_consent_groups['necessary'] = true; 4865 4866 window.cookie_consent_config = window.cookie_consent_config || {}; 4867 window.cookie_consent_config['necessary'] = [].concat( 4868 window.cookie_consent_config['necessary'] || [], 4869 [ 4870 'user_allowed_save_cookie', 4871 'form_key', 4872 'mage-messages', 4873 'private_content_version', 4874 'mage-cache-sessid', 4875 'last_visited_store', 4876 'section_data_ids' 4877 ] 4878 );</script>
vendor: 1 bytes, line 4878
4878
4879<script> 4880 (function( hyva, undefined ) { 4881 4882 function lifetimeToExpires(options, defaults) { 4883 4884 const lifetime = options.lifetime || defaults.lifetime; 4885 4886 if (lifetime) { 4887 const date = new Date; 4888 date.setTime(date.getTime() + lifetime * 1000); 4889 return date; 4890 } 4891 4892 return null; 4893 } 4894 4895 function generateRandomString() { 4896 4897 const allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 4898 length = 16; 4899 4900 let formKey = '', 4901 charactersLength = allowedCharacters.length; 4902 4903 for (let i = 0; i < length; i++) { 4904 formKey += allowedCharacters[Math.round(Math.random() * (charactersLength - 1))] 4905 } 4906 4907 return formKey; 4908 } 4909 4910 const sessionCookieMarker = {noLifetime: true} 4911 4912 const cookieTempStorage = {}; 4913 4914 const internalCookie = { 4915 get(name) { 4916 const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)'); 4917 return v ? v[2] : null; 4918 }, 4919 set(name, value, days, skipSetDomain) { 4920 let expires, 4921 path, 4922 domain, 4923 secure, 4924 samesite; 4925 4926 const defaultCookieConfig = { 4927 expires: null, 4928 path: '/', 4929 domain: null, 4930 secure: false, 4931 lifetime: null, 4932 samesite: 'lax' 4933 }; 4934 4935 const cookieConfig = window.COOKIE_CONFIG || {}; 4936 4937 expires = days && days !== sessionCookieMarker 4938 ? lifetimeToExpires({lifetime: 24 * 60 * 60 * days, expires: null}, defaultCookieConfig) 4939 : lifetimeToExpires(window.COOKIE_CONFIG, defaultCookieConfig) || defaultCookieConfig.expires; 4940 4941 path = cookieConfig.path || defaultCookieConfig.path; 4942 domain = !skipSetDomain && (cookieConfig.domain || defaultCookieConfig.domain); 4943 secure = cookieConfig.secure || defaultCookieConfig.secure; 4944 samesite = cookieConfig.samesite || defaultCookieConfig.samesite; 4945 4946 document.cookie = name + "=" + encodeURIComponent(value) + 4947 (expires && days !== sessionCookieMarker ? '; expires=' + expires.toGMTString() : '') + 4948 (path ? '; path=' + path : '') + 4949 (domain ? '; domain=' + domain : '') + 4950 (secure ? '; secure' : '') + 4951 (samesite ? '; samesite=' + samesite : 'lax'); 4952 }, 4953 isWebsiteAllowedToSaveCookie() { 4954 const allowedCookies = this.get('user_allowed_save_cookie'); 4955 if (allowedCookies) { 4956 const allowedWebsites = JSON.parse(unescape(allowedCookies)); 4957 4958 return allowedWebsites[CURRENT_WEBSITE_ID] === 1; 4959 } 4960 return false; 4961 }, 4962 getGroupByCookieName(name) { 4963 const cookieConsentConfig = window.cookie_consent_config || {}; 4964 let group = null; 4965 for (let prop in cookieConsentConfig) { 4966 if (!cookieConsentConfig.hasOwnProperty(prop)) continue; 4967 if (cookieConsentConfig[prop].includes(name)) { 4968 group = prop; 4969 break; 4970 } 4971 } 4972 return group; 4973 }, 4974 isCookieAllowed(name) { 4975 const cookieGroup = this.getGroupByCookieName(name); 4976 return cookieGroup 4977 ? window.cookie_consent_groups[cookieGroup] 4978 : this.isWebsiteAllowedToSaveCookie(); 4979 }, 4980 saveTempStorageCookies() { 4981 for (const [name, data] of Object.entries(cookieTempStorage)) { 4982 if (this.isCookieAllowed(name)) { 4983 this.set(name, data['value'], data['days'], data['skipSetDomain']); 4984 delete cookieTempStorage[name]; 4985 } 4986 } 4987 } 4988 }; 4989 4990 hyva.getCookie = (name) => { 4991 const cookieConfig = window.COOKIE_CONFIG || {}; 4992 4993 if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) { 4994 return cookieTempStorage[name] ? cookieTempStorage[name]['value'] : null; 4995 } 4996 4997 return internalCookie.get(name); 4998 } 4999 5000 hyva.setCookie = (name, value, days, skipSetDomain) => { 5001 const cookieConfig = window.COOKIE_CONFIG || {}; 5002 5003 if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) { 5004 cookieTempStorage[name] = {value, days, skipSetDomain}; 5005 return; 5006 } 5007 return internalCookie.set(name, value, days, skipSetDomain); 5008 } 5009 5010 5011 hyva.setSessionCookie = (name, value, skipSetDomain) => { 5012 return hyva.setCookie(name, value, sessionCookieMarker, skipSetDomain) 5013 } 5014 5015 hyva.getBrowserStorage = () => { 5016 const browserStorage = window.localStorage || window.sessionStorage; 5017 if (!browserStorage) { 5018 console.warn('Browser Storage is unavailable'); 5019 return false;
5020 } 5021 try { 5022 browserStorage.setItem('storage_test', '1'); 5023 browserStorage.removeItem('storage_test'); 5024 } catch (error) { 5025 console.warn('Browser Storage is not accessible', error); 5026 return false; 5027 } 5028 return browserStorage; 5029 } 5030 5031 hyva.postForm = (postParams) => { 5032 const form = document.createElement("form"); 5033 5034 let data = postParams.data; 5035 5036 if (! postParams.skipUenc && ! data.uenc) { 5037 data.uenc = btoa(window.location.href); 5038 } 5039 form.method = "POST"; 5040 form.action = postParams.action; 5041 5042 Object.keys(postParams.data).map(key => { 5043 const field = document.createElement("input"); 5044 field.type = 'hidden' 5045 field.value = postParams.data[key]; 5046 field.name = key; 5047 form.appendChild(field); 5048 }); 5049 5050 const form_key = document.createElement("input"); 5051 form_key.type = 'hidden'; 5052 form_key.value = hyva.getFormKey(); 5053 form_key.name="form_key"; 5054 form.appendChild(form_key); 5055 5056 document.body.appendChild(form); 5057 5058 form.submit(); 5059 } 5060 5061 hyva.getFormKey = function () { 5062 let formKey = hyva.getCookie('form_key'); 5063 5064 if (!formKey) { 5065 formKey = generateRandomString(); 5066 hyva.setCookie('form_key', formKey); 5067 } 5068 5069 return formKey; 5070 } 5071 5072 hyva.formatPrice = (value, showSign, options = {}) => { 5073 const groupSeparator = options.groupSeparator; 5074 const decimalSeparator = options.decimalSeparator 5075 delete options.groupSeparator; 5076 delete options.decimalSeparator; 5077 const formatter = new Intl.NumberFormat( 5078 'en\u002DGB', 5079 Object.assign({ 5080 style: 'currency', 5081 currency: 'GBP', 5082 signDisplay: showSign ? 'always' : 'auto' 5083 }, options) 5084 ); 5085 return (typeof Intl.NumberFormat.prototype.formatToParts === 'function') ? 5086 formatter.formatToParts(value).map(({type, value}) => { 5087 switch (type) { 5088 case 'currency': 5089 return '\u00A3' || value; 5090 case 'minusSign': 5091 return '- '; 5092 case 'plusSign': 5093 return '+ '; 5094 case 'group': 5095 return groupSeparator !== undefined ? groupSeparator : value; 5096 case 'decimal': 5097 return decimalSeparator !== undefined ? decimalSeparator : value; 5098 default : 5099 return value; 5100 } 5101 }).reduce((string, part) => string + part) : 5102 formatter.format(value); 5103 } 5104 5105 const formatStr = function (str, nStart) { 5106 const args = Array.from(arguments).slice(2); 5107 5108 return str.replace(/(%+)([0-9]+)/g, (m, p, n) => { 5109 const idx = parseInt(n) - nStart; 5110 5111 if (args[idx] === null || args[idx] === void 0) { 5112 return m; 5113 } 5114 return p.length % 2 5115 ? p.slice(0, -1).replace('%%', '%') + args[idx] 5116 : p.replace('%%', '%') + n; 5117 }) 5118 } 5119 5120 hyva.str = function (string) { 5121 const args = Array.from(arguments); 5122 args.splice(1, 0, 1); 5123 5124 return formatStr.apply(undefined, args); 5125 } 5126 5127 hyva.strf = function () { 5128 const args = Array.from(arguments); 5129 args.splice(1, 0, 0); 5130 5131 return formatStr.apply(undefined, args); 5132 } 5133 5134 /** 5135 * Take a html string as `content` parameter and 5136 * extract an element from the DOM to replace in 5137 * the current page under the same selector, 5138 * defined by `targetSelector` 5139 */ 5140 hyva.replaceDomElement = (targetSelector, content) => { 5141 5142 const parser = new DOMParser(); 5143 const doc = parser.parseFromString(content, 'text/html');
5144 const contentNode = doc.querySelector(targetSelector); 5145 5146 5147 if (!contentNode || !document.querySelector(targetSelector)) { 5148 return; 5149 } 5150 5151 hyva.activateScripts(contentNode); 5152 document.querySelector(targetSelector).replaceWith(contentNode); 5153 5154 5155 window.dispatchEvent(new CustomEvent("reload-customer-section-data")); 5156 hyva.initMessages(); 5157 } 5158 5159 hyva.removeScripts = (contentNode) => { 5160 const scripts = contentNode.getElementsByTagName('script'); 5161 for (let i = 0; i < scripts.length; i++) { 5162 scripts[i].parentNode.removeChild(scripts[i]); 5163 } 5164 const templates = contentNode.getElementsByTagName('template'); 5165 for (let i = 0; i < templates.length; i++) { 5166 const container = document.createElement('div'); 5167 container.innerHTML = templates[i].innerHTML; 5168 hyva.removeScripts(container); 5169 templates[i].innerHTML = container.innerHTML; 5170 } 5171 } 5172 5173 hyva.activateScripts = (contentNode) => { 5174 const scripts = Array.from(contentNode.getElementsByTagName('script')); 5175 5176 5177 for (const original of scripts) { 5178 const script = document.createElement('script'); 5179 original.type && (script.type = original.type); 5180 script.innerHTML = original.innerHTML; 5181 5182 5183 original.parentNode.removeChild(original) 5184 5185 5186 document.head.appendChild(script); 5187 } 5188 5189 return contentNode; 5190 } 5191 5192 const replace = {['+']: '-', ['/']: '_', ['=']: ','}; 5193 hyva.getUenc = () => btoa(window.location.href).replace(/[+/=]/g, match => replace[match]); 5194 5195 let currentTrap; 5196 5197 const focusableElements = (rootElement) => { 5198 const selector = 'button, [href], input, select, textarea, details, [tabindex]:not([tabindex="-1"]'; 5199 return Array.from(rootElement.querySelectorAll(selector)) 5200 .filter(el => { 5201 return el.style.display !== 'none' 5202 && !el.disabled 5203 && el.tabIndex !== -1 5204 && (el.offsetWidth || el.offsetHeight || el.getClientRects().length) 5205 }) 5206 } 5207 5208 const focusTrap = (e) => { 5209 const isTabPressed = e.key === 'Tab' || e.keyCode === 9; 5210 if (!isTabPressed) return; 5211 5212 const focusable = focusableElements(currentTrap) 5213 const firstFocusableElement = focusable[0] 5214 const lastFocusableElement = focusable[focusable.length - 1] 5215 5216 e.shiftKey 5217 ? document.activeElement === firstFocusableElement && (lastFocusableElement.focus(), e.preventDefault()) 5218 : document.activeElement === lastFocusableElement && (firstFocusableElement.focus(), e.preventDefault()) 5219 }; 5220 5221 hyva.releaseFocus = (rootElement) => { 5222 if (currentTrap && (!rootElement || rootElement === currentTrap)) { 5223 currentTrap.removeEventListener('keydown', focusTrap) 5224 currentTrap = null 5225 } 5226 } 5227 hyva.trapFocus = (rootElement) => { 5228 if (!rootElement) return; 5229 hyva.releaseFocus() 5230 currentTrap = rootElement 5231 rootElement.addEventListener('keydown', focusTrap) 5232 const firstElement = focusableElements(rootElement)[0] 5233 firstElement && firstElement.focus() 5234 } 5235 5236 hyva.safeParseNumber = (rawValue) => { 5237 const number = rawValue ? parseFloat(rawValue) : null; 5238 5239 return Array.isArray(number) || isNaN(number) ? rawValue : number; 5240 } 5241 5242 const toCamelCase = s => s.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(''); 5243 hyva.createBooleanObject = (name, value = false, additionalMethods = {}) => { 5244 5245 const camelCase = toCamelCase(name); 5246 const key = '__hyva_bool_' + name 5247 5248 return new Proxy(Object.assign( 5249 additionalMethods, 5250 { 5251 [key]: !!value, 5252 [name]() {return !!this[key]}, 5253 ['!' + name]() {return !this[key]}, 5254 ['not' + camelCase]() {return !this[key]}, 5255 ['toggle' + camelCase]() {this[key] = !this[key]}, 5256 [`set${camelCase}True`]() {this[key] = true}, 5257 [`set${camelCase}False`]() {this[key] = false}, 5258 } 5259 ), { 5260 set(target, prop, value) { 5261 return prop === name 5262 ? (target[key] = !!value) 5263 : Reflect.set(...arguments); 5264 } 5265 }) 5266 } 5267 5268 hyva.alpineInitialized = (fn) => window.addEventListener('alpine:initialized', fn, {once: true}) 5269 window.addEventListener('alpine:init', () => Alpine.data('{}', () => ({})), {once: true}); 5270 window.addEventListener('user-allowed-save-cookie', () => internalCookie.saveTempStorageCookies()) 5271 5272 }( window.hyva = window.hyva || {} ));</script>
vendor: 1 bytes, line 5272
5272
5273<script type="speculationrules"> 5274{ 5275 "tag": "Hyva Theme", 5276 "prefetch": [{ 5277 "source": "document", 5278 "where": { 5279 "and": [ 5280 { "href_matches": "/*" }, 5281 { "not": { 5282 "href_matches": ["/customer/*","/search/*","/sales/*","/wishlist/*","/checkout/*","/paypal/*","/newsletter/*","/stores/store/redirect/*"] }}, 5283 { "not": { 5284 "selector_matches": [".no-preload", ".do-not-prerender", "[download]", "[rel~=nofollow]", "[target]"] 5285 }} 5286 ] 5287 }, 5288 "eagerness": "moderate" 5289 }] 5290}</script>
vendor: 1 bytes, line 5290
5290
5291<script> 5292 const viewTransitionToGalleryPageStorage = 'view-transition-to-gallery-page-type'; 5293 const setTransitionNameBetweenGallery = async (url, promise) => { 5294 if (window.matchMedia('(prefers-reduced-motion)').matches) return; 5295 5296 const productGallery = document.getElementById('gallery-main'); 5297 const productListItem = document.querySelector(`.product-item-photo[href="${url}"]`); 5298 const targetElement = productListItem || productGallery; 5299 5300 if (targetElement) { 5301 targetElement.style.viewTransitionName = 'view-transition-to-gallery'; 5302 5303 await promise; 5304 targetElement.style.viewTransitionName = ''; 5305 } 5306 }; 5307 5308 const getViewTransitionToGalleryPageIsProduct = () => { 5309 return document.body.classList.contains('catalog-product-view') ? 'product-page' : 'other' 5310 } 5311 5312 window.addEventListener('pageswap', async (e) => { 5313 if (!e.viewTransition) return; 5314 const pageType = getViewTransitionToGalleryPageIsProduct(); 5315 const target = new URL(e.activation.entry.url); 5316 5317 sessionStorage.setItem(viewTransitionToGalleryPageStorage, pageType); 5318 setTransitionNameBetweenGallery(target.href, e.viewTransition.finished); 5319 }); 5320 5321 window.addEventListener('pagereveal', async (e) => { 5322 if (!e.viewTransition || (window.navigation && !window.navigation.activation.from)) return; 5323 const previousPageType = sessionStorage.getItem(viewTransitionToGalleryPageStorage); 5324 const pageType = getViewTransitionToGalleryPageIsProduct(); 5325 sessionStorage.removeItem(viewTransitionToGalleryPageStorage); 5326 5327 if (previousPageType === pageType) return; 5328 const target = new URL(window.navigation.activation.from.url); 5329 setTransitionNameBetweenGallery(target.href, e.viewTransition.ready); 5330 }); 5331</script>
vendor: 1 bytes, line 5331
5331
5332<script> 5333 (function () { 5334 let amSplideProcessed = false; 5335 5336 window.addEventListener('load-amsplide', () => { 5337 if (amSplideProcessed) { 5338 window?.Splide && window.dispatchEvent(new CustomEvent('amsplide-loaded', {})); 5339 return; 5340 } 5341 5342 const script = document.createElement('script'); 5343 script.src = 'https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB/Amasty_LibSplideJs/4.1.3/js/splide/splide.min.js'; 5344 script.async = true; 5345 document.body.appendChild(script); 5346 5347 amSplideProcessed = true; 5348 5349 script.onload = () => { 5350 window.dispatchEvent(new CustomEvent('amsplide-loaded', {})); 5351 } 5352 5353 const stylesHref = 'https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB/Amasty_LibSplideJs/4.1.3/css/splide/splide.min.css'; 5354 5355 if (document.querySelector(`link[href="${stylesHref}"]`)) { 5356 return; 5357 } 5358 5359 const styles = document.createElement('link'); 5360 styles.rel = 'stylesheet'; 5361 styles.type = 'text/css'; 5362 styles.href = stylesHref; 5363 5364 document.head.appendChild(styles); 5365 }); 5366 }());</script>
vendor: 1 bytes, line 5366
5366
5367<script>"use strict";"object"!=typeof window.MageMe&&(window.MageMe={}),window.MageMe.loader={addScript:(e,r,d)=>{if(!window[e]){let d=[];window[e]={"-isLoading":e=>d.push(e)};var t=document.createElement("script");t.src=r,t.onload=()=>{d.map(e=>e()),d=[]},document.head.append(t)}window[e]["-isLoading"]&&window[e]["-isLoading"](()=>MageMe.loader.addScript(e,r,d)),!window[e]["-isLoading"]&&d&&d()},addScriptWoCb:e=>{var d;document.querySelector('script[src="'+e+'"]')||((d=document.createElement("script")).src=e,document.head.append(d))},addCss:e=>{var d;document.querySelector('link[href="'+e+'"]')||((d=document.createElement("link")).rel="stylesheet",d.href=e,document.head.appendChild(d))},addCssOrdered:(e,d)=>{var r;document.querySelector('link[href="'+e+'"]')||(d=(d=Number(d))||0,(r=document.createElement("link")).rel="stylesheet",r.href=e,r.setAttribute("data-mm-order",d),(e=Array.from(document.head.querySelectorAll("[data-mm-order]")).filter(e=>Number(e.dataset.mmOrder)>d)).length?document.head.insertBefore(r,e[0]):document.head.appendChild(r))}};</script>
vendor: 1 bytes, line 5367
5367
5368<script> 5369 'use strict'; 5370 (function(webfroms) { 5371 const formValidationRules = { 5372 required(value, options, field, context) { 5373 const el = field.element.type === 'hidden' ? createTextInputFrom(field.element) : field.element, 5374 msg = 'This\u0020is\u0020a\u0020required\u0020field.'; 5375 5376 if (el.type === 'radio' || el.type === 'checkbox') { 5377 return (value === undefined || value.length === 0) ? msg : true; 5378 } 5379 5380 el.setAttribute('required', ''); 5381 el.checkValidity(); 5382 5383 return el.validity.valueMissing ? msg : true; 5384 }, 5385 maxlength(value, options, field, context) { 5386 const n = Number(options) 5387 if (value.length > n) { 5388 return n === 1 5389 ? strf('Please\u0020enter\u0020no\u0020more\u0020than\u00201\u0020character.') 5390 : strf('Please\u0020enter\u0020no\u0020more\u0020than\u0020\u00250\u0020characters.', options) 5391 } 5392 return true; 5393 }, 5394 minlength(value, options, field, context) { 5395 const n = Number(options) 5396 if (value.length > 0 && value.length < n) { 5397 return n === 1 5398 ? strf('Please\u0020enter\u0020at\u0020least\u00201\u0020character.') 5399 : strf('Please\u0020enter\u0020at\u0020least\u0020\u00250\u0020characters.', options) 5400 } 5401 return true; 5402 }, 5403 max(value, options, field, context) { 5404 field.element.setAttribute('max', options); 5405 field.element.checkValidity(); 5406 if (field.element.validity.rangeOverflow) { 5407 return strf('Please\u0020enter\u0020a\u0020value\u0020less\u0020than\u0020or\u0020equal\u0020to\u0020\u0022\u00250\u0022.', options); 5408 } 5409 return true; 5410 }, 5411 min(value, options, field, context) { 5412 field.element.setAttribute('min', options); 5413 field.element.checkValidity(); 5414 if (field.element.validity.rangeUnderflow) { 5415 return strf('Please\u0020enter\u0020a\u0020value\u0020greater\u0020than\u0020or\u0020equal\u0020to\u0020\u0022\u00250\u0022.', options); 5416 } 5417 return true; 5418 }, 5419 step(value, options, field, context) { 5420 field.element.setAttribute('step', options); 5421 field.element.checkValidity(); 5422 if (field.element.validity.stepMismatch) { 5423 const val = Number(value); 5424 const step = Number(options); 5425 const msg = 'Please\u0020enter\u0020a\u0020valid\u0020value.\u0020The\u0020two\u0020nearest\u0020valid\u0020values\u0020are\u0020\u0022\u00250\u0022\u0020and\u0020\u0022\u00251\u0022.'; 5426 return strf(msg, Math.floor(val / step) * step, Math.ceil(val / step) * step); 5427 } 5428 return true; 5429 }, 5430 pattern(value, options, field, context) { 5431 field.element.setAttribute('pattern', options); 5432 field.element.checkValidity(); 5433 if (field.element.validity.patternMismatch) { 5434 return field.element.title 5435 ? strf('Please\u0020match\u0020the\u0020requested\u0020format\u003A\u0020\u00250.', field.element.title) 5436 : 'Please\u0020match\u0020the\u0020requested\u0020format.' 5437 } 5438 return true; 5439 }, 5440 email(value, options, field, context) { 5441 const rule = /^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i; 5442 if (value.length > 0 && !rule.test(value)) { 5443 return 'Please\u0020enter\u0020a\u0020valid\u0020email\u0020address.'; 5444 } 5445 return true; 5446 }, 5447 password(value, options, field, context) { 5448 const rule = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/; 5449 if (value.length > 0 && !rule.test(value)) { 5450 return 'Please\u0020provide\u0020at\u0020least\u0020one\u0020upper\u0020case,\u0020one\u0020lower\u0020case,\u0020one\u0020digit\u0020and\u0020one\u0020special\u0020character\u0020\u0028\u0023\u003F\u0021\u0040\u0024\u0025\u005E\u0026\u002A\u002D\u0029'; 5451 } 5452 return true; 5453 }, 5454 equalTo(value, options, field, context) { 5455 const dependencyField = context.fields[options].element; 5456 if (value !== dependencyField.value) { 5457 const dependencyFieldName = 5458 dependencyField.label || 5459 dependencyField.title || 5460 (dependencyField.labels && dependencyField.labels[0] && dependencyField.labels[0].innerText) || 5461 dependencyField.name; 5462 return strf('This\u0020field\u0020value\u0020must\u0020be\u0020the\u0020same\u0020as\u0020\u0022\u00250\u0022.', dependencyFieldName); 5463 } 5464 return true; 5465 } 5466 }; 5467 5468 function raceSome(promises, pred) { 5469 return new Promise((resolve, reject) => { 5470 5471 if (promises.length === 0) { 5472 return resolve(); 5473 } 5474 5475 let settled = false, nDone = 0; 5476 5477 const resolveIf = v => { 5478 if (!settled && (pred(v) || ++nDone === promises.length)) { 5479 settled = true; 5480 resolve(v); 5481 } 5482 return v; 5483 } 5484 5485 promises.map(promise => {
5486 promise.then(resolveIf).catch(reason => { 5487 settled = true; 5488 reject(reason) 5489 }); 5490 return promise; 5491 }); 5492 }); 5493 } 5494 5495 const INPUT_ATTRIBUTE_RULES = {min: 'min', max: 'max', required: 'required', minlength: 'minlength', maxlength: 'maxlength', step: 'step', pattern: 'pattern'} 5496 const INPUT_TYPE_RULES = {email: 'email'} 5497 5498 function getRules(element) { 5499 let rules = {}; 5500 Object.keys(INPUT_ATTRIBUTE_RULES).forEach(attrName => { 5501 if (element.hasAttribute(attrName)) { 5502 rules[INPUT_ATTRIBUTE_RULES[attrName]] = element.getAttribute(attrName); 5503 } 5504 }) 5505 if (INPUT_TYPE_RULES[element.type]) { 5506 rules[INPUT_TYPE_RULES[element.type]] = true; 5507 } 5508 5509 if (element.dataset.validate) { 5510 try { 5511 const validateRulesStr = element.dataset.validate.replace(/'/g,"\""); 5512 Object.assign(rules, JSON.parse(validateRulesStr)); 5513 } catch (error) { 5514 console.error('Validator error. Cannot parse data-validate attribute of element:\n', element); 5515 } 5516 } 5517 5518 return rules; 5519 } 5520 5521 function isInvalidRuleResult(ruleState) { 5522 return typeof ruleState === 'string' || !ruleState || (ruleState.type && ruleState.content); 5523 } 5524 5525 async function runValidateFn(rule, options, value, field) { 5526 return formValidationRules[rule](value, options, field, this); 5527 } 5528 5529 function generateId() { 5530 let id; 5531 do { 5532 id = `${this.idPrefix}-${++this.idSeq}`; 5533 } while (document.getElementById(id)); 5534 return id; 5535 } 5536 5537 function isVisible(element) { 5538 const el = element.type !== 'hidden' ? element : (element.parentElement || {}); 5539 return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length) 5540 } 5541 5542 function elementWillValidate(element) { 5543 return (element.willValidate || element.type === 'hidden') 5544 && element.tagName !== 'BUTTON' 5545 && element.disabled === false 5546 && !(element.tagName === 'INPUT' && element.type === 'submit') 5547 && (element.hasAttribute('data-validate-hidden') 5548 || element.classList.contains('validate-hidden') 5549 || isVisible(element)) 5550 } 5551 5552 function createMessageContainer(el, fieldWrapperClassName) { 5553 if (! el.parentElement) { 5554 return; 5555 } 5556 const refocus = document.activeElement === el; 5557 const wrapper = document.createElement('div'); 5558 wrapper.classList.add.apply(wrapper.classList, fieldWrapperClassName.split(' ')); 5559 el.parentElement.insertBefore(wrapper, el); 5560 wrapper.appendChild(el); 5561 refocus && document.activeElement !== el && el.focus(); 5562 return wrapper; 5563 } 5564 5565 function containerNotFound(selector, el) { 5566 const msg = `Cannot find message container element ${selector} of ${el.name}`; 5567 console.error(msg, el); 5568 throw msg; 5569 } 5570 5571 function createTextInputFrom(el) { 5572 const text = document.createElement('INPUT'); 5573 text.type = 'text'; 5574 text.value = el.value; 5575 return text; 5576 } 5577 5578 function classNamesToSelector(classNames) { 5579 return classNames.split(' ') 5580 .filter(className => className.length > 0) 5581 .map(className => `.${className}`) 5582 .join('') 5583 } 5584 5585 function hasMessagesWrapper(field, messagesWrapperClassName) { 5586 return this.getMessageContainer(field).querySelector(classNamesToSelector(messagesWrapperClassName)); 5587 } 5588 5589 function getMessagesWrapper(field, messagesWrapperClassName) { 5590 if (hasMessagesWrapper.call(this, field, messagesWrapperClassName)) { 5591 return this.getMessageContainer(field).querySelector(classNamesToSelector(messagesWrapperClassName)); 5592 } 5593 5594 const msgWrapper = document.createElement('ul'); 5595 const msgId = generateId.call(this); 5596 msgWrapper.id = msgId; 5597 field.element.setAttribute('aria-errormessage', msgId); 5598 field.element.setAttribute('aria-describedby', msgId); 5599 msgWrapper.classList.add.apply(msgWrapper.classList, messagesWrapperClassName.split(' ')); 5600 if (field.validateOnChange) { 5601 msgWrapper.setAttribute('aria-live', 'polite'); 5602 } 5603 this.getMessageContainer(field).appendChild(msgWrapper); 5604 5605 return msgWrapper; 5606 } 5607 5608 function getCheckedValues(field) { 5609 const name = field.element.name.replace(/([\\"])/g, '\\$1'); 5610 const elements = field.element.form.querySelectorAll('input[name="' + name + '"]:checked'); 5611 return Array.from(elements).map(el => el.value); 5612 } 5613 5614 function escapeHtml(s) { 5615 const div = document.createElement('div') 5616 div.innerText = s; 5617 return div.innerHTML; 5618 } 5619 5620 function str(string) { 5621 const args = Array.from(arguments); 5622 args.splice(1, 0, 1); 5623 5624 return formatStr.apply(undefined, args); 5625 } 5626 5627 function strf() { 5628 const args = Array.from(arguments); 5629 args.splice(1, 0, 0); 5630 5631 return formatStr.apply(undefined, args); 5632 } 5633 5634 const formatStr = function (str, nStart) { 5635 const args = Array.from(arguments).slice(2); 5636 5637 return str.replace(/(%+)([0-9]+)/g, (m, p, n) => { 5638 const idx = parseInt(n) - nStart; 5639 5640 if (args[idx] === null || args[idx] === void 0) { 5641 return m; 5642 } 5643 return p.length % 2 5644 ? p.slice(0, -1).replace('%%', '%') + args[idx] 5645 : p.replace('%%', '%') + n; 5646 }) 5647 } 5648 5649 function formValidation(form, options = {}) { 5650 const formElement = form || this.$el; 5651 5652 if (formElement.dataset && formElement.dataset.options) { 5653 try { 5654 options = Object.assign(options, JSON.parse(formElement.dataset.options || '{}')); 5655 } catch (e) { 5656 throw new Error('Cannot read the form options from the data-options attribute: not val
5656id JSON'); 5657 } 5658 } 5659 5660 5661 if (formElement.tagName === 'FORM') { 5662 formElement.setAttribute('novalidate', ''); 5663 } else { 5664 console.error('formValidation can be initialized only on FORM element', formElement); 5665 return; 5666 } 5667 5668 options = Object.assign({ 5669 fieldWrapperClassName: 'field field-reserved', 5670 messagesWrapperClassName: 'messages', 5671 validClassName: 'field-success', 5672 invalidClassName: 'field-error', 5673 pageMessagesWrapperSelector: null, 5674 scrollToFirstError: true, 5675 }, options || {}); 5676 5677 return { 5678 state: { 5679 valid: false, 5680 }, 5681 fields: {}, 5682 idSeq: 0, 5683 idPrefix: formElement.id || 'vld-msg', 5684 setupFields(elements) { 5685 this.fields = {}; 5686 Array.from(elements).forEach(element => { 5687 if (elementWillValidate(element)) { 5688 this.setupField(element); 5689 } 5690 }); 5691 }, 5692 setupField(element) { 5693 if (! element) return; 5694 const onChange = !!element.dataset.onChange; 5695 if (elementWillValidate(element)) { 5696 const rules = getRules(element); 5697 if (Object.keys(rules).length > 0) { 5698 if (this.fields[element.name]) { 5699 Object.assign(this.fields[element.name].rules, rules); 5700 } else { 5701 this.fields[element.name] = { 5702 element, 5703 rules: rules, 5704 validateOnChange: onChange, 5705 state: { 5706 valid: null, 5707 rules: {} 5708 } 5709 } 5710 } 5711 } 5712 } else { 5713 console.error('Element will not validate', element); 5714 } 5715 }, 5716 onSubmit(event) { 5717 if (event.target.tagName === 'FORM') { 5718 event.preventDefault(); 5719 5720 this.validate() 5721 .then(() => event.target.submit()) 5722 .catch(invalidElements => {}); 5723 } 5724 }, 5725 onChange(event) { 5726 event.target.dataset.onChange = 'true'; 5727 if (!Object.keys(this.fields).length) { 5728 this.setupFields(formElement.elements); 5729 } 5730 if (!Object.keys(this.fields).includes(event.target.name)) { 5731 this.setupField(event.target); 5732 } 5733 const field = this.fields[event.target.name]; 5734 5735 this.validateField(field); 5736 field && field.element.removeAttribute('data-on-change') 5737 }, 5738 validateSafe() { 5739 return new Promise(resolve => this.validate().then(() => resolve(true)).catch(() => {})) 5740 }, 5741 validate() { 5742 if (!Object.keys(this.fields).length || !Object.keys(this.fields).length !== formElement.elements.length) { 5743 this.setupFields(formElement.elements); 5744 } 5745 return new Promise(async (resolve, reject) => { 5746 if (formElement.elements) { 5747 await raceSome(this.validateFields(), result => result !== true) 5748 const invalidFields = Object.values(this.fields).filter(field => !field.state.valid); 5749 this.state.valid = invalidFields.length === 0; 5750 if (this.state.valid) { 5751 resolve(); 5752 } else { 5753 if (options.scrollToFirstError && invalidFields.length > 0) { 5754 5755 5756 if (invalidFields[0].element.classList.contains('validate-hidden')) { 5757 const uid = invalidFields[0].element.dataset.uid; 5758 if (uid) { 5759 const parent = document.querySelector("#field_" + uid); 5760 if (parent) { 5761 parent.scrollIntoView(); 5762 } 5763 } 5764 } 5765 invalidFields[0].element.focus() 5766 invalidFields[0].element.select && invalidFields[0].element.select(); 5767 } 5768 reject(invalidFields.map(field => field.element)); 5769 } 5770 } 5771 }); 5772 }, 5773 validateFields() { 5774 const fields = Object.values(this.fields); 5775 5776 fields.forEach(field => { 5777 this.getMessageContainer(field).classList.remove(options.validClassName, options.invalidClassName) 5778 }); 5779 return fields.map(field => this.validateField(field)) 5780 }, 5781 validateField(field) { 5782 if (! field || ! elementWillValidate(field.element)) { 5783 return new Promise(resolve => resolve(true)) 5784 } 5785 5786 const uid = field.element.dataset.uid; 5787 if (uid) { 5788 const parent = document.querySelector("#field_" + uid); 5789 if (parent) { 5790 if (window.getComputedStyle(parent).display == 'none') { 5791 field.state.valid = true; 5792 return new Promise(resolve => resolve(true)); 5793 } 5794 } 5795 } 5796 5797 let value; 5798 if (field.element.type === 'checkbox') { 5799 value = getCheckedValues(field); 5800 } else if (field.element.type === 'radio') { 5801 value = getCheckedValues(field)[0] || undefined; 5802 } else if (field.element.tagName === 'SELECT' && field.element.multiple) { 5803 value = Array.from(field.element.selectedOptions).map(opt => opt.value); 5804 } else { 5805 value = field.element.value; 5806 } 5807 5808 const rules = field.rules || {}; 5809 5810 field.state.valid = true;
5811 this.showFieldState(field); 5812 5813 const fieldValidations = Object.keys(rules).filter(rule => formValidationRules[rule]).map(async rule => { 5814 return runValidateFn.call(this, rule, rules[rule], value, field).then(result => { 5815 field.state.rules[rule] = result; 5816 return result; 5817 }) 5818 }); 5819 5820 return new Promise(resolve => { 5821 Promise.all(fieldValidations).then(results => { 5822 field.state.valid = !elementWillValidate(field.element) || rules.length === 0 || !results.some(isInvalidRuleResult) 5823 this.showFieldState(field); 5824 resolve(field.state.valid); 5825 }) 5826 }); 5827 }, 5828 getMessagesByField(field) { 5829 const messages = []; 5830 const invalidRules = Object.keys(field.state.rules).filter(rule => isInvalidRuleResult(field.state.rules[rule])); 5831 5832 field.rules && Object.keys(field.rules).forEach((rule) => { 5833 if (invalidRules.includes(rule)) { 5834 const customMessage = field.element.getAttribute('data-msg-' + rule); 5835 const message = customMessage ? customMessage : field.state.rules[rule]; 5836 const ruleOptions = JSON.parse(JSON.stringify(field.rules[rule])); 5837 5838 if (typeof message === 'undefined' || message === null || (typeof message !== 'string' && ! message.type)) { 5839 messages.push(strf('Validation rule "%0" failed.', rule)); 5840 } else if (Array.isArray(ruleOptions)) { 5841 ruleOptions.unshift(message.type ? message.content : message); 5842 const content = strf.apply(null, ruleOptions); 5843 messages.push(message.type ? {type: message.type, content} : content); 5844 } else { 5845 const content = strf(message.type ? message.content : message, ruleOptions) 5846 messages.push(message.type ? {type: message.type, content} : content); 5847 } 5848 } 5849 }); 5850 return messages; 5851 }, 5852 /** @deprecated */ 5853 getFieldWrapper(field) { 5854 return this.getMessageContainer(field) 5855 }, 5856 getMessageContainer(field) { 5857 let container; 5858 const pageSelector = field.element.getAttribute('data-validation-container') || options.pageMessagesContainerSelector; 5859 if (pageSelector) { 5860 container = document.querySelector(pageSelector) 5861 || containerNotFound(pageSelector, field.element) 5862 } else { 5863 const containerSelector = classNamesToSelector(options.fieldWrapperClassName); 5864 container = field.element.closest(containerSelector) 5865 || createMessageContainer(field.element, options.fieldWrapperClassName) 5866 || containerNotFound(containerSelector, field.element); 5867 } 5868 5869 return container; 5870 }, 5871 showFieldState(field) { 5872 const container = this.getMessageContainer(field), 5873 hasErrorMessages = hasMessagesWrapper.call(this, field, options.messagesWrapperClassName), 5874 messages = this.getMessagesByField(field).map(m => { 5875 return m.type !== 'html' ? escapeHtml(m.type ? m.content : m) : m.content; 5876 }); 5877 container.classList.toggle(options.validClassName, field.state.valid && ! hasErrorMessages); 5878 container.classList.toggle(options.invalidClassName, !field.state.valid || hasErrorMessages); 5879 this.createHtmlErrorMessage(field, messages); 5880 5881 if (field.state.valid) { 5882 field.element.removeAttribute('aria-invalid'); 5883 } else { 5884 field.element.setAttribute('aria-invalid', 'true'); 5885 if (! document.activeElement) { 5886 field.element.focus(); 5887 } 5888 } 5889 }, 5890 removeMessages(field, messagesClass) { 5891 if (! hasMessagesWrapper.call(this, field, messagesClass || options.messagesWrapperClassName)) { 5892 return; 5893 } 5894 5895 const msgWrapper = getMessagesWrapper.call(this, field, messagesClass || options.messagesWrapperClassName); 5896 const messages = msgWrapper.querySelectorAll(`[data-msg-field='${field.element.name}']`);
5897 Array.from(messages).forEach(msg => msg.remove()); 5898 if (msgWrapper && msgWrapper.childElementCount === 0) { 5899 field.element.removeAttribute('aria-errormessage'); 5900 field.element.removeAttribute('aria-describedby'); 5901 msgWrapper.remove(); 5902 } 5903 }, 5904 createErrorMessage(field, messages) { 5905 const htmlMessages = (Array.isArray(messages) ? messages : [messages]).map(escapeHtml) 5906 this.createHtmlErrorMessage(field, htmlMessages); 5907 }, 5908 createHtmlErrorMessage(field, messages) { 5909 this.removeMessages(field, options.messagesWrapperClassName); 5910 field.element.removeAttribute('aria-errormessage'); 5911 field.element.removeAttribute('aria-describedby'); 5912 5913 if (!field.state.valid) { 5914 const msgWrapper = this.addHtmlMessages(field, options.messagesWrapperClassName, messages); 5915 field.element.setAttribute('aria-errormessage', msgWrapper.id); 5916 field.element.setAttribute('aria-describedby', msgWrapper.id); 5917 } 5918 }, 5919 /** @deprecated */ 5920 createMessage(field, message) { 5921 return this.addMessages(field, options.messagesWrapperClassName, message); 5922 }, 5923 addMessages(field, messagesClass, messages) { 5924 const htmlMessages = (Array.isArray(messages) ? messages : [messages]).map(escapeHtml) 5925 return this.addHtmlMessages(field, messagesClass, htmlMessages); 5926 }, 5927 addHtmlMessages(field, messagesClass, htmlMessages) { 5928 const msgWrapper = getMessagesWrapper.call(this, field, messagesClass); 5929 5930 (Array.isArray(htmlMessages) ? htmlMessages : [htmlMessages]).forEach((htmlMessage) => { 5931 const li = document.createElement('li'); 5932 li.innerHTML = htmlMessage; 5933 li.setAttribute('data-msg-field', field.element.name); 5934 msgWrapper.appendChild(li); 5935 }); 5936 5937 return msgWrapper; 5938 }, 5939 setField(name, value) { 5940 this.fields[name].element.value = value; 5941 this.fields[name].element.dispatchEvent((new Event('input'))); 5942 this.validateField(this.fields[name]); 5943 } 5944 } 5945 } 5946 5947 webfroms.formValidation = formValidation; 5948 webfroms.formValidation.rules = formValidationRules; 5949 webfroms.formValidation.setInputAttributeRuleName = (attrName, ruleName) => INPUT_ATTRIBUTE_RULES[attrName] = ruleName || attrName; 5950 webfroms.formValidation.setInputTypeRuleName = (typeName, ruleName) => INPUT_TYPE_RULES[typeName] = ruleName || typeName; 5951 webfroms.formValidation.addRule = (name, validator) => formValidationRules[name] = validator; 5952 5953 5954 webfroms.formValidation.addRule('dateFromTo', (value, options, field, context) => { 5955 const dateFrom = field.element; 5956 const dateTo = document.getElementById(options); 5957 5958 if (!field || !options || isNaN(dateFrom.valueAsNumber) || isNaN(dateTo.valueAsNumber)) { 5959 return true; 5960 } 5961 5962 const valid = dateFrom.valueAsNumber <= dateTo.valueAsNumber; 5963 5964 return !valid ? 'The\u0020\u0027From\u0027\u0020date\u0020must\u0020precede\u0020the\u0020\u0027To\u0027\u0020date.' : true; 5965 }); 5966 5967 5968 webfroms.formValidation.setInputAttributeRuleName('accept', 'file-type'); webfroms.formValidation.addRule('file-type', function (value, options, field, context) { 5969 if (field.element.type !== 'file' || !field.element.files.length || !field.element.accept) { 5970 return true; 5971 } 5972 5973 for (const file of Object.values(field.element.files)) { 5974 const allowedFileTypesArray = field.element.accept.split(','); 5975 const filenameSplit = file.name.split('.');
5976 const fileExtension = `.${filenameSplit[filenameSplit.length - 1]}`; 5977 5978 if (!allowedFileTypesArray.includes(fileExtension)) { 5979 return `${str('\u0022\u00251\u0022\u0020is\u0020not\u0020a\u0020valid\u0020file\u0020extension.', fileExtension)} Allowed\u0020file\u0020types: ${field.element.accept}`; 5980 } 5981 } 5982 5983 return true; 5984 }); 5985 5986 webfroms.formValidation.addRule('file-max-size', function (value, options, field, context) { 5987 if (!field.element.files.length || !options) { 5988 return true; 5989 } 5990 5991 for (const file of Object.values(field.element.files)) { 5992 const maxFileSize = options; 5993 5994 if (file.size > maxFileSize) { 5995 const maxSizeMb = maxFileSize / (1024 * 1024); 5996 return `Maximum\u0020file\u0020size: ${maxSizeMb} MB.`; 5997 } 5998 } 5999 6000 return true; 6001 }); 6002 6003 webfroms.formValidation.addRule('image-max-dimensions', async function (value, options, field, context) { 6004 if (!field.element.files.length) { 6005 return true; 6006 } 6007 6008 const {width: maxWidth, height: maxHeight} = options; 6009 6010 if ((!maxWidth && !maxHeight) || (maxWidth === 0 && maxHeight === 0)) { 6011 return true; } 6012 6013 try { 6014 const dimensions = await new Promise((resolve, reject) => { 6015 const reader = new FileReader(); 6016 reader.onload = function (e) { 6017 const img = new Image(); 6018 6019 img.onload = function () { 6020 resolve({ 6021 width: this.width, 6022 height: this.height 6023 }); 6024 }; 6025 6026 img.onerror = function (e) { 6027 reject(new Error('Failed to load the image.')); 6028 }; 6029 6030 img.src = e.target.result; 6031 }; 6032 6033 reader.onerror = function (e) { 6034 reject(new Error('Failed to read the file.')); 6035 }; 6036 6037 reader.readAsDataURL(field.element.files[0]); 6038 }); 6039 6040 const errorMessages = []; 6041 if (maxWidth && dimensions.width > maxWidth) { 6042 errorMessages.push( 6043 str( 6044 '\u0022\u00251\u0022\u0020width\u0020exceeds\u0020allowed\u0020value\u0020of\u0020\u00252\u0020px.', 6045 `${dimensions.width} px`, 6046 maxWidth 6047 ) 6048 ); 6049 } 6050 if (maxHeight && dimensions.height > maxHeight) { 6051 errorMessages.push( 6052 str( 6053 '\u0022\u00251\u0022\u0020height\u0020exceeds\u0020allowed\u0020value\u0020of\u0020\u00252\u0020px.', 6054 `${dimensions.height} px`, 6055 maxHeight 6056 ) 6057 ); 6058 } 6059 6060 if (errorMessages.length > 0) { 6061 return errorMessages.join(' '); 6062 } 6063 6064 return true; 6065 } catch (error) { 6066 console.error('Error:', error); 6067 return false; 6068 } 6069 }); 6070 6071 6072 webfroms.formValidation.addRule('alpha', function (value, options, field, context) { 6073 const rule = /^[a-zA-Z]+$/; 6074 if (value.length > 0 && !rule.test(value)) { 6075 return 'Please\u0020use\u0020letters\u0020only\u0020\u0028a\u002Dz\u0020or\u0020A\u002DZ\u0029\u0020in\u0020this\u0020field.'; 6076 } 6077 6078 return true; 6079 }); 6080 6081 webfroms.formValidation.addRule('alphanum', function (value, options, field, context) { 6082 const rule = /^[a-zA-Z0-9]+$/; 6083 if (value.length > 0 && !rule.test(value)) { 6084 return 'Please\u0020use\u0020only\u0020letters\u0020\u0028a\u002Dz\u0020or\u0020A\u002DZ\u0029\u0020
6084or\u0020numbers\u0020\u00280\u002D9\u0029\u0020in\u0020this\u0020field.\u0020No\u0020spaces\u0020or\u0020other\u0020characters\u0020are\u0020allowed.'; 6085 } 6086 6087 return true; 6088 }); 6089 6090 webfroms.formValidation.addRule('alphanum-with-spaces', function (value, options, field, context) { 6091 const rule = /^[a-zA-Z0-9 ]+$/; 6092 if (value.length > 0 && !rule.test(value)) { 6093 return 'Please\u0020use\u0020only\u0020letters\u0020\u0028a\u002Dz\u0020or\u0020A\u002DZ\u0029,\u0020numbers\u0020\u00280\u002D9\u0029\u0020or\u0020spaces\u0020only\u0020in\u0020this\u0020field.'; 6094 } 6095 6096 return true; 6097 }); 6098 6099 webfroms.formValidation.setInputTypeRuleName('url'); webfroms.formValidation.addRule('url', function (value, options, field, context) { 6100 const rule = /^(http|https|ftp):\/\/(([A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))(\.[A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))*)(:(\d+))?(\/[A-Z0-9~](([A-Z0-9_~-]|\.)*[A-Z0-9~]|))*\/?(.*)?$/i; 6101 if (value.length > 0 && !rule.test(value)) { 6102 return 'Please\u0020enter\u0020a\u0020valid\u0020URL.'; 6103 } 6104 6105 return true; 6106 }); 6107 6108 6109 webfroms.formValidation.addRule('minMax', (value, options, field, context) => { 6110 const min = field.element; 6111 const max = document.getElementById(options); 6112 6113 if (!min || !max || min.value === '' || max.value === '') { 6114 return true; 6115 } 6116 6117 const valid = !(Number(min.value) > Number(max.value)); 6118 6119 return !valid ? 'The\u0020\u0027Min\u0027\u0020value\u0020must\u0020be\u0020lower\u0020than\u0020the\u0020\u0027Max\u0027\u0020value.' : true; 6120 }); 6121 }((() => { 6122 if (!window.MageMe) window.MageMe = {}; 6123 if (!window.MageMe.WebForms) window.MageMe.WebForms = {} 6124 return window.MageMe.WebForms 6125 })()));</script>
vendor: 1 bytes, line 6125
6125
6126<script id="mm_validation"> 6127 'use strict'; 6128 (() => { 6129 const messages = { 6130 "validate-match-value": "Please make sure your input matches the <i>%1</i>.", 6131 "required-dropzone-file": "Please select a file.", 6132 "validate-options-checkbox-min": "Please check at least %1 options", 6133 "validate-options-checkbox-max": "Please check not more than %1", 6134 "validate-length-min": "The minimum length for this field is %1 characters.", 6135 "validate-length-max": "The maximum length for this field is %1 characters.", 6136 "required-entry": "This is a required field.", 6137 "pattern": "Invalid format.", 6138 "validate-email": "Please enter a valid email address.", 6139 "validate-number": "Please enter a valid number in this field.", 6140 "validate-number-range": "The value is not within the specified range.", 6141 "validate-customer-password": "Minimum length of this field must be equal or greater than %1 symbols. Leading and trailing spaces will be ignored.", 6142 "validate-customer-password-cl": "Minimum of different classes of characters in password is %1. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.", 6143 "validate-select": "Please select an option.", 6144 "validate-one-required-by-name": "Please select one of the options.", 6145 "time": "Please enter a valid time, between 00:00 and 23:59", 6146 "validate-url": "Please enter a valid URL. Protocol is required (http://, https:// or ftp://).", 6147 }; 6148 6149 6150 MageMe.WebForms.formValidation.addRule( 6151 'validate-match-value', function (value, options, field, context) { 6152 const matchInputId = field.element.getAttribute('data-match-id'); 6153 let validateMessage = "Incorrect match validation data, please check validation rules."; 6154 if (!matchInputId) { 6155 return validateMessage; 6156 } 6157 const matchInput = document.getElementById(matchInputId); 6158 if (!matchInput) { 6159 return validateMessage; 6160 } 6161 const label = document.querySelector("label[for='" + matchInputId + "']"); 6162 const fieldLabel = label.value ? label.value : matchInput.getAttribute('placeholder'); 6163 validateMessage = messages["validate-match-value"].replace('%1', fieldLabel); 6164 return matchInput.value === value ? true : validateMessage; 6165 } 6166 ); 6167 MageMe.WebForms.formValidation.addRule( 6168 'validate-dropzone', function (value, options, field, context) { 6169 const uid = field.element.dataset.uid; 6170 if (!uid) { 6171 return messages["validate-dropzone"]; 6172 } 6173 return !document.getElementById('field' + uid + '_preview').querySelectorAll('.drop-zone-error').length ? 6174 true : messages["validate-dropzone"]; 6175 } 6176 ); 6177 MageMe.WebForms.formValidation.addRule( 6178 'validate-dropzone-required', function (value, options, field, context) { 6179 let result = false;
6180 const uid = field.element.dataset.uid; 6181 if (!uid) { 6182 return messages["validate-dropzone-required"]; 6183 } 6184 if (document.getElementById('field' + uid + '_preview').querySelectorAll('.drop-zone-preview-file').length) { 6185 result = true; 6186 } 6187 if (!result) { 6188 if (getDropzoneUploadedCount(uid)) { 6189 result = true; 6190 } 6191 } 6192 return result ? true : messages["validate-dropzone-required"]; 6193 } 6194 ); 6195 MageMe.WebForms.formValidation.addRule( 6196 'validate-dropzone-max-files', function (value, options, field, context) { 6197 const uid = field.element.dataset.uid, 6198 max = field.element.getAttribute('data-max-files'); 6199 if (!uid) { 6200 return messages["validate-dropzone-max-files"]; 6201 } 6202 if (!max) { 6203 return true; 6204 } 6205 const newFiles = document.getElementById('field' + uid + '_preview').querySelectorAll('.drop-zone-preview-file').length; 6206 const uploaded = getDropzoneUploadedCount(uid); 6207 return (newFiles + uploaded <= max) ? true : messages["validate-dropzone-max-files"]; 6208 } 6209 ); 6210 MageMe.WebForms.formValidation.addRule( 6211 'required-dropzone-file', function (value, options, field, context) { 6212 let result = isEmptyNoTrim(value), 6213 ovId, 6214 uid = field.element.dataset.uid; 6215 6216 if (!result) { 6217 ovId = document.getElementById(field.element.getAttribute('id') + '_value'); 6218 6219 if (ovId) { 6220 result = isEmptyNoTrim(ovId.value); 6221 } 6222 } 6223 6224 if (!result && uid) { 6225 if (getDropzoneUploadedCount(uid)) { 6226 result = true; 6227 } 6228 } 6229 6230 return result ? true : messages["required-dropzone-file"]; 6231 } 6232 ); 6233 MageMe.WebForms.formValidation.addRule( 6234 'validate-options-checkbox-min', 6235 function (value, options, field, context) { 6236 const uid = field.element.dataset.uid, 6237 count = parseInt(options); 6238 if (isNaN(count)) { 6239 return "Incorrect min value, please check validation rules."; 6240 } 6241 const counter = document.getElementById('field_'+uid).querySelectorAll('input:checked').length; 6242 return (counter === 0 || counter >= count) ? true : messages["validate-options-checkbox-min"].replace('%1', count); 6243 } 6244 ); 6245 MageMe.WebForms.formValidation.addRule( 6246 'validate-options-checkbox-max', 6247 function (value, options, field, context) { 6248 const uid = field.element.dataset.uid, 6249 count = parseInt(options); 6250 if (isNaN(count)) { 6251 return "Incorrect max value, please check validation rules."; 6252 } 6253 const counter = document.getElementById('field_'+uid).querySelectorAll('input:checked').length; 6254 return (counter === 0 || counter <= count) ? true : messages["validate-options-checkbox-max"].replace('%1', count); 6255 } 6256 ); 6257 MageMe.WebForms.formValidation.addRule( 6258 'validate-length-min', 6259 function (value, options, field, context) { 6260 const length = parseInt(options); 6261 if (isNaN(length)) { 6262 return "Incorrect min value, please check validation rules."; 6263 } 6264 if (length <= 0 || !value) { 6265 return true; 6266 } 6267 return value.length >= length ? true : messages["validate-length-min"].replace('%1', length); 6268 } 6269 ); 6270 MageMe.WebForms.formValidation.addRule( 6271 'validate-length-max', 6272 function (value, options, field, context) { 6273 const length = parseInt(options); 6274 if (isNaN(length)) { 6275 return "Incorrect max value, please check validation rules."; 6276 } 6277 if (!value) { 6278 return true; 6279 } 6280 return value.length <= length ? true : messages["validate-length-max"].replace('%1', length); 6281 } 6282 ); 6283 MageMe.WebForms.formValidation.addRule( 6284 'validate-intl-phone-number', 6285 function (value, options, field, context) { 6286 if (!window.intlTelInput) { 6287 return true; 6288 } 6289 if (!value) { 6290 return true; 6291 } 6292 const phone = window.intlTelInputGlobals.getInstance(field.element); 6293 return phone.isValidNumber() ? true : "Incorrect number."; 6294 } 6295 ); 6296 MageMe.WebForms.formValidation.addRule( 6297 'validate-input-mask-complete', 6298 function (value, options, field, context) { 6299 if (!window.Inputmask) { 6300 return true; 6301 } 6302 if (!value) { 6303 return true; 6304 } 6305 return field.element.inputmask.isComplete() ? true : "Incorrect value."; 6306 } 6307 ); 6308 MageMe.WebForms.formValidation.addRule( 6309 'mm-pattern', 6310 function (value, options, field, context) { 6311 const pattern = options; 6312 const flags = field.element.getAttribute('data-mm-pattern-flags') ?? ''; 6313 if (!value) { 6314 return true; 6315 } 6316 return new RegExp(pattern, flags).test(value) ? true : "Invalid format."; 6317 } 6318 ); 6319 6320 6321 6322 MageMe.WebForms.formValidation.addRule( 6323 'required-entry', function (value, options, field, context) { 6324 return !isEmpty(value) ? true : messages["required-entry"]; 6325 } 6326 ); 6327 MageMe.WebForms.formValidation.addRule( 6328 'pattern', function (value, options, field, context) { 6329 if (isEmptyNoTrim(value)) { 6330 return true; 6331 } 6332 return new RegExp(options).test(value) ? true : messages["pattern"]; 6333 } 6334 ); 6335 MageMe.WebForms.formValidation.addRule( 6336 'validate-email', function (value, options, field, context) { 6337 if (isEmptyNoTrim(value)) { 6338 return true; 6339 } 6340 return /^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i.test(value) ? 6341 true : messages["validate-email"]; 6342 6343 } 6344 ); 6345 MageMe.WebForms.formValidation.addRule( 6346 'validate-number', function (value, options, field, context) { 6347 if (isEmptyNoTrim(value)) { 6348 return true; 6349 } 6350 return (!isNaN(parseNumber(value)) && /^\s*-?\d*(\.\d*)?\s*$/.test(value)) ? true : messages["validate-number"]; 6351 6352 } 6353 ); 6354 MageMe.WebForms.formValidation.addRule( 6355 'validate-number-range', function (value, options, field, context) { 6356 let numValue, dataAttrRange, classNameRange, result, range, m, classes, ii; 6357 6358 if (isEmptyNoTrim(value)) { 6359 return true; 6360 } 6361 6362 numValue = parseNumber(value); 6363 6364 if (isNaN(numValue)) { 6365 return messages["validate-number-range"]; 6366 } 6367 6368 dataAttrRange = /^(-?[\d.,]+)?-(-?[\d.,]+)?$/; 6369 classNameRange = /^number-range-(-?[\d.,]+)?-(-?[\d.,]+)?$/; 6370 result = true; 6371 range = options; 6372 6373 if (typeof range === 'string') { 6374 m = dataAttrRange.exec(range); 6375 6376 if (m) { 6377 result = result && isBetween(numValue, m[1], m[2]); 6378 } else { 6379 result = false;
6380 } 6381 } else if (field.element && field.element.className) { 6382 classes = field.element.className.split(' '); 6383 ii = classes.length; 6384 6385 while (ii--) { 6386 range = classes[ii]; 6387 m = classNameRange.exec(range); 6388 6389 if (m) { 6390 result = result && isBetween(numValue, m[1], m[2]); 6391 break; 6392 } 6393 } 6394 } 6395 6396 return result ? true : messages["validate-number-range"]; 6397 } 6398 ); 6399 MageMe.WebForms.formValidation.addRule( 6400 'validate-customer-password', function (value, options, field, context) { 6401 let counter = 0; 6402 const passwordMinLength = field.element.getAttribute('data-password-min-length'), 6403 passwordMinCharacterSets = field.element.getAttribute('data-password-min-character-sets'), 6404 pass = value.trim(); 6405 6406 if (pass.length < passwordMinLength) { 6407 return messages["validate-customer-password"].replace('%1', passwordMinLength); 6408 } 6409 6410 if (pass.match(/\d+/)) { 6411 counter++; 6412 } 6413 6414 if (pass.match(/[a-z]+/)) { 6415 counter++; 6416 } 6417 6418 if (pass.match(/[A-Z]+/)) { 6419 counter++; 6420 } 6421 6422 if (pass.match(/[^a-zA-Z0-9]+/)) { 6423 counter++; 6424 } 6425 6426 if (counter < passwordMinCharacterSets) { 6427 return messages["validate-customer-password-cl"].replace('%1', passwordMinCharacterSets); 6428 } 6429 6430 return true; 6431 } 6432 ); 6433 MageMe.WebForms.formValidation.addRule( 6434 'validate-select', function (value, options, field, context) { 6435 return (value !== 'none' && value != null && value.length !== 0) ? true : messages["validate-select"]; 6436 } 6437 ); 6438 MageMe.WebForms.formValidation.addRule( 6439 'validate-one-required-by-name', function (value, options, field, context) { 6440 const name = field.element.name.replace(/([\\"])/g, '\\$1'); 6441 options = options === true ? 'input[name="' + name + '"]:checked' : options; 6442 return field.element.form.querySelectorAll(options).length ? true : messages["validate-one-required-by-name"]; 6443 } 6444 ); 6445 MageMe.WebForms.formValidation.addRule( 6446 'time', function (value, options, field, context) { 6447 if (isEmptyNoTrim(value)) { 6448 return true; 6449 } 6450 return /^([01]\d|2[0-3])(:[0-5]\d){0,2}$/.test(value) ? true : messages["time"]; 6451 } 6452 ); 6453 MageMe.WebForms.formValidation.addRule( 6454 'validate-url', function (value, options, field, context) { 6455 if (isEmptyNoTrim(value)) { 6456 return true; 6457 } 6458 value = (value || '').replace(/^\s+/, '').replace(/\s+$/, ''); 6459 6460 return (/^(http|https|ftp):\/\/(([A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))(\.[A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))*)(:(\d+))?(\/[A-Z0-9~](([A-Z0-9_~-]|\.)*[A-Z0-9~]|))*\/?(.*)?$/i).test(value) ? 6461 true : messages["validate-url"]; 6462 } 6463 ); 6464 6465 /** 6466 * Uploaded count 6467 * 6468 * @param uid - From uid 6469 * @returns {number} 6470 */ 6471 function getDropzoneUploadedCount(uid) { 6472 const selectAll = document.getElementById(uid + 'selectall'); 6473 if (selectAll && selectAll.checked) { 6474 return 0; 6475 } 6476 const filePool = document.getElementById(uid + 'filepool'); 6477 return filePool ? filePool.querySelectorAll("input[name^='delete_file_']:not(:checked)").length : 0; 6478 } 6479 6480 /** 6481 * Check if string is empty with trim. 6482 * 6483 * @param {String} value 6484 * @return {Boolean} 6485 */ 6486 function isEmpty(value) { 6487 return value === '' || value == null || value.length === 0 || /^\s+$/.test(value); 6488 } 6489 6490 /** 6491 * Check if string is empty no trim. 6492 * 6493 * @param {String} value 6494 * @return {Boolean} 6495 */ 6496 function isEmptyNoTrim(value) { 6497 return value === '' || value == null || value.length === 0; 6498 } 6499 6500 /** 6501 * Checks if {value} is between numbers {from} and {to}. 6502 * 6503 * @param {String} value 6504 * @param {String} from 6505 * @param {String} to 6506 * @return {Boolean} 6507 */ 6508 function isBetween(value, from, to) { 6509 return (from === null || from === '' || value >= parseNumber(from)) && 6510 (to === null || to === '' || value <= parseNumber(to)); 6511 } 6512 6513 /** 6514 * Parse price string. 6515 * 6516 * @param {String} value 6517 * @return {Number} 6518 */ 6519 function parseNumber(value) { 6520 let isDot, isComa; 6521 6522 if (typeof value !== 'string') { 6523 return parseFloat(value); 6524 } 6525 isDot = value.indexOf('.'); 6526 isComa = value.indexOf(','); 6527 6528 if (isDot !== -1 && isComa !== -1) { 6529 if (isComa > isDot) { 6530 value = value.replace('.', '').replace(',', '.'); 6531 } else { 6532 value = value.replace(',', ''); 6533 } 6534 } else if (isComa !== -1) { 6535 value = value.replace(',', '.'); 6536 } 6537 6538 return parseFloat(value); 6539 } 6540 6541 /** 6542 * Removes HTML tags and space characters, numbers and punctuation. 6543 * 6544 * @param {String} value - Value being stripped. 6545 * @return {String} 6546 */ 6547 function stripHtml(value) { 6548 return value.replace(/<.[^<>]*?>/g, ' ').replace(/ | /gi, ' ') 6549 .replace(/[0-9.(),;:!?%#$'"_+=\/-]*/g, ''); 6550 } 6551 6552 MageMe.WebForms.formValidation.utils = { 6553 getDropzoneUploadedCount: getDropzoneUploadedCount, 6554 isEmpty: isEmpty, 6555 isEmptyNoTrim: isEmptyNoTrim, 6556 isBetween: isBetween, 6557 parseNumber: parseNumber,
6558 stripHtml: stripHtml 6559 }; 6560 })();</script>
vendor: 1 bytes, line 6560
6560
6561<script> 6562 'use strict'; 6563 6564 (() => { 6565 if (typeof window.MageMe !== 'object') { 6566 window.MageMe = {}; 6567 } 6568 if (typeof window.MageMe.WebForms !== 'object') { 6569 window.MageMe.WebForms = {}; 6570 } 6571 window.MageMe.WebForms.loadValidation = () => { 6572 if (!document.getElementById("mm_validation")) { 6573 return fetch("https://www.banham.co.uk/webforms/form/validation/").then( 6574 response => response.text() 6575 ).then(html => { 6576 if (!document.getElementById("mm_validation")) 6577 document.head.append(document.createRange().createContextualFragment(html)); 6578 }); 6579 } else { 6580 return Promise.resolve(); 6581 } 6582 }; 6583 window.MageMe.WebForms.customerData = () => { 6584 return { 6585 customer: false, 6586 receiveCustomerData(data) { 6587 if (data.webforms) { 6588 this.customer = data.webforms; 6589 } 6590 }, 6591 } 6592 }; 6593 })();</script>
vendor: 1 bytes, line 6593
6593
6594<script> 6595 window.loqateFindUrl = "https:\/\/www.banham.co.uk\/loqate\/capture\/find\/"; 6596 window.loqateRetrieveUrl = "https:\/\/www.banham.co.uk\/loqate\/capture\/retrieve\/"; 6597</script>
vendor: 1 bytes, line 6597
6597
6598<script type="module"> 6599 6600 import { bbPCAForm } from 'https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB/Hyva_MageMeWebForms/js/alpine-components/bb-pca-form.js'; 6601 6602 if (!window.bbPCAFormRegistered) { 6603 console.log('Loading bbPCAForm component'); 6604 window.bbPCAFormRegistered = true; 6605 if (window.Alpine) { 6606 window.Alpine.data('bbPCAForm', bbPCAForm); 6607 } else { 6608 document.addEventListener('alpine:init', () => { 6609 window.Alpine.data('bbPCAForm', bbPCAForm); 6610 }); 6611 } 6612 } 6613</script>
vendor: 1 bytes, line 6613
6613
6614<script> 6615 'use strict'; 6616 (() => { 6617 document.querySelectorAll('input[name="field[1778][]"]').forEach((el) => { 6618 el.initValidation = function (form) { 6619 el.parentElement.parentElement.parentElement.addEventListener('focusout', (e) => { 6620 if ( 6621 e.relatedTarget !== e.currentTarget && 6622 !e.currentTarget.contains(e.relatedTarget) 6623 ) { 6624 form.validateField(el); 6625 } 6626 }); 6627 el.parentElement.parentElement.parentElement.tabIndex = -1; 6628 } 6629 }); 6630 })(); 6631</script>
vendor: 1 bytes, line 6631
6631
6632<script> 6633 function mmWebformsTextareaDatafieldfh3oTm8() { 6634 return Object.assign( 6635 MageMe.WebForms.customerData(), 6636 { 6637 setCustomerData(event) { 6638 this.receiveCustomerData(event.detail.data) 6639 if (this.$el) { 6640 this.$el.value = this.customer[this.$el.dataset.hyvacspCustomerData] ?? ''; 6641 } 6642 }, 6643 } 6644 ); 6645 } 6646 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsTextareaDatafieldfh3oTm8', mmWebformsTextareaDatafieldfh3oTm8), {once: true});</script>
vendor: 1 bytes, line 6646
6646
6647<script> 6648 function mmWebformsEmailDatafieldfh3oTm2() { 6649 return Object.assign( 6650 MageMe.WebForms.customerData(), 6651 { 6652 trimSpace() { 6653 if (this.$el.value.search(' ') >= 0) { 6654 this.$el.value =Â this.$el.value.replace(' ',''); 6655 } 6656 }, 6657 setCustomerData(event) { 6658 this.receiveCustomerData(event.detail.data) 6659 if (this.$el) { 6660 this.$el.value = this.customer['customer_email'] ?? ''; 6661 } 6662 }, 6663 } 6664 ); 6665 } 6666 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsEmailDatafieldfh3oTm2', mmWebformsEmailDatafieldfh3oTm2), {once: true});</script>
vendor: 1 bytes, line 6666
6666
6667<script> 6668 'use strict'; 6669 6670 (() => { 6671 if (!window.MageMe || !MageMe.loader) { 6672 return; 6673 } 6674 MageMe.loader.addCssOrdered( 6675 'https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB/Hyva_MageMeWebForms/css/field/datepicker.min.css', 6676 '40' 6677 ); 6678 MageMe.loader.addScript("Datepicker", 6679 "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fdatepicker.min.js", 6680 () => { 6681 const isPastDisabled = true; 6682 const isFutureDisabled = false; 6683 const isTodayDisabled = false; 6684 const isWeekNumbersShowed = false; 6685 const pastOffset = 0; 6686 const futureOffset = 0; 6687 const disabledWeekDays = [6,0]; 6688 const format = convertFormat('d/M/Y', 'date'); 6689 const today = new Date(); 6690 const elm = document.getElementById('fieldfh3oTm1032'); 6691 6692 let config = { 6693 autohide: true, 6694 datesDisabled: [], 6695 showWeekNumbers: isWeekNumbersShowed, 6696 daysOfWeekDisabled: [], 6697 weekStart: 1, 6698 format: format 6699 }; 6700 if (config.rtl) { 6701 $('#fieldfh3oTm1032_calendar').addClass('rtl'); 6702 } 6703 if (isPastDisabled) { 6704 config.minDate = new Date(); 6705 if (pastOffset) { 6706 config.minDate.setDate(config.minDate.getDate() + pastOffset) 6707 } 6708 } 6709 if (isFutureDisabled) { 6710 config.maxDate = new Date(); 6711 if (futureOffset) { 6712 config.maxDate.setDate(config.maxDate.getDate() + futureOffset) 6713 } 6714 } 6715 if (isTodayDisabled) { 6716 config.datesDisabled.push(today); 6717 } 6718 for (let i = 0; i < disabledWeekDays.length; i++) { 6719 config.daysOfWeekDisabled.push(disabledWeekDays[i]); 6720 } 6721 Datepicker.locales.en = { 6722 days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], 6723 daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], 6724 daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], 6725 months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
6725November", "December"], 6726 monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], 6727 today: "Today", 6728 clear: "Clear", 6729 titleFormat: "MM y", 6730 format: "d/M/Y", 6731 weekStart: 0 6732 }; 6733 6734 new Datepicker(elm, config); 6735 }); 6736 })(); 6737</script>
vendor: 1 bytes, line 6737
6737
6738<script> 6739 'use strict'; 6740 (() => { 6741 const input = document.getElementById('fieldfh3oTm380'); 6742 if (input) { 6743 input.initValidation = function (form) { 6744 input.parentElement.addEventListener('focusout', (e) => { 6745 if ( 6746 e.relatedTarget !== e.currentTarget && 6747 !e.currentTarget.contains(e.relatedTarget) 6748 ) { 6749 form.validateField(input); 6750 } 6751 }); 6752 input.parentElement.tabIndex = -1; 6753 } 6754 } 6755 })();</script>
vendor: 1 bytes, line 6755
6755
6756<script> 6757function stepProgress() { 6758 return { 6759 totalSteps: 1, 6760 currentStep: 1, 6761 items: [], 6762 6763 init() { 6764 const list = this.$refs.stepList; 6765 if (!list) return; 6766 6767 // Initialize items (exclude logically hidden) 6768 const computeItems = () => Array.from(list.querySelectorAll('li')) 6769 .filter(li => !li.classList.contains('mm-logic-hidden')); 6770 6771 const detectCurrentIndex = (arr) => { 6772 // Try common active markers that your wizard might use 6773 let idx = arr.findIndex(li => 6774 li.classList.contains('is-active') || 6775 li.classList.contains('active') || 6776 li.getAttribute('aria-current') === 'step' 6777 ); 6778 // Fallback: if none marked, assume first visible step 6779 if (idx < 0) idx = 0; 6780 return idx + 1; // 1-based 6781 }; 6782 6783 // Set initial state 6784 this.items = computeItems(); 6785 this.totalSteps = this.items.length || 1; 6786 this.currentStep = detectCurrentIndex(this.items); 6787 6788 // Watch for step visibility or active class changes 6789 const updateState = () => { 6790 this.items = computeItems(); 6791 this.totalSteps = this.items.length || 1; 6792 this.currentStep = Math.min(this.currentStep, this.totalSteps) || 1; 6793 6794 // If the wizard toggled which item is active, respect it 6795 const activeIdx = this.items.findIndex(li => 6796 li.classList.contains('is-active') || 6797 li.classList.contains('active') || 6798 li.getAttribute('aria-current') === 'step' 6799 ); 6800 if (activeIdx >= 0) this.currentStep = activeIdx + 1; 6801 }; 6802 6803 const mo = new MutationObserver(updateState); 6804 mo.observe(list, { childList: true, subtree: true, attributes: true, attributeFilter: ['class', 'aria-current'] }); 6805 6806 // Also sync on anchor clicks (in case wizard uses hash navigation) 6807 Array.from(list.querySelectorAll('li > a')).forEach((a, i) => { 6808 a.addEventListener('click', () => { 6809 // Update current step optimistically;
6809 observer will correct if needed 6810 const visibleIndex = computeItems().indexOf(a.closest('li')); 6811 if (visibleIndex >= 0) this.currentStep = visibleIndex + 1; 6812 }); 6813 }); 6814 }, 6815 6816 percent() { 6817 return (this.currentStep / this.totalSteps) * 100; 6818 } 6819 } 6820} 6821// data layer for survey 6822window.surveyTypeValue = ''; 6823window.selectedCategories = []; 6824 6825function updateSurveyType() { 6826 let currentStepNumber = document.querySelector('span[x-text="currentStep"]')?.textContent || ''; 6827 if (currentStepNumber === '1') { 6828 window.selectedCategories = Array.from( 6829 document.querySelectorAll('.mm-swatches input[type=checkbox]:checked') 6830 ).map(el => el.value); 6831 window.surveyTypeValue = window.selectedCategories.length > 0 ? window.selectedCategories.join(', ') : ''; 6832 } 6833} 6834 6835document.querySelectorAll('.mm-swatches input[type=checkbox]').forEach(cb => { 6836 cb.addEventListener('change', updateSurveyType); 6837}); 6838 6839updateSurveyType(); 6840 6841document.addEventListener('change', function(e) { 6842 if (e.target && e.target.matches('.webforms-fields-enquiry-type select.hyva-select')) { 6843 e.target.dataset.userChanged = 'true'; 6844 } 6845}); 6846 6847function handleNextStep() {
6848 let currentStepNumber = parseInt(document.querySelector('span[x-text="currentStep"]')?.textContent || '', 10) + 1; 6849 console.log('Handling next step, current step:', currentStepNumber); 6850 window.dataLayer = window.dataLayer || []; 6851 const enquiryTopic = document.getElementById('enquiry-topic'); 6852 var selectEl = document.querySelector('.webforms-fields-enquiry-type select.hyva-select'); 6853 var survey_client_type = selectEl ? selectEl.value : ''; 6854 var enquiryTopicVal = (enquiryTopic && enquiryTopic.value) ? (window.surveyTypeVal || enquiryTopic.value) : (window.surveyTypeVal || ''); 6855 var onProductPage = !!window.product_name; 6856 var _cats = window.selectedCategories.length > 0 6857 ? [...window.selectedCategories] 6858 : (!onProductPage && enquiryTopicVal ? [enquiryTopicVal] : []); 6859 if (!onProductPage && enquiryTopicVal && !_cats.includes(enquiryTopicVal)) { 6860 _cats.unshift(enquiryTopicVal); 6861 } 6862 if (selectEl && selectEl.value && selectEl.dataset.userChanged === 'true' && !_cats.includes(selectEl.value)) { 6863 _cats.push(selectEl.value); 6864 } 6865 if (_cats.length === 0 && selectEl && selectEl.value) { 6866 _cats.push(selectEl.value); 6867 } 6868 const categoriesToUse = _cats; 6869 if (categoriesToUse.length > 0) { 6870 window.dataLayer.pushedSteps = window.dataLayer.pushedSteps || []; 6871 6872 categoriesToUse.forEach(category => { 6873 const eventKey = `step_${currentStepNumber}_${category}`; 6874 6875 if (!window.dataLayer.pushedSteps.includes(eventKey)) { 6876 const dataLayerEvent ={ 6877 event: 'survey_screen', 6878 site_type: window.site_type, 6879 logged_in_status: false, 6880 journey_type: 'product', 6881 screen_number: currentStepNumber, 6882 page_name: document.querySelector('.step-tab-panel.form-step.active .hyva-fieldset-label span')?.textContent || '', 6883 survey_opening: window.surveyOpening, 6884 survey_type: category, 6885 }; 6886 if (survey_client_type){ 6887 dataLayerEvent.survey_client_type = survey_client_type; 6888 } 6889 window.dataLayer.push(dataLayerEvent); 6890 window.dataLayer.pushedSteps.push(eventKey); 6891 } 6892 }); 6893 } 6894 6895 if (currentStepNumber === 2 && categoriesToUse.length > 0) { 6896 categoriesToUse.forEach(category => { 6897 const eventKey = `step_${currentStepNumber}_${category}_category_selected`; 6898 6899 if (!window.dataLayer.pushedSteps.includes(eventKey)) { 6900 window.dataLayer.push({ 6901 event: 'survey_category_selected', 6902 site_type: window.site_type, 6903 logged_in_status: false, 6904 journey_type: 'product', 6905 screen_number: currentStepNumber, 6906 survey_opening: window.surveyOpening, 6907 survey_type: category, 6908 6909 }); 6910 window.dataLayer.pushedSteps.push(eventKey); 6911 } 6912 }); 6913 } 6914} 6915 6916window.user_id = ''; 6917window.logged_in_status = false; 6918window.hasProduct = false; 6919window.product_id = ''; 6920window.product_name = ''; 6921window.surveyType = ''; 6922window.surveyOpening = window.surveyOpening || 'Opened from CTA'; 6923</script>
vendor: 1 bytes, line 6923
6923
6924<script> 6925 'use strict'; 6926 6927 window.addEventListener('private-content-loaded', () => { 6928 MageMe.loader.addScript('swal', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Fsweetalert2.min.js", () => { 6929 MageMe.loader.addScript('tingle', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Ftingle.min.js", () => { 6930 const options = { 6931 "submitUrl": "https://www.banham.co.uk/webforms/form/submit/ajax/1/", 6932 "uid": "fh3oTm", 6933 "formId": "2", 6934 "ajax": true, 6935 "success": false, 6936 "displayAfterSubmission": false, 6937 "scrollAfterSubmission": true, 6938 "showReview": false, 6939 "saveDataLocal": false, 6940 "useCaptcha": true, 6941 "captchaResponseName": "g-recaptcha-response", 6942 "messages": { 6943 "success": "Success!", 6944 "redirecting": "Redirecting", 6945 "complete": "Complete", 6946 "error": "Error", 6947 "captchaTxt": "Please click on the Captcha", 6948 "errorTxt": "Error(s) occurred. Please try again.", 6949 "unknownTxt": "Unknown error(s) occurred" 6950 } 6951 } 6952 6953 options.afterInit = (form) => { 6954 document.body.addEventListener('touchstart', MageMe.WebForms.loadValidation, {once: true}); 6955 document.body.addEventListener('mouseover', MageMe.WebForms.loadValidation, {once: true}); 6956 } 6957 6958 options.validationCb = (form, valid) => new Promise(async (resolve, reject) => { 6959 if (!valid) { 6960 resolve(false); 6961 } 6962 MageMe.WebForms.loadValidation().then(() => { 6963 return MageMe.WebForms.formValidation(form.controls.form, { 6964 fieldWrapperClassName: 'control', 6965 messagesWrapperClassName: 'hyva-validation' 6966 }); 6967 }).then(validator => { 6968 return validator.validate(); 6969 }).then(() => { 6970 resolve(true); 6971 }).catch((er) => { 6972 resolve(false); 6973 }); 6974 }); 6975 options.fieldValidationCb = (field, form, valid) => new Promise(async (resolve, reject) => { 6976 if (!valid) { 6977 resolve(false); 6978 } 6979 MageMe.WebForms.loadValidation().then(() => { 6980 return MageMe.WebForms.formValidation(form.controls.form, { 6981 fieldWrapperClassName: 'control', 6982 messagesWrapperClassName: 'hyva-validation' 6983 }); 6984 }).then(validator => { 6985 validator.setupField(field); 6986 const fieldObj = validator.fields[field.name]; 6987 return validator.validateField(fieldObj); 6988 }).then((isValid) => { 6989 resolve(isValid); 6990 }).catch((er) => { 6991 resolve(false); 6992 }); 6993 }); 6994 6995 options.getFormKey = () => { 6996 return hyva.getCookie('form_key'); 6997 }; 6998 options.swal = swal; 6999 options.tingle = tingle; 7000 7001 MageMe.loader.addScript('mmForm', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fform.min.js", () => { 7002 new mmForm(options); 7003 }); 7004 }); 7005 }); 7006 });</script>
vendor: 1 bytes, line 7006
7006
7007<script type="text/javascript"> 7008 let logicRules_fh3oTm = []; 7009 const targets_fh3oTm = [{"id":"field_fh3oTm23","logic_visibility":"hidden","required":true}]; 7010 const fieldMap_fh3oTm = {"fieldset_56":["626","1778"],"fieldset_59":["8"],"fieldset_62":["5","23","11","14","2","17"],"fieldset_65":["1781","20","629","632","26","29","32"],"fieldset_68":["1032","38"],"fieldset_0":["submit"]}; 7011 logicRules_fh3oTm.push({ 7012 'field_id': '5', 7013 'action': 'show', 7014 'logic_condition': 'equal', 7015 'aggregation': 'any', 7016 'value': ["Business"], 7017 'target': ["field_fh3oTm23"] }); 7018 window.addEventListener("mm_webform_loadedfh3oTm", () => { 7019 MageMe.loader.addScript('mmLogic', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Flogic.min.js", () => { 7020 new mmLogic({ 7021 targets: targets_fh3oTm, 7022 logicRules: logicRules_fh3oTm, 7023 fieldMap: fieldMap_fh3oTm, 7024 uid: 'fh3oTm', 7025 containerId: "webform_fh3oTm_form" 7026 }); 7027 }); 7028 });</script>
vendor: 1 bytes, line 7028
7028
7029<script> 7030 'use strict'; 7031 (() => { 7032 document.getElementById("captcha-container-fh3oTm").innerHTML = '<div class="captcha-wrapper" x-data="mmWebformsCaptchaDatafh3oTm" x-init="initCaptcha"><input type="hidden" name="g-recaptcha-response" class="required-entry"/><div class="recaptcha-position-bottomright"><div class="recaptcha-container"></div></div></div>'; 7033 })();</script>
vendor: 1 bytes, line 7033
7033
7034<script> 7035 function mmWebformsCaptchaDatafh3oTm() { 7036 return { 7037 initCaptcha() { 7038 const options = { 7039 globalOnLoadCallback: 'webformsCaptchaOnload', 7040 captchaReadyEvent: 'webformsCaptchaApiReady', 7041 languageCode: 'en', 7042 publicKey: '6LfHDCMrAAAAACnDJl581eICSW3VnauItgp_hR2S', 7043 scriptId: 'mm_captcha', 7044 scriptExists: false, 7045 responseFieldName: 'g-recaptcha-response', 7046 version: '3', 7047 position: 'bottomright', 7048 theme: 'standard', 7049 action: '', 7050 checkboxChallenge: false, 7051 render: 'explicit' 7052 } 7053 7054 addCaptchaScriptTag(); 7055 let captcha; 7056 try { 7057 captcha = getCaptchaObject(); 7058 } catch { 7059 captcha = false; 7060 } 7061 if (captcha && captcha.render) { 7062 initCaptcha(); 7063 } else { 7064 window.addEventListener(options.captchaReadyEvent, function () { 7065 initCaptcha(); 7066 }); 7067 } 7068 7069 function initCaptcha() { 7070 const captcha = getCaptchaObject(); 7071 const params = {theme: options.theme, sitekey: options.publicKey}; 7072 7073 7074 if (isEnterprise() && options.checkboxChallenge) { 7075 params.size = 'normal'; 7076 params.callback = saveToken; 7077 } else if (isEnterprise() && !options.checkboxChallenge) { 7078 7079 params.size = 'invisible'; 7080 } else if (getIsInvisibleRecaptcha()) { 7081 params.size = 'invisible'; 7082 } else { 7083 params.callback = saveToken; 7084 } 7085 7086 const self = this; 7087 captcha.ready(function () { 7088 const captchaDivs = document.querySelectorAll('[class="recaptcha-container"]'); 7089 for (let i = 0; i < captchaDivs.length; i++) { 7090 try { 7091 const cid = captcha.render(captchaDivs[i], params); 7092 captchaDivs[i].setAttribute('cid', cid); 7093 } catch (e) { /* recaptcha was already rendered */ } 7094 } 7095 7096 window.addEventListener('mm-form-captcha-promise', (e) => { 7097 let cid = null; 7098 let form = null; 7099 if (e && e.detail) { 7100 cid = e.detail.cid; 7101 form = e.detail.form; 7102 } 7103 if (typeof cid === "undefined" || cid === null) { 7104 return; 7105 } 7106 if (typeof form === "undefined" || form === null) { 7107 return; 7108 } 7109 captcha.reset(cid); 7110 form.setCaptchaPromise(getToken.bind(self), self); 7111 }); 7112 7113 window.addEventListener('mm-form-captcha-reload', (e) => { 7114 let cid = null; 7115 if (e && e.detail) { 7116 cid = e.detail.cid; 7117 } 7118 if (typeof cid === "undefined" || cid === null) { 7119 return; 7120 } 7121 captcha.reset(cid); 7122 }); 7123 }) 7124 7125 function getToken(cid, form) { 7126 const captcha = getCaptchaObject(); 7127 switch (options.version) { 7128 case '3': { 7129 return captcha.execute(cid); 7130 } 7131 case 'enterprise': { 7132 7133 if (options.checkboxChallenge) { 7134 return new Promise(async (resolve, reject) => { 7135 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 7136 if (token) { 7137 resolve(token.value); 7138 } 7139 resolve(''); 7140 }); 7141 } 7142 return captcha.execute(cid, {action: options.action}); 7143 } 7144 default: { 7145 return new Promise(async (resolve, reject) => { 7146 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 7147 if (token) { 7148 resolve(token.value); 7149 } 7150 resolve(''); 7151 }); 7152 } 7153 } 7154 } 7155 7156 function saveToken(token) { 7157 const rFields = document.querySelectorAll(`[name="${options.responseFieldName}"]`); 7158 for (let i = 0; i < rFields.length; i++) { 7159 rFields[i].value = token; 7160 } 7161 } 7162 } 7163
7164 function getIsInvisibleRecaptcha() { 7165 return options.version === '3'; 7166 } 7167 7168 function isEnterprise() { 7169 return options.version === 'enterprise'; 7170 } 7171 7172 function addCaptchaScriptTag() { 7173 if (!document.getElementById(options.scriptId)) { 7174 const script = document.createElement('script'); 7175 const firstScriptTag = document.getElementsByTagName('script')[0]; 7176 const api = isEnterprise() ? 'enterprise' : 'api'; 7177 7178 script.async = true; 7179 script.defer = true; 7180 7181 script.src = `https://www.google.com/recaptcha/${api}.js?render=${options.render}`; 7182 7183 if (options.languageCode) { 7184 script.src += `&hl=${options.languageCode}` 7185 } 7186 if (options.position) { 7187 script.src += `&badge=${options.position}` 7188 } 7189 script.onload = () => { 7190 window.dispatchEvent(new CustomEvent(options.captchaReadyEvent)); 7191 } 7192 firstScriptTag.parentNode.insertBefore(script, firstScriptTag); 7193 } 7194 options.scriptExists = true; 7195 } 7196 7197 function getCaptchaObject() { 7198 return isEnterprise() ? window.grecaptcha.enterprise : window.grecaptcha; 7199 } 7200 } 7201 } 7202 } 7203 7204 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsCaptchaDatafh3oTm', mmWebformsCaptchaDatafh3oTm), {once: true});</script>
vendor: 1 bytes, line 7204
7204
7205<script> 7206 (() => { 7207 if (!window.MageMe || !MageMe.loader) { 7208 return; 7209 } 7210 MageMe.loader.addCssOrdered( 7211 'https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB/MageMe_WebForms/css/recaptcha.min.css', 7212 '50' 7213 ); 7214 })();</script>
vendor: 1 bytes, line 7214
7214
7215<script> 7216 7217 [...document.getElementById('webform_fh3oTm_form').querySelectorAll("input")].forEach((input) => { 7218 input.onkeydown = function(e) { 7219 const key = e.charCode || e.keyCode || 0; 7220 if (key === 13) { 7221 const index = [...input.form].indexOf(this); 7222 if (input.form.elements[index + 1] != null) { 7223 input.form.elements[index + 1].focus(); 7224 } 7225 e.preventDefault(); 7226 return false; 7227 } 7228 } 7229 }); 7230 7231 7232 document.addEventListener('alpine:init', () => { 7233 const enquiryTopic = window.enquiryTopic; 7234 const enquiryTopicProduct = window.enquiryTopicProduct; 7235 if (window.Alpine) { 7236 Alpine.store('CRMForm', window.CRMForm); 7237 } 7238 const topicField = document.querySelector('#enquiry-topic'); 7239 if (!topicField) return; 7240 topicField.setAttribute('autocomplete', 'off'); 7241 document.querySelectorAll('.type-swatches input').forEach(input => { 7242 input.setAttribute('autocomplete', 'off'); 7243 }); 7244 if (enquiryTopic !== '' && enquiryTopicProduct !== '') { 7245 topicField.setAttribute('required', 'true'); 7246 topicField.closest('.form-group')?.classList.remove('!hidden'); 7247 topicField.value = enquiryTopic; 7248 document.querySelectorAll('.type-swatches input').forEach(input => { 7249 const inputValue = input.value.toLowerCase(); 7250 const topicLower = enquiryTopic.toLowerCase(); 7251 7252 if (topicLower.includes(inputValue) || inputValue.includes(topicLower)) { 7253 input.closest('.field.choice')?.remove(); 7254 return; 7255 } 7256 if (enquiryTopicProduct.toLowerCase().includes(input.value.toLowerCase())) { 7257 input.checked = true; 7258 } 7259 input.removeAttribute('data-validate'); 7260 }); 7261 window.selectedCategories = [enquiryTopicProduct]; 7262 } else if (enquiryTopicProduct !== '') { 7263 topicField.removeAttribute('required'); 7264 topicField.closest('.webforms-fields-enquiry-topic')?.classList.add('!hidden'); 7265 document.querySelectorAll('.type-swatches input').forEach(input => { 7266 const inputValue = input.value.toLowerCase(); 7267 const topicLower = enquiryTopic.toLowerCase(); 7268 if (topicLower.includes(inputValue) || inputValue.includes(topicLower)) { 7269 input.closest('.field.choice')?.remove(); 7270 return; 7271 } 7272 if (enquiryTopicProduct.toLowerCase().includes(input.value.toLowerCase())) { 7273 input.checked = true; 7274 } 7275 input.removeAttribute('data-validate'); 7276 }); 7277 window.selectedCategories = [enquiryTopicProduct]; 7278 } else if (enquiryTopic !== '') { 7279 topicField.setAttribute('required', 'true'); 7280 topicField.closest('.form-group')?.classList.remove('!hidden'); 7281 topicField.value = enquiryTopic; 7282 document.querySelectorAll('.type-swatches input').forEach(input => { 7283 const inputValue = input.value.toLowerCase(); 7284 const topicLower = enquiryTopic.toLowerCase(); 7285 7286 if (topicLower.includes(inputValue) || inputValue.includes(topicLower)) { 7287 input.closest('.field.choice')?.remove(); 7288 return; 7289 } 7290 input.removeAttribute('data-validate'); 7291 }); 7292 } else { 7293 topicField.removeAttribute('required'); 7294 topicField.closest('.webforms-fields-enquiry-topic')?.classList.add('!hidden'); 7295 document.querySelectorAll('.type-swatches input').forEach(input => { 7296 input.setAttribute('data-validate', JSON.stringify({ 7297 'validate-one-required-by-name': true, 7298 'validate-options-checkbox-min': '1' 7299 })); 7300 }); 7301 } 7302}); </script>
vendor: 1 bytes, line 7302
7302
7303<script> 7304 (() => { 7305 if (!window.MageMe || !MageMe.loader) { 7306 return; 7307 } 7308 })();</script>
vendor: 1 bytes, line 7308
7308
7309<script type="text/javascript"> 7310 'use strict'; 7311 7312 (() => { 7313 if (!window.MageMe || !MageMe.loader) { 7314 return; 7315 } 7316 MageMe.loader.addScript('mmWebformsMultistep',"https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fmultistep.min.js", () => { 7317 const formId = 'webform_fh3oTm'; 7318 const uid = 'fh3oTm'; 7319 const showReview = false; 7320 const controls = { 7321 form: document.getElementById(formId), 7322 wizard: document.getElementById('wizardfh3oTm') 7323 }; 7324 function isIntersecting(el) { 7325 return new Promise(resolve => { 7326 const o = new IntersectionObserver(([entry]) => { 7327 resolve(entry.intersectionRatio === 1); 7328 o.disconnect(); 7329 }); 7330 o.observe(el); 7331 }); 7332 } 7333 7334 MageMe.WebForms.loadValidation().then(() => { 7335 return MageMe.WebForms.formValidation(controls.form, {fieldWrapperClassName: 'control', messagesWrapperClassName: 'hyva-validation'}); 7336 }).then(validator => { 7337 return { 7338 uid: 'fh3oTm', 7339 onFinish: () => { 7340 validator.validate().then(() => { 7341 if (window.mmForms && window.mmForms[uid]) { 7342 if (showReview) { 7343 window.mmForms[uid].review(); 7344 } else { 7345 window.mmForms[uid].submit(); 7346 } 7347 } 7348 }).catch(fields => { 7349 if (!controls.wizard) { 7350 console.log('No wizard'); 7351 return; 7352 } 7353 const fieldset = controls.wizard.querySelector('.form-step.active fieldset'); 7354 if (!fieldset || fieldset.style.display === 'none') { 7355 return; 7356 } 7357 for (let i = 0; i < fields.length; i++) { 7358 if (fieldset.querySelector('[name="' + fields[i].name + '"]')) { 7359 throw new Error('jqstps'); 7360 } 7361 } 7362 if (window.mmForms && window.mmForms[uid]) { 7363 if (showReview) { 7364 window.mmForms[uid].review(); 7365 } else { 7366 window.mmForms[uid].submit(); 7367 } 7368 } 7369 }); 7370 }, 7371 onChange: (currentIndex, newIndex, stepDirection) => { 7372 if(stepDirection === 'forward') { 7373 return validator.validate().then(() => { 7374 isIntersecting(controls.wizard).then(result => { 7375 if (!result) { 7376 window.scrollTo({top: controls.wizard.offsetTop - 20, behavior: 'smooth'}); 7377 } 7378 }); 7379 }).catch(fields => { 7380 if (!controls.wizard) { 7381 console.log('No wizard'); 7382 return; 7383 } 7384 const fieldset = controls.wizard.querySelector('.form-step.active fieldset'); 7385 if (!fieldset) { 7386 console.log('No fieldset'); 7387 return; 7388 } 7389 if (fieldset.style.display === 'none') { 7390 return; 7391 } 7392 if (fieldset.classList.contains('mm-logic-hidden')) { 7393 return; 7394 } 7395 for (let i = 0; i < fields.length; i++) { 7396 if (fieldset.querySelector('[name="' + fields[i].name + '"]')) { 7397 throw new Error('jqstps'); 7398 } 7399 const errorMessage = controls.wizard.querySelector('[data-msg-field="' + fields[i].name + '"]'); 7400 if (errorMessage) { 7401 errorMessage.remove(); 7402 } 7403 } 7404 }); 7405 7406 } else return new Promise(async (resolve, reject) => { 7407 resolve(); 7408 }); 7409 }, 7410 } 7411 }).then(config => { 7412 window.addEventListener('unhandledrejection', function(event) { 7413 if (event.reason.message === 'jqstps') { 7414 event.preventDefault(); 7415 } 7416 }); 7417 const mmSteps = new mmWebformsMultistep(document.getElementById('wizardfh3oTm'),config); 7418 mmSteps.init(); 7419 }).catch((er) => { 7420 console.log(er); 7421 }); 7422 }); 7423 })();</script>
vendor: 1 bytes, line 7423
7423
7424<script defer> 7425 (() => { 7426 window.dispatchEvent(new CustomEvent("mm_webform_loadedfh3oTm")); 7427 })();</script>
vendor: 1 bytes, line 7427
7427
7428<script> 7429 window.surveyTypeVal = ''; 7430 document.addEventListener("DOMContentLoaded", function () { 7431 document.querySelectorAll('a[href="#open_enquiry_form"]').forEach(function(el){ 7432 el.addEventListener("click", function (e) { 7433 e.preventDefault(); 7434 window.surveyOpeningSource = 'Opened from CTA'; 7435 document.querySelector(".open-slide-form-button")?.click(); 7436 }); 7437 }); 7438 const idEl = document.getElementById("open_enquiry_form"); 7439 if (idEl) { 7440 idEl.addEventListener("click", function (e) { 7441 e.preventDefault(); 7442 window.surveyOpeningSource = 'Opened from CTA'; 7443 document.querySelector(".open-slide-form-button")?.click(); 7444 }); 7445 } 7446 7447 if (window.location.hash === '#open_enquiry_form' || window.location.search.includes('open=enquiry')) { 7448 setTimeout(function() { 7449 window.surveyOpeningSource = 'Opened from CTA'; 7450 document.querySelector(".open-slide-form-button")?.click(); 7451 }, 300); 7452 } 7453 }); 7454 7455 (function () { 7456 var successDiv = document.getElementById('webform_fh3oTm_success_text'); 7457 var headingDiv = document.getElementById('webform_fh3oTm_heading'); 7458 var closeBtn = document.querySelector('#webform-slide-out-fh3oTm .close-btn'); 7459 if (successDiv && headingDiv) { 7460 new MutationObserver(function () { 7461 var isSuccess = successDiv.style.display !== 'none'; 7462 headingDiv.classList.toggle('hidden', isSuccess); 7463 if (closeBtn) closeBtn.classList.toggle('success-close', isSuccess); 7464 }).observe(successDiv, { attributes: true, attributeFilter: ['style'] }); 7465 } 7466 })(); 7467</script>
vendor: 1 bytes, line 7467
7467
7468<script> 7469 window.site_type = "Retail"; 7470</script>
vendor: 1 bytes, line 7470
7470
7471<script> 7472 document.body.addEventListener('touchstart', () => {}, {passive: true}) 7473</script>
vendor: 1 bytes, line 7473
7473
7474<script> 7475 'use strict'; 7476 7477 (function () { 7478 /** 7479 * @typedef amPickupLocalStorage 7480 * @property {Object} scheduleData 7481 * @property {Object} store 7482 * @property {boolean} isPickupSelected 7483 * @property {boolean} isCurbsideChecked 7484 * @property {string} curbsideComment 7485 * @property {Object} dateValue 7486 * @property {string} timeValue 7487 */ 7488 window.amPickupLocalStorage = window.amPickupLocalStorage || { 7489 getObject: function () { 7490 return hyva.getBrowserStorage().getItem('amPickupLocation') 7491 ? JSON.parse(hyva.getBrowserStorage().getItem('amPickupLocation')) 7492 : {}; 7493 }, 7494 setObject: function (newObject) { 7495 hyva.getBrowserStorage().setItem('amPickupLocation', JSON.stringify(newObject)); 7496 }, 7497 remove: function () { 7498 hyva.getBrowserStorage().removeItem('amPickupLocation'); 7499 }, 7500 setIsPickupSelected: function (value) { 7501 this.setObject({ 7502 ...this.getObject(), 7503 isPickupSelected: value 7504 }); 7505 }, 7506 isPickupSelected: function () { 7507 return (this.getObject().isPickupSelected && this.getObject().isPickupSelected !== undefined) 7508 ? Boolean(Number(this.getObject().isPickupSelected)) 7509 : null; 7510 }, 7511 setScheduleData: function (value) { 7512 this.setObject({ 7513 ...this.getObject(), 7514 scheduleData: value 7515 }); 7516 }, 7517 getScheduleData: function () { 7518 return (this.getObject().scheduleData && this.getObject().scheduleData !== undefined) 7519 ? this.getObject().scheduleData 7520 : null; 7521 }, 7522 setStore: function (value) { 7523 this.setObject({ 7524 ...this.getObject(), 7525 store: value 7526 }); 7527 }, 7528 getStore: function () { 7529 return (this.getObject().store && this.getObject().store !== undefined) 7530 ? this.getObject().store 7531 : null; 7532 }, 7533 setCurbsideChecked: function (value) { 7534 this.setObject({ 7535 ...this.getObject(), 7536 isCurbsideChecked: value 7537 }); 7538 }, 7539 getCurbsideChecked: function () { 7540 return (this.getObject().isCurbsideChecked && this.getObject().isCurbsideChecked !== undefined) 7541 ? this.getObject().isCurbsideChecked 7542 : false; 7543 }, 7544 setCurbsideComment: function (value) { 7545 this.setObject({ 7546 ...this.getObject(), 7547 curbsideComment: value 7548 }); 7549 }, 7550 getCurbsideComment: function () { 7551 return (this.getObject().curbsideComment && this.getObject().curbsideComment !== undefined) 7552 ? this.getObject().curbsideComment 7553 : null; 7554 }, 7555 setDateValue: function (value) { 7556 this.setObject({ 7557 ...this.getObject(), 7558 dateValue: value 7559 }); 7560 }, 7561 getDateValue: function () { 7562 return (this.getObject().dateValue && this.getObject().dateValue !== undefined) 7563 ? new Date(Number(this.getObject().dateValue)) 7564 : null; 7565 }, 7566 setTimeValue: function (value) { 7567 this.setObject({ 7568 ...this.getObject(), 7569 timeValue: value 7570 }); 7571 }, 7572 getTimeValue: function () { 7573 return (this.getObject().timeValue && this.getObject().timeValue !== undefined) 7574 ? this.getObject().timeValue 7575 : null; 7576 } 7577 }; 7578 })();</script>
vendor: 1 bytes, line 7578
7578
7579<script> 7580 function initHeader () { 7581 return { 7582 searchOpen: false, 7583 cart: {}, 7584 isCartOpen: false, 7585 getData(data) { 7586 if (data.cart) { this.cart = data.cart } 7587 }, 7588 isCartEmpty() { 7589 return !this.cart.summary_count 7590 }, 7591 toggleCart(event) { 7592 if (event.detail && event.detail.isOpen !== undefined) { 7593 this.isCartOpen = event.detail.isOpen 7594 if (!this.isCartOpen && this.$refs && this.$refs.cartButton) { 7595 this.$refs.cartButton.focus() 7596 } 7597 } else { 7598 this.isCartOpen = true 7599 } 7600 } 7601 } 7602 } 7603 function initCompareHeader() { 7604 return { 7605 compareProducts: null, 7606 itemCount: 0, 7607 receiveCompareData(data) { 7608 if (data['compare-products']) { 7609 this.compareProducts = data['compare-products']; 7610 this.itemCount = this.compareProducts.count; 7611 } 7612 } 7613 } 7614 } 7615</script>
vendor: 1 bytes, line 7615
7615
7616<script> 7617 'use strict'; 7618 7619 const initMenuMobile_6ab56541136c6 = () => { 7620 return { 7621 mobilePanelActiveId: null, 7622 open: false, 7623 isLoggedIn: false, 7624 signInText: 'Sign\u0020In', 7625 accountText: 'My\u0020Account', 7626 accountUrl: 'https\u003A\u002F\u002Fwww.banham.co.uk\u002Fcustomer\u002Faccount\u002F', 7627 signOutText: 'Sign\u0020Out', 7628 signOutUrl: 'https\u003A\u002F\u002Fwww.banham.co.uk\u002Fcustomer\u002Faccount\u002Flogout\u002F', 7629 init() { 7630 this.setActiveMenu(this.$root); 7631 this.setCustomerStateFromStorage(); 7632 }, 7633 setCustomerState(data) { 7634 this.isLoggedIn = !!(data && data.customer && (data.customer.firstname || data.customer.id)); 7635 }, 7636 setCustomerStateFromStorage() { 7637 try { 7638 const cached = JSON.parse(localStorage.getItem('mage-cache-storage') || '{}'); 7639 this.isLoggedIn = !!(cached.customer && (cached.customer.firstname || cached.customer.id)); 7640 } catch (e) { 7641 this.isLoggedIn = false; 7642 } 7643 },
7644 setActiveMenu(menuNode) { 7645 Array.from(menuNode.querySelectorAll('a')).filter(link => { 7646 return link.href === window.location.href.split('?')[0]; 7647 }).map(item => { 7648 item.classList.add('active'); 7649 item.closest('li.level-0')?.classList.add('active'); 7650 item.closest('li.level-0') && 7651 item.closest('li.level-0').querySelector('a.level-0').classList.add('active'); 7652 }); 7653 }, 7654 openMenu() { 7655 this.open = true 7656 this.$nextTick(() => hyva.trapFocus(this.$refs['mobileMenuNavLinks'])); 7657 // Prevent from body scrolling while mobile menu opened 7658 document.body.style.overflow = 'hidden'; 7659 }, 7660 closeMenu() { 7661 document.body.style.overflow = ''; 7662 7663 if (this.open) { 7664 this.$nextTick(() => this.$refs['mobileMenuTrigger'].focus() || hyva.releaseFocus()); 7665 } 7666 7667 this.open = false 7668 this.mobilePanelActiveId = null 7669 }, 7670 openSubcategory(index) { 7671 const menuNodeRef = document.querySelector('[data-child-id=' + index + ']') 7672 this.mobilePanelActiveId = this.mobilePanelActiveId === index ? 0 : index 7673 this.$nextTick(() => hyva.trapFocus(menuNodeRef)) 7674 }, 7675 backToMainCategories(index) { 7676 const menuNodeRef = document.querySelector('[data-child-id=' + index + ']') 7677 this.mobilePanelActiveId = 0 7678 this.$nextTick(() => { 7679 hyva.trapFocus(this.$refs['mobileMenuNavLinks']) 7680 menuNodeRef.querySelector('a').focus() 7681 }) 7682 } 7683 } 7684 } 7685</script>
vendor: 1 bytes, line 7685
7685
7686<script> 7687 'use strict'; 7688 7689 function initMiniSearch() { 7690 return { 7691 minSearchLength: 3, 7692 search(term) { 7693 const search = this.$refs.searchInput; 7694 term = term || search.value; 7695 if (term.length < this.minSearchLength) { 7696 search.setCustomValidity('Minimum\u0020Search\u0020query\u0020length\u0020is\u00203'); 7697 search.reportValidity(); 7698 } else { 7699 search.setCustomValidity(''); 7700 search.value = term; 7701 this.$refs.form.submit(); 7702 } 7703 }, 7704 focusElement(element) { 7705 if (element && element.nodeName === "DIV") { 7706 element.focus(); 7707 return true; 7708 } else { 7709 return false; 7710 } 7711 } 7712 } 7713 } 7714</script>
vendor: 1 bytes, line 7714
7714
7715<script> 7716 function initCartDrawer() { 7717 return { 7718 open: false, 7719 isLoading: false, 7720 cart: {}, 7721 isLoggedIn: false, 7722 customerId: null, 7723 maxItemsToDisplay: 10, 7724 itemsCount: 0, 7725 extraProducts: [], 7726 extraProductQtys: {}, 7727 extraSplideInstance: null, 7728 getData(data) { 7729 if (data.customer) { 7730 this.isLoggedIn = !!(data.customer.firstname); 7731 this.customerId = data.customer.id || null; 7732 } 7733 if (data.cart) { 7734 this.cart = data.cart; 7735 //this.itemsCount = data.cart.items && data.cart.items.length || 0; 7736 this.itemsCount = data.cart.items ? data.cart.items.reduce((total, item) => total + parseInt(item.qty), 0) : 0; 7737 this.setCartItems(); 7738 this.loadExtraProducts(); 7739 } 7740 this.isLoading = false; 7741 }, 7742 cartItems: [], 7743 getItemCountTitle() { 7744 return hyva.strf('\u00250\u0020of\u0020\u00251\u0020products\u0020in\u0020cart\u0020displayed', this.maxItemsToDisplay, this.itemsCount) 7745 }, 7746 setCartItems() { 7747 this.cartItems = this.cart.items && this.cart.items.sort((a, b) => b.item_id - a.item_id) || []; 7748 7749 if (this.maxItemsToDisplay > 0) { 7750 this.cartItems = this.cartItems.slice(0, parseInt(this.maxItemsToDisplay, 10)); 7751 } 7752 }, 7753 deleteItemFromCart(itemId) { 7754 this.isLoading = true; 7755 7756 const itemData = this.cart.items.filter((item) => item['item_id'] === itemId); 7757 const formKey = hyva.getFormKey(); 7758 const postUrl = BASE_URL + 'checkout/sidebar/removeItem/'; 7759 7760 fetch(postUrl, { 7761 "headers": { 7762 "content-type": "application/x-www-form-urlencoded; charset=UTF-8", 7763 }, 7764 "body": "form_key=" + formKey + "&item_id=" + itemId, 7765 "method": "POST", 7766 "mode": "cors", 7767 "credentials": "include" 7768 }).then(response => { 7769 if (response.redirected) { 7770 window.location.href = response.url; 7771 } else if (response.ok) { 7772 return response.json(); 7773 } else { 7774 window.dispatchMessages && window.dispatchMessages([{ 7775 type: 'warning', 7776 text: 'Could\u0020not\u0020remove\u0020item\u0020from\u0020quote.' 7777 }]); 7778 this.isLoading = false; 7779 } 7780 }).then(result => { 7781 window.dispatchMessages && window.dispatchMessages([{ 7782 type: result.success ? 'success' : 'error', 7783 text: result.success 7784 ? 'You\u0020removed\u0020the\u0020item.' 7785 : result.error_message 7786 }], result.success ? 5000 : 0); 7787 7788 if (result.success && itemData) { 7789 const removedItem = itemData[0]; 7790 if (removedItem) { 7791 this.pushCartEvent('remove_from_cart', removedItem, parseInt(removedItem.qty) || 1); 7792 } 7793 window.dispatchEvent(new CustomEvent('cart-item-removed', { detail: itemData })); 7794 } 7795 7796 window.dispatchEvent(new CustomEvent('reload-customer-section-data')); 7797 }); 7798 }, 7799 scrollLock(use = true) { 7800 document.body.style.overflow = use ? "hidden" : ""; 7801 }, 7802 toggleCartDrawer(event) { 7803 if (event.detail && event.detail.isOpen !== undefined) { 7804 if (event.detail.isOpen) { 7805 this.openCartDrawer(); 7806 } else { 7807 this.open = false;
7808 this.scrollLock(false); 7809 this.$refs && this.$refs.cartDialogContent && hyva.releaseFocus(this.$refs.cartDialogContent); 7810 } 7811 } else { 7812 this.openCartDrawer() 7813 } 7814 }, 7815 openCartDrawer() { 7816 this.open = true; 7817 this.scrollLock(true); 7818 this.$nextTick(() => { 7819 this.$refs && this.$refs.cartDialogContent && hyva.trapFocus(this.$refs.cartDialogContent) 7820 this.initExtraProductsSplide(); 7821 }); 7822 // Fire view_cart GTM event when cart opens 7823 if (this.cart && this.cart.items) { 7824 this.pushViewCartEvent(); 7825 } 7826 }, 7827 pushViewCartEvent() { 7828 window.dataLayer = window.dataLayer || []; 7829 window.dataLayer.push({ ecommerce: null }); 7830 window.dataLayer.push({ 7831 event: 'view_cart', 7832 site_type: this.cart.storeId == 1 ? 'Retail' : 'Trade', 7833 journey_type: 'product', 7834 logged_in_status: this.isLoggedIn, 7835 ...(this.customerId ? { 'user_id': this.customerId } : {}), 7836 page_type: 'cart_modal', 7837 ecommerce: { 7838 currency: 'GBP', 7839 value: this.cart.subtotalAmount || 0, 7840 items: (this.cart.items || []).map((item, index) => ({ 7841 item_id: item.product_sku, 7842 item_name: item.product_name || '', 7843 index: index, 7844 item_category: 'product', 7845 item_category2: item.item_category2 || '', 7846 item_category3: item.item_category3 || '', 7847 cta_type: 'add to cart', 7848 price: parseFloat(item.product_price_value) || 0, 7849 discount: item.discount_amount || 0, 7850 quantity: item.qty 7851 })) 7852 } 7853 }); 7854 }, 7855 closeCartDrawer() { 7856 this.$dispatch('toggle-cart', { isOpen: false }) 7857 }, 7858 getSectionDataExtraActions() { 7859 if (!this.cart.extra_actions) { 7860 return ''; 7861 } 7862 7863 const contentNode = document.createElement('div'); 7864 contentNode.innerHTML = this.cart.extra_actions; 7865 7866 hyva.activateScripts(contentNode); 7867 7868 return contentNode.innerHTML; 7869 }, 7870 incrementQty(item) { 7871 item.qty = parseInt(item.qty) + 1; 7872 this.updateItemQty(item); 7873 this.pushCartEvent('add_to_cart', item, 1); 7874 }, 7875 decrementQty(item) { 7876 if (parseInt(item.qty) > 1) { 7877 item.qty = parseInt(item.qty) - 1; 7878 this.updateItemQty(item); 7879 this.pushCartEvent('remove_from_cart', item, 1); 7880 } 7881 }, 7882 pushCartEvent(eventType, item, quantity) { 7883 window.dataLayer = window.dataLayer || []; 7884 window.dataLayer.push({ ecommerce: null }); 7885 window.dataLayer.push({ 7886 event: eventType, 7887 site_type: this.cart.storeId == 1 ? 'Retail' : 'Trade', 7888 journey_type: 'product', 7889 logged_in_status: this.isLoggedIn, 7890 ...(this.customerId ? { 'user_id': this.customerId } : {}), 7891 product_category: item.item_category2 || '', 7892 product_id: item.product_sku, 7893 product_name: item.product_name || '', 7894 page_type: 'cart_modal', 7895 ecommerce: { 7896 currency: 'GBP', 7897 value: parseFloat(item.product_price_value) * quantity, 7898 items: [{ 7899 item_id: item.product_sku, 7900 item_name: item.product_name || '', 7901 index: -1, 7902 item_category: 'product', 7903 item_category2: item.item_category2 || '', 7904 item_category3: item.item_category3 || '', 7905 cta_type: 'cart', 7906 price: parseFloat(item.product_price_value) || 0, 7907 discount: item.discount_amount || 0, 7908 quantity: quantity 7909 }] 7910 } 7911 }); 7912 }, 7913 updateItemQty(item) { 7914 this.isLoading = true; 7915 const formKey = hyva.getFormKey(); 7916 const postUrl = BASE_URL + 'checkout/cart/updatePost/'; 7917 7918 const body = new URLSearchParams(); 7919 body.append("form_key", formKey); 7920 body.append("cart[" + item.item_id + "][qty]", item.qty); 7921 7922 fetch(postUrl, { 7923 method: "POST", 7924 credentials: "include", 7925 headers: { 7926 "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" 7927 }, 7928 body: body.toString() 7929 }).then(response => { 7930 if (response.redirected) { 7931 window.location.href = response.url; 7932 } else if (response.ok) { 7933 return response.json(); 7934 } else { 7935 this.isLoading = false;
7936 throw new Error("Failed to update cart"); 7937 } 7938 }).then(result => { 7939 // Refresh minicart 7940 window.dispatchEvent(new CustomEvent('reload-customer-section-data')); 7941 this.isLoading = false; 7942 }).catch(() => { 7943 this.isLoading = false; 7944 window.dispatchMessages && window.dispatchMessages([{ 7945 type: 'error', 7946 text: 'Could\u0020not\u0020update\u0020cart.' 7947 }]); 7948 }); 7949 }, 7950 loadExtraProducts() { 7951 fetch(BASE_URL + 'extracartproduct/minicart/product/') 7952 .then(response => response.json()) 7953 .then(data => { 7954 if (data.products && Array.isArray(data.products)) { 7955 this.extraProducts = data.products; 7956 data.products.forEach((p, i) => { 7957 this.extraProductQtys[i] = 1; 7958 }); 7959 this.$nextTick(() => this.initExtraProductsSplide()); 7960 } else { 7961 this.extraProducts = []; 7962 if (this.extraSplideInstance) { 7963 this.extraSplideInstance.destroy(); 7964 this.extraSplideInstance = null; 7965 } 7966 } 7967 }) 7968 .catch(() => { 7969 this.extraProducts = []; 7970 if (this.extraSplideInstance) { 7971 this.extraSplideInstance.destroy(); 7972 this.extraSplideInstance = null; 7973 } 7974 }); 7975 }, 7976 initExtraProductsSplide() { 7977 if (!this.$refs || !this.$refs.extraProductsSplide) { 7978 return; 7979 } 7980 7981 if (this.extraSplideInstance) { 7982 this.extraSplideInstance.destroy(); 7983 this.extraSplideInstance = null; 7984 } 7985 7986 if (this.extraProducts.length <= 1) { 7987 return; 7988 } 7989 7990 if (typeof Splide === 'undefined') { 7991 return; 7992 } 7993 7994 this.extraSplideInstance = new Splide(this.$refs.extraProductsSplide, { 7995 type: 'fade', 7996 pagination: false, 7997 autoplay: false, 7998 arrows: true 7999 }); 8000 this.extraSplideInstance.mount(); 8001 }, 8002 incrementExtraQty(index) { 8003 if (this.extraProductQtys[index] < 10000) { 8004 this.extraProductQtys[index]++; 8005 } 8006 }, 8007 decrementExtraQty(index) { 8008 if (this.extraProductQtys[index] > 1) { 8009 this.extraProductQtys[index]--; 8010 } 8011 }, 8012 addExtraProduct(product, index) { 8013 this.isLoading = true; 8014 const formKey = hyva.getFormKey(); 8015 const postUrl = BASE_URL + 'checkout/cart/add/'; 8016 const qty = this.extraProductQtys[index] || 1; 8017 8018 const body = new URLSearchParams(); 8019 body.append('form_key', formKey); 8020 body.append('product', product.id); 8021 body.append('qty', qty); 8022 8023 fetch(postUrl, { 8024 method: 'POST', 8025 credentials: 'include', 8026 headers: { 8027 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 8028 'X-Requested-With': 'XMLHttpRequest' 8029 }, 8030 body: body.toString() 8031 }).then(response => { 8032 if (response.ok) { 8033 window.dispatchEvent(new CustomEvent('reload-customer-section-data')); 8034 } 8035 this.isLoading = false;
8036 }).catch(() => { 8037 this.isLoading = false; 8038 window.dispatchMessages && window.dispatchMessages([{ 8039 type: 'error', 8040 text: 'Could\u0020not\u0020add\u0020product\u0020to\u0020cart.' 8041 }]); 8042 }); 8043 } 8044 } 8045 } 8046</script>
vendor: 1 bytes, line 8046
8046
8047<script> 8048 function initAuthentication() { 8049 return { 8050 open: false, 8051 close() { 8052 this.open = false; 8053 }, 8054 forceAuthentication: false, 8055 checkoutUrl: 'https://www.banham.co.uk/checkout/index/', 8056 errors: 0, 8057 hasCaptchaToken: 0, 8058 displayErrorMessage: false, 8059 errorMessages: [], 8060 setErrorMessages(message) { 8061 this.errorMessages = [message]; 8062 this.displayErrorMessage = true; 8063 }, 8064 submitForm() { 8065 // Do not rename $form, the variable is expected to be declared in the recaptcha output 8066 const $form = document.querySelector('#login-form'); 8067 if (!this.hasCaptchaToken) { 8068 this.errors = 1; 8069 8070 let retryCount = 0; 8071 const executeGreCaptcha = () => { 8072 grecaptcha.ready(() => { 8073 try { 8074 grecaptcha.execute( 8075 '6LfHDCMrAAAAACnDJl581eICSW3VnauItgp_hR2S', 8076 {action: 'submit'} 8077 ).then((token) => { 8078 const tokenElement = $form['g\u002Drecaptcha\u002Dresponse']; 8079 8080 if (tokenElement && token && token.length > 0) { 8081 if (tokenElement.length !== undefined && !tokenElement.tagName) { 8082 Array.from(tokenElement).forEach(el => el.value = token); 8083 } else { 8084 tokenElement.value = token; 8085 } 8086 this.errors = 0; 8087 this.hasCaptchaToken = 1; 8088 (this.submitForm || $form.submit).call(this); 8089 } else { 8090 this.errors = 1; 8091 const error = tokenElement 8092 ? 'ReCaptcha\u0020validation\u0020failed,\u0020please\u0020try\u0020again' 8093 : 'ReCaptcha\u0020token\u0020element\u0020is\u0020missing.\u0020Please\u0020refresh\u0020the\u0020page\u0020and\u0020trying\u0020again.'; 8094 if (this.setErrorMessages) { 8095 this.setErrorMessages([error]) 8096 this.displayErrorMessage = true; 8097 } else { 8098 window.dispatchMessages && window.dispatchMessages([{type: "error", text: error}], 5000); 8099 } 8100 } 8101 }).catch(exception => { 8102 console.error(exception || `An unknown error occurred during ReCaptcha validation. Are the tokens and the domain correctly set up in the Google console?`) 8103 }); 8104 } catch (e) { 8105 if (e && e.message && e.message.includes('Invalid site key or not loaded in api.js') && retryCount < 20) { 8106 retryCount++; 8107 setTimeout(executeGreCaptcha, 250); 8108 } else { 8109 console.error('ReCaptcha validation failed: ', e); 8110 } 8111 } 8112 }) 8113 } 8114 8115 const recaptchaUrl = "https://www.google.com/recaptcha/api.js?render=6LfHDCMrAAAAACnDJl581eICSW3VnauItgp_hR2S"; 8116 let existingScript = document.querySelector(`script[src="${recaptchaUrl}"]`); 8117 8118 if (!existingScript) { 8119 existingScript = document.createElement('script'); 8120 existingScript.setAttribute('type', 'text/javascript'); 8121 existingScript.setAttribute('src', recaptchaUrl); 8122 document.head.appendChild(existingScript); 8123 } 8124 8125 if (window.grecaptcha) { 8126 executeGreCaptcha(); 8127 } else { 8128 existingScript.addEventListener("load", executeGreCaptcha, false); 8129 } 8130 } 8131 8132 if (this.errors === 0) { 8133 this.dispatchLoginRequest($form); 8134 } 8135 }, 8136 onPrivateContentLoaded() { 8137 const data = this.$event.detail.data; 8138 const isLoggedIn = data.customer && data.customer.firstname; 8139 if (data.cart && !isLoggedIn) {
8140 this.forceAuthentication = !data.cart.isGuestCheckoutAllowed; 8141 } 8142 }, 8143 redirectIfAuthenticated() { 8144 const event = this.$event; 8145 this.open = this.forceAuthentication; 8146 8147 if (event.detail && event.detail.url) { 8148 this.checkoutUrl = event.detail.url; 8149 } 8150 if (!this.forceAuthentication) { 8151 window.location.href = this.checkoutUrl; 8152 } 8153 }, 8154 resetErrors() { 8155 this.errors = 0; 8156 }, 8157 dispatchLoginRequest(form) { 8158 this.isLoading = true; 8159 const username = this.$refs['customer-email'].value; 8160 const password = this.$refs['customer-password'].value; 8161 const formKey = hyva.getFormKey(); 8162 const bodyFields = { 8163 'username': username, 8164 'password': password, 8165 'formKey': formKey 8166 }; 8167 const fieldName = 'g\u002Drecaptcha\u002Dresponse'; 8168 const recaptchaField = fieldName && form[fieldName]; 8169 if (recaptchaField) { 8170 bodyFields[fieldName] = recaptchaField.value; 8171 } 8172 fetch('https://www.banham.co.uk/customer/ajax/login/', { 8173 method: 'POST', 8174 headers: { 8175 'Content-Type': 'application/json', 8176 'X-Requested-With': 'XMLHttpRequest' 8177 }, 8178 body: JSON.stringify(bodyFields) 8179 } 8180 ).then(response => { 8181 return response.json() 8182 } 8183 ).then(data => { 8184 this.isLoading = false; 8185 if (data.errors) { 8186 this.setErrorMessages(data.message); 8187 this.errors = 1; 8188 this.hasCaptchaToken = 0; 8189 } else { 8190 window.location.href = this.checkoutUrl; 8191 } 8192 }); 8193 }, 8194 eventListeners: { 8195 ['@private-content-loaded.window']() { 8196 this.onPrivateContentLoaded(); 8197 }, 8198 ['@toggle-authentication.window']() { 8199 this.redirectIfAuthenticated(); 8200 }, 8201 ['@pageshow.window'](event) { 8202 if (event.persisted) { 8203 this.close(); 8204 }; 8205 } 8206 } 8207 } 8208 } 8209 8210 window.addEventListener('alpine:init', () => Alpine.data('initAuthentication', initAuthentication), {once: true}) 8211</script>
vendor: 1 bytes, line 8211
8211
8212<script type="application/ld+json"> 8213 { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{"@type":"ListItem","position":1,"item":{"@id":"https:\/\/www.banham.co.uk\/","name":"Home"}},{"@type":"ListItem","position":2,"item":{"@id":"https:\/\/www.banham.co.uk\/contact\/","name":"Contact"}}] } 8214 </script>
vendor: 1 bytes, line 8214
8214
8215<script> 8216 function initMessages() { 8217 "use strict"; 8218 return { 8219 isSticky: false, 8220 messages: window.mageMessages || [], 8221 init() { 8222 window.addEventListener('scroll', () => { 8223 this.isSticky = window.scrollY > 50; 8224 }); 8225 }, 8226 sectionClass() { 8227 return this.isSticky 8228 ? 'fixed top-[60px] lg:top-[84px] left-0 z-[99] w-full' 8229 : ' relative w-full'; 8230 }, 8231 isEmpty() { 8232 return this.messages.reduce( 8233 function (isEmpty, message) { 8234 return isEmpty && message === undefined 8235 }, true 8236 ) 8237 }, 8238 hasMessages() { 8239 return !this.isEmpty(); 8240 }, 8241 hasMessage() { 8242 return !!this.message; 8243 }, 8244 removeMessage() { 8245 this.messages[this.index] = undefined; 8246 }, 8247 addMessages(messages, hideAfter) { 8248 messages.map((message) => { 8249 this.messages = this.messages.concat(message); 8250 if (hideAfter === undefined && message.type === 'success' && window.defaultSuccessMessageTimeout) { 8251 hideAfter = window.defaultSuccessMessageTimeout; 8252 } 8253 if (hideAfter) { 8254 this.setHideTimeOut(this.messages.length -1, hideAfter); 8255 } 8256 }); 8257 }, 8258 setHideTimeOut(messageIndex, hideAfter) { 8259 setTimeout((messageIndex) => { 8260 this.messages[messageIndex] = undefined; 8261 }, hideAfter, messageIndex); 8262 }, 8263 eventListeners: { 8264 ['@messages-loaded.window'](event) { 8265 this.addMessages(event.detail.messages, event.detail.hideAfter) 8266 }, 8267 ['@private-content-loaded.window'](event) { 8268 const data = event.detail.data; 8269 if ( 8270 data.messages && 8271 data.messages.messages && 8272 data.messages.messages.length 8273 ) { 8274 this.addMessages(data.messages.messages); 8275 } 8276 }, 8277 ['@clear-messages.window']() { 8278 this.messages = []; 8279 } 8280 }, 8281 getMessageUiId() { 8282 return 'message-' + this.message.type; 8283 } 8284 } 8285 } 8286 8287 window.addEventListener('alpine:init', () => Alpine.data('initMessages', initMessages), {once: true}) 8288</script>
vendor: 1 bytes, line 8288
8288
8289<script> 8290 function mmWebformsEmailDatafieldPpTRdM41() { 8291 return Object.assign( 8292 MageMe.WebForms.customerData(), 8293 { 8294 trimSpace() { 8295 if (this.$el.value.search(' ') >= 0) { 8296 this.$el.value =Â this.$el.value.replace(' ',''); 8297 } 8298 }, 8299 setCustomerData(event) { 8300 this.receiveCustomerData(event.detail.data) 8301 if (this.$el) { 8302 this.$el.value = this.customer['customer_email'] ?? ''; 8303 } 8304 }, 8305 } 8306 ); 8307 } 8308 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsEmailDatafieldPpTRdM41', mmWebformsEmailDatafieldPpTRdM41), {once: true});</script>
vendor: 1 bytes, line 8308
8308
8309<script> 8310 function mmWebformsTextareaDatafieldPpTRdM47() { 8311 return Object.assign( 8312 MageMe.WebForms.customerData(), 8313 { 8314 setCustomerData(event) { 8315 this.receiveCustomerData(event.detail.data) 8316 if (this.$el) { 8317 this.$el.value = this.customer[this.$el.dataset.hyvacspCustomerData] ?? ''; 8318 } 8319 }, 8320 } 8321 ); 8322 } 8323 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsTextareaDatafieldPpTRdM47', mmWebformsTextareaDatafieldPpTRdM47), {once: true});</script>
vendor: 1 bytes, line 8323
8323
8324<script> 8325 'use strict'; 8326 8327 window.addEventListener('private-content-loaded', () => { 8328 MageMe.loader.addScript('swal', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Fsweetalert2.min.js", () => { 8329 MageMe.loader.addScript('tingle', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Ftingle.min.js", () => { 8330 const options = { 8331 "submitUrl": "https://www.banham.co.uk/webforms/form/submit/ajax/1/", 8332 "uid": "PpTRdM", 8333 "formId": "4", 8334 "ajax": true, 8335 "success": false, 8336 "displayAfterSubmission": true, 8337 "scrollAfterSubmission": true, 8338 "showReview": false, 8339 "saveDataLocal": false, 8340 "useCaptcha": true, 8341 "captchaResponseName": "g-recaptcha-response", 8342 "messages": { 8343 "success": "Success!", 8344 "redirecting": "Redirecting", 8345 "complete": "Complete", 8346 "error": "Error", 8347 "captchaTxt": "Please click on the Captcha", 8348 "errorTxt": "Error(s) occurred. Please try again.", 8349 "unknownTxt": "Unknown error(s) occurred" 8350 } 8351 } 8352 8353 options.afterInit = (form) => { 8354 document.body.addEventListener('touchstart', MageMe.WebForms.loadValidation, {once: true}); 8355 document.body.addEventListener('mouseover', MageMe.WebForms.loadValidation, {once: true}); 8356 } 8357 8358 options.validationCb = (form, valid) => new Promise(async (resolve, reject) => { 8359 if (!valid) { 8360 resolve(false); 8361 } 8362 MageMe.WebForms.loadValidation().then(() => { 8363 return MageMe.WebForms.formValidation(form.controls.form, { 8364 fieldWrapperClassName: 'control', 8365 messagesWrapperClassName: 'hyva-validation' 8366 }); 8367 }).then(validator => { 8368 return validator.validate(); 8369 }).then(() => { 8370 resolve(true); 8371 }).catch((er) => { 8372 resolve(false); 8373 }); 8374 }); 8375 options.fieldValidationCb = (field, form, valid) => new Promise(async (resolve, reject) => { 8376 if (!valid) { 8377 resolve(false); 8378 } 8379 MageMe.WebForms.loadValidation().then(() => { 8380 return MageMe.WebForms.formValidation(form.controls.form, { 8381 fieldWrapperClassName: 'control', 8382 messagesWrapperClassName: 'hyva-validation' 8383 }); 8384 }).then(validator => { 8385 validator.setupField(field); 8386 const fieldObj = validator.fields[field.name]; 8387 return validator.validateField(fieldObj); 8388 }).then((isValid) => { 8389 resolve(isValid); 8390 }).catch((er) => { 8391 resolve(false); 8392 }); 8393 }); 8394 8395 options.getFormKey = () => { 8396 return hyva.getCookie('form_key'); 8397 }; 8398 options.swal = swal; 8399 options.tingle = tingle; 8400 8401 MageMe.loader.addScript('mmForm', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fform.min.js", () => { 8402 new mmForm(options); 8403 }); 8404 }); 8405 }); 8406 });</script>
vendor: 1 bytes, line 8406
8406
8407<script type="text/javascript"> 8408 let logicRules_PpTRdM = []; 8409 const targets_PpTRdM = [{"id":"field_PpTRdM89","logic_visibility":"hidden","required":true},{"id":"field_PpTRdM86","logic_visibility":"hidden","required":true}]; 8410 const fieldMap_PpTRdM = {"fieldset_0":["80","86","89","98","41","47","56","59","65","68","71","92","submit"]}; 8411 logicRules_PpTRdM.push({ 8412 'field_id': '80', 8413 'action': 'show', 8414 'logic_condition': 'equal', 8415 'aggregation': 'any', 8416 'value': [1], 8417 'target': ["field_PpTRdM89"] }); 8418 logicRules_PpTRdM.push({ 8419 'field_id': '80', 8420 'action': 'show', 8421 'logic_condition': 'equal', 8422 'aggregation': 'any', 8423 'value': [], 8424 'target': ["field_PpTRdM86"] }); 8425 window.addEventListener("mm_webform_loadedPpTRdM", () => { 8426 MageMe.loader.addScript('mmLogic', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Flogic.min.js", () => { 8427 new mmLogic({ 8428 targets: targets_PpTRdM, 8429 logicRules: logicRules_PpTRdM, 8430 fieldMap: fieldMap_PpTRdM, 8431 uid: 'PpTRdM', 8432 containerId: "webform_PpTRdM_form" 8433 }); 8434 }); 8435 });</script>
vendor: 1 bytes, line 8435
8435
8436<script> 8437 'use strict'; 8438 (() => { 8439 document.getElementById("captcha-container-PpTRdM").innerHTML = '<div class="captcha-wrapper" x-data="mmWebformsCaptchaDataPpTRdM" x-init="initCaptcha"><input type="hidden" name="g-recaptcha-response" class="required-entry"/><div class="recaptcha-position-bottomright"><div class="recaptcha-container"></div></div></div>'; 8440 })();</script>
vendor: 1 bytes, line 8440
8440
8441<script> 8442 function mmWebformsCaptchaDataPpTRdM() { 8443 return { 8444 initCaptcha() { 8445 const options = { 8446 globalOnLoadCallback: 'webformsCaptchaOnload', 8447 captchaReadyEvent: 'webformsCaptchaApiReady', 8448 languageCode: 'en', 8449 publicKey: '6LfHDCMrAAAAACnDJl581eICSW3VnauItgp_hR2S', 8450 scriptId: 'mm_captcha', 8451 scriptExists: false, 8452 responseFieldName: 'g-recaptcha-response', 8453 version: '3', 8454 position: 'bottomright', 8455 theme: 'standard', 8456 action: '', 8457 checkboxChallenge: false, 8458 render: 'explicit' 8459 } 8460 8461 addCaptchaScriptTag(); 8462 let captcha; 8463 try { 8464 captcha = getCaptchaObject(); 8465 } catch { 8466 captcha = false; 8467 } 8468 if (captcha && captcha.render) { 8469 initCaptcha(); 8470 } else { 8471 window.addEventListener(options.captchaReadyEvent, function () { 8472 initCaptcha(); 8473 }); 8474 } 8475 8476 function initCaptcha() { 8477 const captcha = getCaptchaObject(); 8478 const params = {theme: options.theme, sitekey: options.publicKey}; 8479 8480 8481 if (isEnterprise() && options.checkboxChallenge) { 8482 params.size = 'normal'; 8483 params.callback = saveToken; 8484 } else if (isEnterprise() && !options.checkboxChallenge) { 8485 8486 params.size = 'invisible'; 8487 } else if (getIsInvisibleRecaptcha()) { 8488 params.size = 'invisible'; 8489 } else { 8490 params.callback = saveToken; 8491 } 8492 8493 const self = this; 8494 captcha.ready(function () { 8495 const captchaDivs = document.querySelectorAll('[class="recaptcha-container"]'); 8496 for (let i = 0; i < captchaDivs.length; i++) { 8497 try { 8498 const cid = captcha.render(captchaDivs[i], params); 8499 captchaDivs[i].setAttribute('cid', cid); 8500 } catch (e) { /* recaptcha was already rendered */ } 8501 } 8502 8503 window.addEventListener('mm-form-captcha-promise', (e) => { 8504 let cid = null; 8505 let form = null; 8506 if (e && e.detail) { 8507 cid = e.detail.cid; 8508 form = e.detail.form; 8509 } 8510 if (typeof cid === "undefined" || cid === null) { 8511 return; 8512 } 8513 if (typeof form === "undefined" || form === null) { 8514 return; 8515 } 8516 captcha.reset(cid); 8517 form.setCaptchaPromise(getToken.bind(self), self); 8518 }); 8519 8520 window.addEventListener('mm-form-captcha-reload', (e) => { 8521 let cid = null; 8522 if (e && e.detail) { 8523 cid = e.detail.cid; 8524 } 8525 if (typeof cid === "undefined" || cid === null) { 8526 return; 8527 } 8528 captcha.reset(cid); 8529 }); 8530 }) 8531 8532 function getToken(cid, form) { 8533 const captcha = getCaptchaObject(); 8534 switch (options.version) { 8535 case '3': { 8536 return captcha.execute(cid); 8537 } 8538 case 'enterprise': { 8539 8540 if (options.checkboxChallenge) { 8541 return new Promise(async (resolve, reject) => { 8542 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 8543 if (token) { 8544 resolve(token.value); 8545 } 8546 resolve(''); 8547 }); 8548 } 8549 return captcha.execute(cid, {action: options.action}); 8550 } 8551 default: { 8552 return new Promise(async (resolve, reject) => { 8553 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 8554 if (token) { 8555 resolve(token.value); 8556 } 8557 resolve(''); 8558 }); 8559 } 8560 } 8561 } 8562 8563 function saveToken(token) { 8564 const rFields = document.querySelectorAll(`[name="${options.responseFieldName}"]`); 8565 for (let i = 0; i < rFields.length; i++) { 8566 rFields[i].value = token; 8567 } 8568 } 8569 } 8570
8571 function getIsInvisibleRecaptcha() { 8572 return options.version === '3'; 8573 } 8574 8575 function isEnterprise() { 8576 return options.version === 'enterprise'; 8577 } 8578 8579 function addCaptchaScriptTag() { 8580 if (!document.getElementById(options.scriptId)) { 8581 const script = document.createElement('script'); 8582 const firstScriptTag = document.getElementsByTagName('script')[0]; 8583 const api = isEnterprise() ? 'enterprise' : 'api'; 8584 8585 script.async = true; 8586 script.defer = true; 8587 8588 script.src = `https://www.google.com/recaptcha/${api}.js?render=${options.render}`; 8589 8590 if (options.languageCode) { 8591 script.src += `&hl=${options.languageCode}` 8592 } 8593 if (options.position) { 8594 script.src += `&badge=${options.position}` 8595 } 8596 script.onload = () => { 8597 window.dispatchEvent(new CustomEvent(options.captchaReadyEvent)); 8598 } 8599 firstScriptTag.parentNode.insertBefore(script, firstScriptTag); 8600 } 8601 options.scriptExists = true; 8602 } 8603 8604 function getCaptchaObject() { 8605 return isEnterprise() ? window.grecaptcha.enterprise : window.grecaptcha; 8606 } 8607 } 8608 } 8609 } 8610 8611 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsCaptchaDataPpTRdM', mmWebformsCaptchaDataPpTRdM), {once: true});</script>
vendor: 1 bytes, line 8611
8611
8612<script> 8613 8614 [...document.getElementById('webform_PpTRdM_form').querySelectorAll("input")].forEach((input) => { 8615 input.onkeydown = function(e) { 8616 const key = e.charCode || e.keyCode || 0; 8617 if (key === 13) { 8618 const index = [...input.form].indexOf(this); 8619 if (input.form.elements[index + 1] != null) { 8620 input.form.elements[index + 1].focus(); 8621 } 8622 e.preventDefault(); 8623 return false; 8624 } 8625 } 8626 }); 8627 8628 8629 </script>
vendor: 1 bytes, line 8629
8629
8630<script defer> 8631 (() => { 8632 window.dispatchEvent(new CustomEvent("mm_webform_loadedPpTRdM")); 8633 })();</script>
vendor: 1 bytes, line 8633
8633
8634<script> 8635 'use strict'; 8636 (() => { 8637 document.querySelectorAll('input[name="field[329]"]').forEach((el) => { 8638 el.initValidation = function (form) { 8639 el.parentElement.parentElement.addEventListener('focusout', (e) => { 8640 if ( 8641 e.relatedTarget !== e.currentTarget && 8642 !e.currentTarget.contains(e.relatedTarget) 8643 ) { 8644 form.validateField(el); 8645 } 8646 }); 8647 el.parentElement.parentElement.tabIndex = -1; 8648 } 8649 }); 8650 })();</script>
vendor: 1 bytes, line 8650
8650
8651<script> 8652 function mmWebformsTextareaDatafieldde7Gm7335() { 8653 return Object.assign( 8654 MageMe.WebForms.customerData(), 8655 { 8656 setCustomerData(event) { 8657 this.receiveCustomerData(event.detail.data) 8658 if (this.$el) { 8659 this.$el.value = this.customer[this.$el.dataset.hyvacspCustomerData] ?? ''; 8660 } 8661 }, 8662 } 8663 ); 8664 } 8665 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsTextareaDatafieldde7Gm7335', mmWebformsTextareaDatafieldde7Gm7335), {once: true});</script>
vendor: 1 bytes, line 8665
8665
8666<script> 8667 function mmWebformsEmailDatafieldde7Gm7332() { 8668 return Object.assign( 8669 MageMe.WebForms.customerData(), 8670 { 8671 trimSpace() { 8672 if (this.$el.value.search(' ') >= 0) { 8673 this.$el.value =Â this.$el.value.replace(' ',''); 8674 } 8675 }, 8676 setCustomerData(event) { 8677 this.receiveCustomerData(event.detail.data) 8678 if (this.$el) { 8679 this.$el.value = this.customer['customer_email'] ?? ''; 8680 } 8681 }, 8682 } 8683 ); 8684 } 8685 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsEmailDatafieldde7Gm7332', mmWebformsEmailDatafieldde7Gm7332), {once: true});</script>
vendor: 1 bytes, line 8685
8685
8686<script> 8687 'use strict'; 8688 8689 (() => { 8690 if (!window.MageMe || !MageMe.loader) { 8691 return; 8692 } 8693 MageMe.loader.addCssOrdered( 8694 'https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB/Hyva_MageMeWebForms/css/field/datepicker.min.css', 8695 '40' 8696 ); 8697 MageMe.loader.addScript("Datepicker", 8698 "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fdatepicker.min.js", 8699 () => { 8700 const isPastDisabled = true; 8701 const isFutureDisabled = false; 8702 const isTodayDisabled = false; 8703 const isWeekNumbersShowed = false; 8704 const pastOffset = 0; 8705 const futureOffset = 0; 8706 const disabledWeekDays = [6,0]; 8707 const format = convertFormat('d/M/Y', 'date'); 8708 const today = new Date(); 8709 const elm = document.getElementById('fieldde7Gm7362'); 8710 8711 let config = { 8712 autohide: true, 8713 datesDisabled: [], 8714 showWeekNumbers: isWeekNumbersShowed, 8715 daysOfWeekDisabled: [], 8716 weekStart: 1, 8717 format: format 8718 }; 8719 if (config.rtl) { 8720 $('#fieldde7Gm7362_calendar').addClass('rtl'); 8721 } 8722 if (isPastDisabled) { 8723 config.minDate = new Date(); 8724 if (pastOffset) { 8725 config.minDate.setDate(config.minDate.getDate() + pastOffset) 8726 } 8727 } 8728 if (isFutureDisabled) { 8729 config.maxDate = new Date(); 8730 if (futureOffset) { 8731 config.maxDate.setDate(config.maxDate.getDate() + futureOffset) 8732 } 8733 } 8734 if (isTodayDisabled) { 8735 config.datesDisabled.push(today); 8736 } 8737 for (let i = 0; i < disabledWeekDays.length; i++) { 8738 config.daysOfWeekDisabled.push(disabledWeekDays[i]); 8739 } 8740 Datepicker.locales.en = { 8741 days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], 8742 daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], 8743 daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], 8744 months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
8744November", "December"], 8745 monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], 8746 today: "Today", 8747 clear: "Clear", 8748 titleFormat: "MM y", 8749 format: "d/M/Y", 8750 weekStart: 0 8751 }; 8752 8753 new Datepicker(elm, config); 8754 }); 8755 })(); 8756</script>
vendor: 1 bytes, line 8756
8756
8757<script> 8758 'use strict'; 8759 (() => { 8760 const input = document.getElementById('fieldde7Gm73650'); 8761 if (input) { 8762 input.initValidation = function (form) { 8763 input.parentElement.addEventListener('focusout', (e) => { 8764 if ( 8765 e.relatedTarget !== e.currentTarget && 8766 !e.currentTarget.contains(e.relatedTarget) 8767 ) { 8768 form.validateField(input); 8769 } 8770 }); 8771 input.parentElement.tabIndex = -1; 8772 } 8773 } 8774 })();</script>
vendor: 1 bytes, line 8774
8774
8775<script> 8776 'use strict'; 8777 8778 window.addEventListener('private-content-loaded', () => { 8779 MageMe.loader.addScript('swal', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Fsweetalert2.min.js", () => { 8780 MageMe.loader.addScript('tingle', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Ftingle.min.js", () => { 8781 const options = { 8782 "submitUrl": "https://www.banham.co.uk/webforms/form/submit/ajax/1/", 8783 "uid": "de7Gm7", 8784 "formId": "27", 8785 "ajax": true, 8786 "success": false, 8787 "displayAfterSubmission": false, 8788 "scrollAfterSubmission": true, 8789 "showReview": false, 8790 "saveDataLocal": false, 8791 "useCaptcha": true, 8792 "captchaResponseName": "g-recaptcha-response", 8793 "messages": { 8794 "success": "Success!", 8795 "redirecting": "Redirecting", 8796 "complete": "Complete", 8797 "error": "Error", 8798 "captchaTxt": "Please click on the Captcha", 8799 "errorTxt": "Error(s) occurred. Please try again.", 8800 "unknownTxt": "Unknown error(s) occurred" 8801 } 8802 } 8803 8804 options.afterInit = (form) => { 8805 document.body.addEventListener('touchstart', MageMe.WebForms.loadValidation, {once: true}); 8806 document.body.addEventListener('mouseover', MageMe.WebForms.loadValidation, {once: true}); 8807 } 8808 8809 options.validationCb = (form, valid) => new Promise(async (resolve, reject) => { 8810 if (!valid) { 8811 resolve(false); 8812 } 8813 MageMe.WebForms.loadValidation().then(() => { 8814 return MageMe.WebForms.formValidation(form.controls.form, { 8815 fieldWrapperClassName: 'control', 8816 messagesWrapperClassName: 'hyva-validation' 8817 }); 8818 }).then(validator => { 8819 return validator.validate(); 8820 }).then(() => { 8821 resolve(true); 8822 }).catch((er) => { 8823 resolve(false); 8824 }); 8825 }); 8826 options.fieldValidationCb = (field, form, valid) => new Promise(async (resolve, reject) => { 8827 if (!valid) { 8828 resolve(false); 8829 } 8830 MageMe.WebForms.loadValidation().then(() => { 8831 return MageMe.WebForms.formValidation(form.controls.form, { 8832 fieldWrapperClassName: 'control', 8833 messagesWrapperClassName: 'hyva-validation' 8834 }); 8835 }).then(validator => { 8836 validator.setupField(field); 8837 const fieldObj = validator.fields[field.name]; 8838 return validator.validateField(fieldObj); 8839 }).then((isValid) => { 8840 resolve(isValid); 8841 }).catch((er) => { 8842 resolve(false); 8843 }); 8844 }); 8845 8846 options.getFormKey = () => { 8847 return hyva.getCookie('form_key'); 8848 }; 8849 options.swal = swal; 8850 options.tingle = tingle; 8851 8852 MageMe.loader.addScript('mmForm', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fform.min.js", () => { 8853 new mmForm(options); 8854 }); 8855 }); 8856 }); 8857 });</script>
vendor: 1 bytes, line 8857
8857
8858<script> 8859 'use strict'; 8860 (() => { 8861 document.getElementById("captcha-container-de7Gm7").innerHTML = '<div class="captcha-wrapper" x-data="mmWebformsCaptchaDatade7Gm7" x-init="initCaptcha"><input type="hidden" name="g-recaptcha-response" class="required-entry"/><div class="recaptcha-position-bottomright"><div class="recaptcha-container"></div></div></div>'; 8862 })();</script>
vendor: 1 bytes, line 8862
8862
8863<script> 8864 function mmWebformsCaptchaDatade7Gm7() { 8865 return { 8866 initCaptcha() { 8867 const options = { 8868 globalOnLoadCallback: 'webformsCaptchaOnload', 8869 captchaReadyEvent: 'webformsCaptchaApiReady', 8870 languageCode: 'en', 8871 publicKey: '6LfHDCMrAAAAACnDJl581eICSW3VnauItgp_hR2S', 8872 scriptId: 'mm_captcha', 8873 scriptExists: false, 8874 responseFieldName: 'g-recaptcha-response', 8875 version: '3', 8876 position: 'bottomright', 8877 theme: 'standard', 8878 action: '', 8879 checkboxChallenge: false, 8880 render: 'explicit' 8881 } 8882 8883 addCaptchaScriptTag(); 8884 let captcha; 8885 try { 8886 captcha = getCaptchaObject(); 8887 } catch { 8888 captcha = false; 8889 } 8890 if (captcha && captcha.render) { 8891 initCaptcha(); 8892 } else { 8893 window.addEventListener(options.captchaReadyEvent, function () { 8894 initCaptcha(); 8895 }); 8896 } 8897 8898 function initCaptcha() { 8899 const captcha = getCaptchaObject(); 8900 const params = {theme: options.theme, sitekey: options.publicKey}; 8901 8902 8903 if (isEnterprise() && options.checkboxChallenge) { 8904 params.size = 'normal'; 8905 params.callback = saveToken; 8906 } else if (isEnterprise() && !options.checkboxChallenge) { 8907 8908 params.size = 'invisible'; 8909 } else if (getIsInvisibleRecaptcha()) { 8910 params.size = 'invisible'; 8911 } else { 8912 params.callback = saveToken; 8913 } 8914 8915 const self = this; 8916 captcha.ready(function () { 8917 const captchaDivs = document.querySelectorAll('[class="recaptcha-container"]'); 8918 for (let i = 0; i < captchaDivs.length; i++) { 8919 try { 8920 const cid = captcha.render(captchaDivs[i], params); 8921 captchaDivs[i].setAttribute('cid', cid); 8922 } catch (e) { /* recaptcha was already rendered */ } 8923 } 8924 8925 window.addEventListener('mm-form-captcha-promise', (e) => { 8926 let cid = null; 8927 let form = null; 8928 if (e && e.detail) { 8929 cid = e.detail.cid; 8930 form = e.detail.form; 8931 } 8932 if (typeof cid === "undefined" || cid === null) { 8933 return; 8934 } 8935 if (typeof form === "undefined" || form === null) { 8936 return; 8937 } 8938 captcha.reset(cid); 8939 form.setCaptchaPromise(getToken.bind(self), self); 8940 }); 8941 8942 window.addEventListener('mm-form-captcha-reload', (e) => { 8943 let cid = null; 8944 if (e && e.detail) { 8945 cid = e.detail.cid; 8946 } 8947 if (typeof cid === "undefined" || cid === null) { 8948 return; 8949 } 8950 captcha.reset(cid); 8951 }); 8952 }) 8953 8954 function getToken(cid, form) { 8955 const captcha = getCaptchaObject(); 8956 switch (options.version) { 8957 case '3': { 8958 return captcha.execute(cid); 8959 } 8960 case 'enterprise': { 8961 8962 if (options.checkboxChallenge) { 8963 return new Promise(async (resolve, reject) => { 8964 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 8965 if (token) { 8966 resolve(token.value); 8967 } 8968 resolve(''); 8969 }); 8970 } 8971 return captcha.execute(cid, {action: options.action}); 8972 } 8973 default: { 8974 return new Promise(async (resolve, reject) => { 8975 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 8976 if (token) { 8977 resolve(token.value); 8978 } 8979 resolve(''); 8980 }); 8981 } 8982 } 8983 } 8984 8985 function saveToken(token) { 8986 const rFields = document.querySelectorAll(`[name="${options.responseFieldName}"]`); 8987 for (let i = 0; i < rFields.length; i++) { 8988 rFields[i].value = token; 8989 } 8990 } 8991 } 8992
8993 function getIsInvisibleRecaptcha() { 8994 return options.version === '3'; 8995 } 8996 8997 function isEnterprise() { 8998 return options.version === 'enterprise'; 8999 } 9000 9001 function addCaptchaScriptTag() { 9002 if (!document.getElementById(options.scriptId)) { 9003 const script = document.createElement('script'); 9004 const firstScriptTag = document.getElementsByTagName('script')[0]; 9005 const api = isEnterprise() ? 'enterprise' : 'api'; 9006 9007 script.async = true; 9008 script.defer = true; 9009 9010 script.src = `https://www.google.com/recaptcha/${api}.js?render=${options.render}`; 9011 9012 if (options.languageCode) { 9013 script.src += `&hl=${options.languageCode}` 9014 } 9015 if (options.position) { 9016 script.src += `&badge=${options.position}` 9017 } 9018 script.onload = () => { 9019 window.dispatchEvent(new CustomEvent(options.captchaReadyEvent)); 9020 } 9021 firstScriptTag.parentNode.insertBefore(script, firstScriptTag); 9022 } 9023 options.scriptExists = true; 9024 } 9025 9026 function getCaptchaObject() { 9027 return isEnterprise() ? window.grecaptcha.enterprise : window.grecaptcha; 9028 } 9029 } 9030 } 9031 } 9032 9033 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsCaptchaDatade7Gm7', mmWebformsCaptchaDatade7Gm7), {once: true});</script>
vendor: 1 bytes, line 9033
9033
9034<script> 9035 9036 [...document.getElementById('webform_de7Gm7_form').querySelectorAll("input")].forEach((input) => { 9037 input.onkeydown = function(e) { 9038 const key = e.charCode || e.keyCode || 0; 9039 if (key === 13) { 9040 const index = [...input.form].indexOf(this); 9041 if (input.form.elements[index + 1] != null) { 9042 input.form.elements[index + 1].focus(); 9043 } 9044 e.preventDefault(); 9045 return false; 9046 } 9047 } 9048 }); 9049 9050 9051 </script>
vendor: 1 bytes, line 9051
9051
9052<script defer> 9053 (() => { 9054 window.dispatchEvent(new CustomEvent("mm_webform_loadedde7Gm7")); 9055 })();</script>
vendor: 1 bytes, line 9055
9055
9056<script> 9057 function mmWebformsEmailDatafieldXpSqJw41() { 9058 return Object.assign( 9059 MageMe.WebForms.customerData(), 9060 { 9061 trimSpace() { 9062 if (this.$el.value.search(' ') >= 0) { 9063 this.$el.value =Â this.$el.value.replace(' ',''); 9064 } 9065 }, 9066 setCustomerData(event) { 9067 this.receiveCustomerData(event.detail.data) 9068 if (this.$el) { 9069 this.$el.value = this.customer['customer_email'] ?? ''; 9070 } 9071 }, 9072 } 9073 ); 9074 } 9075 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsEmailDatafieldXpSqJw41', mmWebformsEmailDatafieldXpSqJw41), {once: true});</script>
vendor: 1 bytes, line 9075
9075
9076<script> 9077 function mmWebformsTextareaDatafieldXpSqJw47() { 9078 return Object.assign( 9079 MageMe.WebForms.customerData(), 9080 { 9081 setCustomerData(event) { 9082 this.receiveCustomerData(event.detail.data) 9083 if (this.$el) { 9084 this.$el.value = this.customer[this.$el.dataset.hyvacspCustomerData] ?? ''; 9085 } 9086 }, 9087 } 9088 ); 9089 } 9090 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsTextareaDatafieldXpSqJw47', mmWebformsTextareaDatafieldXpSqJw47), {once: true});</script>
vendor: 1 bytes, line 9090
9090
9091<script> 9092 'use strict'; 9093 9094 window.addEventListener('private-content-loaded', () => { 9095 MageMe.loader.addScript('swal', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Fsweetalert2.min.js", () => { 9096 MageMe.loader.addScript('tingle', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Ftingle.min.js", () => { 9097 const options = { 9098 "submitUrl": "https://www.banham.co.uk/webforms/form/submit/ajax/1/", 9099 "uid": "XpSqJw", 9100 "formId": "4", 9101 "ajax": true, 9102 "success": false, 9103 "displayAfterSubmission": true, 9104 "scrollAfterSubmission": true, 9105 "showReview": false, 9106 "saveDataLocal": false, 9107 "useCaptcha": true, 9108 "captchaResponseName": "g-recaptcha-response", 9109 "messages": { 9110 "success": "Success!", 9111 "redirecting": "Redirecting", 9112 "complete": "Complete", 9113 "error": "Error", 9114 "captchaTxt": "Please click on the Captcha", 9115 "errorTxt": "Error(s) occurred. Please try again.", 9116 "unknownTxt": "Unknown error(s) occurred" 9117 } 9118 } 9119 9120 options.afterInit = (form) => { 9121 document.body.addEventListener('touchstart', MageMe.WebForms.loadValidation, {once: true}); 9122 document.body.addEventListener('mouseover', MageMe.WebForms.loadValidation, {once: true}); 9123 } 9124 9125 options.validationCb = (form, valid) => new Promise(async (resolve, reject) => { 9126 if (!valid) { 9127 resolve(false); 9128 } 9129 MageMe.WebForms.loadValidation().then(() => { 9130 return MageMe.WebForms.formValidation(form.controls.form, { 9131 fieldWrapperClassName: 'control', 9132 messagesWrapperClassName: 'hyva-validation' 9133 }); 9134 }).then(validator => { 9135 return validator.validate(); 9136 }).then(() => { 9137 resolve(true); 9138 }).catch((er) => { 9139 resolve(false); 9140 }); 9141 }); 9142 options.fieldValidationCb = (field, form, valid) => new Promise(async (resolve, reject) => { 9143 if (!valid) { 9144 resolve(false); 9145 } 9146 MageMe.WebForms.loadValidation().then(() => { 9147 return MageMe.WebForms.formValidation(form.controls.form, { 9148 fieldWrapperClassName: 'control', 9149 messagesWrapperClassName: 'hyva-validation' 9150 }); 9151 }).then(validator => { 9152 validator.setupField(field); 9153 const fieldObj = validator.fields[field.name]; 9154 return validator.validateField(fieldObj); 9155 }).then((isValid) => { 9156 resolve(isValid); 9157 }).catch((er) => { 9158 resolve(false); 9159 }); 9160 }); 9161 9162 options.getFormKey = () => { 9163 return hyva.getCookie('form_key'); 9164 }; 9165 options.swal = swal; 9166 options.tingle = tingle; 9167 9168 MageMe.loader.addScript('mmForm', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fform.min.js", () => { 9169 new mmForm(options); 9170 }); 9171 }); 9172 }); 9173 });</script>
vendor: 1 bytes, line 9173
9173
9174<script type="text/javascript"> 9175 let logicRules_XpSqJw = []; 9176 const targets_XpSqJw = [{"id":"field_XpSqJw89","logic_visibility":"hidden","required":true},{"id":"field_XpSqJw86","logic_visibility":"hidden","required":true}]; 9177 const fieldMap_XpSqJw = {"fieldset_0":["80","86","89","98","41","47","56","59","65","68","71","92","submit"]}; 9178 logicRules_XpSqJw.push({ 9179 'field_id': '80', 9180 'action': 'show', 9181 'logic_condition': 'equal', 9182 'aggregation': 'any', 9183 'value': [1], 9184 'target': ["field_XpSqJw89"] }); 9185 logicRules_XpSqJw.push({ 9186 'field_id': '80', 9187 'action': 'show', 9188 'logic_condition': 'equal', 9189 'aggregation': 'any', 9190 'value': [], 9191 'target': ["field_XpSqJw86"] }); 9192 window.addEventListener("mm_webform_loadedXpSqJw", () => { 9193 MageMe.loader.addScript('mmLogic', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Flogic.min.js", () => { 9194 new mmLogic({ 9195 targets: targets_XpSqJw, 9196 logicRules: logicRules_XpSqJw, 9197 fieldMap: fieldMap_XpSqJw, 9198 uid: 'XpSqJw', 9199 containerId: "webform_XpSqJw_form" 9200 }); 9201 }); 9202 });</script>
vendor: 1 bytes, line 9202
9202
9203<script> 9204 'use strict'; 9205 (() => { 9206 document.getElementById("captcha-container-XpSqJw").innerHTML = '<div class="captcha-wrapper" x-data="mmWebformsCaptchaDataXpSqJw" x-init="initCaptcha"><input type="hidden" name="g-recaptcha-response" class="required-entry"/><div class="recaptcha-position-bottomright"><div class="recaptcha-container"></div></div></div>'; 9207 })();</script>
vendor: 1 bytes, line 9207
9207
9208<script> 9209 function mmWebformsCaptchaDataXpSqJw() { 9210 return { 9211 initCaptcha() { 9212 const options = { 9213 globalOnLoadCallback: 'webformsCaptchaOnload', 9214 captchaReadyEvent: 'webformsCaptchaApiReady', 9215 languageCode: 'en', 9216 publicKey: '6LfHDCMrAAAAACnDJl581eICSW3VnauItgp_hR2S', 9217 scriptId: 'mm_captcha', 9218 scriptExists: false, 9219 responseFieldName: 'g-recaptcha-response', 9220 version: '3', 9221 position: 'bottomright', 9222 theme: 'standard', 9223 action: '', 9224 checkboxChallenge: false, 9225 render: 'explicit' 9226 } 9227 9228 addCaptchaScriptTag(); 9229 let captcha; 9230 try { 9231 captcha = getCaptchaObject(); 9232 } catch { 9233 captcha = false; 9234 } 9235 if (captcha && captcha.render) { 9236 initCaptcha(); 9237 } else { 9238 window.addEventListener(options.captchaReadyEvent, function () { 9239 initCaptcha(); 9240 }); 9241 } 9242 9243 function initCaptcha() { 9244 const captcha = getCaptchaObject(); 9245 const params = {theme: options.theme, sitekey: options.publicKey}; 9246 9247 9248 if (isEnterprise() && options.checkboxChallenge) { 9249 params.size = 'normal'; 9250 params.callback = saveToken; 9251 } else if (isEnterprise() && !options.checkboxChallenge) { 9252 9253 params.size = 'invisible'; 9254 } else if (getIsInvisibleRecaptcha()) { 9255 params.size = 'invisible'; 9256 } else { 9257 params.callback = saveToken; 9258 } 9259 9260 const self = this; 9261 captcha.ready(function () { 9262 const captchaDivs = document.querySelectorAll('[class="recaptcha-container"]'); 9263 for (let i = 0; i < captchaDivs.length; i++) { 9264 try { 9265 const cid = captcha.render(captchaDivs[i], params); 9266 captchaDivs[i].setAttribute('cid', cid); 9267 } catch (e) { /* recaptcha was already rendered */ } 9268 } 9269 9270 window.addEventListener('mm-form-captcha-promise', (e) => { 9271 let cid = null; 9272 let form = null; 9273 if (e && e.detail) { 9274 cid = e.detail.cid; 9275 form = e.detail.form; 9276 } 9277 if (typeof cid === "undefined" || cid === null) { 9278 return; 9279 } 9280 if (typeof form === "undefined" || form === null) { 9281 return; 9282 } 9283 captcha.reset(cid); 9284 form.setCaptchaPromise(getToken.bind(self), self); 9285 }); 9286 9287 window.addEventListener('mm-form-captcha-reload', (e) => { 9288 let cid = null; 9289 if (e && e.detail) { 9290 cid = e.detail.cid; 9291 } 9292 if (typeof cid === "undefined" || cid === null) { 9293 return; 9294 } 9295 captcha.reset(cid); 9296 }); 9297 }) 9298 9299 function getToken(cid, form) { 9300 const captcha = getCaptchaObject(); 9301 switch (options.version) { 9302 case '3': { 9303 return captcha.execute(cid); 9304 } 9305 case 'enterprise': { 9306 9307 if (options.checkboxChallenge) { 9308 return new Promise(async (resolve, reject) => { 9309 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 9310 if (token) { 9311 resolve(token.value); 9312 } 9313 resolve(''); 9314 }); 9315 } 9316 return captcha.execute(cid, {action: options.action}); 9317 } 9318 default: { 9319 return new Promise(async (resolve, reject) => { 9320 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 9321 if (token) { 9322 resolve(token.value); 9323 } 9324 resolve(''); 9325 }); 9326 } 9327 } 9328 } 9329 9330 function saveToken(token) { 9331 const rFields = document.querySelectorAll(`[name="${options.responseFieldName}"]`); 9332 for (let i = 0; i < rFields.length; i++) { 9333 rFields[i].value = token; 9334 } 9335 } 9336 } 9337
9338 function getIsInvisibleRecaptcha() { 9339 return options.version === '3'; 9340 } 9341 9342 function isEnterprise() { 9343 return options.version === 'enterprise'; 9344 } 9345 9346 function addCaptchaScriptTag() { 9347 if (!document.getElementById(options.scriptId)) { 9348 const script = document.createElement('script'); 9349 const firstScriptTag = document.getElementsByTagName('script')[0]; 9350 const api = isEnterprise() ? 'enterprise' : 'api'; 9351 9352 script.async = true; 9353 script.defer = true; 9354 9355 script.src = `https://www.google.com/recaptcha/${api}.js?render=${options.render}`; 9356 9357 if (options.languageCode) { 9358 script.src += `&hl=${options.languageCode}` 9359 } 9360 if (options.position) { 9361 script.src += `&badge=${options.position}` 9362 } 9363 script.onload = () => { 9364 window.dispatchEvent(new CustomEvent(options.captchaReadyEvent)); 9365 } 9366 firstScriptTag.parentNode.insertBefore(script, firstScriptTag); 9367 } 9368 options.scriptExists = true; 9369 } 9370 9371 function getCaptchaObject() { 9372 return isEnterprise() ? window.grecaptcha.enterprise : window.grecaptcha; 9373 } 9374 } 9375 } 9376 } 9377 9378 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsCaptchaDataXpSqJw', mmWebformsCaptchaDataXpSqJw), {once: true});</script>
vendor: 1 bytes, line 9378
9378
9379<script> 9380 9381 [...document.getElementById('webform_XpSqJw_form').querySelectorAll("input")].forEach((input) => { 9382 input.onkeydown = function(e) { 9383 const key = e.charCode || e.keyCode || 0; 9384 if (key === 13) { 9385 const index = [...input.form].indexOf(this); 9386 if (input.form.elements[index + 1] != null) { 9387 input.form.elements[index + 1].focus(); 9388 } 9389 e.preventDefault(); 9390 return false; 9391 } 9392 } 9393 }); 9394 9395 9396 </script>
vendor: 1 bytes, line 9396
9396
9397<script defer> 9398 (() => { 9399 window.dispatchEvent(new CustomEvent("mm_webform_loadedXpSqJw")); 9400 })();</script>
vendor: 1 bytes, line 9400
9400
9401<script> 9402 'use strict'; 9403 (() => { 9404 document.querySelectorAll('input[name="field[368]"]').forEach((el) => { 9405 el.initValidation = function (form) { 9406 el.parentElement.parentElement.addEventListener('focusout', (e) => { 9407 if ( 9408 e.relatedTarget !== e.currentTarget && 9409 !e.currentTarget.contains(e.relatedTarget) 9410 ) { 9411 form.validateField(el); 9412 } 9413 }); 9414 el.parentElement.parentElement.tabIndex = -1; 9415 } 9416 }); 9417 })();</script>
vendor: 1 bytes, line 9417
9417
9418<script> 9419 function mmWebformsEmailDatafieldcvQP2X371() { 9420 return Object.assign( 9421 MageMe.WebForms.customerData(), 9422 { 9423 trimSpace() { 9424 if (this.$el.value.search(' ') >= 0) { 9425 this.$el.value =Â this.$el.value.replace(' ',''); 9426 } 9427 }, 9428 setCustomerData(event) { 9429 this.receiveCustomerData(event.detail.data) 9430 if (this.$el) { 9431 this.$el.value = this.customer['customer_email'] ?? ''; 9432 } 9433 }, 9434 } 9435 ); 9436 } 9437 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsEmailDatafieldcvQP2X371', mmWebformsEmailDatafieldcvQP2X371), {once: true});</script>
vendor: 1 bytes, line 9437
9437
9438<script> 9439 'use strict'; 9440 (() => { 9441 document.querySelectorAll('input[name="field[407]"]').forEach((el) => { 9442 el.initValidation = function (form) { 9443 el.parentElement.parentElement.addEventListener('focusout', (e) => { 9444 if ( 9445 e.relatedTarget !== e.currentTarget && 9446 !e.currentTarget.contains(e.relatedTarget) 9447 ) { 9448 form.validateField(el); 9449 } 9450 }); 9451 el.parentElement.parentElement.tabIndex = -1; 9452 } 9453 }); 9454 })();</script>
vendor: 1 bytes, line 9454
9454
9455<script> 9456 function mmWebformsTextareaDatafieldcvQP2X410() { 9457 return Object.assign( 9458 MageMe.WebForms.customerData(), 9459 { 9460 setCustomerData(event) { 9461 this.receiveCustomerData(event.detail.data) 9462 if (this.$el) { 9463 this.$el.value = this.customer[this.$el.dataset.hyvacspCustomerData] ?? ''; 9464 } 9465 }, 9466 } 9467 ); 9468 } 9469 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsTextareaDatafieldcvQP2X410', mmWebformsTextareaDatafieldcvQP2X410), {once: true});</script>
vendor: 1 bytes, line 9469
9469
9470<script> 9471 'use strict'; 9472 (() => { 9473 const input = document.getElementById('fieldcvQP2X4040'); 9474 if (input) { 9475 input.initValidation = function (form) { 9476 input.parentElement.addEventListener('focusout', (e) => { 9477 if ( 9478 e.relatedTarget !== e.currentTarget && 9479 !e.currentTarget.contains(e.relatedTarget) 9480 ) { 9481 form.validateField(input); 9482 } 9483 }); 9484 input.parentElement.tabIndex = -1; 9485 } 9486 } 9487 })();</script>
vendor: 1 bytes, line 9487
9487
9488<script> 9489 'use strict'; 9490 9491 window.addEventListener('private-content-loaded', () => { 9492 MageMe.loader.addScript('swal', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Fsweetalert2.min.js", () => { 9493 MageMe.loader.addScript('tingle', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Ftingle.min.js", () => { 9494 const options = { 9495 "submitUrl": "https://www.banham.co.uk/webforms/form/submit/ajax/1/", 9496 "uid": "cvQP2X", 9497 "formId": "32", 9498 "ajax": true, 9499 "success": false, 9500 "displayAfterSubmission": false, 9501 "scrollAfterSubmission": true, 9502 "showReview": false, 9503 "saveDataLocal": false, 9504 "useCaptcha": true, 9505 "captchaResponseName": "g-recaptcha-response", 9506 "messages": { 9507 "success": "Success!", 9508 "redirecting": "Redirecting", 9509 "complete": "Complete", 9510 "error": "Error", 9511 "captchaTxt": "Please click on the Captcha", 9512 "errorTxt": "Error(s) occurred. Please try again.", 9513 "unknownTxt": "Unknown error(s) occurred" 9514 } 9515 } 9516 9517 options.afterInit = (form) => { 9518 document.body.addEventListener('touchstart', MageMe.WebForms.loadValidation, {once: true}); 9519 document.body.addEventListener('mouseover', MageMe.WebForms.loadValidation, {once: true}); 9520 } 9521 9522 options.validationCb = (form, valid) => new Promise(async (resolve, reject) => { 9523 if (!valid) { 9524 resolve(false); 9525 } 9526 MageMe.WebForms.loadValidation().then(() => { 9527 return MageMe.WebForms.formValidation(form.controls.form, { 9528 fieldWrapperClassName: 'control', 9529 messagesWrapperClassName: 'hyva-validation' 9530 }); 9531 }).then(validator => { 9532 return validator.validate(); 9533 }).then(() => { 9534 resolve(true); 9535 }).catch((er) => { 9536 resolve(false); 9537 }); 9538 }); 9539 options.fieldValidationCb = (field, form, valid) => new Promise(async (resolve, reject) => { 9540 if (!valid) { 9541 resolve(false); 9542 } 9543 MageMe.WebForms.loadValidation().then(() => { 9544 return MageMe.WebForms.formValidation(form.controls.form, { 9545 fieldWrapperClassName: 'control', 9546 messagesWrapperClassName: 'hyva-validation' 9547 }); 9548 }).then(validator => { 9549 validator.setupField(field); 9550 const fieldObj = validator.fields[field.name]; 9551 return validator.validateField(fieldObj); 9552 }).then((isValid) => { 9553 resolve(isValid); 9554 }).catch((er) => { 9555 resolve(false); 9556 }); 9557 }); 9558 9559 options.getFormKey = () => { 9560 return hyva.getCookie('form_key'); 9561 }; 9562 options.swal = swal; 9563 options.tingle = tingle; 9564 9565 MageMe.loader.addScript('mmForm', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fform.min.js", () => { 9566 new mmForm(options); 9567 }); 9568 }); 9569 }); 9570 });</script>
vendor: 1 bytes, line 9570
9570
9571<script> 9572 'use strict'; 9573 (() => { 9574 document.getElementById("captcha-container-cvQP2X").innerHTML = '<div class="captcha-wrapper" x-data="mmWebformsCaptchaDatacvQP2X" x-init="initCaptcha"><input type="hidden" name="g-recaptcha-response" class="required-entry"/><div class="recaptcha-position-bottomright"><div class="recaptcha-container"></div></div></div>'; 9575 })();</script>
vendor: 1 bytes, line 9575
9575
9576<script> 9577 function mmWebformsCaptchaDatacvQP2X() { 9578 return { 9579 initCaptcha() { 9580 const options = { 9581 globalOnLoadCallback: 'webformsCaptchaOnload', 9582 captchaReadyEvent: 'webformsCaptchaApiReady', 9583 languageCode: 'en', 9584 publicKey: '6LfHDCMrAAAAACnDJl581eICSW3VnauItgp_hR2S', 9585 scriptId: 'mm_captcha', 9586 scriptExists: false, 9587 responseFieldName: 'g-recaptcha-response', 9588 version: '3', 9589 position: 'bottomright', 9590 theme: 'standard', 9591 action: '', 9592 checkboxChallenge: false, 9593 render: 'explicit' 9594 } 9595 9596 addCaptchaScriptTag(); 9597 let captcha; 9598 try { 9599 captcha = getCaptchaObject(); 9600 } catch { 9601 captcha = false; 9602 } 9603 if (captcha && captcha.render) { 9604 initCaptcha(); 9605 } else { 9606 window.addEventListener(options.captchaReadyEvent, function () { 9607 initCaptcha(); 9608 }); 9609 } 9610 9611 function initCaptcha() { 9612 const captcha = getCaptchaObject(); 9613 const params = {theme: options.theme, sitekey: options.publicKey}; 9614 9615 9616 if (isEnterprise() && options.checkboxChallenge) { 9617 params.size = 'normal'; 9618 params.callback = saveToken; 9619 } else if (isEnterprise() && !options.checkboxChallenge) { 9620 9621 params.size = 'invisible'; 9622 } else if (getIsInvisibleRecaptcha()) { 9623 params.size = 'invisible'; 9624 } else { 9625 params.callback = saveToken; 9626 } 9627 9628 const self = this; 9629 captcha.ready(function () { 9630 const captchaDivs = document.querySelectorAll('[class="recaptcha-container"]'); 9631 for (let i = 0; i < captchaDivs.length; i++) { 9632 try { 9633 const cid = captcha.render(captchaDivs[i], params); 9634 captchaDivs[i].setAttribute('cid', cid); 9635 } catch (e) { /* recaptcha was already rendered */ } 9636 } 9637 9638 window.addEventListener('mm-form-captcha-promise', (e) => { 9639 let cid = null; 9640 let form = null; 9641 if (e && e.detail) { 9642 cid = e.detail.cid; 9643 form = e.detail.form; 9644 } 9645 if (typeof cid === "undefined" || cid === null) { 9646 return; 9647 } 9648 if (typeof form === "undefined" || form === null) { 9649 return; 9650 } 9651 captcha.reset(cid); 9652 form.setCaptchaPromise(getToken.bind(self), self); 9653 }); 9654 9655 window.addEventListener('mm-form-captcha-reload', (e) => { 9656 let cid = null; 9657 if (e && e.detail) { 9658 cid = e.detail.cid; 9659 } 9660 if (typeof cid === "undefined" || cid === null) { 9661 return; 9662 } 9663 captcha.reset(cid); 9664 }); 9665 }) 9666 9667 function getToken(cid, form) { 9668 const captcha = getCaptchaObject(); 9669 switch (options.version) { 9670 case '3': { 9671 return captcha.execute(cid); 9672 } 9673 case 'enterprise': { 9674 9675 if (options.checkboxChallenge) { 9676 return new Promise(async (resolve, reject) => { 9677 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 9678 if (token) { 9679 resolve(token.value); 9680 } 9681 resolve(''); 9682 }); 9683 } 9684 return captcha.execute(cid, {action: options.action}); 9685 } 9686 default: { 9687 return new Promise(async (resolve, reject) => { 9688 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 9689 if (token) { 9690 resolve(token.value); 9691 } 9692 resolve(''); 9693 }); 9694 } 9695 } 9696 } 9697 9698 function saveToken(token) { 9699 const rFields = document.querySelectorAll(`[name="${options.responseFieldName}"]`); 9700 for (let i = 0; i < rFields.length; i++) { 9701 rFields[i].value = token; 9702 } 9703 } 9704 } 9705
9706 function getIsInvisibleRecaptcha() { 9707 return options.version === '3'; 9708 } 9709 9710 function isEnterprise() { 9711 return options.version === 'enterprise'; 9712 } 9713 9714 function addCaptchaScriptTag() { 9715 if (!document.getElementById(options.scriptId)) { 9716 const script = document.createElement('script'); 9717 const firstScriptTag = document.getElementsByTagName('script')[0]; 9718 const api = isEnterprise() ? 'enterprise' : 'api'; 9719 9720 script.async = true; 9721 script.defer = true; 9722 9723 script.src = `https://www.google.com/recaptcha/${api}.js?render=${options.render}`; 9724 9725 if (options.languageCode) { 9726 script.src += `&hl=${options.languageCode}` 9727 } 9728 if (options.position) { 9729 script.src += `&badge=${options.position}` 9730 } 9731 script.onload = () => { 9732 window.dispatchEvent(new CustomEvent(options.captchaReadyEvent)); 9733 } 9734 firstScriptTag.parentNode.insertBefore(script, firstScriptTag); 9735 } 9736 options.scriptExists = true; 9737 } 9738 9739 function getCaptchaObject() { 9740 return isEnterprise() ? window.grecaptcha.enterprise : window.grecaptcha; 9741 } 9742 } 9743 } 9744 } 9745 9746 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsCaptchaDatacvQP2X', mmWebformsCaptchaDatacvQP2X), {once: true});</script>
vendor: 1 bytes, line 9746
9746
9747<script> 9748 9749 [...document.getElementById('webform_cvQP2X_form').querySelectorAll("input")].forEach((input) => { 9750 input.onkeydown = function(e) { 9751 const key = e.charCode || e.keyCode || 0; 9752 if (key === 13) { 9753 const index = [...input.form].indexOf(this); 9754 if (input.form.elements[index + 1] != null) { 9755 input.form.elements[index + 1].focus(); 9756 } 9757 e.preventDefault(); 9758 return false; 9759 } 9760 } 9761 }); 9762 9763 9764 </script>
vendor: 1 bytes, line 9764
9764
9765<script defer> 9766 (() => { 9767 window.dispatchEvent(new CustomEvent("mm_webform_loadedcvQP2X")); 9768 })();</script>
vendor: 1 bytes, line 9768
9768
9769<script> 9770 function mmWebformsEmailDatafieldFAq7sZ41() { 9771 return Object.assign( 9772 MageMe.WebForms.customerData(), 9773 { 9774 trimSpace() { 9775 if (this.$el.value.search(' ') >= 0) { 9776 this.$el.value =Â this.$el.value.replace(' ',''); 9777 } 9778 }, 9779 setCustomerData(event) { 9780 this.receiveCustomerData(event.detail.data) 9781 if (this.$el) { 9782 this.$el.value = this.customer['customer_email'] ?? ''; 9783 } 9784 }, 9785 } 9786 ); 9787 } 9788 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsEmailDatafieldFAq7sZ41', mmWebformsEmailDatafieldFAq7sZ41), {once: true});</script>
vendor: 1 bytes, line 9788
9788
9789<script> 9790 function mmWebformsTextareaDatafieldFAq7sZ47() { 9791 return Object.assign( 9792 MageMe.WebForms.customerData(), 9793 { 9794 setCustomerData(event) { 9795 this.receiveCustomerData(event.detail.data) 9796 if (this.$el) { 9797 this.$el.value = this.customer[this.$el.dataset.hyvacspCustomerData] ?? ''; 9798 } 9799 }, 9800 } 9801 ); 9802 } 9803 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsTextareaDatafieldFAq7sZ47', mmWebformsTextareaDatafieldFAq7sZ47), {once: true});</script>
vendor: 1 bytes, line 9803
9803
9804<script> 9805 'use strict'; 9806 9807 window.addEventListener('private-content-loaded', () => { 9808 MageMe.loader.addScript('swal', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Fsweetalert2.min.js", () => { 9809 MageMe.loader.addScript('tingle', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Ftingle.min.js", () => { 9810 const options = { 9811 "submitUrl": "https://www.banham.co.uk/webforms/form/submit/ajax/1/", 9812 "uid": "FAq7sZ", 9813 "formId": "4", 9814 "ajax": true, 9815 "success": false, 9816 "displayAfterSubmission": true, 9817 "scrollAfterSubmission": true, 9818 "showReview": false, 9819 "saveDataLocal": false, 9820 "useCaptcha": true, 9821 "captchaResponseName": "g-recaptcha-response", 9822 "messages": { 9823 "success": "Success!", 9824 "redirecting": "Redirecting", 9825 "complete": "Complete", 9826 "error": "Error", 9827 "captchaTxt": "Please click on the Captcha", 9828 "errorTxt": "Error(s) occurred. Please try again.", 9829 "unknownTxt": "Unknown error(s) occurred" 9830 } 9831 } 9832 9833 options.afterInit = (form) => { 9834 document.body.addEventListener('touchstart', MageMe.WebForms.loadValidation, {once: true}); 9835 document.body.addEventListener('mouseover', MageMe.WebForms.loadValidation, {once: true}); 9836 } 9837 9838 options.validationCb = (form, valid) => new Promise(async (resolve, reject) => { 9839 if (!valid) { 9840 resolve(false); 9841 } 9842 MageMe.WebForms.loadValidation().then(() => { 9843 return MageMe.WebForms.formValidation(form.controls.form, { 9844 fieldWrapperClassName: 'control', 9845 messagesWrapperClassName: 'hyva-validation' 9846 }); 9847 }).then(validator => { 9848 return validator.validate(); 9849 }).then(() => { 9850 resolve(true); 9851 }).catch((er) => { 9852 resolve(false); 9853 }); 9854 }); 9855 options.fieldValidationCb = (field, form, valid) => new Promise(async (resolve, reject) => { 9856 if (!valid) { 9857 resolve(false); 9858 } 9859 MageMe.WebForms.loadValidation().then(() => { 9860 return MageMe.WebForms.formValidation(form.controls.form, { 9861 fieldWrapperClassName: 'control', 9862 messagesWrapperClassName: 'hyva-validation' 9863 }); 9864 }).then(validator => { 9865 validator.setupField(field); 9866 const fieldObj = validator.fields[field.name]; 9867 return validator.validateField(fieldObj); 9868 }).then((isValid) => { 9869 resolve(isValid); 9870 }).catch((er) => { 9871 resolve(false); 9872 }); 9873 }); 9874 9875 options.getFormKey = () => { 9876 return hyva.getCookie('form_key'); 9877 }; 9878 options.swal = swal; 9879 options.tingle = tingle; 9880 9881 MageMe.loader.addScript('mmForm', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fform.min.js", () => { 9882 new mmForm(options); 9883 }); 9884 }); 9885 }); 9886 });</script>
vendor: 1 bytes, line 9886
9886
9887<script type="text/javascript"> 9888 let logicRules_FAq7sZ = []; 9889 const targets_FAq7sZ = [{"id":"field_FAq7sZ89","logic_visibility":"hidden","required":true},{"id":"field_FAq7sZ86","logic_visibility":"hidden","required":true}]; 9890 const fieldMap_FAq7sZ = {"fieldset_0":["80","86","89","98","41","47","56","59","65","68","71","92","submit"]}; 9891 logicRules_FAq7sZ.push({ 9892 'field_id': '80', 9893 'action': 'show', 9894 'logic_condition': 'equal', 9895 'aggregation': 'any', 9896 'value': [1], 9897 'target': ["field_FAq7sZ89"] }); 9898 logicRules_FAq7sZ.push({ 9899 'field_id': '80', 9900 'action': 'show', 9901 'logic_condition': 'equal', 9902 'aggregation': 'any', 9903 'value': [], 9904 'target': ["field_FAq7sZ86"] }); 9905 window.addEventListener("mm_webform_loadedFAq7sZ", () => { 9906 MageMe.loader.addScript('mmLogic', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Flogic.min.js", () => { 9907 new mmLogic({ 9908 targets: targets_FAq7sZ, 9909 logicRules: logicRules_FAq7sZ, 9910 fieldMap: fieldMap_FAq7sZ, 9911 uid: 'FAq7sZ', 9912 containerId: "webform_FAq7sZ_form" 9913 }); 9914 }); 9915 });</script>
vendor: 1 bytes, line 9915
9915
9916<script> 9917 'use strict'; 9918 (() => { 9919 document.getElementById("captcha-container-FAq7sZ").innerHTML = '<div class="captcha-wrapper" x-data="mmWebformsCaptchaDataFAq7sZ" x-init="initCaptcha"><input type="hidden" name="g-recaptcha-response" class="required-entry"/><div class="recaptcha-position-bottomright"><div class="recaptcha-container"></div></div></div>'; 9920 })();</script>
vendor: 1 bytes, line 9920
9920
9921<script> 9922 function mmWebformsCaptchaDataFAq7sZ() { 9923 return { 9924 initCaptcha() { 9925 const options = { 9926 globalOnLoadCallback: 'webformsCaptchaOnload', 9927 captchaReadyEvent: 'webformsCaptchaApiReady', 9928 languageCode: 'en', 9929 publicKey: '6LfHDCMrAAAAACnDJl581eICSW3VnauItgp_hR2S', 9930 scriptId: 'mm_captcha', 9931 scriptExists: false, 9932 responseFieldName: 'g-recaptcha-response', 9933 version: '3', 9934 position: 'bottomright', 9935 theme: 'standard', 9936 action: '', 9937 checkboxChallenge: false, 9938 render: 'explicit' 9939 } 9940 9941 addCaptchaScriptTag(); 9942 let captcha; 9943 try { 9944 captcha = getCaptchaObject(); 9945 } catch { 9946 captcha = false; 9947 } 9948 if (captcha && captcha.render) { 9949 initCaptcha(); 9950 } else { 9951 window.addEventListener(options.captchaReadyEvent, function () { 9952 initCaptcha(); 9953 }); 9954 } 9955 9956 function initCaptcha() { 9957 const captcha = getCaptchaObject(); 9958 const params = {theme: options.theme, sitekey: options.publicKey}; 9959 9960 9961 if (isEnterprise() && options.checkboxChallenge) { 9962 params.size = 'normal'; 9963 params.callback = saveToken; 9964 } else if (isEnterprise() && !options.checkboxChallenge) { 9965 9966 params.size = 'invisible'; 9967 } else if (getIsInvisibleRecaptcha()) { 9968 params.size = 'invisible'; 9969 } else { 9970 params.callback = saveToken; 9971 } 9972 9973 const self = this; 9974 captcha.ready(function () { 9975 const captchaDivs = document.querySelectorAll('[class="recaptcha-container"]'); 9976 for (let i = 0; i < captchaDivs.length; i++) { 9977 try { 9978 const cid = captcha.render(captchaDivs[i], params); 9979 captchaDivs[i].setAttribute('cid', cid); 9980 } catch (e) { /* recaptcha was already rendered */ } 9981 } 9982 9983 window.addEventListener('mm-form-captcha-promise', (e) => { 9984 let cid = null; 9985 let form = null; 9986 if (e && e.detail) { 9987 cid = e.detail.cid; 9988 form = e.detail.form; 9989 } 9990 if (typeof cid === "undefined" || cid === null) { 9991 return; 9992 } 9993 if (typeof form === "undefined" || form === null) { 9994 return; 9995 } 9996 captcha.reset(cid); 9997 form.setCaptchaPromise(getToken.bind(self), self); 9998 }); 9999 10000 window.addEventListener('mm-form-captcha-reload', (e) => { 10001 let cid = null; 10002 if (e && e.detail) { 10003 cid = e.detail.cid; 10004 } 10005 if (typeof cid === "undefined" || cid === null) { 10006 return; 10007 } 10008 captcha.reset(cid); 10009 }); 10010 }) 10011 10012 function getToken(cid, form) { 10013 const captcha = getCaptchaObject(); 10014 switch (options.version) { 10015 case '3': { 10016 return captcha.execute(cid); 10017 } 10018 case 'enterprise': { 10019 10020 if (options.checkboxChallenge) { 10021 return new Promise(async (resolve, reject) => { 10022 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 10023 if (token) { 10024 resolve(token.value); 10025 } 10026 resolve(''); 10027 }); 10028 } 10029 return captcha.execute(cid, {action: options.action}); 10030 } 10031 default: { 10032 return new Promise(async (resolve, reject) => { 10033 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 10034 if (token) { 10035 resolve(token.value); 10036 } 10037 resolve(''); 10038 }); 10039 } 10040 } 10041 } 10042 10043 function saveToken(token) { 10044 const rFields = document.querySelectorAll(`[name="${options.responseFieldName}"]`); 10045 for (let i = 0; i < rFields.length; i++) { 10046 rFields[i].value = token; 10047 } 10048 } 10049 } 10050
10051 function getIsInvisibleRecaptcha() { 10052 return options.version === '3'; 10053 } 10054 10055 function isEnterprise() { 10056 return options.version === 'enterprise'; 10057 } 10058 10059 function addCaptchaScriptTag() { 10060 if (!document.getElementById(options.scriptId)) { 10061 const script = document.createElement('script'); 10062 const firstScriptTag = document.getElementsByTagName('script')[0]; 10063 const api = isEnterprise() ? 'enterprise' : 'api'; 10064 10065 script.async = true; 10066 script.defer = true; 10067 10068 script.src = `https://www.google.com/recaptcha/${api}.js?render=${options.render}`; 10069 10070 if (options.languageCode) { 10071 script.src += `&hl=${options.languageCode}` 10072 } 10073 if (options.position) { 10074 script.src += `&badge=${options.position}` 10075 } 10076 script.onload = () => { 10077 window.dispatchEvent(new CustomEvent(options.captchaReadyEvent)); 10078 } 10079 firstScriptTag.parentNode.insertBefore(script, firstScriptTag); 10080 } 10081 options.scriptExists = true; 10082 } 10083 10084 function getCaptchaObject() { 10085 return isEnterprise() ? window.grecaptcha.enterprise : window.grecaptcha; 10086 } 10087 } 10088 } 10089 } 10090 10091 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsCaptchaDataFAq7sZ', mmWebformsCaptchaDataFAq7sZ), {once: true});</script>
vendor: 1 bytes, line 10091
10091
10092<script> 10093 10094 [...document.getElementById('webform_FAq7sZ_form').querySelectorAll("input")].forEach((input) => { 10095 input.onkeydown = function(e) { 10096 const key = e.charCode || e.keyCode || 0; 10097 if (key === 13) { 10098 const index = [...input.form].indexOf(this); 10099 if (input.form.elements[index + 1] != null) { 10100 input.form.elements[index + 1].focus(); 10101 } 10102 e.preventDefault(); 10103 return false; 10104 } 10105 } 10106 }); 10107 10108 10109 </script>
vendor: 1 bytes, line 10109
10109
10110<script defer> 10111 (() => { 10112 window.dispatchEvent(new CustomEvent("mm_webform_loadedFAq7sZ")); 10113 })();</script>
vendor: 1 bytes, line 10113
10113
10114<script> 10115 function mmWebformsEmailDatafieldSSA2ZV41() { 10116 return Object.assign( 10117 MageMe.WebForms.customerData(), 10118 { 10119 trimSpace() { 10120 if (this.$el.value.search(' ') >= 0) { 10121 this.$el.value =Â this.$el.value.replace(' ',''); 10122 } 10123 }, 10124 setCustomerData(event) { 10125 this.receiveCustomerData(event.detail.data) 10126 if (this.$el) { 10127 this.$el.value = this.customer['customer_email'] ?? ''; 10128 } 10129 }, 10130 } 10131 ); 10132 } 10133 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsEmailDatafieldSSA2ZV41', mmWebformsEmailDatafieldSSA2ZV41), {once: true});</script>
vendor: 1 bytes, line 10133
10133
10134<script> 10135 function mmWebformsTextareaDatafieldSSA2ZV47() { 10136 return Object.assign( 10137 MageMe.WebForms.customerData(), 10138 { 10139 setCustomerData(event) { 10140 this.receiveCustomerData(event.detail.data) 10141 if (this.$el) { 10142 this.$el.value = this.customer[this.$el.dataset.hyvacspCustomerData] ?? ''; 10143 } 10144 }, 10145 } 10146 ); 10147 } 10148 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsTextareaDatafieldSSA2ZV47', mmWebformsTextareaDatafieldSSA2ZV47), {once: true});</script>
vendor: 1 bytes, line 10148
10148
10149<script> 10150 'use strict'; 10151 10152 window.addEventListener('private-content-loaded', () => { 10153 MageMe.loader.addScript('swal', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Fsweetalert2.min.js", () => { 10154 MageMe.loader.addScript('tingle', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Ftingle.min.js", () => { 10155 const options = { 10156 "submitUrl": "https://www.banham.co.uk/webforms/form/submit/ajax/1/", 10157 "uid": "SSA2ZV", 10158 "formId": "4", 10159 "ajax": true, 10160 "success": false, 10161 "displayAfterSubmission": true, 10162 "scrollAfterSubmission": true, 10163 "showReview": false, 10164 "saveDataLocal": false, 10165 "useCaptcha": true, 10166 "captchaResponseName": "g-recaptcha-response", 10167 "messages": { 10168 "success": "Success!", 10169 "redirecting": "Redirecting", 10170 "complete": "Complete", 10171 "error": "Error", 10172 "captchaTxt": "Please click on the Captcha", 10173 "errorTxt": "Error(s) occurred. Please try again.", 10174 "unknownTxt": "Unknown error(s) occurred" 10175 } 10176 } 10177 10178 options.afterInit = (form) => { 10179 document.body.addEventListener('touchstart', MageMe.WebForms.loadValidation, {once: true}); 10180 document.body.addEventListener('mouseover', MageMe.WebForms.loadValidation, {once: true}); 10181 } 10182 10183 options.validationCb = (form, valid) => new Promise(async (resolve, reject) => { 10184 if (!valid) { 10185 resolve(false); 10186 } 10187 MageMe.WebForms.loadValidation().then(() => { 10188 return MageMe.WebForms.formValidation(form.controls.form, { 10189 fieldWrapperClassName: 'control', 10190 messagesWrapperClassName: 'hyva-validation' 10191 }); 10192 }).then(validator => { 10193 return validator.validate(); 10194 }).then(() => { 10195 resolve(true); 10196 }).catch((er) => { 10197 resolve(false); 10198 }); 10199 }); 10200 options.fieldValidationCb = (field, form, valid) => new Promise(async (resolve, reject) => { 10201 if (!valid) { 10202 resolve(false); 10203 } 10204 MageMe.WebForms.loadValidation().then(() => { 10205 return MageMe.WebForms.formValidation(form.controls.form, { 10206 fieldWrapperClassName: 'control', 10207 messagesWrapperClassName: 'hyva-validation' 10208 }); 10209 }).then(validator => { 10210 validator.setupField(field); 10211 const fieldObj = validator.fields[field.name]; 10212 return validator.validateField(fieldObj); 10213 }).then((isValid) => { 10214 resolve(isValid); 10215 }).catch((er) => { 10216 resolve(false); 10217 }); 10218 }); 10219 10220 options.getFormKey = () => { 10221 return hyva.getCookie('form_key'); 10222 }; 10223 options.swal = swal; 10224 options.tingle = tingle; 10225 10226 MageMe.loader.addScript('mmForm', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fform.min.js", () => { 10227 new mmForm(options); 10228 }); 10229 }); 10230 }); 10231 });</script>
vendor: 1 bytes, line 10231
10231
10232<script type="text/javascript"> 10233 let logicRules_SSA2ZV = []; 10234 const targets_SSA2ZV = [{"id":"field_SSA2ZV89","logic_visibility":"hidden","required":true},{"id":"field_SSA2ZV86","logic_visibility":"hidden","required":true}]; 10235 const fieldMap_SSA2ZV = {"fieldset_0":["80","86","89","98","41","47","56","59","65","68","71","92","submit"]}; 10236 logicRules_SSA2ZV.push({ 10237 'field_id': '80', 10238 'action': 'show', 10239 'logic_condition': 'equal', 10240 'aggregation': 'any', 10241 'value': [1], 10242 'target': ["field_SSA2ZV89"] }); 10243 logicRules_SSA2ZV.push({ 10244 'field_id': '80', 10245 'action': 'show', 10246 'logic_condition': 'equal', 10247 'aggregation': 'any', 10248 'value': [], 10249 'target': ["field_SSA2ZV86"] }); 10250 window.addEventListener("mm_webform_loadedSSA2ZV", () => { 10251 MageMe.loader.addScript('mmLogic', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Flogic.min.js", () => { 10252 new mmLogic({ 10253 targets: targets_SSA2ZV, 10254 logicRules: logicRules_SSA2ZV, 10255 fieldMap: fieldMap_SSA2ZV, 10256 uid: 'SSA2ZV', 10257 containerId: "webform_SSA2ZV_form" 10258 }); 10259 }); 10260 });</script>
vendor: 1 bytes, line 10260
10260
10261<script> 10262 'use strict'; 10263 (() => { 10264 document.getElementById("captcha-container-SSA2ZV").innerHTML = '<div class="captcha-wrapper" x-data="mmWebformsCaptchaDataSSA2ZV" x-init="initCaptcha"><input type="hidden" name="g-recaptcha-response" class="required-entry"/><div class="recaptcha-position-bottomright"><div class="recaptcha-container"></div></div></div>'; 10265 })();</script>
vendor: 1 bytes, line 10265
10265
10266<script> 10267 function mmWebformsCaptchaDataSSA2ZV() { 10268 return { 10269 initCaptcha() { 10270 const options = { 10271 globalOnLoadCallback: 'webformsCaptchaOnload', 10272 captchaReadyEvent: 'webformsCaptchaApiReady', 10273 languageCode: 'en', 10274 publicKey: '6LfHDCMrAAAAACnDJl581eICSW3VnauItgp_hR2S', 10275 scriptId: 'mm_captcha', 10276 scriptExists: false, 10277 responseFieldName: 'g-recaptcha-response', 10278 version: '3', 10279 position: 'bottomright', 10280 theme: 'standard', 10281 action: '', 10282 checkboxChallenge: false, 10283 render: 'explicit' 10284 } 10285 10286 addCaptchaScriptTag(); 10287 let captcha; 10288 try { 10289 captcha = getCaptchaObject(); 10290 } catch { 10291 captcha = false; 10292 } 10293 if (captcha && captcha.render) { 10294 initCaptcha(); 10295 } else { 10296 window.addEventListener(options.captchaReadyEvent, function () { 10297 initCaptcha(); 10298 }); 10299 } 10300 10301 function initCaptcha() { 10302 const captcha = getCaptchaObject(); 10303 const params = {theme: options.theme, sitekey: options.publicKey}; 10304 10305 10306 if (isEnterprise() && options.checkboxChallenge) { 10307 params.size = 'normal'; 10308 params.callback = saveToken; 10309 } else if (isEnterprise() && !options.checkboxChallenge) { 10310 10311 params.size = 'invisible'; 10312 } else if (getIsInvisibleRecaptcha()) { 10313 params.size = 'invisible'; 10314 } else { 10315 params.callback = saveToken; 10316 } 10317 10318 const self = this; 10319 captcha.ready(function () { 10320 const captchaDivs = document.querySelectorAll('[class="recaptcha-container"]'); 10321 for (let i = 0; i < captchaDivs.length; i++) { 10322 try { 10323 const cid = captcha.render(captchaDivs[i], params); 10324 captchaDivs[i].setAttribute('cid', cid); 10325 } catch (e) { /* recaptcha was already rendered */ } 10326 } 10327 10328 window.addEventListener('mm-form-captcha-promise', (e) => { 10329 let cid = null; 10330 let form = null; 10331 if (e && e.detail) { 10332 cid = e.detail.cid; 10333 form = e.detail.form; 10334 } 10335 if (typeof cid === "undefined" || cid === null) { 10336 return; 10337 } 10338 if (typeof form === "undefined" || form === null) { 10339 return; 10340 } 10341 captcha.reset(cid); 10342 form.setCaptchaPromise(getToken.bind(self), self); 10343 }); 10344 10345 window.addEventListener('mm-form-captcha-reload', (e) => { 10346 let cid = null; 10347 if (e && e.detail) { 10348 cid = e.detail.cid; 10349 } 10350 if (typeof cid === "undefined" || cid === null) { 10351 return; 10352 } 10353 captcha.reset(cid); 10354 }); 10355 }) 10356 10357 function getToken(cid, form) { 10358 const captcha = getCaptchaObject(); 10359 switch (options.version) { 10360 case '3': { 10361 return captcha.execute(cid); 10362 } 10363 case 'enterprise': { 10364 10365 if (options.checkboxChallenge) { 10366 return new Promise(async (resolve, reject) => { 10367 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 10368 if (token) { 10369 resolve(token.value); 10370 } 10371 resolve(''); 10372 }); 10373 } 10374 return captcha.execute(cid, {action: options.action}); 10375 } 10376 default: { 10377 return new Promise(async (resolve, reject) => { 10378 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 10379 if (token) { 10380 resolve(token.value); 10381 } 10382 resolve(''); 10383 }); 10384 } 10385 } 10386 } 10387 10388 function saveToken(token) { 10389 const rFields = document.querySelectorAll(`[name="${options.responseFieldName}"]`); 10390 for (let i = 0; i < rFields.length; i++) { 10391 rFields[i].value = token; 10392 } 10393 } 10394 } 10395
10396 function getIsInvisibleRecaptcha() { 10397 return options.version === '3'; 10398 } 10399 10400 function isEnterprise() { 10401 return options.version === 'enterprise'; 10402 } 10403 10404 function addCaptchaScriptTag() { 10405 if (!document.getElementById(options.scriptId)) { 10406 const script = document.createElement('script'); 10407 const firstScriptTag = document.getElementsByTagName('script')[0]; 10408 const api = isEnterprise() ? 'enterprise' : 'api'; 10409 10410 script.async = true; 10411 script.defer = true; 10412 10413 script.src = `https://www.google.com/recaptcha/${api}.js?render=${options.render}`; 10414 10415 if (options.languageCode) { 10416 script.src += `&hl=${options.languageCode}` 10417 } 10418 if (options.position) { 10419 script.src += `&badge=${options.position}` 10420 } 10421 script.onload = () => { 10422 window.dispatchEvent(new CustomEvent(options.captchaReadyEvent)); 10423 } 10424 firstScriptTag.parentNode.insertBefore(script, firstScriptTag); 10425 } 10426 options.scriptExists = true; 10427 } 10428 10429 function getCaptchaObject() { 10430 return isEnterprise() ? window.grecaptcha.enterprise : window.grecaptcha; 10431 } 10432 } 10433 } 10434 } 10435 10436 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsCaptchaDataSSA2ZV', mmWebformsCaptchaDataSSA2ZV), {once: true});</script>
vendor: 1 bytes, line 10436
10436
10437<script> 10438 10439 [...document.getElementById('webform_SSA2ZV_form').querySelectorAll("input")].forEach((input) => { 10440 input.onkeydown = function(e) { 10441 const key = e.charCode || e.keyCode || 0; 10442 if (key === 13) { 10443 const index = [...input.form].indexOf(this); 10444 if (input.form.elements[index + 1] != null) { 10445 input.form.elements[index + 1].focus(); 10446 } 10447 e.preventDefault(); 10448 return false; 10449 } 10450 } 10451 }); 10452 10453 10454 </script>
vendor: 1 bytes, line 10454
10454
10455<script defer> 10456 (() => { 10457 window.dispatchEvent(new CustomEvent("mm_webform_loadedSSA2ZV")); 10458 })();</script>
vendor: 1 bytes, line 10458
10458
10459<script> 10460 function mmWebformsEmailDatafieldXFDzRA41() { 10461 return Object.assign( 10462 MageMe.WebForms.customerData(), 10463 { 10464 trimSpace() { 10465 if (this.$el.value.search(' ') >= 0) { 10466 this.$el.value =Â this.$el.value.replace(' ',''); 10467 } 10468 }, 10469 setCustomerData(event) { 10470 this.receiveCustomerData(event.detail.data) 10471 if (this.$el) { 10472 this.$el.value = this.customer['customer_email'] ?? ''; 10473 } 10474 }, 10475 } 10476 ); 10477 } 10478 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsEmailDatafieldXFDzRA41', mmWebformsEmailDatafieldXFDzRA41), {once: true});</script>
vendor: 1 bytes, line 10478
10478
10479<script> 10480 function mmWebformsTextareaDatafieldXFDzRA47() { 10481 return Object.assign( 10482 MageMe.WebForms.customerData(), 10483 { 10484 setCustomerData(event) { 10485 this.receiveCustomerData(event.detail.data) 10486 if (this.$el) { 10487 this.$el.value = this.customer[this.$el.dataset.hyvacspCustomerData] ?? ''; 10488 } 10489 }, 10490 } 10491 ); 10492 } 10493 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsTextareaDatafieldXFDzRA47', mmWebformsTextareaDatafieldXFDzRA47), {once: true});</script>
vendor: 1 bytes, line 10493
10493
10494<script> 10495 'use strict'; 10496 10497 window.addEventListener('private-content-loaded', () => { 10498 MageMe.loader.addScript('swal', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Fsweetalert2.min.js", () => { 10499 MageMe.loader.addScript('tingle', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Ftingle.min.js", () => { 10500 const options = { 10501 "submitUrl": "https://www.banham.co.uk/webforms/form/submit/ajax/1/", 10502 "uid": "XFDzRA", 10503 "formId": "4", 10504 "ajax": true, 10505 "success": false, 10506 "displayAfterSubmission": true, 10507 "scrollAfterSubmission": true, 10508 "showReview": false, 10509 "saveDataLocal": false, 10510 "useCaptcha": true, 10511 "captchaResponseName": "g-recaptcha-response", 10512 "messages": { 10513 "success": "Success!", 10514 "redirecting": "Redirecting", 10515 "complete": "Complete", 10516 "error": "Error", 10517 "captchaTxt": "Please click on the Captcha", 10518 "errorTxt": "Error(s) occurred. Please try again.", 10519 "unknownTxt": "Unknown error(s) occurred" 10520 } 10521 } 10522 10523 options.afterInit = (form) => { 10524 document.body.addEventListener('touchstart', MageMe.WebForms.loadValidation, {once: true}); 10525 document.body.addEventListener('mouseover', MageMe.WebForms.loadValidation, {once: true}); 10526 } 10527 10528 options.validationCb = (form, valid) => new Promise(async (resolve, reject) => { 10529 if (!valid) { 10530 resolve(false); 10531 } 10532 MageMe.WebForms.loadValidation().then(() => { 10533 return MageMe.WebForms.formValidation(form.controls.form, { 10534 fieldWrapperClassName: 'control', 10535 messagesWrapperClassName: 'hyva-validation' 10536 }); 10537 }).then(validator => { 10538 return validator.validate(); 10539 }).then(() => { 10540 resolve(true); 10541 }).catch((er) => { 10542 resolve(false); 10543 }); 10544 }); 10545 options.fieldValidationCb = (field, form, valid) => new Promise(async (resolve, reject) => { 10546 if (!valid) { 10547 resolve(false); 10548 } 10549 MageMe.WebForms.loadValidation().then(() => { 10550 return MageMe.WebForms.formValidation(form.controls.form, { 10551 fieldWrapperClassName: 'control', 10552 messagesWrapperClassName: 'hyva-validation' 10553 }); 10554 }).then(validator => { 10555 validator.setupField(field); 10556 const fieldObj = validator.fields[field.name]; 10557 return validator.validateField(fieldObj); 10558 }).then((isValid) => { 10559 resolve(isValid); 10560 }).catch((er) => { 10561 resolve(false); 10562 }); 10563 }); 10564 10565 options.getFormKey = () => { 10566 return hyva.getCookie('form_key'); 10567 }; 10568 options.swal = swal; 10569 options.tingle = tingle; 10570 10571 MageMe.loader.addScript('mmForm', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fform.min.js", () => { 10572 new mmForm(options); 10573 }); 10574 }); 10575 }); 10576 });</script>
vendor: 1 bytes, line 10576
10576
10577<script type="text/javascript"> 10578 let logicRules_XFDzRA = []; 10579 const targets_XFDzRA = [{"id":"field_XFDzRA89","logic_visibility":"hidden","required":true},{"id":"field_XFDzRA86","logic_visibility":"hidden","required":true}]; 10580 const fieldMap_XFDzRA = {"fieldset_0":["80","86","89","98","41","47","56","59","65","68","71","92","submit"]}; 10581 logicRules_XFDzRA.push({ 10582 'field_id': '80', 10583 'action': 'show', 10584 'logic_condition': 'equal', 10585 'aggregation': 'any', 10586 'value': [1], 10587 'target': ["field_XFDzRA89"] }); 10588 logicRules_XFDzRA.push({ 10589 'field_id': '80', 10590 'action': 'show', 10591 'logic_condition': 'equal', 10592 'aggregation': 'any', 10593 'value': [], 10594 'target': ["field_XFDzRA86"] }); 10595 window.addEventListener("mm_webform_loadedXFDzRA", () => { 10596 MageMe.loader.addScript('mmLogic', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Flogic.min.js", () => { 10597 new mmLogic({ 10598 targets: targets_XFDzRA, 10599 logicRules: logicRules_XFDzRA, 10600 fieldMap: fieldMap_XFDzRA, 10601 uid: 'XFDzRA', 10602 containerId: "webform_XFDzRA_form" 10603 }); 10604 }); 10605 });</script>
vendor: 1 bytes, line 10605
10605
10606<script> 10607 'use strict'; 10608 (() => { 10609 document.getElementById("captcha-container-XFDzRA").innerHTML = '<div class="captcha-wrapper" x-data="mmWebformsCaptchaDataXFDzRA" x-init="initCaptcha"><input type="hidden" name="g-recaptcha-response" class="required-entry"/><div class="recaptcha-position-bottomright"><div class="recaptcha-container"></div></div></div>'; 10610 })();</script>
vendor: 1 bytes, line 10610
10610
10611<script> 10612 function mmWebformsCaptchaDataXFDzRA() { 10613 return { 10614 initCaptcha() { 10615 const options = { 10616 globalOnLoadCallback: 'webformsCaptchaOnload', 10617 captchaReadyEvent: 'webformsCaptchaApiReady', 10618 languageCode: 'en', 10619 publicKey: '6LfHDCMrAAAAACnDJl581eICSW3VnauItgp_hR2S', 10620 scriptId: 'mm_captcha', 10621 scriptExists: false, 10622 responseFieldName: 'g-recaptcha-response', 10623 version: '3', 10624 position: 'bottomright', 10625 theme: 'standard', 10626 action: '', 10627 checkboxChallenge: false, 10628 render: 'explicit' 10629 } 10630 10631 addCaptchaScriptTag(); 10632 let captcha; 10633 try { 10634 captcha = getCaptchaObject(); 10635 } catch { 10636 captcha = false; 10637 } 10638 if (captcha && captcha.render) { 10639 initCaptcha(); 10640 } else { 10641 window.addEventListener(options.captchaReadyEvent, function () { 10642 initCaptcha(); 10643 }); 10644 } 10645 10646 function initCaptcha() { 10647 const captcha = getCaptchaObject(); 10648 const params = {theme: options.theme, sitekey: options.publicKey}; 10649 10650 10651 if (isEnterprise() && options.checkboxChallenge) { 10652 params.size = 'normal'; 10653 params.callback = saveToken; 10654 } else if (isEnterprise() && !options.checkboxChallenge) { 10655 10656 params.size = 'invisible'; 10657 } else if (getIsInvisibleRecaptcha()) { 10658 params.size = 'invisible'; 10659 } else { 10660 params.callback = saveToken; 10661 } 10662 10663 const self = this; 10664 captcha.ready(function () { 10665 const captchaDivs = document.querySelectorAll('[class="recaptcha-container"]'); 10666 for (let i = 0; i < captchaDivs.length; i++) { 10667 try { 10668 const cid = captcha.render(captchaDivs[i], params); 10669 captchaDivs[i].setAttribute('cid', cid); 10670 } catch (e) { /* recaptcha was already rendered */ } 10671 } 10672 10673 window.addEventListener('mm-form-captcha-promise', (e) => { 10674 let cid = null; 10675 let form = null; 10676 if (e && e.detail) { 10677 cid = e.detail.cid; 10678 form = e.detail.form; 10679 } 10680 if (typeof cid === "undefined" || cid === null) { 10681 return; 10682 } 10683 if (typeof form === "undefined" || form === null) { 10684 return; 10685 } 10686 captcha.reset(cid); 10687 form.setCaptchaPromise(getToken.bind(self), self); 10688 }); 10689 10690 window.addEventListener('mm-form-captcha-reload', (e) => { 10691 let cid = null; 10692 if (e && e.detail) { 10693 cid = e.detail.cid; 10694 } 10695 if (typeof cid === "undefined" || cid === null) { 10696 return; 10697 } 10698 captcha.reset(cid); 10699 }); 10700 }) 10701 10702 function getToken(cid, form) { 10703 const captcha = getCaptchaObject(); 10704 switch (options.version) { 10705 case '3': { 10706 return captcha.execute(cid); 10707 } 10708 case 'enterprise': { 10709 10710 if (options.checkboxChallenge) { 10711 return new Promise(async (resolve, reject) => { 10712 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 10713 if (token) { 10714 resolve(token.value); 10715 } 10716 resolve(''); 10717 }); 10718 } 10719 return captcha.execute(cid, {action: options.action}); 10720 } 10721 default: { 10722 return new Promise(async (resolve, reject) => { 10723 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 10724 if (token) { 10725 resolve(token.value); 10726 } 10727 resolve(''); 10728 }); 10729 } 10730 } 10731 } 10732 10733 function saveToken(token) { 10734 const rFields = document.querySelectorAll(`[name="${options.responseFieldName}"]`); 10735 for (let i = 0; i < rFields.length; i++) { 10736 rFields[i].value = token; 10737 } 10738 } 10739 } 10740
10741 function getIsInvisibleRecaptcha() { 10742 return options.version === '3'; 10743 } 10744 10745 function isEnterprise() { 10746 return options.version === 'enterprise'; 10747 } 10748 10749 function addCaptchaScriptTag() { 10750 if (!document.getElementById(options.scriptId)) { 10751 const script = document.createElement('script'); 10752 const firstScriptTag = document.getElementsByTagName('script')[0]; 10753 const api = isEnterprise() ? 'enterprise' : 'api'; 10754 10755 script.async = true; 10756 script.defer = true; 10757 10758 script.src = `https://www.google.com/recaptcha/${api}.js?render=${options.render}`; 10759 10760 if (options.languageCode) { 10761 script.src += `&hl=${options.languageCode}` 10762 } 10763 if (options.position) { 10764 script.src += `&badge=${options.position}` 10765 } 10766 script.onload = () => { 10767 window.dispatchEvent(new CustomEvent(options.captchaReadyEvent)); 10768 } 10769 firstScriptTag.parentNode.insertBefore(script, firstScriptTag); 10770 } 10771 options.scriptExists = true; 10772 } 10773 10774 function getCaptchaObject() { 10775 return isEnterprise() ? window.grecaptcha.enterprise : window.grecaptcha; 10776 } 10777 } 10778 } 10779 } 10780 10781 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsCaptchaDataXFDzRA', mmWebformsCaptchaDataXFDzRA), {once: true});</script>
vendor: 1 bytes, line 10781
10781
10782<script> 10783 10784 [...document.getElementById('webform_XFDzRA_form').querySelectorAll("input")].forEach((input) => { 10785 input.onkeydown = function(e) { 10786 const key = e.charCode || e.keyCode || 0; 10787 if (key === 13) { 10788 const index = [...input.form].indexOf(this); 10789 if (input.form.elements[index + 1] != null) { 10790 input.form.elements[index + 1].focus(); 10791 } 10792 e.preventDefault(); 10793 return false; 10794 } 10795 } 10796 }); 10797 10798 10799 </script>
vendor: 1 bytes, line 10799
10799
10800<script defer> 10801 (() => { 10802 window.dispatchEvent(new CustomEvent("mm_webform_loadedXFDzRA")); 10803 })();</script>
vendor: 1 bytes, line 10803
10803
10804<script> 10805 function mmWebformsEmailDatafieldzxVI0s1793() { 10806 return Object.assign( 10807 MageMe.WebForms.customerData(), 10808 { 10809 trimSpace() { 10810 if (this.$el.value.search(' ') >= 0) { 10811 this.$el.value =Â this.$el.value.replace(' ',''); 10812 } 10813 }, 10814 setCustomerData(event) { 10815 this.receiveCustomerData(event.detail.data) 10816 if (this.$el) { 10817 this.$el.value = this.customer['customer_email'] ?? ''; 10818 } 10819 }, 10820 } 10821 ); 10822 } 10823 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsEmailDatafieldzxVI0s1793', mmWebformsEmailDatafieldzxVI0s1793), {once: true});</script>
vendor: 1 bytes, line 10823
10823
10824<script> 10825 function mmWebformsTextareaDatafieldzxVI0s1820() { 10826 return Object.assign( 10827 MageMe.WebForms.customerData(), 10828 { 10829 setCustomerData(event) { 10830 this.receiveCustomerData(event.detail.data) 10831 if (this.$el) { 10832 this.$el.value = this.customer[this.$el.dataset.hyvacspCustomerData] ?? ''; 10833 } 10834 }, 10835 } 10836 ); 10837 } 10838 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsTextareaDatafieldzxVI0s1820', mmWebformsTextareaDatafieldzxVI0s1820), {once: true});</script>
vendor: 1 bytes, line 10838
10838
10839<script> 10840 'use strict'; 10841 10842 window.addEventListener('private-content-loaded', () => { 10843 MageMe.loader.addScript('swal', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Fsweetalert2.min.js", () => { 10844 MageMe.loader.addScript('tingle', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Ftingle.min.js", () => { 10845 const options = { 10846 "submitUrl": "https://www.banham.co.uk/webforms/form/submit/ajax/1/", 10847 "uid": "zxVI0s", 10848 "formId": "95", 10849 "ajax": true, 10850 "success": false, 10851 "displayAfterSubmission": true, 10852 "scrollAfterSubmission": true, 10853 "showReview": false, 10854 "saveDataLocal": false, 10855 "useCaptcha": true, 10856 "captchaResponseName": "g-recaptcha-response", 10857 "messages": { 10858 "success": "Success!", 10859 "redirecting": "Redirecting", 10860 "complete": "Complete", 10861 "error": "Error", 10862 "captchaTxt": "Please click on the Captcha", 10863 "errorTxt": "Error(s) occurred. Please try again.", 10864 "unknownTxt": "Unknown error(s) occurred" 10865 } 10866 } 10867 10868 options.afterInit = (form) => { 10869 document.body.addEventListener('touchstart', MageMe.WebForms.loadValidation, {once: true}); 10870 document.body.addEventListener('mouseover', MageMe.WebForms.loadValidation, {once: true}); 10871 } 10872 10873 options.validationCb = (form, valid) => new Promise(async (resolve, reject) => { 10874 if (!valid) { 10875 resolve(false); 10876 } 10877 MageMe.WebForms.loadValidation().then(() => { 10878 return MageMe.WebForms.formValidation(form.controls.form, { 10879 fieldWrapperClassName: 'control', 10880 messagesWrapperClassName: 'hyva-validation' 10881 }); 10882 }).then(validator => { 10883 return validator.validate(); 10884 }).then(() => { 10885 resolve(true); 10886 }).catch((er) => { 10887 resolve(false); 10888 }); 10889 }); 10890 options.fieldValidationCb = (field, form, valid) => new Promise(async (resolve, reject) => { 10891 if (!valid) { 10892 resolve(false); 10893 } 10894 MageMe.WebForms.loadValidation().then(() => { 10895 return MageMe.WebForms.formValidation(form.controls.form, { 10896 fieldWrapperClassName: 'control', 10897 messagesWrapperClassName: 'hyva-validation' 10898 }); 10899 }).then(validator => { 10900 validator.setupField(field); 10901 const fieldObj = validator.fields[field.name]; 10902 return validator.validateField(fieldObj); 10903 }).then((isValid) => { 10904 resolve(isValid); 10905 }).catch((er) => { 10906 resolve(false); 10907 }); 10908 }); 10909 10910 options.getFormKey = () => { 10911 return hyva.getCookie('form_key'); 10912 }; 10913 options.swal = swal; 10914 options.tingle = tingle; 10915 10916 MageMe.loader.addScript('mmForm', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fform.min.js", () => { 10917 new mmForm(options); 10918 }); 10919 }); 10920 }); 10921 });</script>
vendor: 1 bytes, line 10921
10921
10922<script> 10923 'use strict'; 10924 (() => { 10925 document.getElementById("captcha-container-zxVI0s").innerHTML = '<div class="captcha-wrapper" x-data="mmWebformsCaptchaDatazxVI0s" x-init="initCaptcha"><input type="hidden" name="g-recaptcha-response" class="required-entry"/><div class="recaptcha-position-bottomright"><div class="recaptcha-container"></div></div></div>'; 10926 })();</script>
vendor: 1 bytes, line 10926
10926
10927<script> 10928 function mmWebformsCaptchaDatazxVI0s() { 10929 return { 10930 initCaptcha() { 10931 const options = { 10932 globalOnLoadCallback: 'webformsCaptchaOnload', 10933 captchaReadyEvent: 'webformsCaptchaApiReady', 10934 languageCode: 'en', 10935 publicKey: '6LfHDCMrAAAAACnDJl581eICSW3VnauItgp_hR2S', 10936 scriptId: 'mm_captcha', 10937 scriptExists: false, 10938 responseFieldName: 'g-recaptcha-response', 10939 version: '3', 10940 position: 'bottomright', 10941 theme: 'standard', 10942 action: '', 10943 checkboxChallenge: false, 10944 render: 'explicit' 10945 } 10946 10947 addCaptchaScriptTag(); 10948 let captcha; 10949 try { 10950 captcha = getCaptchaObject(); 10951 } catch { 10952 captcha = false; 10953 } 10954 if (captcha && captcha.render) { 10955 initCaptcha(); 10956 } else { 10957 window.addEventListener(options.captchaReadyEvent, function () { 10958 initCaptcha(); 10959 }); 10960 } 10961 10962 function initCaptcha() { 10963 const captcha = getCaptchaObject(); 10964 const params = {theme: options.theme, sitekey: options.publicKey}; 10965 10966 10967 if (isEnterprise() && options.checkboxChallenge) { 10968 params.size = 'normal'; 10969 params.callback = saveToken; 10970 } else if (isEnterprise() && !options.checkboxChallenge) { 10971 10972 params.size = 'invisible'; 10973 } else if (getIsInvisibleRecaptcha()) { 10974 params.size = 'invisible'; 10975 } else { 10976 params.callback = saveToken; 10977 } 10978 10979 const self = this; 10980 captcha.ready(function () { 10981 const captchaDivs = document.querySelectorAll('[class="recaptcha-container"]'); 10982 for (let i = 0; i < captchaDivs.length; i++) { 10983 try { 10984 const cid = captcha.render(captchaDivs[i], params); 10985 captchaDivs[i].setAttribute('cid', cid); 10986 } catch (e) { /* recaptcha was already rendered */ } 10987 } 10988 10989 window.addEventListener('mm-form-captcha-promise', (e) => { 10990 let cid = null; 10991 let form = null; 10992 if (e && e.detail) { 10993 cid = e.detail.cid; 10994 form = e.detail.form; 10995 } 10996 if (typeof cid === "undefined" || cid === null) { 10997 return; 10998 } 10999 if (typeof form === "undefined" || form === null) { 11000 return; 11001 } 11002 captcha.reset(cid); 11003 form.setCaptchaPromise(getToken.bind(self), self); 11004 }); 11005 11006 window.addEventListener('mm-form-captcha-reload', (e) => { 11007 let cid = null; 11008 if (e && e.detail) { 11009 cid = e.detail.cid; 11010 } 11011 if (typeof cid === "undefined" || cid === null) { 11012 return; 11013 } 11014 captcha.reset(cid); 11015 }); 11016 }) 11017 11018 function getToken(cid, form) { 11019 const captcha = getCaptchaObject(); 11020 switch (options.version) { 11021 case '3': { 11022 return captcha.execute(cid); 11023 } 11024 case 'enterprise': { 11025 11026 if (options.checkboxChallenge) { 11027 return new Promise(async (resolve, reject) => { 11028 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 11029 if (token) { 11030 resolve(token.value); 11031 } 11032 resolve(''); 11033 }); 11034 } 11035 return captcha.execute(cid, {action: options.action}); 11036 } 11037 default: { 11038 return new Promise(async (resolve, reject) => { 11039 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 11040 if (token) { 11041 resolve(token.value); 11042 } 11043 resolve(''); 11044 }); 11045 } 11046 } 11047 } 11048 11049 function saveToken(token) { 11050 const rFields = document.querySelectorAll(`[name="${options.responseFieldName}"]`); 11051 for (let i = 0; i < rFields.length; i++) { 11052 rFields[i].value = token; 11053 } 11054 } 11055 } 11056
11057 function getIsInvisibleRecaptcha() { 11058 return options.version === '3'; 11059 } 11060 11061 function isEnterprise() { 11062 return options.version === 'enterprise'; 11063 } 11064 11065 function addCaptchaScriptTag() { 11066 if (!document.getElementById(options.scriptId)) { 11067 const script = document.createElement('script'); 11068 const firstScriptTag = document.getElementsByTagName('script')[0]; 11069 const api = isEnterprise() ? 'enterprise' : 'api'; 11070 11071 script.async = true; 11072 script.defer = true; 11073 11074 script.src = `https://www.google.com/recaptcha/${api}.js?render=${options.render}`; 11075 11076 if (options.languageCode) { 11077 script.src += `&hl=${options.languageCode}` 11078 } 11079 if (options.position) { 11080 script.src += `&badge=${options.position}` 11081 } 11082 script.onload = () => { 11083 window.dispatchEvent(new CustomEvent(options.captchaReadyEvent)); 11084 } 11085 firstScriptTag.parentNode.insertBefore(script, firstScriptTag); 11086 } 11087 options.scriptExists = true; 11088 } 11089 11090 function getCaptchaObject() { 11091 return isEnterprise() ? window.grecaptcha.enterprise : window.grecaptcha; 11092 } 11093 } 11094 } 11095 } 11096 11097 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsCaptchaDatazxVI0s', mmWebformsCaptchaDatazxVI0s), {once: true});</script>
vendor: 1 bytes, line 11097
11097
11098<script> 11099 11100 [...document.getElementById('webform_zxVI0s_form').querySelectorAll("input")].forEach((input) => { 11101 input.onkeydown = function(e) { 11102 const key = e.charCode || e.keyCode || 0; 11103 if (key === 13) { 11104 const index = [...input.form].indexOf(this); 11105 if (input.form.elements[index + 1] != null) { 11106 input.form.elements[index + 1].focus(); 11107 } 11108 e.preventDefault(); 11109 return false; 11110 } 11111 } 11112 }); 11113 11114 11115 </script>
vendor: 1 bytes, line 11115
11115
11116<script defer> 11117 (() => { 11118 window.dispatchEvent(new CustomEvent("mm_webform_loadedzxVI0s")); 11119 })();</script>
vendor: 1 bytes, line 11119
11119
11120<script> 11121 function mmWebformsEmailDatafieldhVWOVe1202() { 11122 return Object.assign( 11123 MageMe.WebForms.customerData(), 11124 { 11125 trimSpace() { 11126 if (this.$el.value.search(' ') >= 0) { 11127 this.$el.value =Â this.$el.value.replace(' ',''); 11128 } 11129 }, 11130 setCustomerData(event) { 11131 this.receiveCustomerData(event.detail.data) 11132 if (this.$el) { 11133 this.$el.value = this.customer['customer_email'] ?? ''; 11134 } 11135 }, 11136 } 11137 ); 11138 } 11139 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsEmailDatafieldhVWOVe1202', mmWebformsEmailDatafieldhVWOVe1202), {once: true});</script>
vendor: 1 bytes, line 11139
11139
11140<script> 11141 function mmWebformsEmailDatafieldhVWOVe1205() { 11142 return Object.assign( 11143 MageMe.WebForms.customerData(), 11144 { 11145 trimSpace() { 11146 if (this.$el.value.search(' ') >= 0) { 11147 this.$el.value =Â this.$el.value.replace(' ',''); 11148 } 11149 }, 11150 setCustomerData(event) { 11151 this.receiveCustomerData(event.detail.data) 11152 if (this.$el) { 11153 this.$el.value = this.customer['customer_email'] ?? ''; 11154 } 11155 }, 11156 } 11157 ); 11158 } 11159 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsEmailDatafieldhVWOVe1205', mmWebformsEmailDatafieldhVWOVe1205), {once: true});</script>
vendor: 1 bytes, line 11159
11159
11160<script> 11161 'use strict'; 11162 11163 (() => { 11164 if (!window.MageMe || !MageMe.loader) { 11165 return; 11166 } 11167 MageMe.loader.addCssOrdered( 11168 'https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB/MageMe_WebForms/css/lib/phone.min.css', 11169 '20' 11170 ); 11171 MageMe.loader.addScript("intlTelInput", "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fphone.min.js", () => { 11172 const input = document.getElementById("phonefieldhVWOVe1208"); 11173 const preferredCountries = []; 11174 const onlyCountries = []; 11175 const initialCountry = 'GB'; 11176 const initialValue = ""; 11177 let config = { 11178 separateDialCode: true, 11179 autoPlaceholder: 'off', 11180 utilsScript: "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fphone\u002Dutils.js", 11181 } 11182 if (!!initialCountry) { 11183 config['initialCountry'] = initialCountry; 11184 } else { 11185 config['initialCountry'] = 'auto'; 11186 config['geoIpLookup'] = function (success, failure) { 11187 fetch("https://ipinfo.io/json").then( 11188 function (response) { 11189 return response.json(); 11190 } 11191 ).then( 11192 function (jsonResponse) { 11193 const countryCode = (jsonResponse && jsonResponse.country) ? jsonResponse.country : "us"; 11194 const iti = window.intlTelInputGlobals.getInstance(input); 11195 try { 11196 iti.setCountry(countryCode); 11197 11198 success(countryCode); 11199 } catch {} 11200 return jsonResponse; 11201 } 11202 ).catch( 11203 function (err) { 11204 const iti = window.intlTelInputGlobals.getInstance(input); 11205 11206 const countryCode = 'us'; 11207 try { 11208 iti.setCountry(countryCode); 11209 failure(countryCode); 11210 } catch {} 11211 } 11212 ); 11213 }; 11214 } 11215 if (preferredCountries.length > 0) { 11216 config['preferredCountries'] = preferredCountries; 11217 } 11218 if (onlyCountries.length > 0) { 11219 config['onlyCountries'] = onlyCountries; 11220 } 11221 const phone = window.intlTelInput(input, config); 11222 input.oninput = function () { 11223 document.getElementById("fieldhVWOVe1208").value = phone.getNumber(); 11224 }; 11225 if (!!initialValue) { 11226 phone.setNumber(initialValue); 11227 document.getElementById("fieldhVWOVe1208").value = phone.getNumber(); 11228 } 11229 }); 11230 })();</script>
vendor: 1 bytes, line 11230
11230
11231<script> 11232 MageMe.loader.addScript("intlTelInput", "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fphone.min.js", () => { 11233 const input = document.getElementById("phonefieldhVWOVe1208"); 11234 if (input) { 11235 const phone = window.intlTelInputGlobals.getInstance(input); 11236 input.loadData = function (val, uid) { 11237 phone.setNumber(val); 11238 } 11239 input.saveData = function (formData) { 11240 formData[input.id] = phone.getNumber(); 11241 } 11242 } 11243 });</script>
vendor: 1 bytes, line 11243
11243
11244<script> 11245 'use strict'; 11246 (() => { 11247 const input = document.getElementById('phonefieldhVWOVe1208'); 11248 if (input) { 11249 input.initValidation = function (form) { 11250 input.parentElement.addEventListener('focusout', (e) => { 11251 if ( 11252 e.relatedTarget !== e.currentTarget && 11253 !e.currentTarget.contains(e.relatedTarget) 11254 ) { 11255 form.validateField(input); 11256 } 11257 }); 11258 input.parentElement.tabIndex = -1; 11259 } 11260 } 11261 })();</script>
vendor: 1 bytes, line 11261
11261
11262<script> 11263 function mmWebformsPhoneDatafieldhVWOVe1208() { 11264 return Object.assign( 11265 MageMe.WebForms.customerData(), 11266 { 11267 setCustomerData(event) { 11268 this.receiveCustomerData(event.detail.data) 11269 if (this.$el) { 11270 this.$el.value = this.customer[this.$el.dataset.hyvacspCustomerData] ?? ''; 11271 } 11272 }, 11273 } 11274 ); 11275 } 11276 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsPhoneDatafieldhVWOVe1208', mmWebformsPhoneDatafieldhVWOVe1208), {once: true});</script>
vendor: 1 bytes, line 11276
11276
11277<script> 11278 'use strict'; 11279 11280 (() => { 11281 if (!window.MageMe || !MageMe.loader) { 11282 return; 11283 } 11284 MageMe.loader.addCssOrdered( 11285 'https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB/MageMe_WebForms/css/lib/phone.min.css', 11286 '20' 11287 ); 11288 MageMe.loader.addScript("intlTelInput", "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fphone.min.js", () => { 11289 const input = document.getElementById("phonefieldhVWOVe1211"); 11290 const preferredCountries = []; 11291 const onlyCountries = []; 11292 const initialCountry = 'GB'; 11293 const initialValue = ""; 11294 let config = { 11295 separateDialCode: true, 11296 autoPlaceholder: 'off', 11297 utilsScript: "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fphone\u002Dutils.js", 11298 } 11299 if (!!initialCountry) { 11300 config['initialCountry'] = initialCountry; 11301 } else { 11302 config['initialCountry'] = 'auto'; 11303 config['geoIpLookup'] = function (success, failure) { 11304 fetch("https://ipinfo.io/json").then( 11305 function (response) { 11306 return response.json(); 11307 } 11308 ).then( 11309 function (jsonResponse) { 11310 const countryCode = (jsonResponse && jsonResponse.country) ? jsonResponse.country : "us"; 11311 const iti = window.intlTelInputGlobals.getInstance(input); 11312 try { 11313 iti.setCountry(countryCode); 11314 11315 success(countryCode); 11316 } catch {} 11317 return jsonResponse; 11318 } 11319 ).catch( 11320 function (err) { 11321 const iti = window.intlTelInputGlobals.getInstance(input); 11322 11323 const countryCode = 'us'; 11324 try { 11325 iti.setCountry(countryCode); 11326 failure(countryCode); 11327 } catch {} 11328 } 11329 ); 11330 }; 11331 } 11332 if (preferredCountries.length > 0) { 11333 config['preferredCountries'] = preferredCountries; 11334 } 11335 if (onlyCountries.length > 0) { 11336 config['onlyCountries'] = onlyCountries; 11337 } 11338 const phone = window.intlTelInput(input, config); 11339 input.oninput = function () { 11340 document.getElementById("fieldhVWOVe1211").value = phone.getNumber(); 11341 }; 11342 if (!!initialValue) { 11343 phone.setNumber(initialValue); 11344 document.getElementById("fieldhVWOVe1211").value = phone.getNumber(); 11345 } 11346 }); 11347 })();</script>
vendor: 1 bytes, line 11347
11347
11348<script> 11349 MageMe.loader.addScript("intlTelInput", "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fphone.min.js", () => { 11350 const input = document.getElementById("phonefieldhVWOVe1211"); 11351 if (input) { 11352 const phone = window.intlTelInputGlobals.getInstance(input); 11353 input.loadData = function (val, uid) { 11354 phone.setNumber(val); 11355 } 11356 input.saveData = function (formData) { 11357 formData[input.id] = phone.getNumber(); 11358 } 11359 } 11360 });</script>
vendor: 1 bytes, line 11360
11360
11361<script> 11362 'use strict'; 11363 (() => { 11364 const input = document.getElementById('phonefieldhVWOVe1211'); 11365 if (input) { 11366 input.initValidation = function (form) { 11367 input.parentElement.addEventListener('focusout', (e) => { 11368 if ( 11369 e.relatedTarget !== e.currentTarget && 11370 !e.currentTarget.contains(e.relatedTarget) 11371 ) { 11372 form.validateField(input); 11373 } 11374 }); 11375 input.parentElement.tabIndex = -1; 11376 } 11377 } 11378 })();</script>
vendor: 1 bytes, line 11378
11378
11379<script> 11380 function mmWebformsPhoneDatafieldhVWOVe1211() { 11381 return Object.assign( 11382 MageMe.WebForms.customerData(), 11383 { 11384 setCustomerData(event) { 11385 this.receiveCustomerData(event.detail.data) 11386 if (this.$el) { 11387 this.$el.value = this.customer[this.$el.dataset.hyvacspCustomerData] ?? ''; 11388 } 11389 }, 11390 } 11391 ); 11392 } 11393 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsPhoneDatafieldhVWOVe1211', mmWebformsPhoneDatafieldhVWOVe1211), {once: true});</script>
vendor: 1 bytes, line 11393
11393
11394<script> 11395 'use strict'; 11396 11397 window.addEventListener('private-content-loaded', () => { 11398 MageMe.loader.addScript('swal', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Fsweetalert2.min.js", () => { 11399 MageMe.loader.addScript('tingle', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FMageMe_Core\u002Fjs\u002Ftingle.min.js", () => { 11400 const options = { 11401 "submitUrl": "https://www.banham.co.uk/webforms/form/submit/ajax/1/", 11402 "uid": "hVWOVe", 11403 "formId": "62", 11404 "ajax": true, 11405 "success": false, 11406 "displayAfterSubmission": true, 11407 "scrollAfterSubmission": true, 11408 "showReview": false, 11409 "saveDataLocal": false, 11410 "useCaptcha": true, 11411 "captchaResponseName": "g-recaptcha-response", 11412 "messages": { 11413 "success": "Success!", 11414 "redirecting": "Redirecting", 11415 "complete": "Complete", 11416 "error": "Error", 11417 "captchaTxt": "Please click on the Captcha", 11418 "errorTxt": "Error(s) occurred. Please try again.", 11419 "unknownTxt": "Unknown error(s) occurred" 11420 } 11421 } 11422 11423 options.afterInit = (form) => { 11424 document.body.addEventListener('touchstart', MageMe.WebForms.loadValidation, {once: true}); 11425 document.body.addEventListener('mouseover', MageMe.WebForms.loadValidation, {once: true}); 11426 } 11427 11428 options.validationCb = (form, valid) => new Promise(async (resolve, reject) => { 11429 if (!valid) { 11430 resolve(false); 11431 } 11432 MageMe.WebForms.loadValidation().then(() => { 11433 return MageMe.WebForms.formValidation(form.controls.form, { 11434 fieldWrapperClassName: 'control', 11435 messagesWrapperClassName: 'hyva-validation' 11436 }); 11437 }).then(validator => { 11438 return validator.validate(); 11439 }).then(() => { 11440 resolve(true); 11441 }).catch((er) => { 11442 resolve(false); 11443 }); 11444 }); 11445 options.fieldValidationCb = (field, form, valid) => new Promise(async (resolve, reject) => { 11446 if (!valid) { 11447 resolve(false); 11448 } 11449 MageMe.WebForms.loadValidation().then(() => { 11450 return MageMe.WebForms.formValidation(form.controls.form, { 11451 fieldWrapperClassName: 'control', 11452 messagesWrapperClassName: 'hyva-validation' 11453 }); 11454 }).then(validator => { 11455 validator.setupField(field); 11456 const fieldObj = validator.fields[field.name]; 11457 return validator.validateField(fieldObj); 11458 }).then((isValid) => { 11459 resolve(isValid); 11460 }).catch((er) => { 11461 resolve(false); 11462 }); 11463 }); 11464 11465 options.getFormKey = () => { 11466 return hyva.getCookie('form_key'); 11467 }; 11468 options.swal = swal; 11469 options.tingle = tingle; 11470 11471 MageMe.loader.addScript('mmForm', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Fform.min.js", () => { 11472 new mmForm(options); 11473 }); 11474 }); 11475 }); 11476 });</script>
vendor: 1 bytes, line 11476
11476
11477<script type="text/javascript"> 11478 let logicRules_hVWOVe = []; 11479 const targets_hVWOVe = [{"id":"field_hVWOVe1202","logic_visibility":"hidden","required":false},{"id":"field_hVWOVe1205","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1169","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1172","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1175","logic_visibility":"hidden","required":false},{"id":"field_hVWOVe1178","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1181","logic_visibility":"visible","required":true},{"id":"field_hVWOVe1208","logic_visibility":"hidden","required":false},{"id":"field_hVWOVe1211","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1169","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1172","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1175","logic_visibility":"hidden","required":false},{"id":"field_hVWOVe1178","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1181","logic_visibility":"visible","required":true},{"id":"field_hVWOVe1202","logic_visibility":"hidden","required":false},{"id":"field_hVWOVe1205","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1208","logic_visibility":"hidden","required":false},{"id":"field_hVWOVe1211","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1169","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1172","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1175","logic_visibility":"hidden","required":false},{"id":"field_hVWOVe1178","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1181","logic_visibility":"visible","required":true},{"id":"field_hVWOVe1157","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1160","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1163","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1166","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1169","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1172","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1175","logic_visibility":"hidden","required":false},{"id":"field_hVWOVe1178","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1181","logic_visibility":"visible","required":true},{"id":"field_hVWOVe1157","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1160","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1163","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1166","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1169","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1172","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1175","logic_visibility":"hidden","required":false},{"id":"field_hVWOVe1178","logic_visibility":"hidden","required":true},{"id":"field_hVWOVe1181","logic_visibility":"visible","required":true},{"id":"field_hVWOVe1157","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1160","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1163","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1166","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1181","logic_visibility":"visible","required":true},{"id":"field_hVWOVe1157","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1160","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1163","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1166","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1181","logic_visibility":"visible","required":true},{"id":"field_hVWOVe1157","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1160","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1163","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1166","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1181","logic_visibility":"visible","required":true},{"id":"field_hVWOVe1157","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1160","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1163","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1166","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1181","logic_visibility":"visible","required":true},{"id":"field_hVWOVe1157","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1160","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1163","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1166","logic_visibility":"visible","required":false},{"id":"field_hVWOVe1181","logic_visibility":"visible","required":true}];
11480 const fieldMap_hVWOVe = {"fieldset_0":["1193","1196","1199","1145","1202","1205","1208","1211","1169","1172","1175","1178","1181","submit"]}; 11481 logicRules_hVWOVe.push({ 11482 'field_id': '1145', 11483 'action': 'show', 11484 'logic_condition': 'equal', 11485 'aggregation': 'any', 11486 'value': [1], 11487 'target': ["field_hVWOVe1202","field_hVWOVe1205","field_hVWOVe1169","field_hVWOVe1172","field_hVWOVe1175","field_hVWOVe1178","field_hVWOVe1181"] }); 11488 logicRules_hVWOVe.push({ 11489 'field_id': '1145', 11490 'action': 'show', 11491 'logic_condition': 'equal', 11492 'aggregation': 'any', 11493 'value': [2], 11494 'target': ["field_hVWOVe1208","field_hVWOVe1211","field_hVWOVe1169","field_hVWOVe1172","field_hVWOVe1175","field_hVWOVe1178","field_hVWOVe1181"] }); 11495 logicRules_hVWOVe.push({ 11496 'field_id': '1145', 11497 'action': 'show', 11498 'logic_condition': 'equal', 11499 'aggregation': 'any', 11500 'value': [3], 11501 'target': ["field_hVWOVe1202","field_hVWOVe1205","field_hVWOVe1208","field_hVWOVe1211","field_hVWOVe1169","field_hVWOVe1172","field_hVWOVe1175","field_hVWOVe1178","field_hVWOVe1181"] }); 11502 logicRules_hVWOVe.push({ 11503 'field_id': '1145', 11504 'action': 'show', 11505 'logic_condition': 'equal', 11506 'aggregation': 'any', 11507 'value': [], 11508 'target': ["field_hVWOVe1157","field_hVWOVe1160","field_hVWOVe1163","field_hVWOVe1166","field_hVWOVe1169","field_hVWOVe1172","field_hVWOVe1175","field_hVWOVe1178","field_hVWOVe1181"] }); 11509 logicRules_hVWOVe.push({ 11510 'field_id': '1145', 11511 'action': 'show', 11512 'logic_condition': 'equal', 11513 'aggregation': 'any', 11514 'value': [], 11515 'target': ["field_hVWOVe1157","field_hVWOVe1160","field_hVWOVe1163","field_hVWOVe1166","field_hVWOVe1169","field_hVWOVe1172","field_hVWOVe1175","field_hVWOVe1178","field_hVWOVe1181"] }); 11516 logicRules_hVWOVe.push({ 11517 'field_id': '1145', 11518 'action': 'show', 11519 'logic_condition': 'equal', 11520 'aggregation': 'any', 11521 'value': ["Please Select"], 11522 'target': ["field_hVWOVe1157","field_hVWOVe1160","field_hVWOVe1163","field_hVWOVe1166","field_hVWOVe1181"] }); 11523 logicRules_hVWOVe.push({ 11524 'field_id': '1145', 11525 'action': 'show', 11526 'logic_condition': 'equal', 11527 'aggregation': 'any', 11528 'value': [], 11529 'target': ["field_hVWOVe1157","field_hVWOVe1160","field_hVWOVe1163","field_hVWOVe1166","field_hVWOVe1181"] }); 11530 logicRules_hVWOVe.push({ 11531 'field_id': '1145', 11532 'action': 'show', 11533 'logic_condition': 'equal', 11534 'aggregation': 'any', 11535 'value': [], 11536 'target': ["field_hVWOVe1157","field_hVWOVe1160","field_hVWOVe1163","field_hVWOVe1166","field_hVWOVe1181"] }); 11537 logicRules_hVWOVe.push({ 11538 'field_id': '1145', 11539 'action': 'show', 11540 'logic_condition': 'equal', 11541 'aggregation': 'any', 11542 'value': [], 11543 'target': ["field_hVWOVe1157","field_hVWOVe1160","field_hVWOVe1163","field_hVWOVe1166","field_hVWOVe1181"] }); 11544 logicRules_hVWOVe.push({ 11545 'field_id': '1145', 11546 'action': 'show', 11547 'logic_condition': 'equal', 11548 'aggregation': 'any', 11549 'value': [], 11550 'target': ["field_hVWOVe1157","field_hVWOVe1160","field_hVWOVe1163","field_hVWOVe1166","field_hVWOVe1181"] }); 11551 window.addEventListener("mm_webform_loadedhVWOVe", () => { 11552 MageMe.loader.addScript('mmLogic', "https\u003A\u002F\u002Fwww.banham.co.uk\u002Fstatic\u002Fversion1789025993\u002Ffrontend\u002FBraveBison\u002Fdefault\u002Fen_GB\u002FHyva_MageMeWebForms\u002Fjs\u002Flogic.min.js", () => { 11553 new mmLogic({ 11554 targets: targets_hVWOVe, 11555 logicRules: logicRules_hVWOVe, 11556 fieldMap: fieldMap_hVWOVe, 11557 uid: 'hVWOVe', 11558 containerId: "webform_hVWOVe_form" 11559 }); 11560 }); 11561 });</script>
vendor: 1 bytes, line 11561
11561
11562<script> 11563 'use strict'; 11564 (() => { 11565 document.getElementById("captcha-container-hVWOVe").innerHTML = '<div class="captcha-wrapper" x-data="mmWebformsCaptchaDatahVWOVe" x-init="initCaptcha"><input type="hidden" name="g-recaptcha-response" class="required-entry"/><div class="recaptcha-position-bottomright"><div class="recaptcha-container"></div></div></div>'; 11566 })();</script>
vendor: 1 bytes, line 11566
11566
11567<script> 11568 function mmWebformsCaptchaDatahVWOVe() { 11569 return { 11570 initCaptcha() { 11571 const options = { 11572 globalOnLoadCallback: 'webformsCaptchaOnload', 11573 captchaReadyEvent: 'webformsCaptchaApiReady', 11574 languageCode: 'en', 11575 publicKey: '6LfHDCMrAAAAACnDJl581eICSW3VnauItgp_hR2S', 11576 scriptId: 'mm_captcha', 11577 scriptExists: false, 11578 responseFieldName: 'g-recaptcha-response', 11579 version: '3', 11580 position: 'bottomright', 11581 theme: 'standard', 11582 action: '', 11583 checkboxChallenge: false, 11584 render: 'explicit' 11585 } 11586 11587 addCaptchaScriptTag(); 11588 let captcha; 11589 try { 11590 captcha = getCaptchaObject(); 11591 } catch { 11592 captcha = false; 11593 } 11594 if (captcha && captcha.render) { 11595 initCaptcha(); 11596 } else { 11597 window.addEventListener(options.captchaReadyEvent, function () { 11598 initCaptcha(); 11599 }); 11600 } 11601 11602 function initCaptcha() { 11603 const captcha = getCaptchaObject(); 11604 const params = {theme: options.theme, sitekey: options.publicKey}; 11605 11606 11607 if (isEnterprise() && options.checkboxChallenge) { 11608 params.size = 'normal'; 11609 params.callback = saveToken; 11610 } else if (isEnterprise() && !options.checkboxChallenge) { 11611 11612 params.size = 'invisible'; 11613 } else if (getIsInvisibleRecaptcha()) { 11614 params.size = 'invisible'; 11615 } else { 11616 params.callback = saveToken; 11617 } 11618 11619 const self = this; 11620 captcha.ready(function () { 11621 const captchaDivs = document.querySelectorAll('[class="recaptcha-container"]'); 11622 for (let i = 0; i < captchaDivs.length; i++) { 11623 try { 11624 const cid = captcha.render(captchaDivs[i], params); 11625 captchaDivs[i].setAttribute('cid', cid); 11626 } catch (e) { /* recaptcha was already rendered */ } 11627 } 11628 11629 window.addEventListener('mm-form-captcha-promise', (e) => { 11630 let cid = null; 11631 let form = null; 11632 if (e && e.detail) { 11633 cid = e.detail.cid; 11634 form = e.detail.form; 11635 } 11636 if (typeof cid === "undefined" || cid === null) { 11637 return; 11638 } 11639 if (typeof form === "undefined" || form === null) { 11640 return; 11641 } 11642 captcha.reset(cid); 11643 form.setCaptchaPromise(getToken.bind(self), self); 11644 }); 11645 11646 window.addEventListener('mm-form-captcha-reload', (e) => { 11647 let cid = null; 11648 if (e && e.detail) { 11649 cid = e.detail.cid; 11650 } 11651 if (typeof cid === "undefined" || cid === null) { 11652 return; 11653 } 11654 captcha.reset(cid); 11655 }); 11656 }) 11657 11658 function getToken(cid, form) { 11659 const captcha = getCaptchaObject(); 11660 switch (options.version) { 11661 case '3': { 11662 return captcha.execute(cid); 11663 } 11664 case 'enterprise': { 11665 11666 if (options.checkboxChallenge) { 11667 return new Promise(async (resolve, reject) => { 11668 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 11669 if (token) { 11670 resolve(token.value); 11671 } 11672 resolve(''); 11673 }); 11674 } 11675 return captcha.execute(cid, {action: options.action}); 11676 } 11677 default: { 11678 return new Promise(async (resolve, reject) => { 11679 const token = form.controls.form.querySelector(`[name="${options.responseFieldName}"]`); 11680 if (token) { 11681 resolve(token.value); 11682 } 11683 resolve(''); 11684 }); 11685 } 11686 } 11687 } 11688 11689 function saveToken(token) { 11690 const rFields = document.querySelectorAll(`[name="${options.responseFieldName}"]`); 11691 for (let i = 0; i < rFields.length; i++) { 11692 rFields[i].value = token; 11693 } 11694 } 11695 } 11696
11697 function getIsInvisibleRecaptcha() { 11698 return options.version === '3'; 11699 } 11700 11701 function isEnterprise() { 11702 return options.version === 'enterprise'; 11703 } 11704 11705 function addCaptchaScriptTag() { 11706 if (!document.getElementById(options.scriptId)) { 11707 const script = document.createElement('script'); 11708 const firstScriptTag = document.getElementsByTagName('script')[0]; 11709 const api = isEnterprise() ? 'enterprise' : 'api'; 11710 11711 script.async = true; 11712 script.defer = true; 11713 11714 script.src = `https://www.google.com/recaptcha/${api}.js?render=${options.render}`; 11715 11716 if (options.languageCode) { 11717 script.src += `&hl=${options.languageCode}` 11718 } 11719 if (options.position) { 11720 script.src += `&badge=${options.position}` 11721 } 11722 script.onload = () => { 11723 window.dispatchEvent(new CustomEvent(options.captchaReadyEvent)); 11724 } 11725 firstScriptTag.parentNode.insertBefore(script, firstScriptTag); 11726 } 11727 options.scriptExists = true; 11728 } 11729 11730 function getCaptchaObject() { 11731 return isEnterprise() ? window.grecaptcha.enterprise : window.grecaptcha; 11732 } 11733 } 11734 } 11735 } 11736 11737 window.addEventListener('alpine:init', () => Alpine.data('mmWebformsCaptchaDatahVWOVe', mmWebformsCaptchaDatahVWOVe), {once: true});</script>
vendor: 1 bytes, line 11737
11737
11738<script> 11739 11740 [...document.getElementById('webform_hVWOVe_form').querySelectorAll("input")].forEach((input) => { 11741 input.onkeydown = function(e) { 11742 const key = e.charCode || e.keyCode || 0; 11743 if (key === 13) { 11744 const index = [...input.form].indexOf(this); 11745 if (input.form.elements[index + 1] != null) { 11746 input.form.elements[index + 1].focus(); 11747 } 11748 e.preventDefault(); 11749 return false; 11750 } 11751 } 11752 }); 11753 11754 11755 </script>
vendor: 1 bytes, line 11755
11755
11756<script defer> 11757 (() => { 11758 window.dispatchEvent(new CustomEvent("mm_webform_loadedhVWOVe")); 11759 })();</script>
vendor: 1 bytes, line 11759
11759
11760<script> 11761function contactFormTabs() { 11762 return { 11763 activeTab: 0, 11764 tabMap: { 11765 'banham-lock-queries': '10f8a50a-8bba-4ef8-8fe5-88312b39d219', 11766 'locksmiths-emergency-locksmith': 'a682ed85-29c5-437c-b4e3-1113aaa32c62', 11767 'banham-alarm-queries': '93718e28-037a-4c05-9e0d-9299d3ddcf8a', 11768 'keyholding-alarm-response': 'dea59f1d-3c21-48e7-b117-66062eda44f6', 11769 'online-order-queries': '1022ce70-8dbd-4ce4-8ab7-aedfefa4ca79', 11770 'banham-account-queries': '6370bf61-81cf-4eb3-b045-510dfff450b5', 11771 'banham-product-queries': 'e1794b6d-d916-407c-846e-5c918f0f724d', 11772 'banham-contract-queries': '257df155-bcb9-4b83-9e64-7c2c0a251ebd', 11773 'update-your-details': 'eb2d7d4b-9ff0-44db-aa9d-d3ddc041aed3', 11774 }, 11775 enquiryOptionsMap: { 11776 "banham-lock-queries" : "Banham Lock Queries", 11777 "banham-account-queries" : "Banham Alarms", 11778 "keyholding-alarm-response" : "Keyholding & Alarm Response", 11779 "online-order-queries" : "Online Order Queries", 11780 "banham-account-queries" : "Banham Account Queries", 11781 "banham-survey-queries" : "Banham Survey Queries", 11782 "banham-product-queries" : "Banham Product Queries", 11783 } 11784 , 11785 init() { 11786 this.checkHashOnLoad(); 11787 window.addEventListener('hashchange', () => this.checkHashOnLoad()); 11788 }, 11789 11790 checkHashOnLoad() { 11791 const hash = window.location.hash.substring(1); 11792 if (hash && this.tabMap[hash] !== undefined) { 11793 this.activeTab = this.tabMap[hash]; 11794 this.$nextTick(() => { 11795 document.querySelector('.form-block-wrap')?.scrollIntoView({ behavior: 'smooth', block: 'start' }); 11796 }); 11797 11798 let optionText = this.enquiryOptionsMap[hash]; 11799 const enquiryOptions = document.querySelectorAll('.enquiry-options'); 11800 const optionValue = Array.from(document.querySelectorAll('.enquiry-options option')).find(option => option.text === optionText)?.value; 11801 11802 if (optionValue && enquiryOptions) { 11803 enquiryOptions.forEach(select => { 11804 select.value = optionValue; 11805 select.dispatchEvent(new Event('change')); 11806 }); 11807 } else { 11808 console.log("Option with text '" + optionText + "' not found."); 11809 } 11810 } 11811 }, 11812 11813 setActiveTab(index, hash) { 11814 this.activeTab = index; 11815 window.location.hash = hash; 11816 this.$nextTick(() => { 11817 document.querySelector('.form-block-wrap')?.scrollIntoView({ behavior: 'smooth', block: 'start' }); 11818 }); 11819 11820 let optionText = this.enquiryOptionsMap[hash]; 11821 const enquiryOptions = document.querySelectorAll('.enquiry-options'); 11822 const optionValue = Array.from(document.querySelectorAll('.enquiry-options option')).find(option => option.text === optionText)?.value; 11823 11824 if (optionValue && enquiryOptions) { 11825 enquiryOptions.forEach(select => { 11826 select.value = optionValue; 11827 select.dispatchEvent(new Event('change')); 11828 }); 11829 } else { 11830 console.log("Option with text '" + optionText + "' not found."); 11831 } 11832 } 11833 } 11834} 11835</script>
vendor: 1 bytes, line 11835
11835
11836<script> 11837 function initNewsletterForm() { 11838 return { 11839 errors: 0, 11840 hasCaptchaToken: 0, 11841 displayErrorMessage: false, 11842 errorMessages: [], 11843 setErrorMessages(messages) { 11844 this.errorMessages = [messages] 11845 this.displayErrorMessage = this.errorMessages.length 11846 }, 11847 submitForm() { 11848 // Do not rename $form, the variable is expected to be declared in the recaptcha output 11849 const $form = document.querySelector('#newsletter-validate-detail'); 11850 11851 if (this.errors === 0) { 11852 $form.submit(); 11853 } 11854 } 11855 } 11856 } 11857 11858 window.addEventListener('alpine:init', () => Alpine.data('initNewsletterForm', initNewsletterForm), {once: true}) 11859 </script>
vendor: 1 bytes, line 11859
11859
11860<script> 11861document.addEventListener('alpine:init', () => { 11862 Alpine.store('footerResponsive', { 11863 isMobile: window.matchMedia('(max-width: 767px)').matches, 11864 openIndex: null, 11865 init() { 11866 const matchMedia = window.matchMedia('(max-width: 767px)'); 11867 this.isMobile = matchMedia.matches; 11868 11869 const handleChange = (event) => { 11870 this.isMobile = event.matches; 11871 if (!this.isMobile) this.openIndex = null; 11872 }; 11873 11874 if (typeof matchMedia.onchange !== 'object') { 11875 matchMedia.addListener(handleChange); 11876 } else { 11877 matchMedia.addEventListener('change', handleChange); 11878 } 11879 }, 11880 toggle(index) { 11881 this.openIndex = this.openIndex === index ? null : index; 11882 }, 11883 isOpen(index) { 11884 return this.openIndex === index; 11885 } 11886 }); 11887 11888 // FIX: run store init manually (stores donât auto-run init) 11889 Alpine.store('footerResponsive').init(); 11890}); 11891 11892document.addEventListener('DOMContentLoaded', function () { 11893 const el = document.querySelector('.pre-footer'); 11894 if (el) { 11895 new Splide(el, { 11896 perPage: 1, 11897 type: 'loop', 11898 pagination: true, 11899 arrows: false, 11900 mediaQuery: 'min', 11901 autoplay: true, 11902 interval: 3000, 11903 breakpoints: { 11904 1024: { destroy: true }, 11905 } 11906 }).mount(); 11907 } 11908}); 11909</script>
vendor: 1 bytes, line 11909
11909
11910<script> 11911function initNewsletterFormModal() { 11912 const showPopup = 1; 11913 const closedCookieName = 'newsletter-modal-closed'; 11914 const trigger = "on_load_delay"; 11915 const waitForShowingTime = 40000; // ms 11916 const scrollThreshold = 80; 11917 11918 if (showPopup == 1) { 11919 window.cookie_consent_config['necessary'] = [].concat( 11920 window.cookie_consent_config['necessary'] || [], 11921 [closedCookieName] 11922 ); 11923 11924 return { 11925 open: false, 11926 closedCookieName: closedCookieName, 11927 11928 firstname: '', 11929 lastname: '', 11930 email: '', 11931 errors: {}, 11932 11933 validateField(field) { 11934 this.errors[field] = ''; 11935 11936 if (field === 'firstname' && !this.firstname.trim()) { 11937 this.errors.firstname = 'First\u0020Name\u0020is\u0020required.'; 11938 } 11939 if (field === 'lastname' && !this.lastname.trim()) { 11940 this.errors.lastname = 'Last\u0020Name\u0020is\u0020required.'; 11941 } 11942 if (field === 'email') { 11943 if (!this.email.trim()) { 11944 this.errors.email = 'Email\u0020is\u0020required.'; 11945 } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.email)) { 11946 this.errors.email = 'Please\u0020enter\u0020a\u0020valid\u0020email\u0020address.'; 11947 } 11948 } 11949 }, 11950 11951 validateForm() { 11952 this.validateField('firstname'); 11953 this.validateField('lastname'); 11954 this.validateField('email'); 11955 return Object.values(this.errors).every(v => v === ''); 11956 }, 11957 11958 submitForm() { 11959 const $form = document.querySelector('#newsletter-validate-modal'); 11960 11961 if (this.validateForm()) { 11962 this.setCloseCookie(); 11963 $form.submit(); 11964 } 11965 }, 11966 11967 init() { 11968 if (!this.shouldShowModal()) return; 11969 11970 switch (trigger) { 11971 case 'on_load_delay': 11972 setTimeout(() => { this.open = true; }, waitForShowingTime); 11973 break; 11974 11975 case 'scroll_percent': 11976 window.addEventListener('scroll', () => { 11977 const percentScrolled = (window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100; 11978 if (percentScrolled > scrollThreshold && !this.open) { 11979 this.open = true; 11980 } 11981 }, { once: false }); 11982 break; 11983 11984 case 'exit_intent': 11985 document.addEventListener('mousemove', (e) => { 11986 if (e.clientY <= 10 && !this.open && !hyva.getCookie(this.closedCookieName)) { 11987 this.open = true; 11988 } 11989 }); 11990 break; 11991 } 11992 }, 11993 11994 closeModal() { 11995 this.setCloseCookie(); 11996 }, 11997 11998 setCloseCookie() { 11999 hyva.setCookie(this.closedCookieName, true, 365); 12000 this.open = false; 12001 }, 12002 12003 shouldShowModal() { 12004 const isInStoryblokPreview = window.location !== window.parent.location; 12005 const currentUrl = window.location.href; 12006 if(isInStoryblokPreview && !currentUrl.includes('newsletter-popup')) { 12007 return false; 12008 } 12009 return !hyva.getCookie(this.closedCookieName); 12010 } 12011 } 12012 } 12013 12014 window.addEventListener('alpine:init', () => Alpine.data('initNewsletterFormModal', initNewsletterFormModal), { once: true }); 12015} 12016</script>
vendor: 1 bytes, line 12016
12016
12017<script> 12018 window.enquiryTopic = ""; 12019 window.enquiryTopicProduct = ""; 12020 window.CRMForm = {enquiryTopic, enquiryTopicProduct}; 12021 12022</script>
vendor: 1 bytes, line 12022
12022
12023<script type="text/javascript" async> 12024 var w = document.createElement("script"); 12025 w.type = "text/javascript"; 12026 w.src = "//widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js"; 12027 w.async = true; 12028 document.head.appendChild(w); 12029</script>
vendor: 1 bytes, line 12029
12029
12030<script type="text/javascript"> 12031 (function(w,d,s,r,n){w.TrustpilotObject=n;w[n]=w[n]||function(){(w[n].q=w[n].q||[]).push(arguments)}; 12032 a=d.createElement(s);a.async=1;a.src=r;a.type='text/java'+s;f=d.getElementsByTagName(s)[0]; 12033 f.parentNode.insertBefore(a,f)})(window,document,'script', 'https://invitejs.trustpilot.com/tp.min.js', 'tp'); 12034 tp('register',''); 12035</script>
vendor: 1 bytes, line 12035
12035
12036<script type="text/javascript"> 12037 function inIframe () { 12038 try { 12039 return window.self !== window.top; 12040 } catch (e) { 12041 return false; 12042 } 12043 } 12044 12045 function tryParseJson(str) { 12046 if (typeof str === 'string') { 12047 try { 12048 return JSON.parse(str); 12049 } catch (e) { 12050 return false; 12051 } 12052 } 12053 return false; 12054 } 12055 12056 if (inIframe()) { 12057 window.addEventListener('message', function(e) { 12058 var adminOrign = new URL(window.location).hostname; 12059 var eventOriginHostname = new URL(e.origin).hostname; 12060 if (!e.data || adminOrign !== eventOriginHostname) { 12061 return; 12062 } 12063 if (typeof TrustpilotPreview !== 'undefined') { 12064 if (typeof e.data === 'string' && e.data === 'submit') { 12065 TrustpilotPreview.sendTrustboxes(); 12066 } else { 12067 jsonData = tryParseJson(e.data); 12068 if (jsonData.trustbox) { 12069 TrustpilotPreview.setSettings(jsonData.trustbox); 12070 } else if (jsonData.customised) { 12071 TrustpilotPreview.updateActive(jsonData.customised); 12072 } 12073 } 12074 } else { 12075 var settings = tryParseJson(e.data); 12076 if (settings) { 12077 var p = document.createElement("script"); 12078 p.type = "text/javascript"; 12079 p.onload = function () { 12080 const iFrame = e.source.parent.document.getElementById('configuration_iframe').contentWindow; 12081 TrustpilotPreview.init(['//ecommplugins-scripts.trustpilot.com/v2.1/css/preview.min.css'], settings, iFrame, e.source); 12082 }; 12083 p.src = '//ecommplugins-scripts.trustpilot.com/v2.1/js/preview.min.js'; 12084 document.head.appendChild(p); 12085 } 12086 } 12087 }); 12088 } 12089</script>
vendor: 1 bytes, line 12089
12089
12090<script type="text/javascript" async> 12091 const trustpilot_trustbox_settings = {"trustboxes":[]}; 12092 if (trustpilot_trustbox_settings) { 12093 document.addEventListener('DOMContentLoaded', function() { 12094 tp('trustBox', trustpilot_trustbox_settings); 12095 }); 12096 } 12097</script>
vendor: 1 bytes, line 12097
12097
12098<script> 12099 let SnapSlider = class { 12100 constructor(el, { 12101 labelSepparator = 'of', 12102 autoPager, 12103 groupPager 12104 } = {}) { 12105 this.el = el; 12106 this.track = this.el.querySelector("[data-track]"); 12107 if (!this.track) { 12108 console.warn( 12109 "No Slider track defined, reverting back to CSS slider.\nPlease create a wrapper for your slides with the attribute data-track", 12110 this.el 12111 ); 12112 return; 12113 } 12114 this.initialLoad = true; 12115 this.slides = []; 12116 this.inViewObserver; 12117 this.mutationObserver; 12118 this.resizeObserver; 12119 this.pager = this.el.querySelector("[data-pager]"); 12120 this.navBtns = Array.from( 12121 this.el.querySelectorAll("[data-next], [data-prev]") 12122 ); 12123 this.slideLabelSepparator = this.el.dataset.slideLabelSepparator || labelSepparator; 12124 this.useAutoPager = autoPager || this.el.hasAttribute("data-auto-pager") || false; 12125 this.useGroupPager = groupPager || this.el.hasAttribute("data-group-pager") || false; 12126 this.sliderLabel = this.el.hasAttribute("aria-label") && this.el.getAttribute("aria-label").toLowerCase().trim().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, ""); 12127 this.sliderId = this.el.id || this.sliderLabel || "slider"; 12128 this.markerIdName = "data-target-id"; 12129 this.pagerClasses = this.el.dataset.pagerClass || "snap-pager"; 12130 this.markerClasses = this.el.dataset.markerClass || "snap-marker"; 12131 this.init(); 12132 } 12133 init() { 12134 this.setupSlides(); 12135 this.setupNav(); 12136 if (this.useAutoPager) { 12137 this.createPager(); 12138 } else { 12139 this.setupPager(); 12140 } 12141 this.setupObservers(); 12142 this.setupMutationObserver(); 12143 this.setupResizeObserver(); 12144 this.el.addEventListener("click", this.eventHandler.bind(this)); 12145 this.el.addEventListener("keydown", this.eventHandler.bind(this)); 12146 } 12147 destroy() { 12148 this.inViewObserver?.disconnect(); 12149 this.mutationObserver?.disconnect(); 12150 this.resizeObserver?.disconnect(); 12151 this.el.removeEventListener("click", this.eventHandler.bind(this)); 12152 this.el.removeEventListener("keydown", this.eventHandler.bind(this)); 12153 } 12154 roundUpIfGreaterThan(number, min = 8) { 12155 const decimalPart = number - Math.floor(number); 12156 return decimalPart >= min ? Math.ceil(number) : Math.floor(number); 12157 } 12158 getInViewItems() { 12159 const inViewSlides = this.track.querySelectorAll("[data-in-view]"); 12160 const firstInViewSlide = inViewSlides[0] || null; 12161 const lastInViewSlide = inViewSlides[inViewSlides.length - 1] || null; 12162 const isAtStart = firstInViewSlide === this.slides[0]; 12163 const isAtEnd = lastInViewSlide === this.slides[this.slides.length - 1]; 12164 return { 12165 inViewSlides, 12166 totalInViewSlides: inViewSlides.length, 12167 firstInViewSlide, 12168 lastInViewSlide, 12169 isAtStart, 12170 isAtEnd, 12171 hasNoOverflow: isAtStart && isAtEnd 12172 }; 12173 } 12174 groupPagerMarkers() { 12175 if (this.slides.length === 0 || !this.pager || !this.useGroupPager) return; 12176 const totalVisibleSlides = this.roundUpIfGreaterThan( 12177 this.track.offsetWidth / this.slides[0].offsetWidth 12178 ); 12179 const markers = Array.from(this.pager.querySelectorAll("a, button")); 12180 markers.forEach((marker, index) => { 12181 marker.style.display = index % totalVisibleSlides === 0 ? null : "none"; 12182 }); 12183 } 12184 handleInView(entries) { 12185 entries.forEach((entry) => { 12186 const marker = this.pager && (this.pager.querySelector(`[href="#${entry.target.id}"]`) || this.pager.querySelector( 12187 `[${this.markerIdName}="${entry.target.id}"]` 12188 )); 12189 entry.target.toggleAttribute("data-in-view", entry.isIntersecting); 12190 entry.target.toggleAttribute("inert", !entry.isIntersecting); 12191 marker?.setAttribute("aria-current", entry.isIntersecting); 12192 marker?.setAttribute("tabindex", entry.isIntersecting ? "0" : "-1"); 12193 }); 12194 const { 12195 isAtStart, 12196 isAtEnd, 12197 hasNoOverflow 12198 } = this.getInViewItems(); 12199 this.navBtns.forEach((btn) => { 12200 if (btn.hasAttribute("data-next")) { 12201 btn.style.visibility = hasNoOverflow ? "hidden" : null; 12202 isAtEnd ? btn.setAttribute("disabled", "") : btn.removeAttribute("disabled"); 12203 } 12204 if (btn.hasAttribute("data-prev")) { 12205 btn.style.visibility = hasNoOverflow ? "hidden" : null; 12206 isAtStart ? btn.setAttribute("disabled", "") : btn.removeAttribute("disabled"); 12207 } 12208 }); 12209 if (this.pager) { 12210 this.pager.style.visibility = hasNoOverflow ? "hidden" : null; 12211 } 12212 if (!this.initialLoad) { 12213 this.el.dispatchEvent( 12214 new CustomEvent("slideChange", { 12215 detail: this.getInViewItems() 12216 }) 12217 ); 12218 } else { 12219 this.initialLoad = false;
12220 } 12221 if (document.activeElement.parentElement.hasAttribute("data-pager")) { 12222 const activeItems = this.pager.querySelectorAll('[tabindex="0"]'); 12223 if (activeItems.length) { 12224 activeItems[0].focus({ preventScroll: true }); 12225 } 12226 } 12227 } 12228 getSlides() { 12229 if (!this.track) return []; 12230 return Array.from(this.track.children).filter( 12231 (child) => child.tagName.toLowerCase() !== "template" && child.tagName.toLowerCase() !== "style" && child.tagName.toLowerCase() !== "script" 12232 ); 12233 } 12234 refreshSlides() { 12235 this.initialLoad = true; 12236 this.slides = this.getSlides(); 12237 this.setupSlides(); 12238 if (this.useAutoPager) { 12239 this.createPager(); 12240 } else { 12241 this.setupPager(); 12242 } 12243 this.groupPagerMarkers(); 12244 this.setupObservers(); 12245 } 12246 setupSlides() { 12247 this.slides = this.getSlides(); 12248 this.slides.forEach((slide, index) => { 12249 const totalSlides = this.slides.length; 12250 const currentSlide = index + 1; 12251 const existingLabel = slide.getAttribute("aria-label") || ""; 12252 const isImage = slide.tagName.toLowerCase() === "img" || slide.tagName.toLowerCase() === "picture"; 12253 const slideLabelTag = isImage ? "alt" : "aria-label"; 12254 const hasAutoLabel = existingLabel.startsWith( 12255 `${currentSlide} ${this.slideLabelSepparator} ` 12256 ); 12257 if (!slide.hasAttribute("id")) { 12258 slide.setAttribute( 12259 "id", 12260 `${this.sliderId}-item-${currentSlide}` 12261 ); 12262 } 12263 if (!slide.hasAttribute(slideLabelTag) || slide.getAttribute(slideLabelTag) === "" || hasAutoLabel) { 12264 slide.setAttribute( 12265 slideLabelTag, 12266 `${currentSlide} ${this.slideLabelSepparator} ${totalSlides}` 12267 ); 12268 } 12269 if (slide.tagName.toLowerCase() === "div" && !slide.hasAttribute("role")) { 12270 slide.setAttribute("role", "group"); 12271 } 12272 if (this.pager && !isImage) { 12273 slide.setAttribute("role", "tabpanel"); 12274 } 12275 if (slide.getAttribute("role") === "group") { 12276 slide.setAttribute("aria-roledescription", "item"); 12277 } 12278 }); 12279 if (!this.el.hasAttribute("role") && this.el.tagName !== "SECTION") { 12280 this.el.setAttribute("role", "region"); 12281 } 12282 if (!this.el.hasAttribute("aria-roledescription")) { 12283 this.el.setAttribute("aria-roledescription", "carousel"); 12284 } 12285 this.track.setAttribute("tabindex", 0); 12286 this.track.setAttribute("aria-live", "polite"); 12287 } 12288 setupNav() { 12289 this.navBtns.forEach((btn) => { 12290 btn.setAttribute("disabled", ""); 12291 btn.removeAttribute("hidden"); 12292 btn.classList.remove("invisible"); 12293 btn.style.visibility = null; 12294 }); 12295 } 12296 createPager() { 12297 const newPager = document.createElement("nav"); 12298 newPager.setAttribute("data-pager", ""); 12299 newPager.setAttribute("role", "tablist"); 12300 newPager.classList.add(...this.pagerClasses.split(" ")); 12301 this.slides.forEach((slide, index) => { 12302 const marker = document.createElement("button"); 12303 const slideId = slide.id || `${this.sliderId}-item-${index + 1}`; 12304 marker.setAttribute(this.markerIdName, slideId); 12305 marker.classList.add(...this.markerClasses.split(" ")); 12306 this.setupPagerMarker(marker, index); 12307 newPager.appendChild(marker); 12308 if (slide.tagName.toLowerCase() !== "img" && slide.tagName.toLowerCase() !== "picture") { 12309 slide.removeAttribute("aria-roledescription"); 12310 slide.setAttribute("role", "tabpanel"); 12311 } 12312 }); 12313 if (this.pager) { 12314 this.pager.setAttribute("role", "tablist"); 12315 this.pager.replaceChildren(...newPager.children); 12316 } else { 12317 this.track.after(newPager); 12318 this.pager = this.el.querySelector("[data-pager]"); 12319 } 12320 } 12321 setupPager() { 12322 if (!this.pager) return; 12323 this.pager.setAttribute("role", "tablist"); 12324 const items = Array.from(this.pager.querySelectorAll("a, button"));
12325 items.forEach((marker, index) => this.setupPagerMarker(marker, index)); 12326 } 12327 setupPagerMarker(marker, index) { 12328 const markerId = marker.getAttribute("href")?.slice(1) || marker.getAttribute(this.markerIdName); 12329 const slideId = markerId || `${this.sliderId}-item-${index + 1}`; 12330 if (!markerId) { 12331 marker.setAttribute(this.markerIdName, slideId); 12332 } 12333 marker.setAttribute("role", "tab"); 12334 marker.setAttribute("aria-controls", slideId); 12335 marker.setAttribute("aria-posinset", index + 1); 12336 marker.setAttribute("aria-setsize", this.slides.length); 12337 marker.setAttribute("tabindex", "-1"); 12338 if (!marker.hasAttribute("aria-label")) { 12339 marker.setAttribute("aria-label", `Slide ${index + 1}`); 12340 } 12341 } 12342 setupObservers() { 12343 if (this.inViewObserver) { 12344 this.inViewObserver.disconnect(); 12345 } 12346 this.inViewObserver = new IntersectionObserver( 12347 this.handleInView.bind(this), { 12348 root: this.track, 12349 threshold: 0.8 12350 } 12351 ); 12352 this.slides.forEach((slide) => this.inViewObserver.observe(slide)); 12353 } 12354 setupMutationObserver() { 12355 this.mutationObserver = new MutationObserver( 12356 this.refreshSlides.bind(this) 12357 ); 12358 this.mutationObserver.observe(this.track, { 12359 childList: true, 12360 subtree: false 12361 }); 12362 } 12363 setupResizeObserver() { 12364 this.resizeObserver = new ResizeObserver( 12365 this.groupPagerMarkers.bind(this) 12366 ); 12367 this.resizeObserver.observe(this.el); 12368 } 12369 goToSlideDir(dir = "next") { 12370 const { 12371 firstInViewSlide, 12372 lastInViewSlide 12373 } = this.getInViewItems(); 12374 const isPrev = dir === "prev"; 12375 let targetSlide = isPrev ? firstInViewSlide?.previousElementSibling : lastInViewSlide?.nextElementSibling; 12376 if (!targetSlide) return; 12377 if (targetSlide.tagName.toLowerCase() === "template") { 12378 targetSlide = isPrev ? targetSlide?.previousElementSibling : targetSlide?.nextElementSibling; 12379 } 12380 targetSlide.scrollIntoView({ block: "nearest", inline: isPrev ? "end" : "start" }); 12381 } 12382 pagerToSlide(event) { 12383 if (!event.target.closest("[data-pager]")) return; 12384 const marker = event.target.closest("a, button"); 12385 if (!marker) return; 12386 event.preventDefault(); 12387 const slideId = marker.getAttribute("href")?.slice(1) || marker.getAttribute(this.markerIdName); 12388 const targetSlide = this.track.querySelector(`#${slideId}`); 12389 targetSlide?.scrollIntoView({ block: "nearest", inline: "start" }); 12390 } 12391 eventHandler(event) { 12392 const target = event.target.closest( 12393 "[data-next], [data-prev], [data-pager]" 12394 ); 12395 if (!target) return; 12396 if (event.type === "click") { 12397 if (target.hasAttribute("data-next")) { 12398 this.goToSlideDir("next"); 12399 } else if (target.hasAttribute("data-prev")) { 12400 this.goToSlideDir("prev"); 12401 } else if (target.closest("[data-pager]")) { 12402 this.pagerToSlide(event); 12403 } 12404 } 12405 if (event.type === "keydown" && target.closest("[data-pager]")) { 12406 if (event.key === "ArrowRight") { 12407 this.goToSlideDir("next"); 12408 } else if (event.key === "ArrowLeft") { 12409 this.goToSlideDir("prev"); 12410 } 12411 } 12412 } 12413 }; 12414 12415 (() => { 12416 function alpineSnapSlider(Alpine) { 12417 Alpine.directive("snap-slider", (el, { 12418 modifiers 12419 }, { 12420 cleanup 12421 }) => { 12422 const autoPager = modifiers.includes("auto-pager");
12423 const groupPager = modifiers.includes("group-pager"); 12424 const slider = new SnapSlider(el, { 12425 autoPager, 12426 groupPager 12427 }); 12428 cleanup(() => { 12429 slider.destroy(); 12430 }); 12431 }); 12432 } 12433 12434 document.addEventListener("alpine:init", () => { 12435 window.Alpine.plugin(alpineSnapSlider); 12436 }); 12437 })();</script>
vendor: 1 bytes, line 12437
12437
12438<script> 12439 (() => { 12440 // src/dialog.js 12441 function dialog_default(Alpine) { 12442 Alpine.directive("htmldialog", fylgjaAlpineDialog); 12443 12444 function fylgjaAlpineDialog(el, { 12445 expression, 12446 modifiers 12447 }, { 12448 evaluateLater, 12449 cleanup 12450 }) { 12451 const evaluate = expression.length ? evaluateLater(expression) : () => {}; 12452 const lockPageScroll = modifiers.includes("noscroll"); 12453 const closeby = modifierValue(modifiers, "closeby", "any"); 12454 el.style.display = null; 12455 el.hidden = false; 12456 el.style.length === 0 && el.removeAttribute("style"); 12457 el.addEventListener("keydown", escapeDialog); 12458 el.addEventListener("click", backdropDialog); 12459 el.addEventListener("submit", methodDialog); 12460 12461 function scrollLock(use = true) { 12462 document.body.style.overflow = use ? "hidden" : ""; 12463 } 12464 12465 function methodDialog(event) { 12466 if (event.target.getAttribute("method") === "dialog" || event.submitter && event.submitter.getAttribute("formmethod") === "dialog") { 12467 evaluate(); 12468 } 12469 } 12470 12471 function escapeDialog(event) { 12472 if (event.key !== "Escape") 12473 return; 12474 event.preventDefault(); 12475 if (closeby !== "any" && closeby !== "closerequest") 12476 return; 12477 evaluate(); 12478 } 12479 12480 function backdropDialog(event) { 12481 if (event.target !== el || closeby !== "any") 12482 return; 12483 const rect = el.getBoundingClientRect(); 12484 const isInDialog = rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width; 12485 if (isInDialog) 12486 return; 12487 evaluate(); 12488 } 12489 el._x_doShow = () => { 12490 if (el.hasAttribute("open")) 12491 return; 12492 el.showModal(); 12493 scrollLock(lockPageScroll); 12494 }; 12495 el._x_doHide = () => { 12496 if (!el.hasAttribute("open")) 12497 return; 12498 el.close(); 12499 scrollLock(false); 12500 }; 12501 cleanup(() => { 12502 el.removeEventListener("keydown", escapeDialog); 12503 el.removeEventListener("click", backdropDialog); 12504 el.removeEventListener("submit", methodDialog); 12505 scrollLock(false); 12506 }); 12507 } 12508 } 12509 12510 function modifierValue(modifiers, key, fallback) { 12511 if (modifiers.indexOf(key) === -1) 12512 return fallback; 12513 const rawValue = modifiers[modifiers.indexOf(key) + 1]; 12514 if (!rawValue) 12515 return fallback; 12516 if (key === "closeby") { 12517 const allowedValues = ["auto", "none", "closerequest", "any"]; 12518 const options = allowedValues.join(", "); 12519 if (!allowedValues.includes(rawValue)) { 12520 console.warn( 12521 `"${rawValue}" is not one of the allowed values for closeby: ${options}` 12522 ); 12523 } 12524 return fallback; 12525 } 12526 return rawValue; 12527 } 12528 12529 // src/cdn.js 12530 document.addEventListener("alpine:init", () => { 12531 window.Alpine.plugin(dialog_default); 12532 }); 12533 })(); 12534</script>
vendor: 1 bytes, line 12534
12534
vendor: 2,347 bytes, lines 12535-12593
12535<script> 12536 (() => { 12537 function src_default(Alpine) { 12538 Alpine.directive("intersect", Alpine.skipDuringClone((el, { value, expression, modifiers }, { evaluateLater, cleanup }) => { 12539 let evaluate = evaluateLater(expression); 12540 let options = { 12541 rootMargin: getRootMargin(modifiers), 12542 threshold: getThreshold(modifiers) 12543 }; 12544 let observer = new IntersectionObserver((entries) => { 12545 entries.forEach((entry) => { 12546 if (entry.isIntersecting === (value === "leave")) 12547 return; 12548 evaluate(); 12549 modifiers.includes("once") && observer.disconnect(); 12550 }); 12551 }, options); 12552 observer.observe(el); 12553 cleanup(() => { 12554 observer.disconnect(); 12555 }); 12556 })); 12557 } 12558 function getThreshold(modifiers) { 12559 if (modifiers.includes("full")) 12560 return 0.99; 12561 if (modifiers.includes("half")) 12562 return 0.5; 12563 if (!modifiers.includes("threshold")) 12564 return 0; 12565 let threshold = modifiers[modifiers.indexOf("threshold") + 1]; 12566 if (threshold === "100") 12567 return 1; 12568 if (threshold === "0") 12569 return 0; 12570 return Number(`.${threshold}`); 12571 } 12572 function getLengthValue(rawValue) { 12573 let match = rawValue.match(/^(-?[0-9]+)(px|%)?$/); 12574 return match ? match[1] + (match[2] || "px") : void 0; 12575 } 12576 function getRootMargin(modifiers) { 12577 const key = "margin"; 12578 const fallback = "0px 0px 0px 0px"; 12579 const index = modifiers.indexOf(key); 12580 if (index === -1) 12581 return fallback; 12582 let values = []; 12583 for (let i = 1; i < 5; i++) { 12584 values.push(getLengthValue(modifiers[index + i] || "")); 12585 } 12586 values = values.filter((v) => v !== void 0); 12587 return values.length ? values.join(" ").trim() : fallback; 12588 } 12589 12590 document.addEventListener("alpine:init", () => { 12591 window.Alpine.plugin(src_default); 12592 }); 12593 })();</script>
vendor: 1 bytes, line 12593
12593
12594<script> 12595 for (const [selector, deferUntil] of Object.entries({".product-slider section[x-data]:not([x-data] [x-data])":"intersect",".product-info [x-data]:not([x-data] [x-data])":"intersect","#filters-content [x-data]:not([x-data] [x-data])":"intersect","#review_form":"intersect","section[x-data^=initRecentlyViewedProductsComponent]":"intersect","div[x-data^=initBundleOptions]":"intersect","#product_addtocart_form [x-data]:not([x-data] [x-data])":"intersect","#notice-cookie-block":"idle"})) { 12596 document.querySelectorAll(selector).forEach(el => el.setAttribute('x-defer', `${deferUntil}`)); 12597 }</script>
vendor: 1 bytes, line 12597
12597
12598<script> 12599 (() => { 12600 const hasAlpine = new Promise(resolve => { 12601 window.addEventListener('alpine:initialized', resolve, {once: true, passive: true}); 12602 }); 12603 12604 const hasInteract = new Promise(resolve => { 12605 (events => { 12606 const onInteract = () => { 12607 resolve(); 12608 events.forEach(type => window.removeEventListener(type, onInteract)); 12609 } 12610 events.forEach(type => window.addEventListener(type, onInteract, {once: true, passive: true})) 12611 })(['touchstart', 'mouseover', 'wheel', 'scroll', 'keydown']) 12612 }); 12613 12614 const onIntersect = (el) => { 12615 return new Promise(resolve => { 12616 const observer = new IntersectionObserver(entries => { 12617 for (const entry of entries) { 12618 if (entry.isIntersecting) { 12619 observer.disconnect() 12620 resolve(); 12621 } 12622 } 12623 }, {}); 12624 observer.observe(el); 12625 }); 12626 } 12627 12628 function runComponent(el) { 12629 hasAlpine.then(() => { 12630 el.removeAttribute('x-ignore'); 12631 queueMicrotask(() => Alpine.initTree(el)); 12632 }); 12633 } 12634 12635 function initDeferredComponents() { 12636 document.querySelectorAll('[x-data][x-defer]').forEach(el => { 12637 el.setAttribute('x-ignore', ''); 12638 const deferUntil = (el.getAttribute('x-defer') || '').trim(); 12639 switch (deferUntil) { 12640 case 'interact': 12641 hasInteract.then(() => runComponent(el)); 12642 break; 12643 case 'intersect': 12644 onIntersect(el).then(() => runComponent(el)) 12645 break; 12646 case 'idle': 12647 window.requestIdleCallback 12648 ? window.requestIdleCallback(() => runComponent(el), {timeout: 4000}) 12649 : setTimeout(() => runComponent(el), 4000); 12650 break; 12651 case 'eager': 12652 runComponent(el); 12653 break; 12654 default: 12655 if (deferUntil.startsWith('event:') && deferUntil.length > 6) { 12656 window.addEventListener(deferUntil.substring(6), () => runComponent(el), {once: true, passive: true}); 12657 } 12658 } 12659 }); 12660 } 12661 12662 window.addEventListener('alpine:init', initDeferredComponents, {once: true, passive: true}); 12663 })();</script>
vendor: 1 bytes, line 12663
12663
vendor: 4,405 bytes, lines 12664-12771
12664<script> 12665 (() => { 12666 // packages/collapse/src/index.js 12667 function src_default(Alpine) { 12668 Alpine.directive("collapse", collapse); 12669 collapse.inline = (el, { 12670 modifiers 12671 }) => { 12672 if (!modifiers.includes("min")) 12673 return; 12674 el._x_doShow = () => {}; 12675 el._x_doHide = () => {}; 12676 }; 12677 12678 function collapse(el, { 12679 modifiers 12680 }) { 12681 let duration = modifierValue(modifiers, "duration", 250) / 1e3; 12682 let floor = modifierValue(modifiers, "min", 0); 12683 let fullyHide = !modifiers.includes("min"); 12684 if (!el._x_isShown) 12685 el.style.height = `${floor}px`; 12686 if (!el._x_isShown && fullyHide) 12687 el.hidden = true; 12688 if (!el._x_isShown) 12689 el.style.overflow = "hidden"; 12690 let setFunction = (el2, styles) => { 12691 let revertFunction = Alpine.setStyles(el2, styles); 12692 return styles.height ? () => {} : revertFunction; 12693 }; 12694 let transitionStyles = { 12695 transitionProperty: "height", 12696 transitionDuration: `${duration}s`, 12697 transitionTimingFunction: "cubic-bezier(0.4, 0.0, 0.2, 1)" 12698 }; 12699 el._x_transition = { 12700 in(before = () => {}, after = () => {}) { 12701 if (fullyHide) 12702 el.hidden = false; 12703 if (fullyHide) 12704 el.style.display = null; 12705 let current = el.getBoundingClientRect().height; 12706 el.style.height = "auto"; 12707 let full = el.getBoundingClientRect().height; 12708 if (current === full) { 12709 current = floor; 12710 } 12711 Alpine.transition(el, Alpine.setStyles, { 12712 during: transitionStyles, 12713 start: { 12714 height: current + "px" 12715 }, 12716 end: { 12717 height: full + "px" 12718 } 12719 }, () => el._x_isShown = true, () => { 12720 if (Math.abs(el.getBoundingClientRect().height - full) < 1) { 12721 el.style.overflow = null; 12722 } 12723 }); 12724 }, 12725 out(before = () => {}, after = () => {}) { 12726 let full = el.getBoundingClientRect().height; 12727 Alpine.transition(el, setFunction, { 12728 during: transitionStyles, 12729 start: { 12730 height: full + "px" 12731 }, 12732 end: { 12733 height: floor + "px" 12734 } 12735 }, () => el.style.overflow = "hidden", () => { 12736 el._x_isShown = false; 12737 if (el.style.height == `${floor}px` && fullyHide) { 12738 el.style.display = "none"; 12739 el.hidden = true; 12740 } 12741 }); 12742 } 12743 }; 12744 } 12745 } 12746 12747 function modifierValue(modifiers, key, fallback) { 12748 if (modifiers.indexOf(key) === -1) 12749 return fallback; 12750 const rawValue = modifiers[modifiers.indexOf(key) + 1]; 12751 if (!rawValue) 12752 return fallback; 12753 if (key === "duration") { 12754 let match = rawValue.match(/([0-9]+)ms/); 12755 if (match) 12756 return match[1]; 12757 } 12758 if (key === "min") { 12759 let match = rawValue.match(/([0-9]+)px/); 12760 if (match) 12761 return match[1]; 12762 } 12763 return rawValue; 12764 } 12765 12766 // packages/collapse/builds/cdn.js 12767 document.addEventListener("alpine:init", () => { 12768 window.Alpine.plugin(src_default); 12769 }); 12770 })(); 12771</script>
vendor: 1 bytes, line 12771
12771
12772<script> 12773 function r(n,t){for(var i=0;i<t.length;i++){var r=t[i];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(n,r.key,r)}}function Jt(n,t,i){t&&r(n.prototype,t),i&&r(n,i),Object.defineProperty(n,"prototype",{writable:!1})} 12774
vendor: 29,403 bytes, line 12774
12774var n,t;n=this,t=function(){"use strict";var v="(prefers-reduced-motion: reduce)",G=4,rn=5,r={CREATED:1,MOUNTED:2,IDLE:3,MOVING:G,SCROLLING:rn,DRAGGING:6,DESTROYED:7};function D(n){n.length=0}function o(n,t,i){return Array.prototype.slice.call(n,t,i)}function R(n){return n.bind.apply(n,[null].concat(o(arguments,1)))}function on(){}var p=setTimeout;function h(n){return requestAnimationFrame(n)}function u(n,t){return typeof t===n}function un(n){return!c(n)&&u("object",n)}var e=Array.isArray,x=R(u,"function"),C=R(u,"string"),en=R(u,"undefined");function c(n){return null===n}function m(n){try{return n instanceof(n.ownerDocument.defaultView||window).HTMLElement}catch(n){return!1}}function y(n){return e(n)?n:[n]}function g(n,t){y(n).forEach(t)}function b(n,t){return-1<n.indexOf(t)}function k(n,t){return n.push.apply(n,y(t)),n}function A(t,n,i){t&&g(n,function(n){n&&t.classList[i?"add":"remove"](n)})}function M(n,t){A(n,C(t)?t.split(" "):t,!0)}function L(n,t){g(t,n.appendChild.bind(n))}function O(n,i){g(n,function(n){var t=(i||n).parentNode;t&&t.insertBefore(n,i)})}function cn(n,t){return m(n)&&(n.msMatchesSelector||n.matches).call(n,t)}function S(n,t){n=n?o(n.children):[];return t?n.filter(function(n){return cn(n,t)}):n}function fn(n,t){return t?S(n,t)[0]:n.firstElementChild}var E=Object.keys;function w(t,i,n){t&&(n?E(t).reverse():E(t)).forEach(function(n){"__proto__"!==n&&i(t[n],n)})}function an(r){return o(arguments,1).forEach(function(i){w(i,function(n,t){r[t]=i[t]})}),r}function d(i){return o(arguments,1).forEach(function(n){w(n,function(n,t){e(n)?i[t]=n.slice():un(n)?i[t]=d({},un(i[t])?i[t]:{},n):i[t]=n})}),i}function sn(t,n){g(n||E(t),function(n){delete t[n]})}function P(n,i){g(n,function(t){g(i,function(n){t&&t.removeAttribute(n)})})}function I(i,t,r){un(t)?w(t,function(n,t){I(i,t,n)}):g(i,function(n){c(r)||""===r?P(n,t):n.setAttribute(t,String(r))})}function j(n,t,i){n=document.createElement(n);return t&&(C(t)?M:I)(n,t),i&&L(i,n),n}function _(n,t,i){if(en(i))return getComputedStyle(n)[t];c(i)||(n.style[t]=""+i)}function ln(n,t){_(n,"display",t)}function dn(n){n.setActive&&n.setActive()||n.focus({preventScroll:!0})}function z(n,t){return n.getAttribute(t)}function vn(n,t){return n&&n.classList.contains(t)}function N(n){return n.getBoundingClientRect()}function T(n){g(n,function(n){n&&n.parentNode&&n.parentNode.removeChild(n)})}function hn(n){return fn((new DOMParser).parseFromString(n,"text/html").body)}function F(n,t){n.preventDefault(),t&&(n.stopPropagation(),n.stopImmediatePropagation())}function pn(n,t){return n&&n.querySelector(t)}function gn(n,t){return t?o(n.querySelectorAll(t)):[]}function X(n,t){A(n,t,!1)}function mn(n){return n.timeStamp}function W(n){return C(n)?n:n?n+"px":""}var yn="splide",f="data-"+yn;function bn(n,t){if(!n)throw new Error("["+yn+"] "+(t||""))}var Y=Math.min,wn=Math.max,xn=Math.floor,kn=Math.ceil,U=Math.abs;function Sn(n,t,i){return U(n-t)<i}function En(n,t,i,r){var o=Y(t,i),t=wn(t,i);return r?o<n&&n<t:o<=n&&n<=t}function q(n,t,i){var r=Y(t,i),t=wn(t,i);return Y(wn(r,n),t)}function Ln(n){return(0<n)-(n<0)}function On(t,n){return g(n,function(n){t=t.replace("%s",""+n)}),t}function An(n){return n<10?"0"+n:""+n}var _n={};function zn(){var c=[];function i(n,i,r){g(n,function(t){t&&g(i,function(n){n.split(" ").forEach(function(n){n=n.split(".");r(t,n[0],n[1])})})})}return{bind:function(n,t,u,e){i(n,t,function(n,t,i){var r="addEventListener"in n,o=r?n.removeEventListener.bind(n,t,u,e):n.removeListener.bind(n,u);r?n.addEventListener(t,u,e):n.addListener(u),c.push([n,t,i,u,o])})},unbind:function(n,t,o){i(n,t,function(t,i,r){c=c.filter(function(n){return!!(n[0]!==t||n[1]!==i||n[2]!==r||o&&n[3]!==o)||(n[4](),!1)})})},dispatch:function(n,t,i){var r;return"function"==typeof CustomEvent?r=new CustomEvent(t,{bubbles:!0,detail:i}):(r=document.createEvent("CustomEvent")).initCustomEvent(t,!0,!1,i),n.dispatchEvent(r),r},destroy:function(){c.forEach(function(n){n[4]()}),D(c)}}}var B="mounted",H="move",Dn="moved",Mn="click",Pn="active",In="inactive",Rn="visible",Cn="hidden",J="refresh",K="updated",jn="resize",Nn="resized",Tn="scroll",V="scrolled",a="destroy",Gn="navigation:mounted",Fn="autoplay:play",Xn="autoplay:pause",Wn="lazyload:loaded",Yn="sk",Un="sh";function Q(n){var i=n?n.event.bus:document.createDocumentFragment(),r=zn();return n&&n.event.on(a,r.destroy),an(r,{bus:i,on:function(n,t){r.bind(i,y(n).join(" "),function(n){t.apply(t,e(n.detail)?n.detail:[])})},off:R(r.unbind,i),emit:function(n){r.dispatch(i,n,o(arguments,1))}})}function qn(t,n,i,r){var o,u,e=Date.now,c=0,f=!0,a=0;function s(){if(!f){if(c=t?Y((e()-o)/t,1):1,i&&i(c),1<=c&&(n(),o=e(),r&&++a>=r))return l();u=h(s)}}function l(){f=!0}function d(){u&&cancelAnimationFrame(u),f=!(u=c=0)}return{start:function(n){n||d(),o=e()-(n?c*t:0),f=!1,u=h(s)},rewind:function(){o=e(),c=0,i&&i(c)},pause:l,cancel:d,set:function(n){t=n},isPaused:function(){return f}}}function s(n){var t=n;return{set:function(n){t=n},is:function(n){return b(y(n),t)}}}var n="Arrow",Bn=n+"Left",Hn=n+"Right",t=n+"Up",n=n+"Down",Jn="ttb",l={width:["height"],left:["top","right"],right:["bottom","left"],x:["y"],X:["Y"],Y:["X"],ArrowLeft:[t,Hn],ArrowRight:[n,Bn]};var Z="role",$="tabindex",i="aria-",Kn=i+"controls",Vn=i+"current",Qn=i+"selected",nn=i+"label",Zn=i+"labelledby",$n=i+"hidden",nt=i+"orientation",tt=i+"roledescription",it=i+"live",rt=i+"busy",ot=i+"atomic",ut=[Z,$,"disabled",Kn,Vn,nn,Zn,$n,nt,tt],i=yn+"__",et=yn,ct=i+"track",ft=i+"list",at=i+"slide",st=at+"--clone",lt=at+"__container",dt=i+"arrows",vt=i+"arrow",ht=vt+"--prev",pt=vt+"--next",gt=i+"pagination",mt=gt+"__page",yt=i+"progress"+"__bar",bt=i+"toggle",wt=i+"sr",tn="is-active",xt="is-prev",kt="is-next",St="is-visible",Et="is-loading",Lt="is-focus-in",Ot="is-overflow",At=[tn,St,xt,kt,Et,Lt,Ot];var _t="touchstart mousedown",zt="touchmove mousemove",Dt="touchend touchcancel mouseup click";var Mt="slide",Pt="loop",It="fade";function Rt(o,r,t,u){var e,n=Q(o),i=n.on,c=n.emit,f=n.bind,a=o.Components,s=o.root,l=o.options,d=l.isNavigation,v=l.updateOnMove,h=l.i18n,p=l.pagination,g=l.slideFocus,m=a.Direction.resolve,y=z(u,"style"),b=z(u,nn),w=-1<t,x=fn(u,"."+lt);function k(){var n=o.splides.map(function(n){n=n.splide.Components.Slides.getAt(r);return n?n.slide.id:""}).join(" ");I(u,nn,On(h.slideX,(w?t:r)+1)),I(u,Kn,n),I(u,Z,g?"button":""),g&&P(u,tt)}function S(){e||E()}function E(){var n,t,i;e||(n=o.index,(i=L())!==vn(u,tn)&&(A(u,tn,i),I(u,Vn,d&&i||""),c(i?Pn:In,O)),i=function(){if(o.is(It))return L();var n=N(a.Elements.track),t=N(u),i=m("left",!0),r=m("right",!0);return xn(n[i])<=kn(t[i])&&xn(t[r])<=kn(n[r])}(),t=!i&&(!L()||w),o.state.is([G,rn])||I(u,$n,t||""),I(gn(u,l.focusableNodes||""),$,t?-1:""),g&&I(u,$,t?-1:0),i!==vn(u,St)&&(A(u,St,i),c(i?Rn:Cn,O)),i||document.activeElement!==u||(t=a.Slides.getAt(o.index))&&dn(t.slide),A(u,xt,r===n-1),A(u,kt,r===n+1))}function L(){var n=o.index;return n===r||l.cloneStatus&&n===t}var O={index:r,slideIndex:t,slide:u,container:x,isClone:w,mount:function(){w||(u.id=s.id+"-slide"+An(r+1),I(u,Z,p?"tabpanel":"group"),I(u,tt,h.slide),I(u,nn,b||On(h.slideLabel,[r+1,o.length]))),f(u,"click",R(c,Mn,O)),f(u,"keydown",R(c,Yn,O)),i([Dn,Un,V],E),i(Gn,k),v&&i(H,S)},destroy:function(){e=!0,n.destroy(),X(u,At),P(u,ut),I(u,"style",y),I(u,nn,b||"")},update:E,style:function(n,t,i){_(i&&x||u,n,t)},isWithin:function(n,t){return n=U(n-r),(n=w||!l.rewind&&!o.is(Pt)?n:Y(n,o.length-n))<=t}};return O}var Ct=f+"-interval";var jt={passive:!1,capture:!0};var Nt={Spacebar:" ",Right:Hn,Left:Bn,Up:t,Down:n};function Tt(n){return n=C(n)?n:n.key,Nt[n]||n}var Gt="keydown";var Ft=f+"-lazy",Xt=Ft+"-srcset",Wt="["+Ft+"], ["+Xt+"]";var Yt=[" ","Enter"];var Ut=Object.freeze({__proto__:null,Media:function(r,n,o){var u=r.state,t=o.breakpoints||{},e=o.reducedMotion||{},i=zn(),c=[];function f(n){n&&i.destroy()}function a(n,t){t=matchMedia(t);i.bind(t,"change",s),c.push([n,t])}function s(){var n=u.is(7),t=o.direction,i=c.reduce(function(n,t){return d(n,t[1].matches?t[0]:{})},{});sn(o),l(i),o.destroy?r.destroy("completely"===o.destroy):n?(f(!0),r.mount()):t!==o.direction&&r.refresh()}function l(n,t,i){d(o,n),t&&d(Object.getPrototypeOf(o),n),!i&&u.is(1)||r.emit(K,o)}return{setup:function(){var i="min"===o.mediaQuery;E(t).sort(function(n,t){return i?+n-+t:+t-+n}).forEach(function(n){a(t[n],"("+(i?"min":"max")+"-width:"+n+"px)")}),a(e,v),s()},destroy:f,reduce:function(n){matchMedia(v).matches&&(n?d(o,e):sn(o,E(e)))},set:l}},Direction:function(n,t,o){return{resolve:function(n,t,i){var r="rtl"!==(i=i||o.direction)||t?i===Jn?0:-1:1;return l[n]&&l[n][r]||n.replace(/width|left|right/i,function(n,t){n=l[n.toLowerCase()][r]||n;return 0<t?n.charAt(0).toUpperCase()+n.slice(1):n})},orient:function(n){return n*("rtl"===o.direction?1:-1)}}},Elements:function(n,t,i){var r,o,u,e=Q(n),c=e.on,f=e.bind,a=n.root,s=i.i18n,l={},d=[],v=[],h=[];function p(){r=y("."+ct),o=fn(r,"."+ft),bn(r&&o,"A track/list element is missing."),k(d,S(o,"."+at+":not(."+st+")")),w({arrows:dt,pagination:gt,prev:ht,next:pt,bar:yt,toggle:bt},function(n,t){l[t]=y("."+n)}),an(l,{root:a,track:r,list:o,slides:d});var n=a.id||function(n){return""+n+An(_n[n]=(_n[n]||0)+1)}(yn),t=i.role;a.id=n,r.id=r.id||n+"-track",o.id=o.id||n+"-list",!z(a,Z)&&"SECTION"!==a.tagName&&t&&I(a,Z,t),I(a,tt,s.carousel),I(o,Z,"presentation"),m()}function g(n){var t=ut.concat("style");D(d),X(a,v),X(r,h),P([r,o],t),P(a,n?t:["style",tt])}function m(){X(a,v),X(r,h),v=b(et),h=b(ct),M(a,v),M(r,h),I(a,nn,i.label),I(a,Zn,i.labelledby)}function y(n){n=pn(a,n);return n&&function(n,t){if(x(n.closest))return n.closest(t);for(var i=n;i&&1===i.nodeType&&!cn(i,t);)i=i.parentElement;return i}(n,"."+et)===a?n:void 0}function b(n){return[n+"--"+i.type,n+"--"+i.direction,i.drag&&n+"--draggable",i.isNavigation&&n+"--nav",n===et&&tn]}return an(l,{setup:p,mount:function(){c(J,g),c(J,p),c(K,m),f(document,_t+" keydown",function(n){u="keydown"===n.type},{capture:!0}),f(a,"focusin",function(){A(a,Lt,!!u)})},destroy:g})},Slides:function(r,o,u){var n=Q(r),t=n.on,e=n.emit,c=n.bind,f=(n=o.Elements).slides,a=n.list,s=[];function i(){f.forEach(function(n,t){d(n,t,-1)})}function l(){h(function(n){n.destroy()}),D(s)}function d(n,t,i){t=Rt(r,t,i,n);t.mount(),s.push(t),s.sort(function(n,t){return n.index-t.index})}function v(n){return n?p(function(n){return!n.isClone}):s}function h(n,t){v(t).forEach(n)}function p(t){return s.filter(x(t)?t:function(n){return C(t)?cn(n.slide,t):b(y(t),n.index)})}return{mount:function(){i(),t(J,l),t(J,i)},destroy:l,update:function(){h(function(n){n.update()})},register:d,get:v,getIn:function(n){var t=o.Controller,i=t.toIndex(n),r=t.hasFocus()?1:u.perPage;return p(function(n){return En(n.index,i,i+r-1)})},getAt:function(n){return p(n)[0]},add:function(n,o){g(n,function(n){var t,i,r;m(n=C(n)?hn(n):n)&&((t=f[o])?O(n,t):L(a,n),M(n,u.classes.slide),t=n,i=R(e,jn),t=gn(t,"img"),(r=t.length)?t.forEach(function(n){c(n,"load error",function(){--r||i()})}):i())}),e(J)},remove:function(n){T(p(n).map(function(n){return n.slide})),e(J)},forEach:h,filter:p,style:function(t,i,r){h(function(n){n.style(t,i,r)})},getLength:function(n){return(n?f:s).length},isEnough:function(){return s.length>u.perPage}}},Layout:function(t,n,i){var r,o,u,e=(a=Q(t)).on,c=a.bind,f=a.emit,a=n.Slides,s=n.Direction.resolve,l=(n=n.Elements).root,d=n.track,v=n.list,h=a.getAt,p=a.style;function g(){r=i.direction===Jn,_(l,"maxWidth",W(i.width)),_(d,s("paddingLeft"),y(!1)),_(d,s("paddingRight"),y(!0)),m(!0)}function m(n){var t=N(l);!n&&o.width===t.width&&o.height===t.height||(_(d,"height",function(){var n="";r&&(bn(n=b(),"height or heightRatio is missing."),n="calc("+n+" - "+y(!1)+" - "+y(!0)+")");return n}()),p(s("marginRight"),W(i.gap)),p("width",i.autoWidth?null:W(i.fixedWidth)||(r?"":w())),p("height",W(i.fixedHeight)||(r?i.autoHeight?null:w():b()),!0),o=t,f(Nn),u!==(u=O())&&(A(l,Ot,u),f("overflow",u)))}function y(n){var t=i.padding,n=s(n?"right":"left");return t&&W(t[n]||(un(t)?0:t))||"0px"}function b(){return W(i.height||N(v).width*i.heightRatio)}function w(){var n=W(i.gap);return"calc((100%"+(n&&" + "+n)+")/"+(i.perPage||1)+(n&&" - "+n)+")"}function x(){return N(v)[s("width")]}function k(n,t){n=h(n||0);return n?N(n.slide)[s("width")]+(t?0:L()):0}function S(n,t){var i,n=h(n);return n?(n=N(n.slide)[s("right")],i=N(v)[s("left")],U(n-i)+(t?0:L())):0}function E(n){return S(t.length-1)-S(0)+k(0,n)}function L(){var n=h(0);return n&&parseFloat(_(n.slide,s("marginRight")))||0}function O(){return t.is(It)||E(!0)>x()}return{mount:function(){var n,t,i;g(),c(window,"resize load",(n=R(f,jn),i=qn(t||0,n,null,1),function(){i.isPaused()&&i.start()})),e([K,J],g),e(jn,m)},resize:m,listSize:x,slideSize:k,sliderSize:E,totalSize:S,getPadding:function(n){return parseFloat(_(d,s("padding"+(n?"Right":"Left"))))||0},isOverflow:O}},Clones:function(c,i,f){var t,r=Q(c),n=r.on,a=i.Elements,s=i.Slides,o=i.Direction.resolve,l=[];function u(){if(n(J,d),n([K,jn],v),t=h()){var o=t,u=s.get().slice(),e=u.length;if(e){for(;u.length<o;)k(u,u);k(u.slice(-o),u.slice(0,o)).forEach(function(n,t){var i=t<o,r=function(n,t){n=n.cloneNode(!0);return M(n,f.classes.clone),n.id=c.root.id+"-clone"+An(t+1),n}(n.slide,t);i?O(r,u[0].slide):L(a.list,r),k(l,r),s.register(r,t-o+(i?0:e),n.index)})}i.Layout.resize(!0)}}function d(){e(),u()}function e(){T(l),D(l),r.destroy()}function v(){var n=h();t!==n&&(t<n||!n)&&r.emit(J)}function h(){var n,t=f.clones;return c.is(Pt)?en(t)&&(t=(n=f[o("fixedWidth")]&&i.Layout.slideSize(0))&&kn(N(a.track)[o("width")]/n)||f[o("autoWidth")]&&c.length||2*f.perPage):t=0,t}return{mount:u,destroy:e}},Move:function(r,c,o){var e,n=Q(r),t=n.on,f=n.emit,a=r.state.set,u=(n=c.Layout).slideSize,i=n.getPadding,s=n.totalSize,l=n.listSize,d=n.sliderSize,v=(n=c.Direction).resolve,h=n.orient,p=(n=c.Elements).list,g=n.track;function m(){c.Controller.isBusy()||(c.Scroll.cancel(),y(r.index),c.Slides.update())}function y(n){b(S(n,!0))}function b(n,t){r.is(It)||(t=t?n:function(n){{var t,i;r.is(Pt)&&(t=k(n),i=t>c.Controller.getEnd(),(t<0||i)&&(n=w(n,i)))}return n}(n),_(p,"transform","translate"+v("X")+"("+t+"px)"),n!==t&&f(Un))}function w(n,t){var i=n-L(t),r=d();return n-=h(r*(kn(U(i)/r)||1))*(t?1:-1)}function x(){b(E(),!0),e.cancel()}function k(n){for(var t=c.Slides.get(),i=0,r=1/0,o=0;o<t.length;o++){var u=t[o].index,e=U(S(u,!0)-n);if(!(e<=r))break;r=e,i=u}return i}function S(n,t){var i=h(s(n-1)-(n=n,"center"===(i=o.focus)?(l()-u(n,!0))/2:+i*u(n)||0));return t?(n=i,n=o.trimSpace&&r.is(Mt)?q(n,0,h(d(!0)-l())):n):i}function E(){var n=v("left");return N(p)[n]-N(g)[n]+h(i(!1))}function L(n){return S(n?c.Controller.getEnd():0,!!o.trimSpace)}return{mount:function(){e=c.Transition,t([B,Nn,K,J],m)},move:function(n,t,i,r){var o,u;n!==t&&(o=i<n,u=h(w(E(),o)),o?0<=u:u<=p[v("scrollWidth")]-N(g)[v("width")])&&(x(),b(w(E(),i<n),!0)),a(G),f(H,t,i,n),e.start(t,function(){a(3),f(Dn,t,i,n),r&&r()})},jump:y,translate:b,shift:w,cancel:x,toIndex:k,toPosition:S,getPosition:E,getLimit:L,exceededLimit:function(n,t){t=en(t)?E():t;var i=!0!==n&&h(t)<h(L(!1)),n=!1!==n&&h(t)>h(L(!0));return i||n},reposition:m}},Controller:function(o,u,e){var c,f,a,s,n=Q(o),t=n.on,i=n.emit,l=u.Move,d=l.getPosition,r=l.getLimit,v=l.toPosition,h=(n=u.Slides).isEnough,p=n.getLength,g=e.omitEnd,m=o.is(Pt),y=o.is(Mt),b=R(L,!1),w=R(L,!0),x=e.start||0,k=x;function S(){f=p(!0),a=e.perMove,s=e.perPage,c=_();var n=q(x,0,g?c:f-1);n!==x&&(x=n,l.reposition())}function E(){c!==_()&&i("ei")}function L(n,t){var i=a||(P()?1:s),i=O(x+i*(n?-1:1),x,!(a||P()));return-1===i&&y&&!Sn(d(),r(!n),1)?n?0:c:t?i:A(i)}function O(n,t,i){var r;return h()||P()?((r=function(n){if(y&&"move"===e.trimSpace&&n!==x)for(var t=d();t===v(n,!0)&&En(n,0,o.length-1,!e.rewind);)n<x?--n:++n;return n}(n))!==n&&(t=n,n=r,i=!1),n<0||c<n?n=a||!En(0,n,t,!0)&&!En(c,t,n,!0)?m?i?n<0?-(f%s||s):f:n:e.rewind?n<0?c:0:-1:z(D(n)):i&&n!==t&&(n=z(D(t)+(n<t?-1:1)))):n=-1,n}function A(n){return m?(n+f)%f||0:n}function _(){for(var n=f-(P()||m&&a?1:s);g&&0<n--;)if(v(f-1,!0)!==v(n,!0)){n++;break}return q(n,0,f-1)}function z(n){return q(P()?n:s*n,0,c)}function D(n){return P()?Y(n,c):xn((c<=n?f-1:n)/s)}function M(n){n!==x&&(k=x,x=n)}function P(){return!en(e.focus)||e.isNavigation}function I(){return o.state.is([G,rn])&&!!e.waitForTransition}return{mount:function(){S(),t([K,J,"ei"],S),t(Nn,E)},go:function(n,t,i){var r;I()||-1<(r=A(n=function(n){var t=x;{var i,r;C(n)?(r=n.match(/([+\-<>])(\d+)?/)||[],i=r[1],r=r[2],"+"===i||"-"===i?t=O(x+ +(""+i+(+r||1)),x):">"===i?t=r?z(+r):b(!0):"<"===i&&(t=w(!0))):t=m?n:q(n,0,c)}return t}(n)))&&(t||r!==x)&&(M(r),l.move(n,r,k,i))},scroll:function(n,t,i,r){u.Scroll.scroll(n,t,i,function(){var n=A(l.toIndex(d()));M(g?Y(n,c):n),r&&r()})},getNext:b,getPrev:w,getAdjacent:L,getEnd:_,setIndex:M,getIndex:function(n){return n?k:x},toIndex:z,toPage:D,toDest:function(n){return n=l.toIndex(n),y?q(n,0,c):n},hasFocus:P,isBusy:I}},Arrows:function(o,n,t){var i,r,u=Q(o),e=u.on,c=u.bind,f=u.emit,a=t.classes,s=t.i18n,l=n.Elements,d=n.Controller,v=l.arrows,h=l.track,p=v,g=l.prev,m=l.next,y={};function b(){var n=t.arrows;!n||g&&m||(p=v||j("div",a.arrows),g=S(!0),m=S(!1),i=!0,L(p,[g,m]),v||O(p,h)),g&&m&&(an(y,{prev:g,next:m}),ln(p,n?"":"none"),M(p,r=dt+"--"+t.direction),n&&(e([B,Dn,J,V,"ei"],E),c(m,"click",R(k,">")),c(g,"click",R(k,"<")),E(),I([g,m],Kn,h.id),f("arrows:mounted",g,m))),e(K,w)}function w(){x(),b()}function x(){u.destroy(),X(p,r),i?(T(v?[g,m]:p),g=m=null):P([g,m],ut)}function k(n){d.go(n,!0)}function S(n){return hn('<button class="'+a.arrow+" "+(n?a.prev:a.next)+'" type="button"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" width="40" height="40" focusable="false"><path d="'+(t.arrowPath||"m15.5 0.932-4.3 4.38 14.5 14.6-14.5 14.5 4.3 4.4 14.6-14.6 4.4-4.3-4.4-4.4-14.6-14.6z")+'" />')}function E(){var n,t,i,r;g&&m&&(r=o.index,n=d.getPrev(),t=d.getNext(),i=-1<n&&r<n?s.last:s.prev,r=-1<t&&t<r?s.first:s.next,g.disabled=n<0,m.disabled=t<0,I(g,nn,i),I(m,nn,r),f("arrows:updated",g,m,n,t))}return{arrows:y,mount:b,destroy:x,update:E}},Autoplay:function(n,t,i){var r,o,u=Q(n),e=u.on,c=u.bind,f=u.emit,a=qn(i.interval,n.go.bind(n,">"),function(n){var t=l.bar;t&&_(t,"width",100*n+"%"),f("autoplay:playing",n)}),s=a.isPaused,l=t.Elements,d=(u=t.Elements).root,v=u.toggle,h=i.autoplay,p="pause"===h;function g(){s()&&t.Slides.isEnough()&&(a.start(!i.resetProgress),o=r=p=!1,b(),f(Fn))}function m(n){p=!!(n=void 0===n?!0:n),b(),s()||(a.pause(),f(Xn))}function y(){p||(r||o?m(!1):g())}function b(){v&&(A(v,tn,!p),I(v,nn,i.i18n[p?"play":"pause"]))}function w(n){n=t.Slides.getAt(n);a.set(n&&+z(n.slide,Ct)||i.interval)}return{mount:function(){h&&(i.pauseOnHover&&c(d,"mouseenter mouseleave",function(n){r="mouseenter"===n.type,y()}),i.pauseOnFocus&&c(d,"focusin focusout",function(n){o="focusin"===n.type,y()}),v&&c(v,"click",function(){p?g():m(!0)}),e([H,Tn,J],a.rewind),e(H,w),v&&I(v,Kn,l.track.id),p||g(),b())},destroy:a.cancel,play:g,pause:m,isPaused:s}},Cover:function(n,t,i){var r=Q(n).on;function o(i){t.Slides.forEach(function(n){var t=fn(n.container||n.slide,"img");t&&t.src&&u(i,t,n)})}function u(n,t,i){i.style("background",n?'center/cover no-repeat url("'+t.src+'")':"",!0),ln(t,n?"none":"")}return{mount:function(){i.cover&&(r(Wn,R(u,!0)),r([B,K,J],R(o,!0)))},destroy:R(o,!1)}},Scroll:function(n,c,u){var f,a,t=Q(n),i=t.on,s=t.emit,l=n.state.set,d=c.Move,v=d.getPosition,e=d.getLimit,h=d.exceededLimit,p=d.translate,g=n.is(Mt),m=1;function y(n,t,i,r,o){var u,e=v(),i=(x(),!i||g&&h()||(i=c.Layout.sliderSize(),u=Ln(n)*i*xn(U(n)/i)||0,n=d.toPosition(c.Controller.toDest(n%i))+u),Sn(e,n,1));m=1,t=i?0:t||wn(U(n-e)/1.5,800),a=r,f=qn(t,b,R(w,e,n,o),1),l(rn),s(Tn),f.start()}function b(){l(3),a&&a(),s(V)}function w(n,t,i,r){var o=v(),r=(n+(t-n)*(t=r,(n=u.easingFunc)?n(t):1-Math.pow(1-t,4))-o)*m;p(o+r),g&&!i&&h()&&(m*=.6,U(r)<10&&y(e(h(!0)),600,!1,a,!0))}function x(){f&&f.cancel()}function r(){f&&!f.isPaused()&&(x(),b())}return{mount:function(){i(H,x),i([K,J],r)},destroy:x,scroll:y,cancel:r}},Drag:function(e,o,c){var f,t,u,a,s,l,d,v,n=Q(e),i=n.on,h=n.emit,p=n.bind,g=n.unbind,m=e.state,y=o.Move,b=o.Scroll,w=o.Controller,x=o.Elements.track,k=o.Media.reduce,r=(n=o.Direction).resolve,S=n.orient,E=y.getPosition,L=y.exceededLimit,O=!1;function j(){var n=c.drag;C(!n),a="free"===n}function N(n){var t,i,r;l=!1,d||(t=R(n),i=n.target,r=c.noDrag,cn(i,"."+mt+", ."+vt)||r&&cn(i,r)||!t&&n.button||(w.isBusy()?F(n,!0):(v=t?x:window,s=m.is([G,rn]),u=null,p(v,zt,A,jt),p(v,Dt,_,jt),y.cancel(),b.cancel(),z(n))))}function A(n){var t,i,r,o,u;m.is(6)||(m.set(6),h("drag")),n.cancelable&&(s?(y.translate(f+D(n)/(O&&e.is(Mt)?5:1)),u=200<M(n),t=O!==(O=L()),(u||t)&&z(n),l=!0,h("dragging"),F(n)):U(D(u=n))>U(D(u,!0))&&(t=n,i=c.dragMinThreshold,r=un(i),o=r&&i.mouse||0,r=(r?i.touch:+i)||10,s=U(D(t))>(R(t)?r:o),F(n)))}function _(n){var t,i,r;m.is(6)&&(m.set(3),h("dragged")),s&&(i=function(n){return E()+Ln(n)*Y(U(n)*(c.flickPower||600),a?1/0:o.Layout.listSize()*(c.flickMaxPages||1))}(t=function(n){if(e.is(Pt)||!O){var t=M(n);if(t&&t<200)return D(n)/t}return 0}(t=n)),r=c.rewind&&c.rewindByDrag,k(!1),a?w.scroll(i,0,c.snap):e.is(It)?w.go(S(Ln(t))<0?r?"<":"-":r?">":"+"):e.is(Mt)&&O&&r?w.go(L(!0)?">":"<"):w.go(w.toDest(i),!0),k(!0),F(n)),g(v,zt,A),g(v,Dt,_),s=!1}function T(n){!d&&l&&F(n,!0)}function z(n){u=t,t=n,f=E()}function D(n,t){return I(n,t)-I(P(n),t)}function M(n){return mn(n)-mn(P(n))}function P(n){return t===n&&u||t}function I(n,t){return(R(n)?n.changedTouches[0]:n)["page"+r(t?"Y":"X")]}function R(n){return"undefined"!=typeof TouchEvent&&n instanceof TouchEvent}function C(n){d=n}return{mount:function(){p(x,zt,on,jt),p(x,Dt,on,jt),p(x,_t,N,jt),p(x,"click",T,{capture:!0}),p(x,"dragstart",F),i([B,K],j)},disable:C,isDragging:function(){return s}}},Keyboard:function(t,n,i){var r,o,u=Q(t),e=u.on,c=u.bind,f=u.unbind,a=t.root,s=n.Direction.resolve;function l(){var n=i.keyboard;n&&(r="global"===n?window:a,c(r,Gt,h))}function d(){f(r,Gt)}function v(){var n=o;o=!0,p(function(){o=n})}function h(n){o||((n=Tt(n))===s(Bn)?t.go("<"):n===s(Hn)&&t.go(">"))}return{mount:function(){l(),e(K,d),e(K,l),e(H,v)},destroy:d,disable:function(n){o=n}}},LazyLoad:function(i,n,o){var t=Q(i),r=t.on,u=t.off,e=t.bind,c=t.emit,f="sequential"===o.lazyLoad,a=[Dn,V],s=[];function l(){D(s),n.Slides.forEach(function(r){gn(r.slide,Wt).forEach(function(n){var t=z(n,Ft),i=z(n,Xt);t===n.src&&i===n.srcset||(t=o.classes.spinner,t=fn(i=n.parentElement,"."+t)||j("span",t,i),s.push([n,r,t]),n.src||ln(n,"none"))})}),(f?p:(u(a),r(a,d),d))()}function d(){(s=s.filter(function(n){var t=o.perPage*((o.preloadPages||1)+1)-1;return!n[1].isWithin(i.index,t)||v(n)})).length||u(a)}function v(n){var t=n[0];M(n[1].slide,Et),e(t,"load error",R(h,n)),I(t,"src",z(t,Ft)),I(t,"srcset",z(t,Xt)),P(t,Ft),P(t,Xt)}function h(n,t){var i=n[0],r=n[1];X(r.slide,Et),"error"!==t.type&&(T(n[2]),ln(i,""),c(Wn,i,r),c(jn)),f&&p()}function p(){s.length&&v(s.shift())}return{mount:function(){o.lazyLoad&&(l(),r(J,l))},destroy:R(D,s),check:d}},Pagination:function(l,n,d){var v,h,t=Q(l),p=t.on,g=t.emit,m=t.bind,y=n.Slides,b=n.Elements,w=n.Controller,x=w.hasFocus,r=w.getIndex,e=w.go,c=n.Direction.resolve,k=b.pagination,S=[];function E(){v&&(T(k?o(v.children):v),X(v,h),D(S),v=null),t.destroy()}function L(n){e(">"+n,!0)}function O(n,t){var i=S.length,r=Tt(t),o=A(),u=-1,o=(r===c(Hn,!1,o)?u=++n%i:r===c(Bn,!1,o)?u=(--n+i)%i:"Home"===r?u=0:"End"===r&&(u=i-1),S[u]);o&&(dn(o.button),e(">"+u),F(t,!0))}function A(){return d.paginationDirection||d.direction}function _(n){return S[w.toPage(n)]}function z(){var n,t=_(r(!0)),i=_(r());t&&(X(n=t.button,tn),P(n,Qn),I(n,$,-1)),i&&(M(n=i.button,tn),I(n,Qn,!0),I(n,$,"")),g("pagination:updated",{list:v,items:S},t,i)}return{items:S,mount:function n(){E(),p([K,J,"ei"],n);var t=d.pagination;if(k&&ln(k,t?"":"none"),t){p([H,Tn,V],z);var t=l.length,i=d.classes,r=d.i18n,o=d.perPage,u=x()?w.getEnd()+1:kn(t/o);M(v=k||j("ul",i.pagination,b.track.parentElement),h=gt+"--"+A()),I(v,Z,"tablist"),I(v,nn,r.select),I(v,nt,A()===Jn?"vertical":"");for(var e=0;e<u;e++){var c=j("li",null,v),f=j("button",{class:i.page,type:"button"},c),a=y.getIn(e).map(function(n){return n.slide.id}),s=!x()&&1<o?r.pageX:r.slideX;m(f,"click",R(L,e)),d.paginationKeyboard&&m(f,"keydown",R(O,e)),I(c,Z,"presentation"),I(f,Z,"tab"),I(f,Kn,a.join(" ")),I(f,nn,On(s,e+1)),I(f,$,-1),S.push({li:c,button:f,page:e})}z(),g("pagination:mounted",{list:v,items:S},_(l.index))}},destroy:E,getAt:_,update:z}},Sync:function(i,n,t){var r=t.isNavigation,o=t.slideFocus,u=[];function e(){var n,t;i.splides.forEach(function(n){n.isParent||(f(i,n.splide),f(n.splide,i))}),r&&(n=Q(i),(t=n.on)(Mn,s),t(Yn,l),t([B,K],a),u.push(n),n.emit(Gn,i.splides))}function c(){u.forEach(function(n){n.destroy()}),D(u)}function f(n,r){n=Q(n);n.on(H,function(n,t,i){r.go(r.is(Pt)?i:n)}),u.push(n)}function a(){I(n.Elements.list,nt,t.direction===Jn?"vertical":"")}function s(n){i.go(n.index)}function l(n,t){b(Yt,Tt(t))&&(s(n),F(t))}return{setup:R(n.Media.set,{slideFocus:en(o)?r:o},!0),mount:e,destroy:c,remount:function(){c(),e()}}},Wheel:function(e,c,f){var n=Q(e).bind,a=0;function t(n){var t,i,r,o,u;n.cancelable&&(t=(u=n.deltaY)<0,i=mn(n),r=f.wheelMinThreshold||0,o=f.wheelSleep||0,U(u)>r&&o<i-a&&(e.go(t?"<":">"),a=i),u=t,f.releaseWheel&&!e.state.is(G)&&-1===c.Controller.getAdjacent(u)||F(n))}return{mount:function(){f.wheel&&n(c.Elements.track,"wheel",t,jt)}}},Live:function(n,t,i){var r=Q(n).on,o=t.Elements.track,u=i.live&&!i.isNavigation,e=j("span",wt),c=qn(90,R(f,!1));function f(n){I(o,rt,n),n?(L(o,e),c.start()):(T(e),c.cancel())}function a(n){u&&I(o,it,n?"off":"polite")}return{mount:function(){u&&(a(!t.Autoplay.isPaused()),I(o,ot,!0),e.textContent="â¦",r(Fn,R(a,!0)),r(Xn,R(a,!1)),r([Dn,V],R(f,!0)))},disable:a,destroy:function(){P(o,[it,ot,rt]),T(e)}}}}),qt={type:"slide",role:"region",speed:400,perPage:1,cloneStatus:!0,arrows:!0,pagination:!0,paginationKeyboard:!0,interval:5e3,pauseOnHover:!0,pauseOnFocus:!0,resetProgress:!0,easing:"cubic-bezier(0.25, 1, 0.5, 1)",drag:!0,direction:"ltr",trimSpace:!0,focusableNodes:"a, button, textarea, input, select, iframe",live:!0,classes:{slide:at,clone:st,arrows:dt,arrow:vt,prev:ht,next:pt,pagination:gt,page:mt,spinner:i+"spinner"},i18n:{prev:"Previous slide",next:"Next slide",first:"Go to first slide",last:"Go to last slide",slideX:"Go to slide %s",pageX:"Go to page %s",play:"Start autoplay",pause:"Pause autoplay",carousel:"carousel",slide:"slide",select:"Select a slide to show",slideLabel:"%s of %s"},reducedMotion:{speed:0,rewindSpeed:0,autoplay:"pause"}};function Bt(n,t,i){var r=t.Slides;function o(){r.forEach(function(n){n.style("transform","translateX(-"+100*n.index+"%)")})}return{mount:function(){Q(n).on([B,J],o)},start:function(n,t){r.style("transition","opacity "+i.speed+"ms "+i.easing),p(t)},cancel:on}}function Ht(u,n,e){var c,f=n.Move,a=n.Controller,s=n.Scroll,t=n.Elements.list,l=R(_,t,"transition");function i(){l(""),s.cancel()}return{mount:function(){Q(u).bind(t,"transitionend",function(n){n.target===t&&c&&(i(),c())})},start:function(n,t){var i=f.toPosition(n,!0),r=f.getPosition(),o=function(n){var t=e.rewindSpeed;if(u.is(Mt)&&t){var i=a.getIndex(!0),r=a.getEnd();if(0===i&&r<=n||r<=i&&0===n)return t}return e.speed}(n);1<=U(i-r)&&1<=o?e.useScroll?s.scroll(i,o,!1,t):(l("transform "+o+"ms "+e.easing),f.translate(i,!0),c=t):(f.jump(n),t())},cancel:i}}t=function(){function i(n,t){this.event=Q(),this.Components={},this.state=s(1),this.splides=[],this.n={},this.t={};n=C(n)?pn(document,n):n;bn(n,n+" is invalid."),t=d({label:z(this.root=n,nn)||"",labelledby:z(n,Zn)||""},qt,i.defaults,t||{});try{d(t,JSON.parse(z(n,f)))}catch(n){bn(!1,"Invalid JSON")}this.n=Object.create(d({},t))}var n=i.prototype;return n.mount=function(n,t){var i=this,r=this.state,o=this.Components;return bn(r.is([1,7]),"Already mounted!"),r.set(1),this.i=o,this.r=t||this.r||(this.is(It)?Bt:Ht),this.t=n||this.t,w(an({},Ut,this.t,{Transition:this.r}),function(n,t){n=n(i,o,i.n);(o[t]=n).setup&&n.setup()}),w(o,function(n){n.mount&&n.mount()}),this.emit(B),M(this.root,"is-initialized"),r.set(3),this.emit("ready"),this},n.sync=function(n){return this.splides.push({splide:n}),n.splides.push({splide:this,isParent:!0}),this.state.is(3)&&(this.i.Sync.remount(),n.Components.Sync.remount()),this},n.go=function(n){return this.i.Controller.go(n),this},n.on=function(n,t){return this.event.on(n,t),this},n.off=function(n){return this.event.off(n),this},n.emit=function(n){var t;return(t=this.event).emit.apply(t,[n].concat(o(arguments,1))),this},n.add=function(n,t){return this.i.Slides.add(n,t),this},n.remove=function(n){return this.i.Slides.remove(n),this},n.is=function(n){return this.n.type===n},n.refresh=function(){return this.emit(J),this},n.destroy=function(t){void 0===t&&(t=!0);var n=this.event,i=this.state;return i.is(1)?Q(this).on("ready",this.destroy.bind(this,t)):(w(this.i,function(n){n.destroy&&n.destroy(t)},!0),n.emit(a),n.destroy(),t&&D(this.splides),i.set(7)),this},Jt(i,[{key:"options",get:function(){return this.n},set:function(n){this.i.Media.set(n,!0,!0)}},{key:"length",get:function(){return this.i.Slides.getLength(!0)}},{key:"index",get:function(){return this.i.Controller.getIndex()}}]),i}();return t.defaults={},t.STATES=r,t},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(n="undefined"!=typeof globalThis?globalThis:n||self).Splide=t();
12775</script>
vendor: 1 bytes, line 12775
12775
12776<script> 12777 function initCustomSelect() { 12778 const selects = document.querySelectorAll("select"); 12779 12780 selects.forEach((selElmnt) => { 12781 // Check if already initialized or if wrapper already exists 12782 if (selElmnt.dataset.customSelectInit) return; 12783 if (!selElmnt.options.length || getComputedStyle(selElmnt).display === 'none') return; 12784 12785 // Check if wrapper already exists to prevent double-wrapping 12786 if (selElmnt.parentNode && selElmnt.parentNode.classList.contains('custom-select-wrapper')) return; 12787 12788 selElmnt.dataset.customSelectInit = true; 12789 12790 const wrapper = document.createElement("DIV"); 12791 wrapper.setAttribute("class", "custom-select-wrapper"); 12792 selElmnt.classList.forEach(cls => { 12793 wrapper.classList.add(cls); 12794 }); 12795 selElmnt.parentNode.insertBefore(wrapper, selElmnt); 12796 12797 const selected = document.createElement("DIV"); 12798 selected.setAttribute("class", "select-selected"); 12799 wrapper.appendChild(selected); 12800 12801 const itemsBox = document.createElement("DIV"); 12802 itemsBox.setAttribute("class", "select-items select-hide"); 12803 wrapper.appendChild(itemsBox); 12804 wrapper.appendChild(selElmnt); 12805 12806 function updateDropdown() { 12807 selected.innerHTML = selElmnt.options[selElmnt.selectedIndex].innerHTML; 12808 itemsBox.innerHTML = ''; 12809 12810 for (let j = 0; j < selElmnt.length; j++) { 12811 const item = document.createElement("DIV"); 12812 item.innerHTML = selElmnt.options[j].innerHTML; 12813 12814 if (j === selElmnt.selectedIndex) { 12815 item.setAttribute("class", "same-as-selected"); 12816 } 12817 12818 item.addEventListener("click", function(e) { 12819 e.stopPropagation(); 12820 selElmnt.selectedIndex = j; 12821 selElmnt.dispatchEvent(new Event('change', { bubbles: true })); 12822 updateDropdown(); 12823 selected.classList.remove("select-arrow-active"); 12824 itemsBox.classList.add("select-hide"); 12825 }); 12826 12827 itemsBox.appendChild(item); 12828 } 12829 } 12830 12831 updateDropdown(); 12832 12833 selected.addEventListener("click", function(e) { 12834 e.stopPropagation(); 12835 closeAllSelects(selected); 12836 itemsBox.classList.toggle("select-hide"); 12837 selected.classList.toggle("select-arrow-active"); 12838 }); 12839 12840 // Sync change 12841 selElmnt.addEventListener('change', () => { 12842 updateDropdown(); 12843 selected.classList.remove('error'); 12844 const errorMsg = wrapper.querySelector('.mage-error'); 12845 if (errorMsg) errorMsg.remove(); 12846 }); 12847 12848 // Native invalid event (triggers Magento's validation message) 12849 selElmnt.addEventListener('invalid', () => { 12850 selected.classList.add('error'); 12851 12852 // Only show message if it doesnât exist already 12853 if (!wrapper.querySelector('.mage-error')) { 12854 const msg = document.createElement('div'); 12855 msg.classList.add('mage-error'); 12856 msg.textContent = 'This is a required field.'; // same as Magento core 12857 wrapper.appendChild(msg); 12858 } 12859 }); 12860 12861 const observer = new MutationObserver(updateDropdown); 12862 observer.observe(selElmnt, { childList: true }); 12863 }); 12864 12865 function closeAllSelects(except) { 12866 document.querySelectorAll(".select-selected").forEach(sel => { 12867 if (sel !== except) { 12868 sel.classList.remove("select-arrow-active"); 12869 sel.nextSibling.classList.add("select-hide"); 12870 } 12871 }); 12872 } 12873 12874 // Global click handler that only closes dropdowns when clicking outside 12875 if (!document._customSelectClickHandlerAdded) { 12876 document.addEventListener("click", function(e) { 12877 // Only close dropdowns if clicking outside of any custom-select-wrapper 12878 if (!e.target.closest('.custom-select-wrapper')) { 12879 closeAllSelects(); 12880 } 12881 }); 12882 document._customSelectClickHandlerAdded = true; 12883 } 12884 } 12885 12886 // Debounce function to prevent multiple rapid calls 12887 let initTimeout; 12888 function debounceInit() { 12889 clearTimeout(initTimeout); 12890 initTimeout = setTimeout(initCustomSelect, 100); 12891 } 12892 12893 // Initial load on DOMContentLoaded 12894 if (document.readyState === 'loading') { 12895 document.addEventListener('DOMContentLoaded', initCustomSelect); 12896 } else { 12897 initCustomSelect(); 12898 } 12899 12900 // Watch for dynamic content changes 12901 if (typeof MutationObserver !== 'undefined') { 12902 const bodyObserver = new MutationObserver(debounceInit); 12903 if (document.readyState === 'loading') { 12904 document.addEventListener('DOMContentLoaded', () => { 12905 bodyObserver.observe(document.body, { 12906 childList: true, 12907 subtree: true 12908 }); 12909 }); 12910 } else { 12911 bodyObserver.observe(document.body, { 12912 childList: true, 12913 subtree: true 12914 }); 12915 } 12916 } 12917 12918 // Hyvä Checkout specific events 12919 window.addEventListener('checkout:step:loaded', debounceInit); 12920 window.addEventListener('alpine:initialized', debounceInit); 12921 12922 // Listen for private content loaded (customer data) 12923 window.addEventListener('private-content-loaded', debounceInit); 12924 12925 // Re-initialize after AJAX updates 12926 document.addEventListener('ajaxComplete', debounceInit); 12927</script>
vendor: 1 bytes, line 12927
12927
12928<script> 12929 function createAjaxLoader() { 12930 const loader = document.createElement('div'); 12931 loader.className = 'absolute inset-0 flex justify-center items-center loader'; 12932 loader.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" class="w-full h-full p-2" role="img"> 12933 <circle style="opacity: .3;" cx="12" cy="12" r="10"/> 12934 <path fill="none" stroke-width="2" d="M12,2 a10,10 0 0,1 10,10"/> 12935<title>Loading...</title></svg> 12936`; 12937 return loader; 12938 } 12939 12940 function addAjaxLoader(button, loader) { 12941 button.setAttribute('data-label', button.getAttribute('aria-label')); 12942 button.removeAttribute('aria-label'); 12943 button.prepend(loader); 12944 button.classList.add('relative', '[&>:not(.loader)]:invisible'); 12945 button.disabled = true; 12946 } 12947 12948 function removeAjaxLoader(button, loader) { 12949 button.setAttribute('aria-label', button.getAttribute('data-label')); 12950 button.removeAttribute('data-label'); 12951 loader.remove(); 12952 button.classList.remove('[&>:not(.loader)]:invisible'); 12953 button.disabled = false; 12954 } 12955 12956 async function addAjaxCartForm(form, extraDelay = 500) { 12957 if (!form) return; 12958 event.preventDefault(); 12959 12960 if (form.hasAttribute('enctype') || !form.reportValidity()) { 12961 return form.submit(); 12962 } 12963 12964 const formData = new FormData(form); 12965 const button = form.querySelector('button:not([type=button], [type=reset])') 12966 ? form.querySelector('button:not([type=button], [type=reset])') 12967 : document.getElementById('product-addtocart-button'); 12968 const loader = createAjaxLoader(button); 12969 const formUenc = hyva.getUenc(); 12970 const postUrl = event.target.action.replace('%25uenc%25', formUenc); 12971 12972 let bodyUrl = new URLSearchParams(formData); 12973 bodyUrl.append("uenc", formUenc); 12974 addAjaxLoader(button, loader); 12975 12976 try { 12977 const response = await fetch(postUrl, { 12978 method: 'POST', 12979 body: bodyUrl.toString(), 12980 mode: "cors", 12981 credentials: "include", 12982 headers: { 12983 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', 12984 'X-Requested-With': 'XMLHttpRequest' 12985 } 12986 }); 12987 12988 if (!response.ok) { 12989 return form.submit(); 12990 } 12991 12992 if (response.redirected) { 12993 return window.location.href = response.url; 12994 } 12995 12996 const responseData = await response.json(); 12997 if (responseData.backUrl) { 12998 return window.location.href = responseData.backUrl; 12999 } 13000 13001 window.dispatchEvent(new CustomEvent("reload-customer-section-data")); 13002 13003 } catch (err) { 13004 console.warn(err); 13005 window.dispatchEvent(new CustomEvent('product-addtocart-error')); 13006 13007 if (typeof window.dispatchMessages === "undefined") return; 13008 window.dispatchMessages([{ 13009 text:'There\u0020was\u0020a\u0020problem\u0020adding\u0020your\u0020item\u0020to\u0020the\u0020cart.', 13010 type: 'error' 13011 }], 5000); 13012 } finally { 13013 setTimeout(() => removeAjaxLoader(button, loader), extraDelay); 13014 } 13015 } 13016 13017 function removeAjaxCartForm(form) { 13018 removeEventListener('submit', form); 13019 } 13020 13021 document.addEventListener('submit', function(event) { 13022 if (!event.target.matches('#product_addtocart_form, .product_addtocart_form')) return; 13023 addAjaxCartForm(event.target, 500); 13024 }); 13025</script>
vendor: 1 bytes, line 13025
13025
13026<script> 13027 13028(_ => { 13029 document.addEventListener('DOMContentLoaded', event => { 13030 13031 if (!Alpine.version.startsWith('2')) { 13032 return; 13033 } 13034 13035 const teleportDirective = (el, expression) => { 13036 let target = document.querySelector(expression) 13037 let clone = el.content.cloneNode(true).firstElementChild; 13038 13039 target.appendChild(clone); 13040 setTimeout(() => { 13041 target.querySelectorAll('[x-data]') 13042 .forEach(el => Alpine.initializeComponent(el)); 13043 }, 0) 13044 }; 13045 13046 document.querySelectorAll('template').forEach(el => { 13047 if (!el.hasAttribute('x-teleport')) { 13048 return; 13049 } 13050 13051 teleportDirective(el, el.getAttribute('x-teleport')); 13052 }); 13053 13054 document.querySelectorAll('[x-data]').forEach(el => { 13055 if (el.hasAttribute('x-init')) { 13056 return; 13057 } 13058 13059 setTimeout(() => { 13060 Alpine.initializeComponent(el); 13061 }, 0); 13062 }); 13063 }); 13064})()</script>
vendor: 1 bytes, line 13064
13064
13065<script type="module" 13066 src="https://www.banham.co.uk/static/version1789025993/frontend/BraveBison/default/en_GB/Hyva_Theme/js/alpine3.min.js" 13067 defer 13068 crossorigin 13069></script>
vendor: 1 bytes, line 13069
13069
13070<script> 13071 function dispatchMessages(messages, hideAfter) { 13072 const messagesEvent = new CustomEvent("messages-loaded", { 13073 detail: { 13074 messages: messages, 13075 hideAfter: hideAfter 13076 } 13077 }); 13078 window.dispatchEvent(messagesEvent); 13079 } 13080 13081 if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) { 13082 console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script"); 13083 } 13084 13085 (function( hyva, undefined ) { 13086 13087 hyva.initFormKey = () => { 13088 const inputSelector = 'input[name="form_key"]', 13089 formKey = hyva.getFormKey(); 13090 13091 Array.from(document.querySelectorAll(inputSelector)).map(function (input) { 13092 input.value = formKey 13093 }); 13094 } 13095 13096 hyva.initMessages = () => { 13097 try { 13098 const messages = hyva.getCookie('mage-messages'); 13099 window.mageMessages = messages ? JSON.parse(decodeURIComponent(messages).replace(/\+/g, ' ')) : []; 13100 13101 dispatchMessages(window.mageMessages); 13102 13103 const skipSetDomain = true; 13104 hyva.setCookie('mage-messages','', -1, skipSetDomain); 13105 13106 } catch (error) { 13107 console.warn('Error parsing Cookie Messages:', error); 13108 } 13109 } 13110 13111 window.addEventListener('DOMContentLoaded', hyva.initFormKey); 13112 hyva.alpineInitialized(hyva.initMessages) 13113 13114 }( window.hyva = window.hyva || {} ));</script>
vendor: 1 bytes, line 13114
13114
13115<script> 13116 { 13117 const private_content_key = 'mage-cache-storage'; 13118 const private_content_expire_key = 'mage-cache-timeout'; 13119 const private_content_version_key = 'private_content_version'; 13120 const section_data_ids_key = 'section_data_ids'; 13121 const mage_cache_session_id_key = 'mage-cache-sessid'; 13122 const last_visited_store_key = 'last_visited_store'; 13123 13124 const ttl = 24800; 13125 13126 if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) { 13127 console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script"); 13128 } 13129 13130 function loadSectionData () { 13131 const browserStorage = hyva.getBrowserStorage(); 13132 if (!browserStorage) { 13133 typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( 13134 [{ 13135 type: "warning", 13136 text: "Please enable LocalStorage in your browser." 13137 }] 13138 ); 13139 return; 13140 } 13141 try { 13142 let isInvalid = false; 13143 13144 if (hyva.getCookie(last_visited_store_key) !== CURRENT_STORE_CODE) { 13145 isInvalid = true; 13146 } 13147 hyva.setCookie(last_visited_store_key, CURRENT_STORE_CODE, false, false); 13148 13149 if (!hyva.getCookie(mage_cache_session_id_key)) { 13150 isInvalid = true; 13151 browserStorage.removeItem(private_content_key); 13152 const skipSetDomain = true; 13153 const days = false; 13154 hyva.setCookie(mage_cache_session_id_key, true, days, skipSetDomain) 13155 } 13156 13157 const cookieVersion = hyva.getCookie(private_content_version_key); 13158 const storageVersion = browserStorage.getItem(private_content_version_key); 13159 13160 if (cookieVersion && !storageVersion || cookieVersion !== storageVersion) { 13161 isInvalid = true; 13162 } 13163 13164 const privateContentExpires = browserStorage.getItem(private_content_expire_key); 13165 if (privateContentExpires && new Date(privateContentExpires) < new Date()) { 13166 browserStorage.removeItem(private_content_key); 13167 } 13168 13169 if (isInvalid && cookieVersion) { 13170 fetchPrivateContent([]); 13171 } else if (cookieVersion && storageVersion && cookieVersion === storageVersion) { 13172 const privateContent = JSON.parse(browserStorage.getItem(private_content_key)); 13173 if ( 13174 privateContent && 13175 privateContentExpires && 13176 privateContent.cart && 13177 privateContent.customer 13178 ) { 13179 dispatchPrivateContent(privateContent); 13180 } else { 13181 fetchPrivateContent([]); 13182 } 13183 } else { 13184 if (document.getElementById('default-section-data')) { 13185 const privateContent = JSON.parse(document.getElementById('default-section-data').innerText.trim()); 13186 dispatchPrivateContent(privateContent); 13187 } else { 13188 dispatchPrivateContent({}); 13189 } 13190 } 13191 13192 } catch (error) { 13193 console.warn('Error retrieving Private Content:', error); 13194 } 13195 } 13196 13197 hyva.alpineInitialized(loadSectionData) 13198 window.addEventListener('reload-customer-section-data', loadSectionData); 13199 13200 window.processSectionDataBeforeDispatch = window.processSectionDataBeforeDispatch || (data => data); 13201 13202 function dispatchPrivateContent(data) { 13203 13204 const privateContentEvent = new CustomEvent("private-content-loaded", { 13205 detail: { 13206 data: window.processSectionDataBeforeDispatch(data) 13207 } 13208 }); 13209 window.dispatchEvent(privateContentEvent); 13210 } 13211 13212 function fetchPrivateContent(sections) { 13213 fetch(`${BASE_URL}customer/section/load/?sections=${encodeURIComponent(sections.join(','))}`, { 13214 method: 'GET', 13215 headers: { 13216 'Content-Type': 'application/json', 13217 'X-Requested-With': 'XMLHttpRequest' 13218 } 13219 }) 13220 .then(response => response.ok && response.json()) 13221 .then( 13222 data => { 13223 if (data) { 13224 try { 13225 const browserStorage = hyva.getBrowserStorage(); 13226 13227 13228 const oldSectionData = JSON.parse(browserStorage.getItem(private_content_key) || '{}') || {}; 13229 13230 if ((! data.cart || ! data.cart.cartId) && oldSectionData['checkout-data']) { 13231 delete oldSectionData['checkout-data']; 13232 } 13233 const newSectionData = Object.assign(oldSectionData, data); 13234 13235 dispatchPrivateContent(newSectionData); 13236 13237 13238 if (newSectionData.messages && newSectionData.messages.messages ) { 13239 newSectionData.messages.messages = []; 13240 } 13241 13242 browserStorage.setItem(private_content_key, JSON.stringify(newSectionData)); 13243 13244 const expiresAt = new Date(Date.now() + (ttl * 1000)).toISOString(); 13245 browserStorage.setItem(private_content_expire_key, expiresAt); 13246 13247 const newCookieVersion = hyva.getCookie(private_content_version_key); 13248 browserStorage.setItem(private_content_version_key, newCookieVersion); 13249 13250 13251 13252 hyva.setCookie( 13253 section_data_ids_key, 13254 JSON.stringify( 13255 Object.keys(data).reduce((sectionDataIds, sectionKey) => { 13256 sectionDataIds[sectionKey] = data[sectionKey]['data_id']; 13257 return sectionDataIds; 13258 }, {}) 13259 ), 13260 false, 13261 true 13262 ); 13263 } catch (error) { 13264 console.warn("Couldn't store privateContent", error); 13265 } 13266 } 13267 } 13268 ); 13269 } 13270 }</script>
vendor: 1 bytes, line 13270
13270
13271<script> 13272 (() => { 13273 document.addEventListener('submit', event => event.target.action = event.target.action.replace('%25uenc%25', hyva.getUenc())); 13274 })()</script>
vendor: 1 bytes, line 13274
13274
13275<script> 13276 (events => { 13277 const dispatchUserInteractionEvent = () => { 13278 events.forEach(type => window.removeEventListener(type, dispatchUserInteractionEvent)) 13279 window.dispatchEvent(new Event('init-external-scripts')) 13280 }; 13281 events.forEach(type => window.addEventListener(type, dispatchUserInteractionEvent, {once: true, passive: true})) 13282 })(['touchstart', 'mousemove', 'wheel', 'scroll', 'keydown']);</script>
vendor: 1 bytes, line 13282
13282
13283<script> 13284 function initConfigurableOptions(productId, optionConfig) { 13285 13286 function findPathParam(key) { 13287 const baseUrl = (BASE_URL.substring(0, 2) === '//' ? 'http:' : '') + BASE_URL; 13288 const baseUrlParts = (new URL(baseUrl)).pathname.replace(/\/$/, '').split('/'); 13289 const pathParts = window.location.pathname.split('/').slice(baseUrlParts.length + 3); 13290 for (let i = 0; i < pathParts.length; i += 2) { 13291 if (pathParts[i] === key && pathParts.length > i) { 13292 return pathParts[i + 1]; 13293 } 13294 } 13295 } 13296 13297 return { 13298 optionConfig, 13299 productId, 13300 itemId: (new URLSearchParams(window.location.search)).get('id') || findPathParam('id'), 13301 allowedAttributeOptions: [], 13302 selectedValues: [], 13303 init() { 13304 this.findAllowedAttributeOptions(); 13305 this.$nextTick(() => { 13306 if (typeof this.optionConfig.defaultValues === 'object') { 13307 for (const [attributeId, value] of Object.entries(this.optionConfig.defaultValues)) { 13308 this.changeOption(attributeId, value + ''); 13309 } 13310 } 13311 this.preselectQuerystringItems(); 13312 this.preselectLocationHashItems(); 13313 }); 13314 }, 13315 productIndex: 0, 13316 productIndexForPrice: 0, 13317 optionIsActive(attributeId, optionId) { 13318 return !!this.getAllowedAttributeOptions(attributeId).find( 13319 option => option.id === optionId 13320 ) 13321 }, 13322 optionIsEnabled(attributeId, optionId) { 13323 for (const productId in this.optionConfig.index) { 13324 if (this.optionConfig.index[productId][attributeId] === optionId) { 13325 return true; 13326 } 13327 } 13328 return false; 13329 }, 13330 findSimpleIndex() { 13331 this.productIndex = this.calculateSimpleIndexForPartialSelection(this.selectedValues); 13332 this.productIndexForPrice = this.findCheapestProductForPartialSelection(this.selectedValues); 13333 }, 13334 calculateSimpleIndexForPartialSelection(selectedValues) { 13335 if (selectedValues.length === 0) return 0; 13336 return this.findProductIdsForPartialSelection(selectedValues)[0]; 13337 }, 13338 calculateSimpleIndexForFullSelection(selectedValues) { 13339 if (! this.isFullSelection(selectedValues)) return false; 13340 13341 const productIndexes = this.optionConfig.index; 13342 return Object.keys(productIndexes).find(productIndex => { 13343 const productCandidateOptions = productIndexes[productIndex]; 13344 13345 for (const productOption in productCandidateOptions) { 13346 if ( 13347 !selectedValues[productOption] || 13348 selectedValues[productOption] !== productCandidateOptions[productOption] 13349 ) { 13350 return false; 13351 } 13352 } 13353 return productIndex; 13354 }); 13355 }, 13356 findAllowedAttributeOptions() { 13357 this.allowedAttributeOptions = this.calculateAllowedAttributeOptions(this.selectedValues); 13358 }, 13359 calculateAllowedAttributeOptions(selectedValues) { 13360 const allAttributes = this.optionConfig.attributes; 13361 const allAttributesSorted = Object.values(allAttributes).sort((a,b) => { 13362 return a.position - b.position 13363 }); 13364 13365 const newAllowedAttributeOptions = []; 13366 13367 allAttributesSorted.forEach(attribute => { 13368 const selectionWithoutAttr = Object.assign({}, this.removeAttrFromSelection(selectedValues, attribute.id)); 13369 const availableIndexes = this.calculateAvailableProductIndexes(selectionWithoutAttr); 13370 newAllowedAttributeOptions[attribute.id] = allAttributes[attribute.id].options.filter(option => { 13371 return !!option.products.find(product => { 13372 return availableIndexes.includes(product); 13373 }) 13374 }); 13375 }); 13376 return newAllowedAttributeOptions; 13377 }, 13378 calculateAvailableProductIndexes(selectedOptions) { 13379 if (Object.keys(selectedOptions).length === 0) { 13380 if (Object.values(this.optionConfig.salable || {}).length) { 13381 return [].concat.apply([], [].concat.apply([], Object.values(this.optionConfig.salable).map(Object.values))).filter((x, i, a) => a.indexOf(x) === i) 13382 } 13383 return Object.keys(this.optionConfig.index); 13384 } 13385 13386 const selectedIds = Object.keys(selectedOptions); 13387 if (Object.values(this.optionConfig.salable || {}).length) { 13388 const selectedOptionIndexes = selectedIds.map(attrId => { 13389 const optionValue = selectedOptions[attrId]; 13390 return this.optionConfig.salable[attrId] && this.optionConfig.salable[attrId][optionValue] || [] 13391 }) 13392 return selectedOptionIndexes.reduce((acc, optionIndexes) => { 13393 return acc.filter(index => optionIndexes.includes(index)); 13394 }); 13395 } else { 13396 const productIndexes = this.optionConfig.index; 13397 return Object.keys(productIndexes).filter(index => { 13398 for (const attrId of selectedIds) { 13399 if (productIndexes[index][attrId] !== `${selectedOptions[attrId]}`) return false 13400 } 13401 return true 13402 }); 13403 } 13404 }, 13405 findAttributeByOptionId(optionId) { 13406 for (const attributeId in this.optionConfig.attributes) { 13407 const attributeOptions = this.optionConfig.attributes[attributeId].options || []; 13408 if (attributeOptions.find(option => option.id === optionId)) { 13409 return attributeId; 13410 } 13411 } 13412 }, 13413 getAllowedAttributeOptions(attributeId) { 13414 return this.allowedAttributeOptions[attributeId] || [] 13415 }, 13416 getAllAttributeOptions(attributeId) { 13417 return ( 13418 this.optionConfig.attributes[attributeId] && 13419 this.optionConfig.attributes[attributeId].options 13420 ) || [] 13421 }, 13422 getProductIdsForOption(option) { 13423 const attributeId = this.findAttributeByOptionId(option.id); 13424 const allOptions = this.optionConfig.attributes[attributeId]; 13425 const opt = (allOptions && allOptions.options || []).find(o => o.id === option.id); 13426 return opt && opt.products 13427 ? opt.products 13428 : []; 13429 }, 13430 findProductIdsForPartialSelection(optionSelection) { 13431 const candidateProducts = Object.values(optionSelection).reduce((candidates, optionId) => { 13432 const newCandidates = this.getProductIdsForOption({id: optionId}); 13433 return candidates === null 13434 ? newCandidates 13435 : candidates.filter(productId => newCandidates.includes(productId)); 13436 }, null); 13437 return candidateProducts || []; 13438 },
13439 findCheapestProductForPartialSelection(optionSelection) { 13440 const candidateProducts = this.findProductIdsForPartialSelection(optionSelection); 13441 return candidateProducts.reduce((cheapest, simpleIdx) => { 13442 // in the first iteration we start with simpleIdx as the currently cheapest product 13443 if (! this.optionConfig.optionPrices[cheapest]) return simpleIdx; 13444 const knownCheapestPrice = this.optionConfig.optionPrices[cheapest].finalPrice.amount; 13445 return knownCheapestPrice > this.optionConfig.optionPrices[simpleIdx].finalPrice.amount 13446 ? simpleIdx 13447 : cheapest; 13448 }, 0) 13449 }, 13450 findProductIdToUseForOptionPrice(option) { 13451 // try to find a product for a complete selection 13452 const attributeId = this.findAttributeByOptionId(option.id); 13453 const optionSelection = Object.assign({}, this.selectedValues, {[attributeId]: option.id}); 13454 const matchingSimpleIndex = this.calculateSimpleIndexForFullSelection(optionSelection); 13455 // if there is no complete selection, use the cheapest product for the option 13456 return matchingSimpleIndex || this.findCheapestProductForPartialSelection(optionSelection); 13457 }, 13458 getAttributeOptionLabel(option) { 13459 const optionProduct = this.findProductIdToUseForOptionPrice(option); 13460 13461 if ((! optionProduct) || (optionProduct === this.productIndexForPrice)) { 13462 return option.label; 13463 } 13464 13465 const currentPrice = this.getOptionPriceAdjustmentBasePrice(); 13466 13467 if (this.optionConfig.optionPrices[optionProduct]) { 13468 const optionPrice = this.optionConfig.optionPrices[optionProduct].finalPrice.amount; 13469 if (optionPrice !== currentPrice){ 13470 return option.label + ' ' + hyva.formatPrice(optionPrice - currentPrice, true); 13471 } 13472 } 13473 return option.label; 13474 }, 13475 getOptionPriceAdjustmentBasePrice() { 13476 if (this.optionConfig.optionPrices[this.productIndexForPrice]) { 13477 return this.optionConfig.optionPrices[this.productIndexForPrice].finalPrice.amount 13478 } 13479 return this.optionConfig.prices.finalPrice.amount; // default price if no option selection 13480 }, 13481 clearOptionIfActive(optionId, value) { 13482 if (this.selectedValues[optionId] === value) { 13483 this.blurLabel() 13484 this.changeOption(optionId, '') 13485 } 13486 }, 13487 removeAttrFromSelection(selectedValues, attributeId) { 13488 attributeId = parseInt(attributeId); 13489 return selectedValues.reduce((newSelection, val, attr) => { 13490 if (attr !== attributeId) { 13491 newSelection[attr] = val; 13492 } 13493 return newSelection; 13494 }, []); 13495 }, 13496 changeOption(attributeId, value) { 13497 if (value === '') { 13498 this.selectedValues = this.removeAttrFromSelection(this.selectedValues, attributeId) 13499 } else if (value && this.getAllowedAttributeOptions(attributeId).find(option => option.id === value)) { 13500 this.selectedValues[attributeId] = value; 13501 } 13502 this.findSimpleIndex(); 13503 this.findAllowedAttributeOptions(); 13504 this.updatePrices(); 13505 this.updateGallery(); 13506 13507 const candidates = this.findProductIdsForPartialSelection(this.selectedValues); 13508 13509 window.dispatchEvent( 13510 new CustomEvent( 13511 'configurable-selection-changed', 13512 { 13513 detail: { 13514 productId: this.productId, 13515 optionId: attributeId, 13516 value: value, 13517 productIndex: this.productIndex, 13518 selectedValues: this.selectedValues, 13519 candidates: candidates, 13520 skuCandidates: Object.values(candidates).map(id =>
13520 this.optionConfig.sku?.[id] ?? null).filter(Boolean), 13521 } 13522 } 13523 ) 13524 ); 13525 }, 13526 calculateIsMinimalPrice() { 13527 return ! this.isFullSelection(this.selectedValues); 13528 }, 13529 isFullSelection(selectedValues) { 13530 return Object.values(selectedValues).length === Object.keys(this.optionConfig.attributes).length; 13531 }, 13532 updatePrices() { 13533 const value = this.optionConfig.optionPrices[this.productIndexForPrice] || this.optionConfig.prices; 13534 window.dispatchEvent( 13535 new CustomEvent( 13536 "update-prices-" + this.productId, 13537 { 13538 detail: Object.assign( 13539 value, 13540 { isMinimalPrice: this.calculateIsMinimalPrice() } 13541 ) 13542 } 13543 ) 13544 ); 13545 }, 13546 updateGallery () { 13547 if (this.productIndex) { 13548 const images = this.optionConfig.images[this.productIndex]; 13549 images && window.dispatchEvent(new CustomEvent( 13550 "update-gallery", 13551 { detail: this.sortImagesByPosition(images) } 13552 )); 13553 } else { 13554 window.dispatchEvent(new Event("reset-gallery")); 13555 } 13556 }, 13557 sortImagesByPosition(images) { 13558 return images.sort((x, y) => { 13559 return x.position === y.position ? 0 : (parseInt(x.position) > parseInt(y.position) ? 1 : -1) 13560 }); 13561 }, 13562 onGetCartData(data) { 13563 }, 13564 preselectCartItems(data) { 13565 // pre-select options based on cart data for current (quote) itemId 13566 const cart = data && data.cart; 13567 if (cart && cart.items) { 13568 const cartItem = cart.items.find((item) => { 13569 return ( 13570 item.item_id === this.itemId 13571 && item.product_id === this.productId 13572 ) 13573 }); 13574 if (cartItem && cartItem.options && cartItem.options.length) { 13575 cartItem.options.map(option => { 13576 this.changeOption(option.option_id, option.option_value); 13577 }) 13578 } 13579 } 13580 }, 13581 preselectQuerystringItems() { 13582 // pre-select option like ?size=167 13583 const urlQueryParams = new URLSearchParams(window.location.search.replace('?','')); 13584 this.preselectItemsBasedOnLocation(attribute => urlQueryParams.get(attribute.code)); 13585 }, 13586 preselectLocationHashItems() { 13587 // pre-select option like #144=167 13588 const urlHashParams = new URLSearchParams(window.location.hash.replace('#','')); 13589 this.preselectItemsBasedOnLocation(attribute => urlHashParams.get(attribute.id)); 13590 }, 13591 preselectItemsBasedOnLocation(getLocationValue) { 13592 Object.values(this.optionConfig.attributes).map(attribute => { 13593 const v = getLocationValue(attribute); 13594 v && this.changeOption(attribute.id, v) 13595 }); 13596 } 13597 } 13598 } 13599</script>
vendor: 1 bytes, line 13599
13599
13600<script> 13601 function initSwatchOptions(swatchConfig) { 13602 return { 13603 swatchConfig, 13604 getAttributeSwatchData(attributeId) { 13605 const swatchConfig = Object.assign({}, this.swatchConfig[attributeId]); 13606 swatchConfig['details'] = JSON.parse(swatchConfig['additional_data']); 13607 13608 return swatchConfig; 13609 }, 13610 mapSwatchTypeNumberToTypeCode(typeNumber) { 13611 switch ("" + typeNumber) { 13612 case "1": 13613 return "color" 13614 case "2": 13615 return "image" 13616 case "3": 13617 return "empty" 13618 case "0": 13619 default: 13620 return "text" 13621 } 13622 }, 13623 getTypeOfFirstOption(attributeId) { 13624 for (const optionId in this.swatchConfig[attributeId]) { 13625 const option = this.swatchConfig[attributeId][optionId]; 13626 if (typeof option.type !== 'undefined') { 13627 return this.mapSwatchTypeNumberToTypeCode(option.type); 13628 } 13629 } 13630 }, 13631 getVisualSwatchType(attributeId, targetOptionId) { 13632 // If a type configuration is present for the given option id, use it 13633 const config = this.swatchConfig[attributeId]; 13634 if (config[targetOptionId] && typeof config[targetOptionId].type !== 'undefined') { 13635 return this.mapSwatchTypeNumberToTypeCode(config[targetOptionId].type); 13636 } 13637 13638 // Otherwise - if no config is present for the target option - use the type of the first option 13639 // with a type property from the attribute, thus assuming its the same type as the target option. 13640 // (This edge case condition can occur on single swatch products if some options are not salable) 13641 return this.getTypeOfFirstOption(attributeId); 13642 }, 13643 getSwatchType(attributeId, optionId) { 13644 // Deserialize the attribute details the first time they are used 13645 if (this.swatchConfig[attributeId] && ! this.swatchConfig[attributeId].details) { 13646 this.swatchConfig[attributeId] = this.getAttributeSwatchData(attributeId); 13647 } 13648 const type = this.swatchConfig[attributeId] && 13649 this.swatchConfig[attributeId].details && 13650 this.swatchConfig[attributeId].details.swatch_input_type || 13651 "empty"; 13652 return type === 'visual' ? this.getVisualSwatchType(attributeId, optionId) : type; 13653 }, 13654 isTextSwatch(attributeId, optionId) { 13655 return this.getSwatchType(attributeId, optionId) === 'text'; 13656 }, 13657 isVisualSwatch(attributeId, optionId) { 13658 const type = this.getSwatchType(attributeId, optionId); 13659 13660 return ['image', 'color'].includes(type); 13661 }, 13662 getSwatchBackgroundStyle(attributeId, optionId) { 13663 const config = this.getSwatchConfig(attributeId, optionId); 13664 const type = this.getSwatchType(attributeId, optionId); 13665 13666 if (type === "color") { 13667 return 'background-color:' + config.value; 13668 } else if (type === "image") { 13669 return "background: #fff url('" + config.value + "') no-repeat center"; 13670 } else { 13671 return ''; 13672 } 13673 }, 13674 getSwatchText(attributeId, optionId) { 13675 const config = this.getSwatchConfig(attributeId, optionId); 13676 return config.label || config.value || this.getOptionLabelFromOptionConfig(attributeId, optionId); 13677 }, 13678 getOptionLabelFromOptionConfig(attributeId, optionId) { 13679 // Fallback if no value is present in swatchConfig data 13680 // Reference issue https://gitlab.hyva.io/hyva-themes/magento2-default-theme/-/issues/190 13681 const option = this.getAllAttributeOptions(attributeId).filter(option => option.id === optionId); 13682 return option && option[0] && option[0].label ||''; 13683 }, 13684 getSwatchConfig(attributeId, optionId) { 13685 return this.swatchConfig[attributeId] && this.swatchConfig[attributeId][optionId] 13686 ? this.swatchConfig[attributeId][optionId] 13687 : false;
13688 }, 13689 activeTooltipItem: false, 13690 tooltipPositionElement: false, 13691 isTooltipVisible() { 13692 return this.activeTooltipItem && 13693 this.getSwatchConfig( 13694 this.activeTooltipItem.attribute, 13695 this.activeTooltipItem.item 13696 ); 13697 }, 13698 isFirstItemCol() { 13699 return this.activeTooltipItem.index === 0; 13700 }, 13701 getTooltipImageStyle(attributeId, optionId) { 13702 const config = this.getSwatchConfig(attributeId, optionId); 13703 const type = this.getSwatchType(attributeId, optionId); 13704 13705 if (type === "color") { 13706 return 'background-color:' + config.value + '; width: 110px; height: 90px;'; 13707 } else if (type === "image") { 13708 return "background: #ffffff url('" + config.thumb + 13709 "') center center no-repeat; width: 110px; height: 90px;"; 13710 } else { 13711 return 'display:none'; 13712 } 13713 }, 13714 getTooltipPosition() { 13715 return this.tooltipPositionElement ? 13716 `top: ${this.tooltipPositionElement.offsetTop}px;` + 13717 `left: ${ 13718 this.tooltipPositionElement.offsetLeft - ( 13719 this.tooltipPositionElement.closest('.snap') && 13720 this.tooltipPositionElement.closest('.snap').scrollLeft || 13721 0 13722 ) 13723 }px;` : '' 13724 }, 13725 getTooltipLabel() { 13726 return this.getSwatchConfig(this.activeTooltipItem.attribute, this.activeTooltipItem.item).label 13727 }, 13728 focusedLabel: false, 13729 focusLabel(optionId) { 13730 this.focusedLabel = optionId; 13731 }, 13732 blurLabel() { 13733 this.focusedLabel = false; 13734 } 13735 } 13736 } 13737</script>
vendor: 1 bytes, line 13737
13737
13738<script> 13739 'use strict'; 13740 13741 const grecaptchaV2LoadCallbacks = []; 13742 13743 function executeRecaptchaLoadCallbacks () { 13744 while (window.grecaptcha && grecaptchaV2LoadCallbacks.length > 0) { 13745 const callback = grecaptchaV2LoadCallbacks.pop(); 13746 typeof callback === 'string' ? window[callback]() : callback(); 13747 } 13748 } 13749 13750 (function() { 13751 const loadRecaptchaScript = (event) => { 13752 13753 if (window.grecaptcha || !event.target.form) { 13754 return; 13755 } 13756 13757 const url = 'https://www.google.com/recaptcha/api.js?onload=executeRecaptchaLoadCallbacks'; 13758 const siteKey = '6LfHDCMrAAAAACnDJl581eICSW3VnauItgp_hR2S'; 13759 const script = document.createElement('script'); 13760 script.type = 'text/javascript'; 13761 script.src = siteKey ? `${url}&render=${siteKey}` : `${url}&render=explicit`; 13762 script.async = true; 13763 document.head.appendChild(script); 13764 13765 script.addEventListener('load', () => { 13766 Array.from(document.querySelectorAll('button[data-recaptcha-btn]:disabled')).forEach(btn => btn.removeAttribute('disabled')); 13767 }); 13768 } 13769 13770 window.forceLoadRecaptchaScript = (form) => { 13771 loadRecaptchaScript({target: {form: form || 'dummy'}}); 13772 executeRecaptchaLoadCallbacks(); 13773 }; 13774 13775 document.body.addEventListener('input', loadRecaptchaScript, { once: true }); 13776 document.body.addEventListener('focus', loadRecaptchaScript, { once: true }); 13777 13778 }()); 13779 13780</script>
vendor: 1 bytes, line 13780
13780
13781<script> 13782 (function (w, d, s, l, i) { 13783 w[l] = w[l] || []; w[l].push({ 13784 'gtm.start': 13785 new Date().getTime(), event: 'gtm.js' 13786 }); var f = d.getElementsByTagName(s)[0], 13787 j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src = 13788 'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f); 13789 })(window, document, 'script', 'dataLayer', 'GTM\u002D5VC2G8L'); 13790</script>
vendor: 1 bytes, line 13790
13790
13791<script> 13792 'use strict'; 13793 13794 function initAmInitConfigurableSwatchOptions() { 13795 const productId = this.$el.dataset.productId ?? this.$el.closest('form')?.querySelector('input[name="product"]').value; 13796 const component = window['initConfigurableSwatchOptions'] ?? window['initConfigurableSwatchOptions_' + productId] 13797 const originInitConfigurableSwatchOptions = component.call(this); 13798 13799 return { 13800 ...originInitConfigurableSwatchOptions, 13801 init() { 13802 if (this.showSwatches !== undefined) { 13803 this.$watch('showSwatches', value => { 13804 if (value) { 13805 this.dispatchConfigurableShowEvent(); 13806 } 13807 }); 13808 } else { 13809 this.$nextTick(() => { 13810 this.dispatchConfigurableShowEvent(); 13811 }); 13812 } 13813 13814 this.findAllowedAttributeOptions(); 13815 this.$nextTick(() => { 13816 if (typeof this.optionConfig.defaultValues === 'object') { 13817 for (const [attributeId, value] of Object.entries(this.optionConfig.defaultValues)) { 13818 this.changeOption(attributeId, value + ''); 13819 } 13820 } 13821 }); 13822 }, 13823 13824 dispatchConfigurableShowEvent() { 13825 window.dispatchEvent(new CustomEvent('configurable-show-swatches', { 13826 detail: { 13827 productId: this.productId, 13828 element: this.$el 13829 } 13830 })); 13831 } 13832 } 13833 } 13834 13835 window.addEventListener('alpine:init', () => { 13836 Alpine.data('initAmInitConfigurableSwatchOptions', initAmInitConfigurableSwatchOptions); 13837 }, {once: true});</script>
vendor: 1 bytes, line 13837
13837
13838<script type="text/json" id="default-section-data"> 13839 {"messages":[],"customer":[],"compare-products":[],"last-ordered-items":[],"requisition":[],"cart":[],"directory-data":{"GB":{"name":"United Kingdom"},"data_id":1790273241},"captcha":[],"wishlist":{"items":[]},"company":[],"company_authorization":[],"customer-companies":[],"negotiable_quote":[],"instant-purchase":[],"loggedAsCustomer":[],"multiplewishlist":[],"purchase_order":[],"persistent":[],"review":[],"payments":[],"amasty-storepickup-data":[],"apptrian_metapixelapi_matching_section":[],"webforms":[],"hyva_checkout":[],"chatData":[],"recently_viewed_product":[],"recently_compared_product":[],"product_data_storage":[],"paypal-billing-agreement":[],"paypal-buyer-country":[]}</script>
vendor: 1 bytes, line 13839
13839
13840<script> 13841 'use strict'; 13842 13843 function attributeIcon() { 13844 return { 13845 labelledById: '', 13846 13847 init() { 13848 const timestamp = Date.now(); 13849 const randomNum = Math.floor(Math.random() * 1000); 13850 this.labelledById = `amshopby-option-id-${timestamp}-${randomNum}`; 13851 } 13852 } 13853 } 13854 window.addEventListener( 13855 'alpine:init', 13856 () => Alpine.data('attributeIcon',attributeIcon), 13857 {once: true} 13858 );</script>
vendor: 1 bytes, line 13858
13858
13859<script> 13860document.addEventListener('alpine:init', () => { 13861 Alpine.data('newsletterForm', () => ({ 13862 firstname: '', 13863 lastname: '', 13864 email: '', 13865 errors: {}, 13866 13867 validateField(field) { 13868 this.errors[field] = ''; 13869 13870 if (field === 'firstname' && !this.firstname.trim()) { 13871 this.errors.firstname = 'First\u0020Name\u0020is\u0020required.'; 13872 } 13873 13874 if (field === 'lastname' && !this.lastname.trim()) { 13875 this.errors.lastname = 'Last\u0020Name\u0020is\u0020required.'; 13876 } 13877 13878 if (field === 'email') { 13879 if (!this.email.trim()) { 13880 this.errors.email = 'Email\u0020is\u0020required.'; 13881 } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.email)) { 13882 this.errors.email = 'Please\u0020enter\u0020a\u0020valid\u0020email\u0020address.'; 13883 } 13884 } 13885 }, 13886 13887 validateForm() { 13888 this.validateField('firstname'); 13889 this.validateField('lastname'); 13890 this.validateField('email'); 13891 return Object.values(this.errors).every(error => error === ''); 13892 }, 13893 13894 submitForm() { 13895 const form = document.querySelector('#newsletter-validate-detail'); 13896 13897 if (this.validateForm()) { 13898 form.submit(); 13899 } 13900 } 13901 })); 13902}); 13903</script>
vendor: 1 bytes, line 13903
13903
13904<script type="text/x-magento-init"> 13905 { 13906 ".popup-newsletter": { 13907 "newsletterPopup": { 13908 13909 "delay":"40", 13910 "closing":"5" 13911 } 13912 } 13913 }</script>
vendor: 1 bytes, line 13913
13913
13914<script type="text/x-magento-init">{"*": 13915 {"Magento_Persistent/js/remember-me-config": { 13916 "config": {"persistenceConfig":{"isRememberMeCheckboxVisible":true,"isRememberMeCheckboxChecked":true}} 13917 }}}</script>
13917 13918</body> 13919</html>
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.