/
engineunity_sub
/
doxml_work_site
Обзор
Документация
Войти
/
engineunity_sub
/
doxml_work_site
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
master
src/js/form.js
214 строк
9 KB
PauloChaser
move content from branch dev to master
12 фев 2025, 18:06
12 фев 2025, 18:06
a2e2735
Код
Авторство
О чём код?
export function initForm(){ const resultModal = document.getElementById('result-modal'); const forms = { registrationForm: { id: 'registration-form', url: 'https://appdev.doxml.ru/v1/applications', successMessage: `<h2 class="modal__title title title--h2">Ваша заявка принята!</h2> <p class="modal__text text text--p3">В день утверждения XML-схемы для заданий на проектирование, Вы получите соответствующее уведомление и ссылку на регистрацию в сервисе. <br>При регистрации по ссылке из письма, месяц бесплатного доступа на вашем аккаунте будет активирован автоматически</p>`, }, footerForm: { id: 'form-footer-callback', url: 'https://appdev.doxml.ru/v1/footer-callback', successMessage: `<h2 class="modal__title title title--h2">Спасибо за обращение!</h2> <p class="modal__text text text--p3">Мы свяжемся с вами в самое ближайшее время.</p>`, }, contactsForm: { id: 'form-contacts', url: 'https://appdev.doxml.ru/v1/contacts-callback', successMessage: `<h2 class="modal__title title title--h2">Спасибо за обращение!</h2> <p class="modal__text text text--p3">Мы свяжемся с вами в самое ближайшее время.</p>`, }, feedbackForm: { id: 'feedback-form', url: 'https://appdev.doxml.ru/v1/feedback', successMessage: `<h2 class="modal__title title title--h2">Спасибо за Вашу обратную связь!</h2> <p class="modal__text text text--p3">Мы обязательно рассмотрим Ваше предложение и передадим Ваши пожелания разработчикам</p>`, }, }; let captchaWidgetId = null; let countdownTimer = null; // Маска для телефона с использованием iMask const phoneInputs = document.querySelectorAll('[name="phone"], [name="footer-phone"]'); phoneInputs.forEach(input => { IMask(input, { mask: '+{7} (000) 000-00-00', }); }); // Валидация function validateInput(input) { const value = input.value.trim(); const name = input.name; if (input.tagName === 'textarea') { return value.length > 5; // } if (name === 'phone' || name === 'footer-phone') { return input.value.replace(/[^0-9]/g, '').length > 8; } if (name === 'name') { return value.length > 1; // Минимум 2 символа } if (name === 'email') { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(value); // Проверка формата email } // if (input.type === 'checkbox' || input.type === 'radio') { // return input.checked; // } return value.length > 0; } function showValidationErrors(inputs) { inputs.forEach(input => { const isValid = validateInput(input); input.classList.toggle('error', !isValid); }); } function validateForm(inputs) { return Array.from(inputs).every(validateInput); } // Функция для добавления/удаления класса loading function toggleLoadingState(form, isLoading) { const submitButton = form.querySelector('.js-submit-button'); if (submitButton) { submitButton.classList.toggle('loading', isLoading); } } async function sendFormData({id, url, successMessage}) { const form = document.getElementById(id); const formData = new FormData(form); try { const response = await fetch(url, { method: 'POST', headers: {accept: 'application/json'}, body: formData, }); // console.log('resp:', response); if (response.ok) { displayResultModal(successMessage); form.reset(); toggleLoadingState(form, false); } else if (response.status === 422) { const messageReRegistration = `<h2 class="modal__title title title--h2">Вы уже подавали заявку!</h2> <p class="modal__text text text--p3">В день утверждения XML-схемы для заданий на проектирование, Вы получите соответствующее уведомление и ссылку на регистрацию в сервисе. <br>При регистрации по ссылке из письма, месяц бесплатного доступа на вашем аккаунте будет активирован автоматически</p>`; displayResultModal(messageReRegistration); form.reset(); } else { throw new Error('Ошибка сервера'); } } catch { displayResultModal('Ошибка при отправке формы.'); } finally { toggleLoadingState(form, false); } } async function captchaCallback(token, formConfig) { console.log('ты внутри captchaCallback'); try { console.log('зашел в try'); const response = await fetch('https://appdev.doxml.ru/v1/captcha', { method: 'POST', headers: {accept: 'application/json', 'Content-Type': 'application/json'}, body: JSON.stringify({token}), }); const result = await response.json(); // console.log(result,); if (result.success) { await sendFormData(formConfig); } else { displayResultModal('Ошибка проверки капчи. Попробуйте ещё раз.'); } } catch { displayResultModal('Ошибка сети при проверке капчи.'); } } function initializeCaptcha(formConfig) { const form = document.getElementById(formConfig.id); toggleLoadingState(form, true); const captchaContainer = form.querySelector('.form__captchaContainer'); captchaContainer.innerHTML = ''; const captchaCallbackWithFormConfig = (token) => { captchaCallback(token, formConfig); }; captchaWidgetId = window.smartCaptcha.render(captchaContainer, { sitekey: 'ysc1_VZNlGpvO3vXsOccnlSfard41FM9PEeI2QFi0AgEQfb2f3ef4', invisible: true, callback: (token) => captchaCallback(token, formConfig), 'error-callback': (error) => { console.error("Ошибка в smartCaptcha:", error); }, hideShield: true, }); // Принудительно вызываем каптчу, так как была проблема с вызовом callback с передачей туда formConfig, решения не смог найти window.smartCaptcha.execute(captchaWidgetId); } // Привязка событий к каждой форме Object.values(forms).forEach((formConfig) => { const form = document.getElementById(formConfig.id); if (form) { const inputs = form.querySelectorAll('input, textarea'); form.addEventListener('submit', async (e) => { e.preventDefault(); // console.log('form::',form); // console.log('e::',e); showValidationErrors(inputs); if (!validateForm(inputs)) return; initializeCaptcha(formConfig); }); inputs.forEach(input => { input.addEventListener('input', () => input.classList.remove('error')); }); } }); // Модальное окно результата с таймером function displayResultModal(message, success = false) { const modalContent = resultModal.querySelector('.modal__content'); modalContent.innerHTML = ` <h2 class="modal__title title title--h2">${message}</h2> <span class="modal__countdown text text--p3 text--gray">Окно закроется через <span id="countdown">5</span></span> `; resultModal.style.display = 'flex'; history.pushState(null, null, '#result-modal'); let countdown = 5; const countdownEl = document.getElementById('countdown'); countdownTimer = setInterval(() => { countdown -= 1; countdownEl.textContent = countdown; if (countdown <= 0) { clearInterval(countdownTimer); resultModal.style.display = 'none'; history.pushState("", document.title, window.location.pathname); } }, 1000); } }