1function onSubmitBookingContactForm(token) { 2 const form = document.getElementById("BookingContactForm"); 3 const formData = new FormData(form); 4 formData.append('g-recaptcha-response', token); 5 6 formData.delete('Documents'); 7 uploadedDocuments.forEach(file => { 8 formData.append('Documents', file); 9 }); 10 11 const submitButton = form.querySelector(".btn-booking-contact-form"); 12 13 resetErrorStyles(); 14 disableButton(submitButton); 15 16 fetch('/umbraco/surface/bookingcontactform/submit', { 17 method: "POST", 18 body: formData, 19 }) 20 .then(response => response.json()) 21 .then(data => { 22 if (data.success) { 23 const service = document.querySelector('select[name="BookingService"]')?.value || 24 document.getElementById('hiddenBookingService')?.value || 'â'; 25 26 document.getElementById('successService').textContent = service; 27 document.getElementById('successDate').textContent = 28 document.querySelector('[name="BookingArrivalDate"]')?.value || ''; 29 document.getElementById('successName').textContent = 30 document.querySelector('[name="BookingName"]')?.value || 'â'; 31 document.getElementById('successEmail').textContent = 32 document.querySelector('[name="BookingEmail"]')?.value || 'â'; 33 document.getElementById('successMessage').textContent = 34 document.querySelector('[name="BookingMessage"]')?.value || 'â'; 35 36 form.reset(); 37 showStep(4); 38 resetErrorStyles(); 39 } else { 40 if (Object.keys(data.errors || {}).length !== 0) { 41 for (const [field, error] of Object.entries(data.errors)) { 42 const fieldInputElement = document.querySelector(`[name="${field}"]`); 43 if (fieldInputElement) { 44 fieldInputElement.classList.add('is-invalid'); 45 attachInputEventListener(fieldInputElement); 46 } 47 } 48 } 49 enableButton(submitButton); 50 } 51 }) 52 .catch(error => { 53 enableButton(submitButton); 54 }); 55} 56 57function resetErrorStyles() { 58 const inputsWithError = document.querySelectorAll('.is-invalid'); 59 inputsWithError.forEach(input => { 60 input.classList.remove('is-invalid'); 61 }); 62} 63 64function attachInputEventListener(inputElement) { 65 inputElement.removeEventListener('input', removeErrorBorder); 66 inputElement.addEventListener('input', removeErrorBorder); 67} 68 69function removeErrorBorder(event) { 70 event.target.classList.remove('is-invalid'); 71} 72 73function disableButton(button) { 74 button.disabled = true; 75 button.classList.add("disabled"); 76} 77 78function enableButton(button) { 79 button.disabled = false; 80 button.classList.remove("disabled"); 81} 82 83document.addEventListener('click', function (e) { 84 const btn = e.target.closest('.btn-booking-contact-form'); 85 if (!btn) return; 86 const siteKey = btn.dataset.sitekey; 87 grecaptcha.enterprise.ready(function () { 88 grecaptcha.enterprise.execute(siteKey, { action: 'submit' }) 89 .then(function (token) { 90 onSubmitBookingContactForm(token); 91 }); 92 }); 93});
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.